diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000000..2e71b1533092 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,7 @@ +root = true + +[*.{jelly, js, less, css, hbs}] +indent_style = space +indent_size = 2 +trim_trailing_whitespace = true +insert_final_newline = true diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 6880e3d1e3cc..3e279801d2f1 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,2 +1,2 @@ community_bridge: jenkins -custom: ["https://jenkins.io/donate/#why-donate"] +custom: ["https://www.jenkins.io/donate/#why-donate"] diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 1b3f1e7e5c6f..73ffa0896a39 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,7 +1,7 @@ See [JENKINS-XXXXX](https://issues.jenkins-ci.org/browse/JENKINS-XXXXX). @@ -19,7 +19,10 @@ If the issue is not fully described in the ticket, add more information here (ju * ... +The changelogs will be integrated by the core maintainers after the merge. +The changelog entry should be in the imperative mood; e.g., write "do this"/"return that" rather than "does this"/"returns that". +For examples, see: https://www.jenkins.io/changelog/ +--> ### Proposed upgrade guidelines @@ -28,9 +31,10 @@ N/A ### Submitter checklist - [ ] (If applicable) Jira issue is well described -- [ ] Changelog entries and upgrade guidelines are appropriate for the audience affected by the change (users or developer, depending on the change). [Examples](https://github.com/jenkins-infra/jenkins.io/blob/master/content/_data/changelogs/weekly.yml) +- [ ] Changelog entries and upgrade guidelines are appropriate for the audience affected by the change (users or developer, depending on the change) and are in the imperative mood. [Examples](https://github.com/jenkins-infra/jenkins.io/blob/master/content/_data/changelogs/weekly.yml) * Fill-in the `Proposed changelog entries` section only if there are breaking changes or other changes which may require extra steps from users during the upgrade - [ ] Appropriate autotests or explanation to why this change has no tests +- [ ] New public classes, fields, and methods are annotated with `@Restricted` or have `@since TODO` Javadoc, as appropriate. - [ ] For dependency updates: links to external changelogs and, if possible, full diffs @@ -49,7 +53,7 @@ Before the changes are marked as `ready-for-merge`: - [ ] There are at least 2 approvals for the pull request and no outstanding requests for change - [ ] Conversations in the pull request are over OR it is explicit that a reviewer does not block the change -- [ ] Changelog entries in the PR title and/or `Proposed changelog entries` are correct +- [ ] Changelog entries in the PR title and/or `Proposed changelog entries` are accurate, human-readable, and in the imperative mood - [ ] Proper changelog labels are set so that the changelog can be generated automatically - [ ] If the change needs additional upgrade steps from users, `upgrade-guide-needed` label is set and there is a `Proposed upgrade guidelines` section in the PR title. ([example](https://github.com/jenkinsci/jenkins/pull/4387)) - [ ] If it would make sense to backport the change to LTS, a Jira issue must exist, be a _Bug_ or _Improvement_, and be labeled as `lts-candidate` to be considered (see [query](https://issues.jenkins-ci.org/issues/?filter=12146)). diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 53f2fdc8732e..2598142fdb15 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -12,22 +12,22 @@ updates: # see https://github.com/jenkinsci/jenkins/pull/5112#issuecomment-744429487 and https://github.com/jenkinsci/jenkins/pull/5116#issuecomment-744526638 # it would be good to update it at some point, but requires significant testing - dependency-name: "org.codehaus.groovy:groovy-all" + versions: [">=2.5.0"] # see https://github.com/jenkinsci/jenkins/pull/5184 should be updated with groovy-all - dependency-name: "org.fusesource.jansi:jansi" # see https://github.com/jenkinsci/jenkins/pull/5144#pullrequestreview-559661934 # will require source code changes to replace javax.mail with jakarta.mail # and some handling for plugins that depend on javax.mail being provided by Jenkins core. - dependency-name: "com.sun.mail:jakarta.mail" - # needs updates in a number of plugins, see https://github.com/jenkinsci/jenkins/pull/5059 and https://github.com/jenkinsci/bom/pull/392 - - dependency-name: "com.google.guava:*" # this is a banned dependency, we have a hack in our pom to prevent anyone else pulling it in - dependency-name: "javax.servlet.servlet-api" # needs a jakarta upgrade project, imports changed - dependency-name: "jakarta.servlet.jsp.jstl.jakarta.servlet.jsp.jstl-api" + # Starting with version 2.0.2, this library requires Java 11 + - dependency-name: "org.glassfish.tyrus.bundles:tyrus-standalone-client-jdk" + versions: [">=2.0.2"] # see https://github.com/jenkinsci/jenkins/pull/4224 can't be updated without breaking api - dependency-name: "org.jfree:jfreechart" - # needs guava upgrades first https://github.com/jenkinsci/jenkins/pull/5200#pullrequestreview-579741619 - - dependency-name: "com.google.inject:guice" # the dependency is actually provided by the Web container, hence it is aligned with Jetty. See https://github.com/jenkinsci/jenkins/pull/5211 - dependency-name: "javax.servlet:javax.servlet-api" # log4j 1.2.17 is the final 1.x release @@ -36,4 +36,9 @@ updates: - dependency-name: "org.jenkins-ci:symbol-annotation" # Must remain within jetty 9.x until Java 8 support is removed, ignore jetty 10.x and jetty 11.x updates - dependency-name: "org.eclipse.jetty:jetty-maven-plugin" - versions: ["10.x", "11.x"] + versions: [">=10.0.0"] + # Winstone upgrades require multiple changes in pom.xml. See https://github.com/jenkinsci/jenkins/pull/5439#discussion_r616418468 + - dependency-name: "org.jenkins-ci:winstone" + # Starting with version 10.0, this library requires Java 11 + - dependency-name: "com.puppycrawl.tools:checkstyle" + versions: [">=10.0"] diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml index c716bd42ff96..9013d1a82412 100644 --- a/.github/release-drafter.yml +++ b/.github/release-drafter.yml @@ -6,9 +6,8 @@ name-template: $NEXT_MINOR_VERSION tag-template: jenkins-$NEXT_MINOR_VERSION template: | - **Disclaimer**: This is an automatically generated changelog draft for Jenkins weekly releases. - See https://jenkins.io/changelog/ for the official changelogs. - For `changelog.yaml` drafts see GitHub action artifacts attached to release commits. + _This is an automatically generated changelog draft for Jenkins weekly releases. + See https://www.jenkins.io/changelog/ for the official changelogs._ $CHANGES diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml index 601bd7d1cd21..10007762203c 100644 --- a/.github/workflows/changelog.yml +++ b/.github/workflows/changelog.yml @@ -3,6 +3,7 @@ name: Changelog Drafter on: + workflow_dispatch: push: # branches to consider in the event; optional, defaults to all branches: @@ -10,34 +11,50 @@ on: jobs: update_draft_release: + if: github.repository_owner == 'jenkinsci' runs-on: ubuntu-latest steps: # Drafts your next Release notes as Pull Requests are merged into "master" - name: Generate GitHub Release Draft id: release-drafter - uses: release-drafter/release-drafter@v5.15.0 + uses: release-drafter/release-drafter@v5.19.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Generates a YAML changelog file using https://github.com/jenkinsci/jenkins-core-changelog-generator + # used by Oleg N in open graph generator experiment for now - name: Generate YAML changelog draft id: jenkins-core-changelog-generator uses: jenkinsci/jenkins-core-changelog-generator@master env: GITHUB_AUTH: github-actions:${{ secrets.GITHUB_TOKEN }} - name: Upload Changelog YAML - uses: actions/upload-artifact@v2.2.3 + uses: actions/upload-artifact@v3 with: name: changelog.yaml path: changelog.yaml -#TODO(oleg-nenashev): It will not work well with Release Drafter which does not recreated releases. Asset does not get overwritten, and there is no ready-to-go API for overriding assets - # Upload YAML to the release draft assets -# - name: Upload changelog.yaml to the Release Draft -# id: upload-changelog-yaml -# uses: actions/upload-release-asset@v1.0.1 -# env: -# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} -# with: -# upload_url: ${{ steps.release-drafter.outputs.upload_url }} -# asset_path: ./changelog.yaml -# asset_name: changelog.yaml -# asset_content_type: text/yaml + + jenkins_io_draft: + runs-on: ubuntu-latest + if: github.repository_owner == 'jenkinsci' + steps: + - uses: tibdex/github-app-token@v1 + id: generate-token + with: + app_id: ${{ secrets.JENKINS_CHANGELOG_UPDATER_APP_ID }} + private_key: ${{ secrets.JENKINS_CHANGELOG_UPDATER_PRIVATE_KEY }} + repository: jenkins-infra/jenkins.io + - name: Check out + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Publish jenkins.io changelog draft + env: + GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }} + GITHUB_AUTH: "nobody:${{ steps.generate-token.outputs.token }}" + GIT_AUTHOR_NAME: jenkins-infra-changelog-generator + GIT_AUTHOR_EMAIL: <86592549+jenkins-infra-changelog-generator[bot]@users.noreply.github.com> + GIT_COMMITTER_NAME: jenkins-infra-changelog-generator + GIT_COMMITTER_EMAIL: <86592549+jenkins-infra-changelog-generator[bot]@users.noreply.github.com> + run: | + wget --quiet https://raw.githubusercontent.com/jenkinsci/core-changelog-generator/master/generate-weekly-changelog.sh + bash generate-weekly-changelog.sh diff --git a/.github/workflows/publish-release-artifact.yml b/.github/workflows/publish-release-artifact.yml index dae36072c087..bc451cbb1bb2 100644 --- a/.github/workflows/publish-release-artifact.yml +++ b/.github/workflows/publish-release-artifact.yml @@ -11,11 +11,11 @@ jobs: project-version: ${{ steps.set-version.outputs.project-version }} is-lts: ${{ steps.set-version.outputs.is-lts }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up JDK 8 - uses: actions/setup-java@v2 + uses: actions/setup-java@v3.0.0 with: - distribution: 'adopt' + distribution: 'temurin' java-version: 8 - name: Set version id: set-version @@ -58,7 +58,7 @@ jobs: wget -q https://get.jenkins.io/${REPO}/${PROJECT_VERSION}/${FILE_NAME} - name: Upload Release Asset id: upload-war - uses: actions/upload-release-asset@v1 + uses: actions/upload-release-asset@v1.0.2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: @@ -92,7 +92,7 @@ jobs: - name: Upload Release Asset id: upload-deb if: always() - uses: actions/upload-release-asset@v1 + uses: actions/upload-release-asset@v1.0.2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: @@ -127,7 +127,7 @@ jobs: - name: Upload Release Asset id: upload-rpm if: always() - uses: actions/upload-release-asset@v1 + uses: actions/upload-release-asset@v1.0.2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: @@ -162,7 +162,7 @@ jobs: - name: Upload Release Asset id: upload-msi if: always() - uses: actions/upload-release-asset@v1 + uses: actions/upload-release-asset@v1.0.2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: @@ -197,7 +197,7 @@ jobs: - name: Upload Release Asset id: upload-suse-rpm if: always() - uses: actions/upload-release-asset@v1 + uses: actions/upload-release-asset@v1.0.2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: diff --git a/.mvn/extensions.xml b/.mvn/extensions.xml index a2d496cc2b21..a65d82e1b647 100644 --- a/.mvn/extensions.xml +++ b/.mvn/extensions.xml @@ -2,6 +2,6 @@ io.jenkins.tools.incrementals git-changelist-maven-extension - 1.0-beta-4 + 1.3 diff --git a/.perltidyrc b/.perltidyrc new file mode 100644 index 000000000000..60845ad9c9cd --- /dev/null +++ b/.perltidyrc @@ -0,0 +1,104 @@ +################################################# +# Categories outlined in this config +# are based on the categories in the +# perltidy man page: +# http://perltidy.sourceforge.net/perltidy.html +################################################# + +################################### +# I/O Control +################################### + +# Send all errors to standard output rather than a file. +--standard-error-output + +# All non-critical warnings will be reported as errors. +--warning-output + +################################### +# Basic Options +################################### + +# Maximum number of characters per line. +--maximum-line-length=80 + +################################### +# Code Indentation Control +################################### + +# The number of spaces to indent a line when a new block starts. +--indent-columns=4 + +# If a line continues, it should be indented 2 spaces. +--continuation-indentation=4 + +# If a comment is longer than the maximum line length, break it up for +# readability. +--outdent-long-comments + +# If a quoted string is longer than the maximum line length, do not break it up +# for readability. +--no-outdent-long-quotes + +################################### +# Whitespace Control +################################### + +# Stack opening braces in order to avoid having a brace sitting by itself on +# a line. +--stack-opening-tokens + +# Stack closing tokens in order to avoid having a brace sitting by itself on +# a line. +--stack-closing-tokens + +# Spaces between parentheses e.g. if ((my $len_tab = length($tabstr)) > 0) { +--paren-tightness=2 + +# Spaces between brackets e.g. $width = $col[$j + $k] - $col[$j]; +--square-bracket-tightness=2 + +# Spaces between braces in expression e.g. $obj->{$parsed_sql->{'table'}[0]}; +--brace-tightness=2 + +# Spaces between braches with blocks of code +# e.g. %bf = map { $_ => -M $_ } grep { /\.deb$/ } dirents '.'; +--block-brace-tightness=0 + +# Do not add spaces between semicolons within for loops. +--nospace-for-semicolon + +################################### +# Comment Controls +################################### + +# Indent comments to be at the same level as the code. +--indent-block-comments + +################################### +# Line Break Control +################################### + +# The else is on the same line as the brace. +--cuddled-else + +# Create a break after -> and period if a break is required. +--want-break-after='-> .' + +################################### +# Blank Line Control +################################### + +# Do not force blank lines before full line comments. +--noblanks-before-comments + +# Do not force blank lines before blocks starting with for, foreach, while, +# until, and if,unless. +--noblanks-before-blocks + +################################### +# Vertical Alignment +################################### + +# Turn off vertical alignment. +-novalign diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 260c3b0d3460..23053598b75a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -9,12 +9,10 @@ This page provides information about contributing code to the Jenkins core codeb 1. Fork the repository on GitHub 2. Clone the forked repository to your machine 3. Install the necessary development tools. In order to develop Jenkins, you need the following: - * Java Development Kit (JDK) 8 or 11. - In the Jenkins project we usually use [OpenJDK](http://openjdk.java.net/) or [AdoptOpenJDK](https://adoptopenjdk.net/), but you can use other JDKs as well. - * For JDK 11 there might be some compatibility issues in developer tools, - please see [this page](https://wiki.jenkins.io/display/JENKINS/Java+11+Developer+Guidelines#Java11DeveloperGuidelines-Knowndevelopertoolsissues) for more info. - If you find a new issue, please report it with a `java11-devtools-compatibility` label in our issue tracker. - * Maven 3.5.4 or above. You can [download Maven here]. + * Java Development Kit (JDK) 11 or 8. + In the Jenkins project we usually use [Eclipse Adoptium](https://adoptium.net/) or [OpenJDK](https://openjdk.java.net/), but you can use other JDKs as well. + * Apache Maven 3.8.1 or above. You can [download Maven here]. + In the Jenkins project we usually use the most recent Maven release. * Any IDE which supports importing Maven projects. * Install [NodeJS](https://nodejs.org/en/). **Note:** only needed to work on the frontend assets found in the `war` module. * Frontend tasks are run using [yarn](https://yarnpkg.com/lang/en/). Run `npm install -g yarn` to install it. @@ -33,7 +31,7 @@ You can read a description of the [building and debugging process here]. If you want simply to build the `jenkins.war` file as fast as possible without tests, run: ```sh -mvn -am -pl war,bom -DskipTests -Dspotbugs.skip clean install +mvn -am -pl war,bom -DskipTests -Dspotbugs.skip -Dspotless.check.skip clean install ``` The WAR file will be created in `war/target/jenkins.war`. @@ -92,7 +90,7 @@ cd war; yarn test ## Proposing Changes The Jenkins project source code repositories are hosted at GitHub. -All proposed changes are submitted, and code reviewed, using the _GitHub Pull Request_ process. +All proposed changes are submitted, and code reviewed, using a [GitHub pull request] process. To submit a pull request: @@ -123,6 +121,7 @@ This will help minimize the diff, which makes reviewing PRs easier. We also do not recommend `*` imports in the production code. Please disable them in Settings > Editor > Codestyle > Java by setting _Class count to use import with '*'_ and Names count to use import with '*'_ to a high value, e.g. 100. + ## Copyright The Jenkins core is licensed under [MIT license], with a few exceptions in bundled classes. @@ -149,24 +148,25 @@ just submit a pull request. # Links -* [Jenkins Contribution Landing Page](https://jenkins.io/participate/) -* [Jenkins IRC Channel](https://jenkins.io/chat/) -* [Beginners Guide To Contributing](https://wiki.jenkins.io/display/JENKINS/Beginners+Guide+to+Contributing) -* [List of newbie-friendly issues in the core](https://issues.jenkins-ci.org/issues/?jql=project%20%3D%20JENKINS%20AND%20status%20in%20(Open%2C%20%22In%20Progress%22%2C%20Reopened)%20AND%20component%20%3D%20core%20AND%20labels%20in%20(newbie-friendly)) +* [Jenkins Contribution Landing Page](https://www.jenkins.io/participate/) +* [Jenkins Chat Channels](https://www.jenkins.io/chat/) +* [Beginners Guide To Contributing](https://www.jenkins.io/participate/) +* [List of newbie-friendly issues in the core](https://issues.jenkins.io/issues/?jql=project%20%3D%20JENKINS%20AND%20status%20in%20(Open%2C%20%22In%20Progress%22%2C%20Reopened)%20AND%20component%20%3D%20core%20AND%20labels%20in%20(newbie-friendly)) -[Preparing for Plugin Development]: https://jenkins.io/doc/developer/tutorial/prepare/ -[newbie friendly issues]: https://issues.jenkins-ci.org/issues/?jql=project%20%3D%20JENKINS%20AND%20status%20in%20(Open%2C%20%22In%20Progress%22%2C%20Reopened)%20AND%20component%20%3D%20core%20AND%20labels%20in%20(newbie-friendly) -[Participate]: https://jenkins.io/participate/ -[building and debugging process here]: https://jenkins.io/doc/developer/building/ -[guide]: https://wiki.jenkins.io/display/JENKINS/Starting+and+Accessing+Jenkins +[Preparing for Plugin Development]: https://www.jenkins.io/doc/developer/tutorial/prepare/ +[newbie friendly issues]: https://issues.jenkins.io/issues/?jql=project%20%3D%20JENKINS%20AND%20status%20in%20(Open%2C%20%22In%20Progress%22%2C%20Reopened)%20AND%20component%20%3D%20core%20AND%20labels%20in%20(newbie-friendly) +[Participate]: https://www.jenkins.io/participate/ +[building and debugging process here]: https://www.jenkins.io/doc/developer/building/ +[guide]: https://www.jenkins.io/doc/book/installing/war-file/#run-the-war-file [Remote Debug Flags]: https://stackoverflow.com/questions/975271/remote-debugging-a-java-application [Acceptance Test Harness (ATH)]: https://github.com/jenkinsci/acceptance-test-harness -[backporting process]: https://jenkins.io/download/lts/ +[backporting process]: https://www.jenkins.io/download/lts/ [proposed template]: .github/PULL_REQUEST_TEMPLATE.md [MIT license]: ./LICENSE.txt -[contributor agreement]: https://jenkins.io/project/governance/#cla -[Jenkins Security Team]: https://jenkins.io/security/#team +[contributor agreement]: https://www.jenkins.io/project/governance/#cla +[Jenkins Security Team]: https://www.jenkins.io/security/#team [ci.jenkins.io]: https://ci.jenkins.io/ -[Jenkins Pipeline]: https://jenkins.io/doc/book/pipeline/ +[Jenkins Pipeline]: https://www.jenkins.io/doc/book/pipeline/ [Jenkinsfile]: ./Jenkinsfile [download Maven here]: https://maven.apache.org/download.cgi +[GitHub pull request]: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests \ No newline at end of file diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 4566c7265f56..000000000000 --- a/Dockerfile +++ /dev/null @@ -1,28 +0,0 @@ -# This is a Dockerfile definition for Experimental Docker builds. -# DockerHub: https://hub.docker.com/r/jenkins/jenkins-experimental/ -# If you are looking for official images, see https://github.com/jenkinsci/docker -FROM maven:3.5.4-jdk-8 as builder - -COPY .mvn/ /jenkins/src/.mvn/ -COPY cli/ /jenkins/src/cli/ -COPY core/ /jenkins/src/core/ -COPY src/ /jenkins/src/src/ -COPY test/ /jenkins/src/test/ -COPY test-pom/ /jenkins/src/test-pom/ -COPY test-jdk8/ /jenkins/src/test-jdk8/ -COPY war/ /jenkins/src/war/ -COPY *.xml /jenkins/src/ -COPY LICENSE.txt /jenkins/src/LICENSE.txt -COPY licenseCompleter.groovy /jenkins/src/licenseCompleter.groovy -COPY show-pom-version.rb /jenkins/src/show-pom-version.rb - -WORKDIR /jenkins/src/ -RUN mvn clean install --batch-mode -Plight-test - -# The image is based on the previous weekly, new changes in jenkinci/docker are not applied -FROM jenkins/jenkins:latest - -LABEL Description="This is an experimental image for the master branch of the Jenkins core" Vendor="Jenkins Project" - -COPY --from=builder /jenkins/src/war/target/jenkins.war /usr/share/jenkins/jenkins.war -ENTRYPOINT ["tini", "--", "/usr/local/bin/jenkins.sh"] diff --git a/Jenkinsfile b/Jenkinsfile index 7d28d339c98c..ba2eebe04921 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -7,131 +7,164 @@ def buildNumber = BUILD_NUMBER as int; if (buildNumber > 1) milestone(buildNumber - 1); milestone(buildNumber) // JENKINS-43353 / JENKINS-58625 -// TEST FLAG - to make it easier to turn on/off unit tests for speeding up access to later stuff. -def runTests = true def failFast = false +// Same memory sizing for both builds and ATH +def javaOpts = [ + 'JAVA_OPTS=-Xmx1536m -Xms512m', + 'MAVEN_OPTS=-Xmx1536m -Xms512m', +] -properties([buildDiscarder(logRotator(numToKeepStr: '50', artifactNumToKeepStr: '3')), durabilityHint('PERFORMANCE_OPTIMIZED')]) +properties([ + buildDiscarder(logRotator(numToKeepStr: '50', artifactNumToKeepStr: '3')), + disableConcurrentBuilds(abortPrevious: true) +]) -// TODO: Restore 'Windows' once https://groups.google.com/forum/#!topic/jenkinsci-dev/v9d-XosOp2s is resolved -def buildTypes = ['Linux'] -def jdks = [8, 11] +def buildTypes = ['Linux', 'Windows'] +def jdks = [8, 11, 17] def builds = [:] -for(i = 0; i < buildTypes.size(); i++) { -for(j = 0; j < jdks.size(); j++) { +for (i = 0; i < buildTypes.size(); i++) { + for (j = 0; j < jdks.size(); j++) { def buildType = buildTypes[i] def jdk = jdks[j] + if (buildType == 'Windows' && jdk == 8) { + continue // unnecessary use of hardware + } + if (buildType == 'Windows' && jdk == 17) { + continue // TODO pending jenkins-infra/helpdesk#2822 + } builds["${buildType}-jdk${jdk}"] = { - // see https://github.com/jenkins-infra/documentation/blob/master/ci.adoc#node-labels for information on what node types are available - node(buildType == 'Linux' ? (jdk == 8 ? 'maven' : 'maven-11') : buildType.toLowerCase()) { - // First stage is actually checking out the source. Since we're using Multibranch - // currently, we can use "checkout scm". - stage('Checkout') { - checkout scm - } + // see https://github.com/jenkins-infra/documentation/blob/master/ci.adoc#node-labels for information on what node types are available + def agentContainerLabel = jdk == 8 ? 'maven' : 'maven-' + jdk + if (buildType == 'Windows') { + agentContainerLabel += '-windows' + } + node(agentContainerLabel) { + // First stage is actually checking out the source. Since we're using Multibranch + // currently, we can use "checkout scm". + stage('Checkout') { + checkout scm + } - def changelistF = "${pwd tmp: true}/changelist" - def m2repo = "${pwd tmp: true}/m2repo" + def changelistF = "${pwd tmp: true}/changelist" + def m2repo = "${pwd tmp: true}/m2repo" + + // Now run the actual build. + stage("${buildType} Build / Test") { + timeout(time: 5, unit: 'HOURS') { + realtimeJUnit(healthScaleFactor: 20.0, testResults: '*/target/surefire-reports/*.xml,war/junit.xml') { + def mavenOptions = [ + '-Pdebug', + '--update-snapshots', + "-Dmaven.repo.local=$m2repo", + '-Dmaven.test.failure.ignore', + '-Dspotbugs.failOnError=false', + '-Dcheckstyle.failOnViolation=false', + '-Dset.changelist', + 'help:evaluate', + '-Dexpression=changelist', + "-Doutput=$changelistF", + 'clean', + 'install', + ] + infra.runMaven(mavenOptions, jdk.toString(), javaOpts, null, true) + if (isUnix()) { + sh 'git add . && git diff --exit-code HEAD' + } + } + } + } - // Now run the actual build. - stage("${buildType} Build / Test") { - timeout(time: 180, unit: 'MINUTES') { - // See below for what this method does - we're passing an arbitrary environment - // variable to it so that JAVA_OPTS and MAVEN_OPTS are set correctly. - withMavenEnv(["JAVA_OPTS=-Xmx1536m -Xms512m", - "MAVEN_OPTS=-Xmx1536m -Xms512m"], buildType, jdk) { - // Actually run Maven! - // -Dmaven.repo.local=… tells Maven to create a subdir in the temporary directory for the local Maven repository - def mvnCmd = "mvn -Pdebug -Pjapicmp -U -Dset.changelist help:evaluate -Dexpression=changelist -Doutput=$changelistF clean install ${runTests ? '-Dmaven.test.failure.ignore' : '-DskipTests'} -V -B -ntp -Dmaven.repo.local=$m2repo -e" + // Once we've built, archive the artifacts and the test results. + stage("${buildType} Publishing") { + archiveArtifacts allowEmptyArchive: true, artifacts: '**/target/surefire-reports/*.dumpstream' + if (!fileExists('core/target/surefire-reports/TEST-jenkins.Junit4TestsRanTest.xml')) { + error 'JUnit 4 tests are no longer being run for the core package' + } + if (!fileExists('test/target/surefire-reports/TEST-jenkins.Junit4TestsRanTest.xml')) { + error 'JUnit 4 tests are no longer being run for the test package' + } + // cli has been migrated to JUnit 5 + if (failFast && currentBuild.result == 'UNSTABLE') { + error 'There were test failures; halting early' + } + if (buildType == 'Linux' && jdk == jdks[0]) { + def folders = env.JOB_NAME.split('/') + if (folders.length > 1) { + discoverGitReferenceBuild(scm: folders[1]) + } - if(isUnix()) { - sh mvnCmd - sh 'git add . && git diff --exit-code HEAD' - } else { - bat mvnCmd - } - } - } - } + echo "Recording static analysis results for '${buildType}'" + recordIssues( + enabledForFailure: true, + tools: [java(), javaDoc()], + filters: [excludeFile('.*Assert.java')], + sourceCodeEncoding: 'UTF-8', + skipBlames: true, + trendChartType: 'TOOLS_ONLY' + ) + recordIssues([tool: spotBugs(pattern: '**/target/spotbugsXml.xml'), + sourceCodeEncoding: 'UTF-8', + skipBlames: true, + trendChartType: 'TOOLS_ONLY', + qualityGates: [ + [threshold: 1, type: 'NEW', unstable: true], + ]]) + recordIssues([tool: checkStyle(pattern: '**/target/checkstyle-result.xml'), + sourceCodeEncoding: 'UTF-8', + skipBlames: true, + trendChartType: 'TOOLS_ONLY', + qualityGates: [ + [threshold: 1, type: 'TOTAL', unstable: true], + ]]) + if (failFast && currentBuild.result == 'UNSTABLE') { + error 'Static analysis quality gates not passed; halting early' + } - // Once we've built, archive the artifacts and the test results. - stage("${buildType} Publishing") { - if (runTests) { - junit healthScaleFactor: 20.0, testResults: '*/target/surefire-reports/*.xml,war/junit.xml' - archiveArtifacts allowEmptyArchive: true, artifacts: '**/target/surefire-reports/*.dumpstream' - } - if (buildType == 'Linux' && jdk == jdks[0]) { - def changelist = readFile(changelistF) - dir(m2repo) { - archiveArtifacts artifacts: "**/*$changelist/*$changelist*", - excludes: '**/*.lastUpdated,**/jenkins-test*/', - allowEmptyArchive: true, // in case we forgot to reincrementalify - fingerprint: true - } - publishHTML([allowMissing: true, alwaysLinkToLastBuild: false, includes: 'japicmp.html', keepAll: false, reportDir: 'core/target/japicmp', reportFiles: 'japicmp.html', reportName: 'API compatibility', reportTitles: 'japicmp report']) - } - } + def changelist = readFile(changelistF) + dir(m2repo) { + archiveArtifacts( + artifacts: "**/*$changelist/*$changelist*", + excludes: '**/*.lastUpdated,**/jenkins-test*/', + allowEmptyArchive: true, // in case we forgot to reincrementalify + fingerprint: true + ) + } + } } + } } -}} + } +} -// TODO: Restore ATH once https://groups.google.com/forum/#!topic/jenkinsci-dev/v9d-XosOp2s is resolved -// TODO: ATH flow now supports Java 8 only, it needs to be reworked (INFRA-1690) builds.ath = { - node("docker&&highmem") { - // Just to be safe - deleteDir() - def fileUri - def metadataPath - dir("sources") { - checkout scm - withMavenEnv(["JAVA_OPTS=-Xmx1536m -Xms512m", - "MAVEN_OPTS=-Xmx1536m -Xms512m"], 8) { - sh "mvn --batch-mode --show-version -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -DskipTests -am -pl war package -Dmaven.repo.local=${pwd tmp: true}/m2repo" - } - dir("war/target") { - fileUri = "file://" + pwd() + "/jenkins.war" - } - metadataPath = pwd() + "/essentials.yml" - } - dir("ath") { - runATH jenkins: fileUri, metadataFile: metadataPath - } + node('docker-highmem') { + // Just to be safe + deleteDir() + def fileUri + def metadataPath + dir('sources') { + checkout scm + def mavenOptions = [ + '-Pquick-build', + '-Dmaven.repo.local=$WORKSPACE_TMP/m2repo', + '-am', + '-pl', + 'war', + 'package', + ] + infra.runMaven(mavenOptions, '11', javaOpts, null, true) + dir('war/target') { + fileUri = 'file://' + pwd() + '/jenkins.war' + } + metadataPath = pwd() + '/essentials.yml' + } + dir('ath') { + runATH jenkins: fileUri, metadataFile: metadataPath } + } } builds.failFast = failFast parallel builds infra.maybePublishIncrementals() - -// This method sets up the Maven and JDK tools, puts them in the environment along -// with whatever other arbitrary environment variables we passed in, and runs the -// body we passed in within that environment. -void withMavenEnv(List envVars = [], def buildType, def javaVersion, def body) { - if (buildType == 'Linux') { - // I.e., a Maven container using ACI. No need to install tools. - return withEnv(envVars) { - body.call() - } - } - - // The names here are currently hardcoded for my test environment. This needs - // to be made more flexible. - // Using the "tool" Workflow call automatically installs those tools on the - // node. - String mvntool = tool name: "mvn", type: 'hudson.tasks.Maven$MavenInstallation' - String jdktool = tool name: "jdk${javaVersion}", type: 'hudson.model.JDK' - - // Set JAVA_HOME, MAVEN_HOME and special PATH variables for the tools we're - // using. - List mvnEnv = ["PATH+MVN=${mvntool}/bin", "PATH+JDK=${jdktool}/bin", "JAVA_HOME=${jdktool}", "MAVEN_HOME=${mvntool}"] - - // Add any additional environment variables. - mvnEnv.addAll(envVars) - - // Invoke the body closure we're passed within the environment we've created. - withEnv(mvnEnv) { - body.call() - } -} diff --git a/README.md b/README.md index fdcbabbf83a3..ecf83732aa6f 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ # About -[![Jenkins Regular Release](https://img.shields.io/endpoint?url=https%3A%2F%2Fwww.jenkins.io%2Fchangelog%2Fbadge.json)](https://jenkins.io/changelog) -[![Jenkins LTS Release](https://img.shields.io/endpoint?url=https%3A%2F%2Fwww.jenkins.io%2Fchangelog-stable%2Fbadge.json)](https://jenkins.io/changelog-stable) +[![Jenkins Regular Release](https://img.shields.io/endpoint?url=https%3A%2F%2Fwww.jenkins.io%2Fchangelog%2Fbadge.json)](https://www.jenkins.io/changelog) +[![Jenkins LTS Release](https://img.shields.io/endpoint?url=https%3A%2F%2Fwww.jenkins.io%2Fchangelog-stable%2Fbadge.json)](https://www.jenkins.io/changelog-stable) [![Docker Pulls](https://img.shields.io/docker/pulls/jenkins/jenkins.svg)](https://hub.docker.com/r/jenkins/jenkins/) [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/3538/badge)](https://bestpractices.coreinfrastructure.org/projects/3538) @@ -35,8 +35,8 @@ For all distributions Jenkins offers two release lines: Older release line which gets periodically updated via bug fix backports. Latest releases: -[![Jenkins Regular Release](https://img.shields.io/endpoint?url=https%3A%2F%2Fwww.jenkins.io%2Fchangelog%2Fbadge.json)](https://jenkins.io/changelog) -[![Jenkins LTS Release](https://img.shields.io/endpoint?url=https%3A%2F%2Fwww.jenkins.io%2Fchangelog-stable%2Fbadge.json)](https://jenkins.io/changelog-stable) +[![Jenkins Regular Release](https://img.shields.io/endpoint?url=https%3A%2F%2Fwww.jenkins.io%2Fchangelog%2Fbadge.json)](https://www.jenkins.io/changelog) +[![Jenkins LTS Release](https://img.shields.io/endpoint?url=https%3A%2F%2Fwww.jenkins.io%2Fchangelog-stable%2Fbadge.json)](https://www.jenkins.io/changelog-stable) # Source @@ -69,8 +69,8 @@ See [adopters](https://www.jenkins.io/project/adopters/) for the list of Jenkins Jenkins is **licensed** under the **[MIT License]**. -[ButlerImage]: https://jenkins.io/sites/default/files/jenkins_logo.png +[ButlerImage]: https://www.jenkins.io/sites/default/files/jenkins_logo.png [MIT License]: https://github.com/jenkinsci/jenkins/blob/master/LICENSE.txt [Mirrors]: http://mirrors.jenkins-ci.org [GitHub]: https://github.com/jenkinsci/jenkins -[website]: https://jenkins.io/ +[website]: https://www.jenkins.io/ diff --git a/bom/pom.xml b/bom/pom.xml index 90f82a140f0f..00c4b72c9cd4 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -37,162 +37,166 @@ THE SOFTWARE. Jenkins BOM The module contains dependencies that are used by a specific Jenkins version - - 11.0.1 - 1.7.30 - 1.263 - 2.4.12 + 9.2 + 1.7.36 + 1669.v95a_4b_919a_b_a_2 + 2.4.21 - + + com.google.inject + guice-bom + 5.0.1 + pom + import + + + org.springframework.security spring-security-bom - 5.4.5 + 5.6.2 pom import + + antlr + antlr + 2.7.7 + + + + args4j + args4j + 2.33 + com.github.spotbugs spotbugs-annotations ${spotbugs-annotations.version} - net.jcip - jcip-annotations - 1.0 + com.google.guava + guava + 31.1-jre - org.apache.ant - ant - 1.10.9 + + com.jcraft + jzlib + 1.1.3-kohsuke-1 - commons-io - commons-io - 2.8.0 + com.sun.solaris + embedded_su4j + 1.1 - commons-lang - commons-lang - 2.6 + com.sun.xml.txw2 + txw2 + 20110809 - commons-httpclient - commons-httpclient - 3.1-jenkins-2 + com.thoughtworks.xstream + xstream + 1.4.19 - org.jenkins-ci.main - remoting - ${remoting.version} + commons-beanutils + commons-beanutils + 1.9.4 - com.google.guava - guava - ${guavaVersion} + commons-codec + commons-codec + 1.15 - com.google.guava - guava-testlib - ${guavaVersion} + commons-collections + commons-collections + 3.2.2 - com.google.inject - guice - 4.0 + commons-fileupload + commons-fileupload + 1.4 - - - org.slf4j - slf4j-api - ${slf4jVersion} + commons-httpclient + commons-httpclient + 3.1-jenkins-3 - org.slf4j - slf4j-jdk14 - ${slf4jVersion} + commons-io + commons-io + 2.11.0 - org.slf4j - jcl-over-slf4j - ${slf4jVersion} + commons-jelly + commons-jelly-tags-fmt + 1.0 - commons-logging - commons-logging - 1.2 - provided + commons-jelly + commons-jelly-tags-xml + 1.1 - org.slf4j - log4j-over-slf4j - ${slf4jVersion} + commons-lang + commons-lang + 2.6 - log4j - log4j - 1.2.17 - provided + io.jenkins.stapler + jenkins-stapler-support + 1.1 - org.samba.jcifs - jcifs - 1.3.18-kohsuke-1 + jakarta.servlet.jsp.jstl + jakarta.servlet.jsp.jstl-api + 1.2.7 - org.kohsuke - access-modifier-annotation - ${access-modifier-annotation.version} + jaxen + jaxen + 1.2.0 - - - javax.servlet - - servlet-api - [0] - - provided - true + net.java.dev.jna + jna + 5.11.0 - - commons-codec - commons-codec - 1.15 + net.java.sezpoz + sezpoz + 1.13 - - org.jenkins-ci - annotation-indexer - 1.14 + net.jcip + jcip-annotations + 1.0 - - org.jenkins-ci - version-number - 1.7 + net.sf.kxml + kxml2 + 2.3.0 - org.jenkins-ci - crypto-util - 1.5 + org.apache.ant + ant + 1.10.12 - org.jvnet.hudson - jtidy - 4aug2000r7-dev-hudson-1 + org.apache.commons + commons-compress + 1.21 + + + org.codehaus.groovy + groovy-all + ${groovy.version} org.connectbot.jbcrypt @@ -200,119 +204,95 @@ THE SOFTWARE. 1.0.0 - com.github.jnr - jnr-posix - 3.1.5 - - - org.kohsuke - windows-package-checker - 1.2 - - - args4j - args4j - 2.33 + + org.fusesource.jansi + jansi + 1.11 org.jenkins-ci - bytecode-compatibility-transformer - 2.0-beta-2 + annotation-indexer + 1.16 org.jenkins-ci - task-reactor - 1.5 - - - org.jvnet.localizer - localizer - 1.31 - - - antlr - antlr - 2.7.7 + commons-jexl + 1.1-jenkins-20111212 - org.jfree - jfreechart - 1.0.19 + org.jenkins-ci + crypto-util + 1.7 - commons-digester - commons-digester - 2.1 + org.jenkins-ci + memory-monitor + 1.11 - commons-beanutils - commons-beanutils - 1.9.4 + org.jenkins-ci + symbol-annotation + 1.1 - org.apache.commons - commons-compress - 1.20 + org.jenkins-ci + task-reactor + 1.7 - commons-collections - commons-collections - 3.2.2 + org.jenkins-ci + version-number + 1.9 - commons-fileupload - commons-fileupload - 1.4 + org.jenkins-ci.main + remoting + ${remoting.version} - com.sun.xml.txw2 - txw2 - 20110809 + org.jenkins-ci.modules + instance-identity + 2.2 - org.jvnet.winp - winp - 1.28 + org.jenkins-ci.modules + launchd-slave-installer + 1.2 - org.jenkins-ci - memory-monitor - 1.9 - - - org.codehaus.woodstox - wstx-asl - 3.2.9 + org.jenkins-ci.modules + slave-installer + 1.7 - net.java.dev.jna - jna - 5.8.0 + org.jenkins-ci.modules + systemd-slave-installer + 1.1 - org.kohsuke - akuma - 1.10 + org.jenkins-ci.modules + upstart-slave-installer + 1.1 - org.kohsuke - libpam4j - 1.11 + org.jenkins-ci.modules + windows-slave-installer + 2.0 - com.sun.solaris - embedded_su4j - 1.1 + org.jfree + jfreechart + 1.0.19 - net.java.sezpoz - sezpoz - 1.13 + org.jvnet.hudson + commons-jelly-tags-define + 1.0.1-hudson-20071021 - org.kohsuke.jinterop - j-interop - 2.0.8-kohsuke-1 + org.jvnet.localizer + localizer + 1.31 org.jvnet.robust-http-client @@ -320,36 +300,30 @@ THE SOFTWARE. 1.2 - com.sun.mail - jakarta.mail - 1.6.5 + org.jvnet.winp + winp + 1.28 - - - com.thoughtworks.xstream - xstream - 1.4.16 + org.kohsuke + access-modifier-annotation + ${access-modifier.version} - net.sf.kxml - kxml2 - 2.3.0 + org.kohsuke + windows-package-checker + 1.2 - - - org.codehaus.groovy - groovy-all - ${groovy.version} + org.kohsuke.jinterop + j-interop + 2.0.8-kohsuke-1 - - org.fusesource.jansi - jansi - 1.11 + + org.kohsuke.stapler + json-lib + 2.4-jenkins-3 - - org.kohsuke.stapler stapler @@ -357,8 +331,8 @@ THE SOFTWARE. org.kohsuke.stapler - stapler-groovy - ${stapler.version} + stapler-adjunct-codemirror + 1.3 org.kohsuke.stapler @@ -367,88 +341,91 @@ THE SOFTWARE. org.kohsuke.stapler - stapler-adjunct-codemirror - 1.3 + stapler-groovy + ${stapler.version} - io.jenkins.stapler - jenkins-stapler-support - 1.1 + org.ow2.asm + asm + ${asm.version} - - org.kohsuke.stapler - json-lib - 2.4-jenkins-2 - - - com.jcraft - jzlib - 1.1.3-kohsuke-1 + org.ow2.asm + asm-analysis + ${asm.version} - - - commons-jelly - commons-jelly-tags-fmt - 1.0 + org.ow2.asm + asm-commons + ${asm.version} - commons-jelly - commons-jelly-tags-xml - 1.1 - - - org.jvnet.hudson - commons-jelly-tags-define - 1.0.1-hudson-20071021 + org.ow2.asm + asm-tree + ${asm.version} - org.jenkins-ci - commons-jexl - 1.1-jenkins-20111212 + org.ow2.asm + asm-util + ${asm.version} - jakarta.servlet.jsp.jstl - jakarta.servlet.jsp.jstl-api - 1.2.7 + org.samba.jcifs + jcifs + 1.3.18-kohsuke-1 - jaxen - jaxen - 1.2.0 + org.slf4j + jcl-over-slf4j + ${slf4jVersion} - - - org.jenkins-ci.modules - instance-identity - 2.2 + org.slf4j + log4j-over-slf4j + ${slf4jVersion} - org.jenkins-ci.modules - slave-installer - 1.7 + + org.slf4j + slf4j-api + ${slf4jVersion} - org.jenkins-ci.modules - windows-slave-installer - 2.0 + org.slf4j + slf4j-jdk14 + ${slf4jVersion} - org.jenkins-ci.modules - launchd-slave-installer + + commons-logging + commons-logging 1.2 + provided - org.jenkins-ci.modules - upstart-slave-installer - 1.1 + + + javax.servlet + + servlet-api + [0] + + provided + true - org.jenkins-ci.modules - systemd-slave-installer - 1.1 + + log4j + log4j + 1.2.17 + provided @@ -467,10 +444,10 @@ THE SOFTWARE. flatten - process-resources flatten + process-resources bom diff --git a/cli/pom.xml b/cli/pom.xml index a6623d626f42..c67f713b0e19 100644 --- a/cli/pom.xml +++ b/cli/pom.xml @@ -12,10 +12,10 @@ Jenkins cli Command line interface for Jenkins + https://github.com/jenkinsci/jenkins - - Medium + 2.8.0 @@ -32,54 +32,48 @@ - org.junit.jupiter - junit-jupiter-api - ${junit.jupiter.version} - test - - - org.junit.jupiter - junit-jupiter-engine - ${junit.jupiter.version} - test + commons-io + commons-io + true - org.junit.jupiter - junit-jupiter - ${junit.jupiter.version} - test + commons-lang + commons-lang + true - org.kohsuke - access-modifier-annotation - provided + + net.i2p.crypto + eddsa + 0.3.0 + true - org.jenkins-ci - annotation-indexer + org.apache.sshd + sshd-common + ${mina-sshd.version} true - commons-io - commons-io + org.apache.sshd + sshd-core + ${mina-sshd.version} true - org.jvnet.localizer - localizer + org.glassfish.tyrus.bundles + tyrus-standalone-client-jdk + 2.0.1 true - org.apache.sshd - sshd-core - 2.6.0 + org.jenkins-ci + annotation-indexer true - - net.i2p.crypto - eddsa - 0.3.0 + org.jvnet.localizer + localizer true @@ -88,20 +82,39 @@ true - org.glassfish.tyrus.bundles - tyrus-standalone-client-jdk - 2.0.0 + com.github.spotbugs + spotbugs-annotations + provided true + + + com.google.code.findbugs + jsr305 + + - com.github.spotbugs - spotbugs-annotations + org.kohsuke + access-modifier-annotation provided - commons-lang - commons-lang - true + org.junit.jupiter + junit-jupiter + ${junit.jupiter.version} + test + + + org.junit.jupiter + junit-jupiter-api + ${junit.jupiter.version} + test + + + org.junit.jupiter + junit-jupiter-engine + ${junit.jupiter.version} + test @@ -112,43 +125,51 @@ - org.apache.maven.plugins - maven-shade-plugin - 3.2.4 - - - package - - shade - - - false - - - javax.websocket - io.jenkins.cli.shaded.javax.websocket - - - org - io.jenkins.cli.shaded.org - - - net - io.jenkins.cli.shaded.net - - - - - hudson.cli.CLI - - ${project.version} - - - - - - - + org.apache.maven.plugins + maven-shade-plugin + 3.2.4 + + + + shade + + package + + false + + + javax.websocket + io.jenkins.cli.shaded.javax.websocket + + + org + io.jenkins.cli.shaded.org + + + net + io.jenkins.cli.shaded.net + + + com + io.jenkins.cli.shaded.com + + + jakarta + io.jenkins.cli.shaded.jakarta + + + + + hudson.cli.CLI + + ${project.version} + + + + + + + org.jvnet.localizer @@ -174,15 +195,15 @@ add-source + + add-source + generate-sources - - add-source - - - - ${project.build.directory}/generated-sources/localizer - - + + + ${project.build.directory}/generated-sources/localizer + + diff --git a/cli/src/main/java/hudson/cli/CLI.java b/cli/src/main/java/hudson/cli/CLI.java index 6c14562c52bd..a6a33c6f800e 100644 --- a/cli/src/main/java/hudson/cli/CLI.java +++ b/cli/src/main/java/hudson/cli/CLI.java @@ -21,16 +21,19 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.cli; +import static java.util.logging.Level.FINE; +import static java.util.logging.Level.parse; + import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.cli.client.Messages; +import jakarta.websocket.ClientEndpointConfig; +import jakarta.websocket.Endpoint; +import jakarta.websocket.EndpointConfig; +import jakarta.websocket.Session; import java.io.DataInputStream; -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSession; -import javax.net.ssl.TrustManager; import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -52,11 +55,11 @@ import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.Logger; -import static java.util.logging.Level.*; -import jakarta.websocket.ClientEndpointConfig; -import jakarta.websocket.Endpoint; -import jakarta.websocket.EndpointConfig; -import jakarta.websocket.Session; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.TrustManager; import org.apache.commons.io.FileUtils; import org.apache.commons.lang.StringUtils; import org.glassfish.tyrus.client.ClientManager; @@ -78,9 +81,10 @@ private CLI() {} * @throws NotTalkingToJenkinsException when connection is not made to Jenkins service. */ /*package*/ static void verifyJenkinsConnection(URLConnection c) throws IOException { - if (c.getHeaderField("X-Hudson")==null && c.getHeaderField("X-Jenkins")==null) + if (c.getHeaderField("X-Hudson") == null && c.getHeaderField("X-Jenkins") == null) throw new NotTalkingToJenkinsException(c); } + /*package*/ static final class NotTalkingToJenkinsException extends IOException { NotTalkingToJenkinsException(String s) { super(s); @@ -104,16 +108,17 @@ public static void main(final String[] _args) throws Exception { } } - private enum Mode {HTTP, SSH, WEB_SOCKET} + private enum Mode { HTTP, SSH, WEB_SOCKET } + public static int _main(String[] _args) throws Exception { List args = Arrays.asList(_args); PrivateKeyProvider provider = new PrivateKeyProvider(); String url = System.getenv("JENKINS_URL"); - if (url==null) + if (url == null) url = System.getenv("HUDSON_URL"); - + boolean noKeyAuth = false; // TODO perhaps allow mode to be defined by environment variable too (assuming $JENKINS_USER_ID can be used for -user) @@ -128,10 +133,10 @@ public static int _main(String[] _args) throws Exception { boolean strictHostKey = false; - while(!args.isEmpty()) { + while (!args.isEmpty()) { String head = args.get(0); if (head.equals("-version")) { - System.out.println("Version: "+computeVersion()); + System.out.println("Version: " + computeVersion()); return 0; } if (head.equals("-http")) { @@ -165,9 +170,9 @@ public static int _main(String[] _args) throws Exception { printUsage("-remoting mode is no longer supported"); return -1; } - if(head.equals("-s") && args.size()>=2) { + if (head.equals("-s") && args.size() >= 2) { url = args.get(1); - args = args.subList(2,args.size()); + args = args.subList(2, args.size()); continue; } if (head.equals("-noCertificateCheck")) { @@ -177,20 +182,21 @@ public static int _main(String[] _args) throws Exception { HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory()); // bypass host name check, too. HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { + @Override @SuppressFBWarnings(value = "WEAK_HOSTNAME_VERIFIER", justification = "User set parameter to skip verifier.") public boolean verify(String s, SSLSession sslSession) { return true; } }); - args = args.subList(1,args.size()); + args = args.subList(1, args.size()); continue; } if (head.equals("-noKeyAuth")) { - noKeyAuth = true; - args = args.subList(1,args.size()); - continue; + noKeyAuth = true; + args = args.subList(1, args.size()); + continue; } - if(head.equals("-i") && args.size()>=2) { + if (head.equals("-i") && args.size() >= 2) { File f = getFileFromArguments(args); if (!f.exists()) { printUsage(Messages.CLI_NoSuchFileExists(f)); @@ -199,7 +205,7 @@ public boolean verify(String s, SSLSession sslSession) { provider.readFrom(f); - args = args.subList(2,args.size()); + args = args.subList(2, args.size()); continue; } if (head.equals("-strictHostKey")) { @@ -236,7 +242,7 @@ public boolean verify(String s, SSLSession sslSession) { break; } - if(url==null) { + if (url == null) { printUsage(Messages.CLI_NoURL()); return -1; } @@ -260,7 +266,7 @@ public boolean verify(String s, SSLSession sslSession) { url += '/'; } - if(args.isEmpty()) + if (args.isEmpty()) args = Collections.singletonList("help"); // default to help if (mode == null) { @@ -335,6 +341,7 @@ class CLIEndpoint extends Endpoint { @Override public void onOpen(Session session, EndpointConfig config) {} } + class Authenticator extends ClientEndpointConfig.Configurator { @Override public void beforeRequest(Map> headers) { @@ -343,6 +350,7 @@ public void beforeRequest(Map> headers) { } } } + ClientManager client = ClientManager.createClient(JdkClientContainer.class.getName()); // ~ ContainerProvider.getWebSocketContainer() client.getProperties().put(ClientProperties.REDIRECT_ENABLED, true); // https://tyrus-project.github.io/documentation/1.13.1/index/tyrus-proprietary-config.html#d0e1775 Session session = client.connectToServer(new CLIEndpoint(), ClientEndpointConfig.Builder.create().configurator(new Authenticator()).build(), URI.create(url.replaceFirst("^http", "ws") + "cli/ws")); @@ -351,6 +359,7 @@ public void beforeRequest(Map> headers) { public void send(byte[] data) throws IOException { session.getBasicRemote().sendBinary(ByteBuffer.wrap(data)); } + @Override public void close() throws IOException { session.close(); @@ -420,10 +429,14 @@ void start(List args) throws IOException { public void run() { try { final OutputStream stdin = streamStdin(); - int c; - // TODO check available to avoid sending lots of one-byte frames - while (!complete && (c = System.in.read()) != -1) { - stdin.write(c); + byte[] buf = new byte[60_000]; // less than 64Kb frame size for WS + while (!complete) { + int len = System.in.read(buf); + if (len == -1) { + break; + } else { + stdin.write(buf, 0, len); + } } sendEndStdin(); } catch (IOException x) { @@ -472,7 +485,7 @@ private static String computeVersion() { Properties props = new Properties(); try { InputStream is = CLI.class.getResourceAsStream("/jenkins/cli/jenkins-cli-version.properties"); - if(is!=null) { + if (is != null) { try { props.load(is); } finally { @@ -482,7 +495,7 @@ private static String computeVersion() { } catch (IOException e) { e.printStackTrace(); // if the version properties is missing, that's OK. } - return props.getProperty("version","?"); + return props.getProperty("version", "?"); } /** @@ -513,7 +526,7 @@ static String usage() { } private static void printUsage(String msg) { - if(msg!=null) System.out.println(msg); + if (msg != null) System.out.println(msg); System.err.println(usage()); } diff --git a/cli/src/main/java/hudson/cli/CLIConnectionFactory.java b/cli/src/main/java/hudson/cli/CLIConnectionFactory.java index eceff79eff3c..9b4295b07cb3 100644 --- a/cli/src/main/java/hudson/cli/CLIConnectionFactory.java +++ b/cli/src/main/java/hudson/cli/CLIConnectionFactory.java @@ -1,10 +1,11 @@ package hudson.cli; +import java.nio.charset.StandardCharsets; import java.util.Base64; /** * Fluent-API to instantiate {@link CLI}. - * + * * @author Kohsuke Kawaguchi */ public class CLIConnectionFactory { @@ -25,7 +26,7 @@ public CLIConnectionFactory authorization(String value) { * Currently unused. */ public CLIConnectionFactory basicAuth(String username, String password) { - return basicAuth(username+':'+password); + return basicAuth(username + ':' + password); } /** @@ -33,7 +34,7 @@ public CLIConnectionFactory basicAuth(String username, String password) { * Cf. {@code BasicHeaderApiTokenAuthenticator}. */ public CLIConnectionFactory basicAuth(String userInfo) { - return authorization("Basic " + Base64.getEncoder().encodeToString(userInfo.getBytes())); + return authorization("Basic " + Base64.getEncoder().encodeToString(userInfo.getBytes(StandardCharsets.UTF_8))); } /** diff --git a/cli/src/main/java/hudson/cli/DiagnosedStreamCorruptionException.java b/cli/src/main/java/hudson/cli/DiagnosedStreamCorruptionException.java index 4708b425dbb7..a701cb303347 100644 --- a/cli/src/main/java/hudson/cli/DiagnosedStreamCorruptionException.java +++ b/cli/src/main/java/hudson/cli/DiagnosedStreamCorruptionException.java @@ -41,14 +41,14 @@ public String toString() { buf.append(super.toString()).append("\n"); buf.append("Read back: ").append(HexDump.toHex(readBack)).append('\n'); buf.append("Read ahead: ").append(HexDump.toHex(readAhead)); - if (diagnoseFailure!=null) { + if (diagnoseFailure != null) { StringWriter w = new StringWriter(); PrintWriter p = new PrintWriter(w); diagnoseFailure.printStackTrace(p); p.flush(); buf.append("\nDiagnosis problem:\n "); - buf.append(w.toString().trim().replace("\n","\n ")); + buf.append(w.toString().trim().replace("\n", "\n ")); } return buf.toString(); } diff --git a/cli/src/main/java/hudson/cli/FlightRecorderInputStream.java b/cli/src/main/java/hudson/cli/FlightRecorderInputStream.java index 505eddccf0fd..5a1167c4fdc5 100644 --- a/cli/src/main/java/hudson/cli/FlightRecorderInputStream.java +++ b/cli/src/main/java/hudson/cli/FlightRecorderInputStream.java @@ -1,7 +1,6 @@ package hudson.cli; import edu.umd.cs.findbugs.annotations.NonNull; - import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; @@ -53,13 +52,13 @@ public DiagnosedStreamCorruptionException analyzeCrash(Exception problem, String final ByteArrayOutputStream readAhead = new ByteArrayOutputStream(); final IOException[] error = new IOException[1]; - Thread diagnosisThread = new Thread(diagnosisName+" stream corruption diagnosis thread") { + Thread diagnosisThread = new Thread(diagnosisName + " stream corruption diagnosis thread") { @Override public void run() { int b; try { // not all InputStream will look for the thread interrupt flag, so check that explicitly to be defensive - while (!Thread.interrupted() && (b=source.read())!=-1) { + while (!Thread.interrupted() && (b = source.read()) != -1) { readAhead.write(b); } } catch (IOException e) { @@ -82,14 +81,14 @@ public void run() { if (diagnosisThread.isAlive()) diagnosisThread.interrupt(); // if it's not dead, kill - return new DiagnosedStreamCorruptionException(problem,diagnosisProblem,getRecord(),readAhead.toByteArray()); + return new DiagnosedStreamCorruptionException(problem, diagnosisProblem, getRecord(), readAhead.toByteArray()); } @Override public int read() throws IOException { int i = source.read(); - if (i>=0) + if (i >= 0) recorder.write(i); return i; } @@ -97,8 +96,8 @@ public int read() throws IOException { @Override public int read(@NonNull byte[] b, int off, int len) throws IOException { len = source.read(b, off, len); - if (len>0) - recorder.write(b,off,len); + if (len > 0) + recorder.write(b, off, len); return len; } @@ -107,8 +106,8 @@ public int read(@NonNull byte[] b, int off, int len) throws IOException { */ @Override public long skip(long n) throws IOException { - byte[] buf = new byte[(int)Math.min(n,64*1024)]; - return read(buf,0,buf.length); + byte[] buf = new byte[(int) Math.min(n, 64 * 1024)]; + return read(buf, 0, buf.length); } @Override @@ -158,12 +157,12 @@ public synchronized byte[] toByteArray() { System.arraycopy(data, 0, ret, capacity - pos, pos); return ret; } - + /** @author @roadrunner2 */ @Override public synchronized void write(@NonNull byte[] buf, int off, int len) { // no point in trying to copy more than capacity; this also simplifies logic below if (len > capacity) { - off += (len - capacity); + off += len - capacity; len = capacity; } diff --git a/cli/src/main/java/hudson/cli/FullDuplexHttpStream.java b/cli/src/main/java/hudson/cli/FullDuplexHttpStream.java index fe8db4511691..ae8917ab3aa6 100644 --- a/cli/src/main/java/hudson/cli/FullDuplexHttpStream.java +++ b/cli/src/main/java/hudson/cli/FullDuplexHttpStream.java @@ -1,7 +1,6 @@ package hudson.cli; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; - import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -19,7 +18,7 @@ */ public class FullDuplexHttpStream { private final URL base; - + private final OutputStream output; private final InputStream input; @@ -66,7 +65,7 @@ public FullDuplexHttpStream(URL base, String relativeTarget, String authorizatio con.setDoOutput(true); // request POST to avoid caching con.setRequestMethod("POST"); con.addRequestProperty("Session", uuid.toString()); - con.addRequestProperty("Side","download"); + con.addRequestProperty("Side", "download"); if (authorization != null) { con.addRequestProperty("Authorization", authorization); } @@ -84,11 +83,11 @@ public FullDuplexHttpStream(URL base, String relativeTarget, String authorizatio con.setDoOutput(true); // request POST con.setRequestMethod("POST"); con.setChunkedStreamingMode(0); - con.setRequestProperty("Content-type","application/octet-stream"); + con.setRequestProperty("Content-type", "application/octet-stream"); con.addRequestProperty("Session", uuid.toString()); - con.addRequestProperty("Side","upload"); + con.addRequestProperty("Side", "upload"); if (authorization != null) { - con.addRequestProperty ("Authorization", authorization); + con.addRequestProperty("Authorization", authorization); } output = con.getOutputStream(); LOGGER.fine("established upload side"); @@ -119,5 +118,5 @@ private URL tryToResolveRedirects(URL base, String authorization) { static final int BLOCK_SIZE = 1024; static final Logger LOGGER = Logger.getLogger(FullDuplexHttpStream.class.getName()); - + } diff --git a/cli/src/main/java/hudson/cli/HexDump.java b/cli/src/main/java/hudson/cli/HexDump.java index ad37158bc16d..0132f47f130d 100644 --- a/cli/src/main/java/hudson/cli/HexDump.java +++ b/cli/src/main/java/hudson/cli/HexDump.java @@ -9,13 +9,14 @@ class HexDump { private static final String CODE = "0123456789abcdef"; public static String toHex(byte[] buf) { - return toHex(buf,0,buf.length); + return toHex(buf, 0, buf.length); } + public static String toHex(byte[] buf, int start, int len) { - StringBuilder r = new StringBuilder(len*2); + StringBuilder r = new StringBuilder(len * 2); boolean inText = false; - for (int i=0; i= 0x20 && b <= 0x7e) { if (!inText) { inText = true; @@ -28,8 +29,8 @@ public static String toHex(byte[] buf, int start, int len) { inText = false; } r.append("0x"); - r.append(CODE.charAt((b>>4)&15)); - r.append(CODE.charAt(b&15)); + r.append(CODE.charAt((b >> 4) & 15)); + r.append(CODE.charAt(b & 15)); if (i < len - 1) { if (b == 10) { r.append('\n'); diff --git a/cli/src/main/java/hudson/cli/NoCheckTrustManager.java b/cli/src/main/java/hudson/cli/NoCheckTrustManager.java index cceacf2b21cb..8a29a22305b3 100644 --- a/cli/src/main/java/hudson/cli/NoCheckTrustManager.java +++ b/cli/src/main/java/hudson/cli/NoCheckTrustManager.java @@ -1,23 +1,25 @@ package hudson.cli; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; - -import javax.net.ssl.X509TrustManager; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; +import javax.net.ssl.X509TrustManager; /** * @author Kohsuke Kawaguchi */ public class NoCheckTrustManager implements X509TrustManager { + @Override @SuppressFBWarnings(value = "WEAK_TRUST_MANAGER", justification = "User set parameter to skip verifier.") public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { } + @Override @SuppressFBWarnings(value = "WEAK_TRUST_MANAGER", justification = "User set parameter to skip verifier.") public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { } + @Override @SuppressFBWarnings(value = "WEAK_TRUST_MANAGER", justification = "User set parameter to skip verifier.") public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; diff --git a/cli/src/main/java/hudson/cli/PlainCLIProtocol.java b/cli/src/main/java/hudson/cli/PlainCLIProtocol.java index 6ed5dc6eae02..4f4fcfc49a66 100644 --- a/cli/src/main/java/hudson/cli/PlainCLIProtocol.java +++ b/cli/src/main/java/hudson/cli/PlainCLIProtocol.java @@ -24,6 +24,7 @@ package hudson.cli; +import edu.umd.cs.findbugs.annotations.NonNull; import java.io.ByteArrayOutputStream; import java.io.Closeable; import java.io.DataInputStream; @@ -36,8 +37,6 @@ import java.nio.channels.ReadPendingException; import java.util.logging.Level; import java.util.logging.Logger; - -import edu.umd.cs.findbugs.annotations.NonNull; import org.apache.commons.io.IOUtils; import org.apache.commons.io.input.BoundedInputStream; import org.apache.commons.io.input.CountingInputStream; @@ -74,6 +73,7 @@ private enum Op { STDERR(false); /** True if sent from the client to the server; false if sent from the server to the client. */ final boolean clientSide; + Op(boolean clientSide) { this.clientSide = clientSide; } @@ -234,10 +234,12 @@ protected final OutputStream stream(final Op op) { public void write(int b) throws IOException { send(op, new byte[] {(byte) b}); } + @Override public void write(@NonNull byte[] b, int off, int len) throws IOException { send(op, b, off, len); } + @Override public void write(@NonNull byte[] b) throws IOException { send(op, b); diff --git a/cli/src/main/java/hudson/cli/PrivateKeyProvider.java b/cli/src/main/java/hudson/cli/PrivateKeyProvider.java index cdcbcb1d52e5..64c84fc2074d 100644 --- a/cli/src/main/java/hudson/cli/PrivateKeyProvider.java +++ b/cli/src/main/java/hudson/cli/PrivateKeyProvider.java @@ -21,17 +21,18 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.cli; import static java.util.logging.Level.FINE; -import static java.nio.charset.StandardCharsets.UTF_8; +import java.io.ByteArrayInputStream; import java.io.Console; import java.io.DataInputStream; -import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.InvalidPathException; import java.nio.file.Paths; @@ -44,7 +45,6 @@ import java.util.List; import java.util.logging.Logger; import java.util.stream.StreamSupport; - import org.apache.sshd.common.config.keys.FilePasswordProvider; import org.apache.sshd.common.util.io.resource.PathResource; import org.apache.sshd.common.util.security.SecurityUtils; @@ -111,15 +111,15 @@ public void readFrom(File keyFile) throws IOException, GeneralSecurityException privateKeys.add(loadKey(keyFile, password)); } - private static boolean isPemEncrypted(File f) throws IOException{ + private static boolean isPemEncrypted(File f) throws IOException { //simple check if the file is encrypted return readPemFile(f).contains("4,ENCRYPTED"); } - private static String askForPasswd(String filePath){ + private static String askForPasswd(String filePath) { Console cons = System.console(); String passwd = null; - if (cons != null){ + if (cons != null) { char[] p = cons.readPassword("%s", "Enter passphrase for " + filePath + ":"); passwd = String.valueOf(p); } @@ -130,12 +130,12 @@ public static KeyPair loadKey(File f, String passwd) throws IOException, General return loadKey(readPemFile(f), passwd); } - private static String readPemFile(File f) throws IOException{ + private static String readPemFile(File f) throws IOException { try (InputStream is = Files.newInputStream(f.toPath()); DataInputStream dis = new DataInputStream(is)) { byte[] bytes = new byte[(int) f.length()]; dis.readFully(bytes); - return new String(bytes); + return new String(bytes, StandardCharsets.UTF_8); } catch (InvalidPathException e) { throw new IOException(e); } @@ -144,7 +144,7 @@ private static String readPemFile(File f) throws IOException{ public static KeyPair loadKey(String pemString, String passwd) throws IOException, GeneralSecurityException { Iterable itr = SecurityUtils.loadKeyPairIdentities(null, new PathResource(Paths.get("key")), - new ByteArrayInputStream(pemString.getBytes(UTF_8)), + new ByteArrayInputStream(pemString.getBytes(StandardCharsets.UTF_8)), FilePasswordProvider.of(passwd)); long numLoaded = itr == null ? 0 : StreamSupport.stream(itr.spliterator(), false).count(); if (numLoaded <= 0) { diff --git a/cli/src/main/java/hudson/cli/SSHCLI.java b/cli/src/main/java/hudson/cli/SSHCLI.java index 5321536c5c62..5badd296fbf0 100644 --- a/cli/src/main/java/hudson/cli/SSHCLI.java +++ b/cli/src/main/java/hudson/cli/SSHCLI.java @@ -24,6 +24,9 @@ package hudson.cli; +import static java.util.logging.Level.FINE; + +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.util.QuotedStringTokenizer; import java.io.IOException; import java.net.SocketAddress; @@ -36,7 +39,6 @@ import java.util.List; import java.util.Set; import java.util.logging.Level; -import static java.util.logging.Level.FINE; import java.util.logging.Logger; import org.apache.sshd.client.SshClient; import org.apache.sshd.client.channel.ClientChannel; @@ -47,12 +49,10 @@ import org.apache.sshd.client.keyverifier.ServerKeyVerifier; import org.apache.sshd.client.session.ClientSession; import org.apache.sshd.common.future.WaitableFuture; -import org.apache.sshd.common.util.io.NoCloseInputStream; -import org.apache.sshd.common.util.io.NoCloseOutputStream; +import org.apache.sshd.common.util.io.input.NoCloseInputStream; +import org.apache.sshd.common.util.io.output.NoCloseOutputStream; import org.apache.sshd.common.util.security.SecurityUtils; -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; - /** * Implements SSH connection mode of {@link CLI}. * In a separate class to avoid any class loading of {@code sshd-core} when not using {@code -ssh} mode. @@ -85,7 +85,7 @@ static int sshConnection(String jenkinsUrl, String user, List args, Priv command.append(' '); } - try(SshClient client = SshClient.setUpDefaultClient()) { + try (SshClient client = SshClient.setUpDefaultClient()) { KnownHostsServerKeyVerifier verifier = new DefaultKnownHostsServerKeyVerifier(new ServerKeyVerifier() { @Override @@ -116,7 +116,7 @@ public boolean verifyServerKey(ClientSession clientSession, SocketAddress remote Set waitMask = channel.waitFor(Collections.singletonList(ClientChannelEvent.CLOSED), 0L); - if(waitMask.contains(ClientChannelEvent.TIMEOUT)) { + if (waitMask.contains(ClientChannelEvent.TIMEOUT)) { throw new SocketTimeoutException("Failed to retrieve command result in time: " + command); } diff --git a/cli/src/main/java/hudson/util/QuotedStringTokenizer.java b/cli/src/main/java/hudson/util/QuotedStringTokenizer.java index 9b263bae6cd8..6f77b758bc1f 100644 --- a/cli/src/main/java/hudson/util/QuotedStringTokenizer.java +++ b/cli/src/main/java/hudson/util/QuotedStringTokenizer.java @@ -33,12 +33,13 @@ // See the License for the specific language governing permissions and // limitations under the License. // ======================================================================== + package hudson.util; +import java.util.ArrayList; +import java.util.List; import java.util.NoSuchElementException; import java.util.StringTokenizer; -import java.util.List; -import java.util.ArrayList; /* ------------------------------------------------------------ */ /** StringTokenizer with Quoting support. @@ -55,24 +56,24 @@ public class QuotedStringTokenizer extends StringTokenizer { - private static final String __delim=" \t\n\r"; + private static final String __delim = " \t\n\r"; private String _string; private String _delim = __delim; - private boolean _returnQuotes=false; - private boolean _returnDelimiters=false; + private boolean _returnQuotes = false; + private boolean _returnDelimiters = false; private StringBuilder _token; - private boolean _hasToken=false; - private int _i=0; - private int _lastStart=0; - private boolean _double=true; - private boolean _single=true; + private boolean _hasToken = false; + private int _i = 0; + private int _lastStart = 0; + private boolean _double = true; + private boolean _single = true; public static String[] tokenize(String str) { return new QuotedStringTokenizer(str).toArray(); } public static String[] tokenize(String str, String delimiters) { - return new QuotedStringTokenizer(str,delimiters).toArray(); + return new QuotedStringTokenizer(str, delimiters).toArray(); } /* ------------------------------------------------------------ */ @@ -94,17 +95,17 @@ public QuotedStringTokenizer(String str, boolean returnQuotes) { super(""); - _string=str; - if (delim!=null) - _delim=delim; - _returnDelimiters=returnDelimiters; - _returnQuotes=returnQuotes; + _string = str; + if (delim != null) + _delim = delim; + _returnDelimiters = returnDelimiters; + _returnQuotes = returnQuotes; - if (_delim.indexOf('\'')>=0 || - _delim.indexOf('"')>=0) - throw new Error("Can't use quotes as delimiters: "+_delim); + if (_delim.indexOf('\'') >= 0 || + _delim.indexOf('"') >= 0) + throw new Error("Can't use quotes as delimiters: " + _delim); - _token=new StringBuilder(_string.length()>1024?512:_string.length()/2); + _token = new StringBuilder(_string.length() > 1024 ? 512 : _string.length() / 2); } /* ------------------------------------------------------------ */ @@ -112,25 +113,25 @@ public QuotedStringTokenizer(String str, String delim, boolean returnDelimiters) { - this(str,delim,returnDelimiters,false); + this(str, delim, returnDelimiters, false); } /* ------------------------------------------------------------ */ public QuotedStringTokenizer(String str, String delim) { - this(str,delim,false,false); + this(str, delim, false, false); } /* ------------------------------------------------------------ */ public QuotedStringTokenizer(String str) { - this(str,null,false,false); + this(str, null, false, false); } public String[] toArray() { List r = new ArrayList<>(); - while(hasMoreTokens()) + while (hasMoreTokens()) r.add(nextToken()); return r.toArray(new String[r.size()]); } @@ -144,75 +145,75 @@ public boolean hasMoreTokens() if (_hasToken) return true; - _lastStart=_i; + _lastStart = _i; - int state=0; - boolean escape=false; - while (_i<_string.length()) + int state = 0; + boolean escape = false; + while (_i < _string.length()) { - char c=_string.charAt(_i++); + char c = _string.charAt(_i++); switch (state) { case 0: // Start - if(_delim.indexOf(c)>=0) + if (_delim.indexOf(c) >= 0) { if (_returnDelimiters) { _token.append(c); - return _hasToken=true; + return _hasToken = true; } } - else if (c=='\'' && _single) + else if (c == '\'' && _single) { if (_returnQuotes) _token.append(c); - state=2; + state = 2; } - else if (c=='\"' && _double) + else if (c == '\"' && _double) { if (_returnQuotes) _token.append(c); - state=3; + state = 3; } else { _token.append(c); - _hasToken=true; - state=1; + _hasToken = true; + state = 1; } continue; case 1: // Token - _hasToken=true; + _hasToken = true; if (escape) { - escape=false; - if(ESCAPABLE_CHARS.indexOf(c)<0) + escape = false; + if (ESCAPABLE_CHARS.indexOf(c) < 0) _token.append('\\'); _token.append(c); } - else if(_delim.indexOf(c)>=0) + else if (_delim.indexOf(c) >= 0) { if (_returnDelimiters) _i--; return _hasToken; } - else if (c=='\'' && _single) + else if (c == '\'' && _single) { if (_returnQuotes) _token.append(c); - state=2; + state = 2; } - else if (c=='\"' && _double) + else if (c == '\"' && _double) { if (_returnQuotes) _token.append(c); - state=3; + state = 3; } - else if (c=='\\') + else if (c == '\\') { - escape=true; + escape = true; } else _token.append(c); @@ -220,25 +221,25 @@ else if (c=='\\') case 2: // Single Quote - _hasToken=true; + _hasToken = true; if (escape) { - escape=false; - if(ESCAPABLE_CHARS.indexOf(c)<0) + escape = false; + if (ESCAPABLE_CHARS.indexOf(c) < 0) _token.append('\\'); _token.append(c); } - else if (c=='\'') + else if (c == '\'') { if (_returnQuotes) _token.append(c); - state=1; + state = 1; } - else if (c=='\\') + else if (c == '\\') { if (_returnQuotes) _token.append(c); - escape=true; + escape = true; } else _token.append(c); @@ -246,29 +247,32 @@ else if (c=='\\') case 3: // Double Quote - _hasToken=true; + _hasToken = true; if (escape) { - escape=false; - if(ESCAPABLE_CHARS.indexOf(c)<0) + escape = false; + if (ESCAPABLE_CHARS.indexOf(c) < 0) _token.append('\\'); _token.append(c); } - else if (c=='\"') + else if (c == '\"') { if (_returnQuotes) _token.append(c); - state=1; + state = 1; } - else if (c=='\\') + else if (c == '\\') { if (_returnQuotes) _token.append(c); - escape=true; + escape = true; } else _token.append(c); continue; + + default: + break; } } @@ -280,11 +284,11 @@ else if (c=='\\') public String nextToken() throws NoSuchElementException { - if (!hasMoreTokens() || _token==null) + if (!hasMoreTokens() || _token == null) throw new NoSuchElementException(); - String t=_token.toString(); + String t = _token.toString(); _token.setLength(0); - _hasToken=false; + _hasToken = false; return t; } @@ -293,10 +297,10 @@ public String nextToken() public String nextToken(String delim) throws NoSuchElementException { - _delim=delim; - _i=_lastStart; + _delim = delim; + _i = _lastStart; _token.setLength(0); - _hasToken=false; + _hasToken = false; return nextToken(); } @@ -335,19 +339,19 @@ public int countTokens() */ public static String quote(String s, String delim) { - if (s==null) + if (s == null) return null; - if (s.length()==0) + if (s.length() == 0) return "\"\""; - for (int i=0;i=0) + if (c == '\\' || c == '"' || c == '\'' || Character.isWhitespace(c) || delim.indexOf(c) >= 0) { - StringBuffer b=new StringBuffer(s.length()+8); - quote(b,s); + StringBuffer b = new StringBuffer(s.length() + 8); + quote(b, s); return b.toString(); } } @@ -365,13 +369,13 @@ public static String quote(String s, String delim) */ public static String quote(String s) { - if (s==null) + if (s == null) return null; - if (s.length()==0) + if (s.length() == 0) return "\"\""; - StringBuffer b=new StringBuffer(s.length()+8); - quote(b,s); + StringBuffer b = new StringBuffer(s.length() + 8); + quote(b, s); return b.toString(); } @@ -385,13 +389,13 @@ public static String quote(String s) */ public static void quote(StringBuffer buf, String s) { - synchronized(buf) + synchronized (buf) { buf.append('"'); - for (int i=0;i= '0') && (b <= '9')) return (byte)(b - '0'); - if ((b >= 'a') && (b <= 'f')) return (byte)(b - 'a' + 10); - if ((b >= 'A') && (b <= 'F')) return (byte)(b - 'A' + 10); + if (b >= '0' && b <= '9') return (byte) (b - '0'); + if (b >= 'a' && b <= 'f') return (byte) (b - 'a' + 10); + if (b >= 'A' && b <= 'F') return (byte) (b - 'A' + 10); return 0; } @@ -545,18 +547,7 @@ public static byte convertHexDigit( byte b ) * * Others, like, say, \W will be left alone instead of becoming just W. * This is important to keep Hudson behave on Windows, which uses '\' as - * the directory separator. + * the directory separator. */ private static final String ESCAPABLE_CHARS = "\\\"' "; } - - - - - - - - - - - diff --git a/cli/src/main/resources/hudson/cli/client/Messages.properties b/cli/src/main/resources/hudson/cli/client/Messages.properties index 91552ef9a9bc..33f9d33ef737 100644 --- a/cli/src/main/resources/hudson/cli/client/Messages.properties +++ b/cli/src/main/resources/hudson/cli/client/Messages.properties @@ -14,7 +14,7 @@ CLI.Usage=Jenkins CLI\n\ \ -auth [ USER:SECRET | @FILE ] : specify username and either password or API token (or load from them both from a file);\n\ \ for use with -http.\n\ \ Passing credentials by file is recommended.\n\ - \ See https://jenkins.io/redirect/cli-http-connection-mode for more info and options.\n\ + \ See https://www.jenkins.io/redirect/cli-http-connection-mode for more info and options.\n\ \ -bearer [ TOKEN | @FILE ] : specify authentication using a bearer token (or load the token from file);\n\ \ for use with -http. Mutually exclusive with -auth.\n\ \ Passing credentials by file is recommended.\n\ diff --git a/cli/src/main/resources/hudson/cli/client/Messages_bg.properties b/cli/src/main/resources/hudson/cli/client/Messages_bg.properties index acd0191d5c8b..6e81e0179afb 100644 --- a/cli/src/main/resources/hudson/cli/client/Messages_bg.properties +++ b/cli/src/main/resources/hudson/cli/client/Messages_bg.properties @@ -28,7 +28,7 @@ CLI.Usage=\ \u0441\u0440\u0435\u0434\u0430\u0442\u0430 \u201eJENKINS_URL\u201c)\n\ -i \u041a\u041b\u042e\u0427 : \u0447\u0430\u0441\u0442\u0435\u043d \u043a\u043b\u044e\u0447 \u0437\u0430 SSH \u0437\u0430 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f\n\ -p \u0425\u041e\u0421\u0422:\u041f\u041e\u0420\u0422 : \u0445\u043e\u0441\u0442 \u0438 \u043f\u043e\u0440\u0442 \u0437\u0430 \u0441\u044a\u0440\u0432\u044a\u0440-\u043f\u043e\u0441\u0440\u0435\u0434\u043d\u0438\u043a \u043f\u043e HTTP \u0437\u0430 \u0442\u0443\u043d\u0435\u043b \u043f\u043e HTTPS.\n\ - \u0417\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f: https://jenkins.io/redirect/cli-https-proxy-tunnel\n\ + \u0417\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f: https://www.jenkins.io/redirect/cli-https-proxy-tunnel\n\ -noCertificateCheck : \u0431\u0435\u0437 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u0430 \u0437\u0430 HTTPS (\u0412\u041d\u0418\u041c\u0410\u041d\u0418\u0415!)\n\ -noKeyAuth : \u0431\u0435\u0437 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u0441 \u0447\u0430\u0441\u0442\u0435\u043d \u043a\u043b\u044e\u0447 \u0437\u0430 SSH, \u043e\u043f\u0446\u0438\u044f\u0442\u0430 \u0435\n\ \u043d\u0435\u0441\u044a\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u0430 \u0441 \u043e\u043f\u0446\u0438\u044f\u0442\u0430 \u201e-i\u201c\n\n\ diff --git a/cli/src/main/resources/hudson/cli/client/Messages_de.properties b/cli/src/main/resources/hudson/cli/client/Messages_de.properties index 70b91e222f02..0643a71f9f7a 100644 --- a/cli/src/main/resources/hudson/cli/client/Messages_de.properties +++ b/cli/src/main/resources/hudson/cli/client/Messages_de.properties @@ -4,7 +4,7 @@ CLI.Usage=Jenkins Kommandozeilenschnittstelle (Jenkins CLI)\n\ Optionen:\n\ -s URL : URL des Jenkins-Servers (Wert der Umgebungsvariable JENKINS_URL ist der Vorgabewert)\n\ -i KEY : Datei mit privatem SSH-Schl\u00FCssel zur Authentisierung\n\ - -p HOST\:PORT : HTTP-Proxy-Host und -Port f\u00FCr HTTPS-Proxy-Tunnel. Siehe https://jenkins.io/redirect/cli-https-proxy-tunnel\n\ + -p HOST\:PORT : HTTP-Proxy-Host und -Port f\u00FCr HTTPS-Proxy-Tunnel. Siehe https://www.jenkins.io/redirect/cli-https-proxy-tunnel\n\ -noCertificateCheck : \u00DCberspringt die Zertifikatspr\u00FCfung bei HTTPS. Bitte mit Vorsicht einsetzen.\n\ -noKeyAuth : \u00DCberspringt die Authentifizierung mit einem privaten SSH-Schl\u00FCssel. Nicht kombinierbar mit -i\n\ \n\ diff --git a/cli/src/main/resources/hudson/cli/client/Messages_es.properties b/cli/src/main/resources/hudson/cli/client/Messages_es.properties index b8ff42b3c23b..304669d0531b 100644 --- a/cli/src/main/resources/hudson/cli/client/Messages_es.properties +++ b/cli/src/main/resources/hudson/cli/client/Messages_es.properties @@ -6,7 +6,7 @@ CLI.Usage=Jenkins CLI\n\ -ssh : usa el protocolo SSH (requiere -user; el puerto SSH debe estar abierto en el servidor y el usuario debe tener registrada su clave publica)\n\ -remoting : usa el protocolo deprecado de Remoting (siempre que est\u00e9 habilitado en el servidor; s\u00f3lo para compatibilidad con comandos heredados o legacy)\n\ -i KEY : clave privada SSH usada para autenticaci\u00f3n (usado con -ssh o -remoting)\n\ - -p HOST:PORT : host y puerto para el uso de proxy HTTPS. Ver https://jenkins.io/redirect/cli-https-proxy-tunnel\n\ + -p HOST:PORT : host y puerto para el uso de proxy HTTPS. Ver https://www.jenkins.io/redirect/cli-https-proxy-tunnel\n\ -noCertificateCheck : elude por completo la verificaci\u00f3n del certificado HTTPS. Usar con precauci\u00f3n\n\ -noKeyAuth : intenta no cargar la clave privada de autenticaci\u00f3n SSH. Presenta conflicto con -i\n\ -user : especifica el usuario (se usa con -ssh)\n\ diff --git a/cli/src/main/resources/hudson/cli/client/Messages_fr.properties b/cli/src/main/resources/hudson/cli/client/Messages_fr.properties index 99fe0930f0d8..0f424e20208a 100644 --- a/cli/src/main/resources/hudson/cli/client/Messages_fr.properties +++ b/cli/src/main/resources/hudson/cli/client/Messages_fr.properties @@ -3,7 +3,7 @@ CLI.Usage=Jenkins CLI\n\ Options:\n\ -s URL : l''URL du serveur (par d\u00e9faut : variable d environnement JENKINS_URL)\n\ -i KEY : fichier de la cl\u00e9 priv\u00e9e SSH \u00e0 utiliser pour l''authentification\n\ - -p HOST:PORT : h\u00f4te et port des proxys HTTP et HTTPS. Voir https://jenkins.io/redirect/cli-https-proxy-tunnel\n\ + -p HOST:PORT : h\u00f4te et port des proxys HTTP et HTTPS. Voir https://www.jenkins.io/redirect/cli-https-proxy-tunnel\n\ -noCertificateCheck : contourne enti\u00e9rement la v\u00e9rification des certificats HTTPS. A utiliser avec pr\u00e9caution\n\ -noKeyAuth : ne charge pas la cl\u00e9 priv\u00e9e d''authentification SSH. En conflit avec -i\n\ \n\ diff --git a/cli/src/main/resources/hudson/cli/client/Messages_it.properties b/cli/src/main/resources/hudson/cli/client/Messages_it.properties index cb2607866a19..df294ad414ee 100644 --- a/cli/src/main/resources/hudson/cli/client/Messages_it.properties +++ b/cli/src/main/resources/hudson/cli/client/Messages_it.properties @@ -56,7 +56,7 @@ CLI.Usage=Interfaccia a riga di comando di Jenkins\n\ \ raccomandato fornire le credenziali \ in un file.\n\ \ Si veda \ - https://jenkins.io/redirect/cli-http-connection-mode per ulteriori \ + https://www.jenkins.io/redirect/cli-http-connection-mode per ulteriori \ informazioni e opzioni.\n\ \ -bearer [ TOKEN | @FILE ] : specifica di utilizzare \ l'autenticazione tramite un bearer token (o carica il token da\n\ diff --git a/cli/src/main/resources/hudson/cli/client/Messages_pt_BR.properties b/cli/src/main/resources/hudson/cli/client/Messages_pt_BR.properties index 779e88f1a6ec..b2a4bfac065a 100644 --- a/cli/src/main/resources/hudson/cli/client/Messages_pt_BR.properties +++ b/cli/src/main/resources/hudson/cli/client/Messages_pt_BR.properties @@ -20,17 +20,17 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -CLI.VersionMismatch=A vers\u00e3o n\u00e3o coincide. Esta CLI n\u00e3o pode funcionar com este servidor Jenkins CLI.Usage=Jenkins CLI\n\ - Uso: java -jar jenkins-cli.jar [-s URL] comando [op\u00e7\u00f5es...] par\u00e2metros...\n\ - Op\u00e7\u00f5es:\n\ - -s URL : a URL do servidor (por padr\u00e3o a vari\u00e1vel de ambiente JENKINS_URL \u00e9 usada)\n\ - -i KEY : arquivo contendo a chave SSH privada usada para autentica\u00e7\u00e3o\n\ - -p HOST:PORT : host e porta do proxy HTTP para tunelamento de proxy HTTPS. Veja https://jenkins.io/redirect/cli-https-proxy-tunnel\n\ - -noCertificateCheck : ignora completamente a valida\u00e7\u00e3o dos certificados HTTPS. Use com cautela\n\ - -noKeyAuth : n\u00e3o tenta carregar a chave privada para autentica\u00e7\u00e3o SSH. Conflita com -i\n\ + Uso: java -jar jenkins-cli.jar [-s URL] comando [op\u00E7\u00F5es...] par\u00E2metros...\n\ + Op\u00E7\u00F5es:\n\ + -s URL : a URL do servidor (por padr\u00E3o a vari\u00E1vel de ambiente JENKINS_URL \u00E9 usada)\n\ + -i KEY : arquivo contendo a chave SSH privada usada para autentica\u00E7\u00E3o\n\ + -p HOST:PORT : host e porta do proxy HTTP para tunelamento de proxy HTTPS. Veja https://www.jenkins.io/redirect/cli-https-proxy-tunnel\n\ + -noCertificateCheck : ignora completamente a valida\u00E7\u00E3o dos certificados HTTPS. Use com cautela\n\ + -noKeyAuth : n\u00E3o tenta carregar a chave privada para autentica\u00E7\u00E3o SSH. Conflita com -i\n\ \n\ - Os comandos dispon\u00edveis dependem do servidor. Execute o comando 'help' para\n\ + Os comandos dispon\u00EDveis dependem do servidor. Execute o comando 'help' para\n\ ver a lista. -CLI.NoURL=N\u00e3o foi especificado nem '-s' e nem a vari\u00e1vel de ambiente JENKINS_URL -CLI.NoSuchFileExists=O arquivo n\u00e3o existe: {0} +CLI.NoURL=N\u00E3o foi especificado nem '-s' e nem a vari\u00E1vel de ambiente JENKINS_URL +CLI.NoSuchFileExists=O arquivo n\u00E3o existe: {0} +CLI.BadAuth=As vari\u00E1veis de ambiente JENKINS_USER_ID e JENKINS_API_TOKEN precisam ser ambas configuradas ou deixadas vazias. diff --git a/cli/src/main/resources/hudson/cli/client/Messages_zh_TW.properties b/cli/src/main/resources/hudson/cli/client/Messages_zh_TW.properties index 4a9068624434..133ee774b621 100644 --- a/cli/src/main/resources/hudson/cli/client/Messages_zh_TW.properties +++ b/cli/src/main/resources/hudson/cli/client/Messages_zh_TW.properties @@ -28,7 +28,7 @@ CLI.Usage=Jenkins CLI\n\ \u9078\u9805:\n\ -s URL : \u4f3a\u670d\u5668 URL (\u9810\u8a2d\u503c\u70ba JENKINS_URL \u74b0\u5883\u8b8a\u6578)\n\ -i KEY : \u9a57\u8b49\u7528\u7684 SSH \u79c1\u9470\u6a94\n\ - -p HOST:PORT : \u5efa HTTPS Proxy Tunnel \u7684 HTTP \u4ee3\u7406\u4f3a\u670d\u5668\u4e3b\u6a5f\u53ca\u9023\u63a5\u57e0\u3002\u8acb\u53c3\u8003 https://jenkins.io/redirect/cli-https-proxy-tunnel\n\ + -p HOST:PORT : \u5efa HTTPS Proxy Tunnel \u7684 HTTP \u4ee3\u7406\u4f3a\u670d\u5668\u4e3b\u6a5f\u53ca\u9023\u63a5\u57e0\u3002\u8acb\u53c3\u8003 https://www.jenkins.io/redirect/cli-https-proxy-tunnel\n\ -noCertificateCheck : \u5b8c\u5168\u7565\u904e HTTPS \u6191\u8b49\u6aa2\u67e5\u3002\u8acb\u5c0f\u5fc3\u4f7f\u7528\n\ \n\ \u53ef\u7528\u7684\u6307\u4ee4\u53d6\u6c7a\u65bc\u4f3a\u670d\u5668\u3002\u57f7\u884c 'help' \u6307\u4ee4\u53ef\u4ee5\u67e5\u770b\u5b8c\u6574\u6e05\u55ae\u3002 diff --git a/cli/src/test/java/hudson/cli/HexDumpTest.java b/cli/src/test/java/hudson/cli/HexDumpTest.java index 095c6db3f0f7..9e15de1453cb 100644 --- a/cli/src/test/java/hudson/cli/HexDumpTest.java +++ b/cli/src/test/java/hudson/cli/HexDumpTest.java @@ -1,5 +1,9 @@ package hudson.cli; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.params.provider.Arguments.arguments; + +import java.util.stream.Stream; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; @@ -7,11 +11,6 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.params.provider.Arguments.arguments; - @Execution(ExecutionMode.CONCURRENT) public class HexDumpTest { @@ -25,9 +24,9 @@ public void testToHex1(String expected, byte[] buf) { static Stream testToHex1Sources() { return Stream.of( arguments("'fooBar'", new byte[] {'f', 'o', 'o', 'B', 'a', 'r'}), - arguments("0xc3", new byte[] {(byte)'Ã'}), - arguments("0xac '100'", new byte[] {(byte)'€', '1', '0', '0'}), - arguments("'1' 0xf7 '2'", new byte[] {'1', (byte)'÷', '2'}), + arguments("0xc3", new byte[] {(byte) 'Ã'}), + arguments("0xac '100'", new byte[] {(byte) '€', '1', '0', '0'}), + arguments("'1' 0xf7 '2'", new byte[] {'1', (byte) '÷', '2'}), arguments("'foo' 0x0a\n'Bar'", new byte[] {'f', 'o', 'o', '\n', 'B', 'a', 'r'}) ); } @@ -42,9 +41,9 @@ public void testToHex2(String expected, byte[] buf, int start, int len) { static Stream testToHex2Sources() { return Stream.of( arguments("'ooBa'", new byte[] {'f', 'o', 'o', 'B', 'a', 'r'}, 1, 4), - arguments("0xc3", new byte[] {(byte)'Ã'}, 0, 1), - arguments("0xac '10'", new byte[] {(byte)'€', '1', '0', '0'}, 0, 3), - arguments("0xf7 '2'", new byte[] {'1', (byte)'÷', '2'}, 1, 2), + arguments("0xc3", new byte[] {(byte) 'Ã'}, 0, 1), + arguments("0xac '10'", new byte[] {(byte) '€', '1', '0', '0'}, 0, 3), + arguments("0xf7 '2'", new byte[] {'1', (byte) '÷', '2'}, 1, 2), arguments("'Bar'", new byte[] {'f', 'o', 'o', '\n', 'B', 'a', 'r'}, 4, 3), arguments("", new byte[] {'f', 'o', 'o', 'B', 'a', 'r'}, 0, 0) ); diff --git a/cli/src/test/java/hudson/cli/PlainCLIProtocolTest.java b/cli/src/test/java/hudson/cli/PlainCLIProtocolTest.java index 953b01d02ca8..98a4fefd8001 100644 --- a/cli/src/test/java/hudson/cli/PlainCLIProtocolTest.java +++ b/cli/src/test/java/hudson/cli/PlainCLIProtocolTest.java @@ -24,16 +24,15 @@ package hudson.cli; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.PipedInputStream; import java.io.PipedOutputStream; - -import static org.junit.jupiter.api.Assertions.assertEquals; - +import java.nio.charset.Charset; +import org.junit.jupiter.api.Test; public class PlainCLIProtocolTest { @@ -44,27 +43,34 @@ public void ignoreUnknownOperations() throws Exception { class Client extends PlainCLIProtocol.ClientSide { int code = -1; final ByteArrayOutputStream stdout = new ByteArrayOutputStream(); + Client() throws IOException { super(new PlainCLIProtocol.FramedOutput(upload)); } + @Override protected synchronized void onExit(int code) { this.code = code; notifyAll(); } + @Override protected void onStdout(byte[] chunk) throws IOException { stdout.write(chunk); } + @Override protected void onStderr(byte[] chunk) throws IOException {} + @Override protected void handleClose() {} + void send() throws IOException { sendArg("command"); sendStart(); - streamStdin().write("hello".getBytes()); + streamStdin().write("hello".getBytes(Charset.defaultCharset())); } + void newop() throws IOException { DataOutputStream dos = new DataOutputStream(upload); dos.writeInt(0); @@ -72,26 +78,33 @@ void newop() throws IOException { dos.flush(); } } + class Server extends PlainCLIProtocol.ServerSide { String arg; boolean started; final ByteArrayOutputStream stdin = new ByteArrayOutputStream(); + Server() throws IOException { super(new PlainCLIProtocol.FramedOutput(download)); } + @Override protected void onArg(String text) { arg = text; } + @Override protected void onLocale(String text) {} + @Override protected void onEncoding(String text) {} + @Override protected synchronized void onStart() { started = true; notifyAll(); } + @Override protected void onStdin(byte[] chunk) throws IOException { /* To inject a race condition: @@ -103,14 +116,18 @@ protected void onStdin(byte[] chunk) throws IOException { */ stdin.write(chunk); } + @Override protected void onEndStdin() throws IOException {} + @Override protected void handleClose() {} + void send() throws IOException { - streamStdout().write("goodbye".getBytes()); + streamStdout().write("goodbye".getBytes(Charset.defaultCharset())); sendExit(2); } + void newop() throws IOException { DataOutputStream dos = new DataOutputStream(download); dos.writeInt(0); @@ -118,6 +135,7 @@ void newop() throws IOException { dos.flush(); } } + Client client = new Client(); Server server = new Server(); new PlainCLIProtocol.FramedReader(client, new PipedInputStream(download)).start(); @@ -139,9 +157,9 @@ void newop() throws IOException { while (server.stdin.size() == 0) { Thread.sleep(100); } - assertEquals("hello", server.stdin.toString()); + assertEquals("hello", server.stdin.toString(Charset.defaultCharset().name())); assertEquals("command", server.arg); - assertEquals("goodbye", client.stdout.toString()); + assertEquals("goodbye", client.stdout.toString(Charset.defaultCharset().name())); assertEquals(2, client.code); } diff --git a/cli/src/test/java/hudson/cli/PrivateKeyProviderTest.java b/cli/src/test/java/hudson/cli/PrivateKeyProviderTest.java index ab4b762a6ee8..8d960e87a461 100644 --- a/cli/src/test/java/hudson/cli/PrivateKeyProviderTest.java +++ b/cli/src/test/java/hudson/cli/PrivateKeyProviderTest.java @@ -1,9 +1,8 @@ package hudson.cli; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.parallel.Execution; -import org.junit.jupiter.api.parallel.ExecutionMode; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; import java.io.File; import java.io.IOException; @@ -11,9 +10,9 @@ import java.security.InvalidKeyException; import java.security.KeyPair; import java.security.spec.InvalidKeySpecException; - -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.Execution; +import org.junit.jupiter.api.parallel.ExecutionMode; /** keys were generated with ssh-keygen from OpenSSH_7.9p1, LibreSSL 2.7.3 @@ -51,7 +50,7 @@ public void loadKeyDSAPassword() throws IOException, GeneralSecurityException { String password = "password"; assertKeyPairNotNull(file, password); } - + /** key command: ssh-keygen -f rsa -t rsa -b 1024 -m PEM */ @@ -70,7 +69,7 @@ public void loadKeyRSAPassword() throws IOException, GeneralSecurityException { String password = "password"; assertKeyPairNotNull(file, password); } - + /** key command: ssh-keygen -f openssh -t rsa -b 1024 */ @@ -79,7 +78,7 @@ public void loadKeyOpenSSH() throws IOException, GeneralSecurityException { File file = new File(this.getClass().getResource("openssh").getFile()); assertKeyPairNotNull(file, null); } - + /** key command: ssh-keygen -f openssh-unsupported -t rsa -b 1024 -m PKCS8 -p password */ @@ -124,7 +123,7 @@ public void loadBlankKey() throws IOException, GeneralSecurityException { /** key command: ssh-keygen -f openssh -t rsa -b 1024 in this key we remove some lines to break the key. - */ + */ @Test public void loadKeyBroken() throws IOException, GeneralSecurityException { File file = new File(this.getClass().getResource("openssh-broken").getFile()); diff --git a/cli/src/test/java/hudson/util/QuotedStringTokenizerTest.java b/cli/src/test/java/hudson/util/QuotedStringTokenizerTest.java index 2ffb902f1ca0..e5c546d11c3e 100644 --- a/cli/src/test/java/hudson/util/QuotedStringTokenizerTest.java +++ b/cli/src/test/java/hudson/util/QuotedStringTokenizerTest.java @@ -21,13 +21,15 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.util; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.Arrays; - -import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; /** * @author Kohsuke Kawaguchi @@ -37,19 +39,19 @@ public class QuotedStringTokenizerTest { @Test public void test1() { check("foo bar", - "foo","bar"); + "foo", "bar"); } @Test public void test2() { check("foo \"bar zot\"", - "foo","bar zot"); + "foo", "bar zot"); } @Test public void test3() { check("foo bar=\"quote zot\"", - "foo","bar=quote zot"); + "foo", "bar=quote zot"); } @Test @@ -67,7 +69,7 @@ public void test5() { @Test public void test6() { check("foo\\\\ bar", - "foo\\","bar"); + "foo\\", "bar"); } // see http://www.nabble.com/Error-parsing-%22-in-msbuild-task-to20535754.html diff --git a/core/pom.xml b/core/pom.xml index bc8a4a1c82a3..0655b4fd724e 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -36,11 +36,12 @@ THE SOFTWARE. Jenkins core Jenkins core code and view files to render HTML. + https://github.com/jenkinsci/jenkins true 2.2 - 2.8.2 + 2.9.0 @@ -55,174 +56,87 @@ THE SOFTWARE. - - - ${project.groupId} - remoting - ${project.groupId} cli ${project.version} - org.jenkins-ci - version-number - - - org.jenkins-ci - crypto-util - - - org.jvnet.hudson - jtidy - - - jdom - jdom - - - - - - org.jenkins-ci - core-annotation-processors - 1.0 - provided - true - - - - com.google.inject - guice - - - com.google.guava - guava - - + ${project.groupId} + remoting - - org.connectbot.jbcrypt - jbcrypt - - - org.jruby.ext.posix - jna-posix - 1.0.3-jenkins-1 + antlr + antlr - com.github.jnr - jnr-posix + args4j + args4j - org.kohsuke.stapler - stapler + com.github.spotbugs + spotbugs-annotations - + com.google.code.findbugs jsr305 - org.kohsuke.stapler - stapler-groovy + com.google.guava + guava - commons-jelly - commons-jelly - - - commons-jexl - commons-jexl + com.google.errorprone + error_prone_annotations - org.jvnet.hudson - commons-jexl + com.google.j2objc + j2objc-annotations - - org.codehaus.groovy - groovy + org.checkerframework + checker-qual - org.kohsuke - windows-package-checker - - - org.kohsuke.stapler - stapler-adjunct-timeline - - - org.kohsuke.stapler - stapler-adjunct-codemirror - - - org.kohsuke.stapler - stapler-adjunct-timeline - 1.5 - tests - test - - - io.jenkins.stapler - jenkins-stapler-support - - - org.hamcrest - hamcrest - ${hamcrest.version} - test - - - org.hamcrest - hamcrest-library - ${hamcrest.version} - test + com.google.inject + guice + + + + aopalliance + aopalliance + + - com.infradna.tool bridge-method-annotation - 1.18 - - - - org.kohsuke.stapler - json-lib - - - commons-httpclient - commons-httpclient - - - args4j - args4j - - - org.jenkins-ci - annotation-indexer + ${bridge-method-injector.version} - org.jenkins-ci - bytecode-compatibility-transformer - - - org.jenkins-ci - task-reactor + + com.jcraft + jzlib - org.jvnet.localizer - localizer + com.sun.solaris + embedded_su4j - antlr - antlr + com.sun.xml.txw2 + txw2 + + + + javax.xml.stream + stax-api + + com.thoughtworks.xstream @@ -238,139 +152,196 @@ THE SOFTWARE. - - xpp3 - xpp3 - 1.1.4c + commons-beanutils + commons-beanutils - net.sf.kxml - kxml2 + commons-codec + commons-codec - org.jfree - jfreechart + commons-collections + commons-collections - org.apache.ant - ant + commons-fileupload + commons-fileupload - javax.servlet - javax.servlet-api - 3.1.0 - provided + commons-httpclient + commons-httpclient commons-io commons-io - - commons-lang - commons-lang + + commons-jelly + commons-jelly-tags-fmt - commons-digester - commons-digester + commons-jelly + commons-jelly-tags-xml - xml-apis - xml-apis + commons-jelly + commons-jelly - - - - commons-beanutils - commons-beanutils - - - org.apache.commons - commons-compress - - - com.sun.mail - jakarta.mail - - - jaxen - jaxen - - dom4j - dom4j + commons-jelly + commons-jelly-tags-junit - xom - xom + commons-jexl + commons-jexl - xml-apis - xml-apis + dom4j + dom4j + + + xalan + xalan xerces xercesImpl - jdom - jdom + xml-apis + xml-apis - commons-jelly - commons-jelly-tags-fmt + + commons-lang + commons-lang - commons-jelly - commons-jelly-tags-xml + io.jenkins.stapler + jenkins-stapler-support + + + + jakarta.servlet.jsp.jstl + jakarta.servlet.jsp.jstl-api + + + jaxen + jaxen - commons-jelly - commons-jelly + dom4j + dom4j - commons-jexl - commons-jexl + jdom + jdom - commons-jelly - commons-jelly-tags-junit + xerces + xercesImpl xml-apis xml-apis - xalan - xalan - - - xerces - xercesImpl - - - dom4j - dom4j + xom + xom + + + jline + jline + 2.14.6 + compile + + + net.java.dev.jna + jna + + + net.java.sezpoz + sezpoz + + + net.jcip + jcip-annotations + + + net.sf.kxml + kxml2 + + + org.apache.ant + ant + + + org.apache.commons + commons-compress + + + org.codehaus.groovy + groovy-all + + + org.connectbot.jbcrypt + jbcrypt + + + + org.fusesource.jansi + jansi + + + org.jenkins-ci + annotation-indexer + + + org.jenkins-ci + commons-jexl + + + org.jenkins-ci + crypto-util + + + org.jenkins-ci + memory-monitor + + + org.jenkins-ci + symbol-annotation + + + org.jenkins-ci + task-reactor + + + org.jenkins-ci + version-number + + + org.jfree + jfreechart + org.jvnet.hudson commons-jelly-tags-define - - dom4j - dom4j - commons-cli commons-cli + + dom4j + dom4j + org.jvnet.hudson commons-jelly @@ -378,203 +349,203 @@ THE SOFTWARE. - org.jenkins-ci - commons-jexl + org.jvnet.localizer + localizer - org.springframework.security - spring-security-web - - - org.springframework - spring-jcl - - + org.jvnet.robust-http-client + robust-http-client - org.codehaus.groovy - groovy-all - - - jline - jline - 2.14.6 - compile - - - org.fusesource.jansi - jansi + org.jvnet.winp + winp - org.junit.jupiter - junit-jupiter-api - ${junit.jupiter.version} - test + org.kohsuke + access-modifier-annotation - org.junit.jupiter - junit-jupiter-engine - ${junit.jupiter.version} - test + org.kohsuke + windows-package-checker - org.junit.vintage - junit-vintage-engine - ${junit.jupiter.version} - test + org.kohsuke.jinterop + j-interop - org.junit.jupiter - junit-jupiter - ${junit.jupiter.version} - test + + org.kohsuke.metainf-services + metainf-services + 1.9 + true - org.mockito - mockito-core - test + org.kohsuke.stapler + json-lib - org.powermock - powermock-module-junit4 - test + org.kohsuke.stapler + stapler - org.powermock - powermock-api-mockito2 - test - - - jakarta.servlet.jsp.jstl - jakarta.servlet.jsp.jstl-api + org.kohsuke.stapler + stapler-adjunct-codemirror - org.slf4j - jcl-over-slf4j + org.kohsuke.stapler + stapler-adjunct-timeline - org.slf4j - log4j-over-slf4j + org.kohsuke.stapler + stapler-groovy + + + commons-jelly + commons-jelly + + + commons-jexl + commons-jexl + + + + org.codehaus.groovy + groovy + + + org.jvnet.hudson + commons-jexl + + - org.slf4j - slf4j-jdk14 - test + org.ow2.asm + asm - com.sun.xml.txw2 - txw2 + org.ow2.asm + asm-analysis - commons-collections - commons-collections + org.ow2.asm + asm-commons - org.jvnet.winp - winp + org.ow2.asm + asm-tree - org.jenkins-ci - memory-monitor - - - org.codehaus.woodstox - wstx-asl + org.ow2.asm + asm-util - net.java.dev.jna - jna + org.slf4j + jcl-over-slf4j - org.kohsuke - akuma + org.slf4j + log4j-over-slf4j - org.kohsuke - libpam4j + org.springframework.security + spring-security-web + + + org.springframework + spring-jcl + + - com.sun.solaris - embedded_su4j + + xpp3 + xpp3 + 1.1.4c - net.java.sezpoz - sezpoz + javax.servlet + javax.servlet-api + 3.1.0 + provided - org.kohsuke.jinterop - j-interop - - - org.kohsuke.metainf-services - metainf-services - 1.8 + + org.jenkins-ci + core-annotation-processors + 1.0 + provided true + + - org.jvnet.robust-http-client - robust-http-client + org.hamcrest + hamcrest + ${hamcrest.version} + test - - org.jenkins-ci - symbol-annotation - 1.1 + + org.hamcrest + hamcrest-library + ${hamcrest.version} + test - - commons-codec - commons-codec + org.jenkins-ci + test-annotations + test - - org.kohsuke - access-modifier-annotation + org.junit.jupiter + junit-jupiter + ${junit.jupiter.version} + test - - com.github.spotbugs - spotbugs-annotations - true + org.junit.jupiter + junit-jupiter-api + ${junit.jupiter.version} + test - net.jcip - jcip-annotations - true + org.junit.jupiter + junit-jupiter-engine + ${junit.jupiter.version} + test - - commons-fileupload - commons-fileupload + org.junit.vintage + junit-vintage-engine + ${junit.jupiter.version} + test - - - - - com.google.guava - guava - - - com.google.code.findbugs - jsr305 - - + + org.kohsuke.stapler + stapler-adjunct-timeline + 1.5 + tests + test - com.google.guava - guava-testlib + org.mockito + mockito-inline + ${mockito.version} test - - com.jcraft - jzlib + org.slf4j + slf4j-jdk14 + test org.xmlunit @@ -592,26 +563,26 @@ THE SOFTWARE. - - org.codehaus.mojo - build-helper-maven-plugin - - - - add-source - generate-sources - - add-source - - - - ${project.build.directory}/generated-sources/antlr - ${project.build.directory}/generated-sources/localizer - ${project.build.directory}/generated-sources/taglib-interface - - - - + + org.codehaus.mojo + build-helper-maven-plugin + + + + add-source + + add-source + + generate-sources + + + ${project.build.directory}/generated-sources/antlr + ${project.build.directory}/generated-sources/localizer + ${project.build.directory}/generated-sources/taglib-interface + + + + org.jenkins-ci.tools @@ -655,7 +626,8 @@ THE SOFTWARE. maven-stapler-plugin - ${staplerFork} + + ${staplerFork} 128m @@ -720,11 +692,11 @@ THE SOFTWARE. winsw - generate-resources copy + generate-resources @@ -746,11 +718,11 @@ THE SOFTWARE. 0.5C - true - -noverify + false - + + maven-jar-plugin @@ -768,7 +740,8 @@ THE SOFTWARE. - + + org.kohsuke.stapler maven-stapler-plugin @@ -778,7 +751,8 @@ THE SOFTWARE. - + + maven-project-info-reports-plugin @@ -825,12 +799,12 @@ THE SOFTWARE. - + spotbugs - true + true @@ -845,37 +819,17 @@ THE SOFTWARE. - japicmp + jdk-9-and-above + + [9,) + - com.github.siom79.japicmp - japicmp-maven-plugin - 0.14.4-20200728.214757-1 + maven-surefire-plugin - - - \d+[.]\d+ - - true - - - - javax.servlet - javax.servlet-api - 3.1.0 - provided - - + --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED - - - verify - - cmp - - - diff --git a/core/src/main/grammar/labelExpr.g b/core/src/main/grammar/labelExpr.g index 4aa14b70f9ab..c100f9e11cd9 100644 --- a/core/src/main/grammar/labelExpr.g +++ b/core/src/main/grammar/labelExpr.g @@ -86,6 +86,10 @@ class LabelExpressionLexer extends Lexer; options { // There must be an options section to satisfy // org.codehaus.mojo.antlr.metadata.MetadataExtracter#intrepret, even if it is empty. + + // https://www.antlr2.org/doc/lexer.html#Common_prefixes + // to prevent nondeterminism between IMPLIES and ATOM related to the first "-" + k=2; } AND: "&&"; @@ -98,12 +102,21 @@ RPAREN: ")"; protected IDENTIFIER_PART - : ~( '&' | '|' | '!' | '<' | '>' | '(' | ')' | ' ' | '\t' | '\"' | '\'' ) + : ~( '&' | '|' | '!' | '<' | '>' | '(' | ')' | ' ' | '\t' | '\"' | '\'' | '-' ) ; ATOM -/* the real check of valid identifier happens in LabelAtom.get() */ - : (IDENTIFIER_PART)+ +/* + the real check of valid identifier happens in LabelAtom.get() + + https://www.antlr2.org/doc/lexer.html#usingexplicit + If we are seeing currently a '-', we check that the next char is not a '>' which will be a IMPLIES. + Otherwise the ATOM and the IMPLIES will collide and expr like a->b will just be parsed as ATOM (without spaces) +*/ + : ( + { LA(2) != '>' }? '-' + | IDENTIFIER_PART + )+ ; WS diff --git a/core/src/main/java/hudson/AbortException.java b/core/src/main/java/hudson/AbortException.java index b68276e8eec1..d3d58122c87e 100644 --- a/core/src/main/java/hudson/AbortException.java +++ b/core/src/main/java/hudson/AbortException.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson; import java.io.IOException; diff --git a/core/src/main/java/hudson/AboutJenkins.java b/core/src/main/java/hudson/AboutJenkins.java index 9876f5701b47..c3c5c43a6e2e 100644 --- a/core/src/main/java/hudson/AboutJenkins.java +++ b/core/src/main/java/hudson/AboutJenkins.java @@ -1,10 +1,9 @@ package hudson; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.model.ManagementLink; import hudson.security.Permission; import java.net.URL; - -import edu.umd.cs.findbugs.annotations.NonNull; import jenkins.model.Jenkins; import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; @@ -12,14 +11,14 @@ /** * Show "About Jenkins" link. - * + * * @author Kohsuke Kawaguchi */ @Extension @Symbol("about") public class AboutJenkins extends ManagementLink { @Override public String getIconFileName() { - return "help.png"; + return "symbol-jenkins"; } @Override @@ -27,6 +26,7 @@ public String getUrlName() { return "about"; } + @Override public String getDisplayName() { return Messages.AboutJenkins_DisplayName(); } diff --git a/core/src/main/java/hudson/AbstractMarkupText.java b/core/src/main/java/hudson/AbstractMarkupText.java index e909b7e9ddd0..b13eeaad3edd 100644 --- a/core/src/main/java/hudson/AbstractMarkupText.java +++ b/core/src/main/java/hudson/AbstractMarkupText.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,14 +21,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson; import hudson.MarkupText.SubText; - -import java.util.List; import java.util.ArrayList; -import java.util.regex.Pattern; +import java.util.List; import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Common part between {@link MarkupText} and {@link MarkupText.SubText}. @@ -75,15 +75,15 @@ public final int length() { * For example, if the text was "abc", then {@code addMarkup(1,2,"","")} * would generate {@code "abc"} */ - public abstract void addMarkup( int startPos, int endPos, String startTag, String endTag ); + public abstract void addMarkup(int startPos, int endPos, String startTag, String endTag); /** * Inserts an A tag that surrounds the given position. * * @since 1.349 */ - public void addHyperlink( int startPos, int endPos, String url ) { - addMarkup(startPos,endPos,"",""); + public void addHyperlink(int startPos, int endPos, String url) { + addMarkup(startPos, endPos, "", ""); } /** @@ -92,22 +92,22 @@ public void addHyperlink( int startPos, int endPos, String url ) { * * @since 1.395 */ - public void addHyperlinkLowKey( int startPos, int endPos, String url ) { - addMarkup(startPos,endPos,"",""); + public void addHyperlinkLowKey(int startPos, int endPos, String url) { + addMarkup(startPos, endPos, "", ""); } /** * Hides the given text. */ - public void hide( int startPos, int endPos ) { - addMarkup(startPos,endPos,"",""); + public void hide(int startPos, int endPos) { + addMarkup(startPos, endPos, "", ""); } /** * Adds a start tag and end tag around the entire text */ public final void wrapBy(String startTag, String endTag) { - addMarkup(0,length(),startTag,endTag); + addMarkup(0, length(), startTag, endTag); } /** @@ -119,7 +119,7 @@ public MarkupText.SubText findToken(Pattern pattern) { String text = getText(); Matcher m = pattern.matcher(text); - if(m.find()) + if (m.find()) return createSubText(m); return null; @@ -143,17 +143,17 @@ public List findTokens(Pattern pattern) { Matcher m = pattern.matcher(text); List r = new ArrayList<>(); - while(m.find()) { + while (m.find()) { int idx = m.start(); - if(idx>0) { - char ch = text.charAt(idx-1); - if(Character.isLetter(ch) || Character.isDigit(ch)) + if (idx > 0) { + char ch = text.charAt(idx - 1); + if (Character.isLetter(ch) || Character.isDigit(ch)) continue; // not at a word boundary } idx = m.end(); - if(idx { }; } diff --git a/core/src/main/java/hudson/ClassicPluginStrategy.java b/core/src/main/java/hudson/ClassicPluginStrategy.java index 8f24c084f409..356e6e8e9065 100644 --- a/core/src/main/java/hudson/ClassicPluginStrategy.java +++ b/core/src/main/java/hudson/ClassicPluginStrategy.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Jean-Baptiste Quenot, Tom Huybrechts - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,8 +21,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson; +import static org.apache.commons.io.FilenameUtils.getBaseName; + +import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.Plugin.DummyImpl; import hudson.PluginWrapper.Dependency; @@ -31,35 +35,12 @@ import hudson.util.CyclicGraphDetector.CycleDetectedException; import hudson.util.IOUtils; import hudson.util.MaskingClassLoader; -import jenkins.ClassLoaderReflectionToolkit; -import jenkins.ExtensionFilter; -import jenkins.plugins.DetachedPluginsUtil; -import jenkins.util.AntClassLoader; -import jenkins.util.AntWithFindResourceClassLoader; -import jenkins.util.SystemProperties; -import org.apache.commons.io.output.NullOutputStream; -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.Project; -import org.apache.tools.ant.taskdefs.Expand; -import org.apache.tools.ant.taskdefs.Zip; -import org.apache.tools.ant.types.FileSet; -import org.apache.tools.ant.types.PatternSet; -import org.apache.tools.ant.types.Resource; -import org.apache.tools.ant.types.ZipFileSet; -import org.apache.tools.ant.types.resources.MappedResourceCollection; -import org.apache.tools.ant.util.GlobPatternMapper; -import org.apache.tools.zip.ZipEntry; -import org.apache.tools.zip.ZipExtraField; -import org.apache.tools.zip.ZipOutputStream; -import org.jenkinsci.bytecode.Transformer; - -import edu.umd.cs.findbugs.annotations.NonNull; -import java.io.Closeable; import java.io.File; import java.io.FileNotFoundException; import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; import java.net.URL; import java.nio.file.Files; import java.nio.file.InvalidPathException; @@ -74,8 +55,26 @@ import java.util.jar.Manifest; import java.util.logging.Level; import java.util.logging.Logger; - -import static org.apache.commons.io.FilenameUtils.getBaseName; +import jenkins.ClassLoaderReflectionToolkit; +import jenkins.ExtensionFilter; +import jenkins.plugins.DetachedPluginsUtil; +import jenkins.util.AntClassLoader; +import jenkins.util.SystemProperties; +import jenkins.util.URLClassLoader2; +import org.apache.commons.io.output.NullOutputStream; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.taskdefs.Expand; +import org.apache.tools.ant.taskdefs.Zip; +import org.apache.tools.ant.types.FileSet; +import org.apache.tools.ant.types.PatternSet; +import org.apache.tools.ant.types.Resource; +import org.apache.tools.ant.types.ZipFileSet; +import org.apache.tools.ant.types.resources.MappedResourceCollection; +import org.apache.tools.ant.util.GlobPatternMapper; +import org.apache.tools.zip.ZipEntry; +import org.apache.tools.zip.ZipExtraField; +import org.apache.tools.zip.ZipOutputStream; public class ClassicPluginStrategy implements PluginStrategy { @@ -84,13 +83,9 @@ public class ClassicPluginStrategy implements PluginStrategy { /** * Filter for jar files. */ - private static final FilenameFilter JAR_FILTER = new FilenameFilter() { - public boolean accept(File dir,String name) { - return name.endsWith(".jar"); - } - }; + private static final FilenameFilter JAR_FILTER = (dir, name) -> name.endsWith(".jar"); - private PluginManager pluginManager; + private final PluginManager pluginManager; /** * All the plugins eventually delegate this classloader to load core, servlet APIs, and SE runtime. @@ -127,7 +122,7 @@ private static boolean isLinked(File archive) { } private static Manifest loadLinkedManifest(File archive) throws IOException { - // resolve the .hpl file to the location of the manifest file + // resolve the .hpl file to the location of the manifest file try { // Locate the manifest String firstLine; @@ -143,7 +138,7 @@ private static Manifest loadLinkedManifest(File archive) throws IOException { // indirection archive = resolve(archive, firstLine); } - + // Read the manifest try (InputStream manifestInput = Files.newInputStream(archive.toPath())) { return new Manifest(manifestInput); @@ -166,7 +161,7 @@ private static Manifest loadLinkedManifest(File archive) throws IOException { if (isLinked) { manifest = loadLinkedManifest(archive); } else { - if (archive.isDirectory()) {// already expanded + if (archive.isDirectory()) { // already expanded expandDir = archive; } else { File f = pluginManager.getWorkDir(); @@ -201,7 +196,7 @@ private static Manifest loadLinkedManifest(File archive) throws IOException { parseClassPath(manifest, archive, paths, "Libraries", ","); parseClassPath(manifest, archive, paths, "Class-Path", " +"); // backward compatibility - baseResourceURL = resolve(archive,atts.getValue("Resource-Path")).toURI().toURL(); + baseResourceURL = resolve(archive, atts.getValue("Resource-Path")).toURI().toURL(); } else { File classes = new File(expandDir, "WEB-INF/classes"); if (classes.exists()) { // should not normally happen, due to createClassJarFromWebInfClasses @@ -238,19 +233,19 @@ private static Manifest loadLinkedManifest(File archive) throws IOException { } } } - - fix(atts,optionalDependencies); + + fix(atts, optionalDependencies); // Register global classpath mask. This is useful for hiding JavaEE APIs that you might see from the container, // such as database plugin for JPA support. The Mask-Classes attribute is insufficient because those classes // also need to be masked by all the other plugins that depend on the database plugin. String masked = atts.getValue("Global-Mask-Classes"); - if(masked!=null) { + if (masked != null) { for (String pkg : masked.trim().split("[ \t\r\n]+")) coreClassLoader.add(pkg); } - ClassLoader dependencyLoader = new DependencyClassLoader(coreClassLoader, archive, Util.join(dependencies,optionalDependencies)); + ClassLoader dependencyLoader = new DependencyClassLoader(coreClassLoader, archive, Util.join(dependencies, optionalDependencies), pluginManager); dependencyLoader = getBaseClassLoader(atts, dependencyLoader); return new PluginWrapper(pluginManager, archive, manifest, baseResourceURL, @@ -259,9 +254,9 @@ private static Manifest loadLinkedManifest(File archive) throws IOException { private void fix(Attributes atts, List optionalDependencies) { String pluginName = atts.getValue("Short-Name"); - + String jenkinsVersion = atts.getValue("Jenkins-Version"); - if (jenkinsVersion==null) + if (jenkinsVersion == null) jenkinsVersion = atts.getValue("Hudson-Version"); for (Dependency d : DetachedPluginsUtil.getImpliedDependencies(pluginName, jenkinsVersion)) { @@ -284,27 +279,40 @@ public static List getImpliedDependencies(String plugi @Deprecated protected ClassLoader createClassLoader(List paths, ClassLoader parent) throws IOException { - return createClassLoader( paths, parent, null ); + return createClassLoader(paths, parent, null); } /** * Creates the classloader that can load all the specified jar files and delegate to the given parent. */ protected ClassLoader createClassLoader(List paths, ClassLoader parent, Attributes atts) throws IOException { - if (atts != null) { - String usePluginFirstClassLoader = atts.getValue( "PluginFirstClassLoader" ); - if (Boolean.parseBoolean( usePluginFirstClassLoader )) { - PluginFirstClassLoader classLoader = new PluginFirstClassLoader(); - classLoader.setParentFirst( false ); - classLoader.setParent( parent ); - classLoader.addPathFiles( paths ); - return classLoader; + boolean usePluginFirstClassLoader = + atts != null && Boolean.parseBoolean(atts.getValue("PluginFirstClassLoader")); + + if (useAntClassLoader) { + AntClassLoader classLoader; + if (usePluginFirstClassLoader) { + classLoader = new PluginFirstClassLoader(); + classLoader.setParentFirst(false); + classLoader.setParent(parent); + } else { + classLoader = new AntClassLoader(parent, true); + } + classLoader.addPathFiles(paths); + return classLoader; + } else { + List urls = new ArrayList<>(); + for (File path : paths) { + urls.add(path.toURI().toURL()); + } + URLClassLoader2 classLoader; + if (usePluginFirstClassLoader) { + classLoader = new PluginFirstClassLoader2(urls.toArray(new URL[0]), parent); + } else { + classLoader = new URLClassLoader2(urls.toArray(new URL[0]), parent); } + return classLoader; } - - AntClassLoader2 classLoader = new AntClassLoader2(parent); - classLoader.addPathFiles(paths); - return classLoader; } /** @@ -315,18 +323,20 @@ protected ClassLoader createClassLoader(List paths, ClassLoader parent, At */ private ClassLoader getBaseClassLoader(Attributes atts, ClassLoader base) { String masked = atts.getValue("Mask-Classes"); - if(masked!=null) + if (masked != null) base = new MaskingClassLoader(base, masked.trim().split("[ \t\r\n]+")); return base; } + @Override public void initializeComponents(PluginWrapper plugin) { } + @Override public List> findComponents(Class type, Hudson hudson) { List finders; - if (type==ExtensionFinder.class) { + if (type == ExtensionFinder.class) { // Avoid infinite recursion of using ExtensionFinders to find ExtensionFinders finders = Collections.singletonList(new ExtensionFinder.Sezpoz()); } else { @@ -337,7 +347,7 @@ public List> findComponents(Class type, Hudson huds * See ExtensionFinder#scout(Class, Hudson) for the dead lock issue and what this does. */ if (LOGGER.isLoggable(Level.FINER)) - LOGGER.log(Level.FINER, "Scout-loading ExtensionList: "+type, new Throwable()); + LOGGER.log(Level.FINER, "Scout-loading ExtensionList: " + type, new Throwable()); for (ExtensionFinder finder : finders) { finder.scout(type, hudson); } @@ -355,13 +365,14 @@ public List> findComponents(Class type, Hudson huds List> filtered = new ArrayList<>(); for (ExtensionComponent e : r) { - if (ExtensionFilter.isAllowed(type,e)) + if (ExtensionFilter.isAllowed(type, e)) filtered.add(e); } return filtered; } + @Override public void load(PluginWrapper wrapper) throws IOException { // override the context classloader. This no longer makes sense, // but it is left for the backward compatibility @@ -369,21 +380,21 @@ public void load(PluginWrapper wrapper) throws IOException { Thread.currentThread().setContextClassLoader(wrapper.classLoader); try { String className = wrapper.getPluginClass(); - if(className==null) { + if (className == null) { // use the default dummy instance wrapper.setPlugin(new DummyImpl()); } else { try { Class clazz = wrapper.classLoader.loadClass(className); - Object o = clazz.newInstance(); - if(!(o instanceof Plugin)) { - throw new IOException(className+" doesn't extend from hudson.Plugin"); + Object o = clazz.getDeclaredConstructor().newInstance(); + if (!(o instanceof Plugin)) { + throw new IOException(className + " doesn't extend from hudson.Plugin"); } wrapper.setPlugin((Plugin) o); } catch (LinkageError | ClassNotFoundException e) { - throw new IOException("Unable to load " + className + " from " + wrapper.getShortName(),e); - } catch (IllegalAccessException | InstantiationException e) { - throw new IOException("Unable to create instance of " + className + " from " + wrapper.getShortName(),e); + throw new IOException("Unable to load " + className + " from " + wrapper.getShortName(), e); + } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) { + throw new IOException("Unable to create instance of " + className + " from " + wrapper.getShortName(), e); } } @@ -392,9 +403,9 @@ public void load(PluginWrapper wrapper) throws IOException { Plugin plugin = wrapper.getPluginOrFail(); plugin.setServletContext(pluginManager.context); startPlugin(wrapper); - } catch(Throwable t) { + } catch (Throwable t) { // gracefully handle any error in plugin. - throw new IOException("Failed to initialize",t); + throw new IOException("Failed to initialize", t); } } finally { Thread.currentThread().setContextClassLoader(old); @@ -409,7 +420,7 @@ public void startPlugin(PluginWrapper plugin) throws Exception { public void updateDependency(PluginWrapper depender, PluginWrapper dependee) { DependencyClassLoader classLoader = findAncestorDependencyClassLoader(depender.classLoader); if (classLoader != null) { - classLoader.updateTransientDependencies(); + classLoader.updateTransitiveDependencies(); LOGGER.log(Level.INFO, "Updated dependency of {0}", depender.getShortName()); } } @@ -418,14 +429,14 @@ private DependencyClassLoader findAncestorDependencyClassLoader(ClassLoader clas { for (; classLoader != null; classLoader = classLoader.getParent()) { if (classLoader instanceof DependencyClassLoader) { - return (DependencyClassLoader)classLoader; + return (DependencyClassLoader) classLoader; } - + if (classLoader instanceof AntClassLoader) { // AntClassLoaders hold parents not only as AntClassLoader#getParent() // but also as AntClassLoader#getConfiguredParent() DependencyClassLoader ret = findAncestorDependencyClassLoader( - ((AntClassLoader)classLoader).getConfiguredParent() + ((AntClassLoader) classLoader).getConfiguredParent() ); if (ret != null) { return ret; @@ -438,29 +449,29 @@ private DependencyClassLoader findAncestorDependencyClassLoader(ClassLoader clas @SuppressFBWarnings(value = "PATH_TRAVERSAL_IN", justification = "Administrator action installing a plugin, which could do far worse.") private static File resolve(File base, String relative) { File rel = new File(relative); - if(rel.isAbsolute()) + if (rel.isAbsolute()) return rel; else - return new File(base.getParentFile(),relative); + return new File(base.getParentFile(), relative); } private static void parseClassPath(Manifest manifest, File archive, List paths, String attributeName, String separator) throws IOException { String classPath = manifest.getMainAttributes().getValue(attributeName); - if(classPath==null) return; // attribute not found + if (classPath == null) return; // attribute not found for (String s : classPath.split(separator)) { File file = resolve(archive, s); - if(file.getName().contains("*")) { + if (file.getName().contains("*")) { // handle wildcard FileSet fs = new FileSet(); File dir = file.getParentFile(); fs.setDir(dir); fs.setIncludes(file.getName()); - for( String included : fs.getDirectoryScanner(new Project()).getIncludedFiles() ) { - paths.add(new File(dir,included)); + for (String included : fs.getDirectoryScanner(new Project()).getIncludedFiles()) { + paths.add(new File(dir, included)); } } else { - if(!file.exists()) - throw new IOException("No such file: "+file); + if (!file.exists()) + throw new IOException("No such file: " + file); paths.add(file); } } @@ -470,11 +481,11 @@ private static void parseClassPath(Manifest manifest, File archive, List p * Explodes the plugin into a directory, if necessary. */ private static void explode(File archive, File destDir) throws IOException { - destDir.mkdirs(); + Util.createDirectories(Util.fileToPath(destDir)); // timestamp check - File explodeTime = new File(destDir,".timestamp2"); - if(explodeTime.exists() && explodeTime.lastModified()==archive.lastModified()) + File explodeTime = new File(destDir, ".timestamp2"); + if (explodeTime.exists() && explodeTime.lastModified() == archive.lastModified()) return; // no need to expand // delete the contents so that old files won't interfere with new files @@ -485,7 +496,7 @@ private static void explode(File archive, File destDir) throws IOException { unzipExceptClasses(archive, destDir, prj); createClassJarFromWebInfClasses(archive, destDir, prj); } catch (BuildException x) { - throw new IOException("Failed to expand " + archive,x); + throw new IOException("Failed to expand " + archive, x); } try { @@ -520,7 +531,7 @@ private static void createClassJarFromWebInfClasses(File archive, File destDir, try (ZipOutputStream wrappedZOut = new ZipOutputStream(NullOutputStream.NULL_OUTPUT_STREAM) { @Override public void putNextEntry(ZipEntry ze) throws IOException { - ze.setTime(dirTime+1999); // roundup + ze.setTime(dirTime + 1999); // roundup super.putNextEntry(ze); } }) { @@ -534,12 +545,12 @@ protected void zipDir(Resource dir, ZipOutputStream zOut, String vPath, int mode, ZipExtraField[] extra) throws IOException { // use wrappedZOut instead of zOut - super.zipDir(dir,wrappedZOut,vPath,mode,extra); + super.zipDir(dir, wrappedZOut, vPath, mode, extra); } }; z.setProject(prj); z.setTaskType("zip"); - classesJar.getParentFile().mkdirs(); + Util.createDirectories(Util.fileToPath(classesJar.getParentFile())); z.setDestFile(classesJar); z.add(mapper); z.execute(); @@ -564,7 +575,7 @@ private static void unzipExceptClasses(File archive, File destDir, Project prj) /** * Used to load classes from dependency plugins. */ - final class DependencyClassLoader extends ClassLoader { + static final class DependencyClassLoader extends ClassLoader { /** * This classloader is created for this plugin. Useful during debugging. */ @@ -572,31 +583,42 @@ final class DependencyClassLoader extends ClassLoader { private List dependencies; + private final PluginManager pluginManager; + /** - * Topologically sorted list of transient dependencies. + * Topologically sorted list of transitive dependencies. Lazily initialized via double-checked locking. */ - private volatile List transientDependencies; + private volatile List transitiveDependencies; + + static { + registerAsParallelCapable(); + } - DependencyClassLoader(ClassLoader parent, File archive, List dependencies) { + DependencyClassLoader(ClassLoader parent, File archive, List dependencies, PluginManager pluginManager) { super(parent); this._for = archive; - this.dependencies = dependencies; + this.dependencies = Collections.unmodifiableList(new ArrayList<>(dependencies)); + this.pluginManager = pluginManager; } - private void updateTransientDependencies() { + private void updateTransitiveDependencies() { // This will be recalculated at the next time. - transientDependencies = null; + transitiveDependencies = null; } private List getTransitiveDependencies() { - if (transientDependencies==null) { + List localTransitiveDependencies = transitiveDependencies; + if (localTransitiveDependencies == null) { + synchronized (this) { + localTransitiveDependencies = transitiveDependencies; + if (localTransitiveDependencies == null) { CyclicGraphDetector cgd = new CyclicGraphDetector() { @Override protected List getEdges(PluginWrapper pw) { List dep = new ArrayList<>(); for (Dependency d : pw.getDependencies()) { PluginWrapper p = pluginManager.getPlugin(d.shortName); - if (p!=null && p.isActive()) + if (p != null && p.isActive()) dep.add(p); } return dep; @@ -606,35 +628,26 @@ protected List getEdges(PluginWrapper pw) { try { for (Dependency d : dependencies) { PluginWrapper p = pluginManager.getPlugin(d.shortName); - if (p!=null && p.isActive()) + if (p != null && p.isActive()) cgd.run(Collections.singleton(p)); } } catch (CycleDetectedException e) { throw new AssertionError(e); // such error should have been reported earlier } - transientDependencies = cgd.getSorted(); + transitiveDependencies = localTransitiveDependencies = cgd.getSorted(); + } } - return transientDependencies; + } + return localTransitiveDependencies; } -// public List getDependencyPluginWrappers() { -// List r = new ArrayList(); -// for (Dependency d : dependencies) { -// PluginWrapper w = pluginManager.getPlugin(d.shortName); -// if (w!=null) r.add(w); -// } -// return r; -// } - @Override protected Class findClass(String name) throws ClassNotFoundException { if (PluginManager.FAST_LOOKUP) { for (PluginWrapper pw : getTransitiveDependencies()) { try { - Class c = ClassLoaderReflectionToolkit._findLoadedClass(pw.classLoader, name); - if (c!=null) return c; - return ClassLoaderReflectionToolkit._findClass(pw.classLoader, name); + return ClassLoaderReflectionToolkit.loadClass(pw.classLoader, name); } catch (ClassNotFoundException ignored) { //not found. try next } @@ -642,7 +655,7 @@ protected Class findClass(String name) throws ClassNotFoundException { } else { for (Dependency dep : dependencies) { PluginWrapper p = pluginManager.getPlugin(dep.shortName); - if(p!=null) { + if (p != null) { try { return p.classLoader.loadClass(name); } catch (ClassNotFoundException ignored) { @@ -670,7 +683,7 @@ protected Enumeration findResources(String name) throws IOException { } else { for (Dependency dep : dependencies) { PluginWrapper p = pluginManager.getPlugin(dep.shortName); - if (p!=null) { + if (p != null) { Enumeration urls = p.classLoader.getResources(name); while (urls != null && urls.hasMoreElements()) result.add(urls.nextElement()); @@ -686,14 +699,14 @@ protected URL findResource(String name) { if (PluginManager.FAST_LOOKUP) { for (PluginWrapper pw : getTransitiveDependencies()) { URL url = ClassLoaderReflectionToolkit._findResource(pw.classLoader, name); - if (url!=null) return url; + if (url != null) return url; } } else { for (Dependency dep : dependencies) { PluginWrapper p = pluginManager.getPlugin(dep.shortName); - if(p!=null) { + if (p != null) { URL url = p.classLoader.getResource(name); - if (url!=null) + if (url != null) return url; } } @@ -703,25 +716,6 @@ protected URL findResource(String name) { } } - /** - * {@link AntClassLoader} with a few methods exposed, {@link Closeable} support, and {@link Transformer} support. - */ - private final class AntClassLoader2 extends AntWithFindResourceClassLoader implements Closeable { - private AntClassLoader2(ClassLoader parent) { - super(parent, true); - } - - @Override - protected Class defineClassFromData(File container, byte[] classData, String classname) throws IOException { - if (!DISABLE_TRANSFORMER) - classData = pluginManager.getCompatibilityTransformer().transform(classname, classData, this); - return super.defineClassFromData(container, classData, classname); - } - } - - /* Unused since 1.527, see https://github.com/jenkinsci/jenkins/commit/47de54d070f67af95b4fefb6d006a72bb31a5cb8 */ - @Deprecated - public static boolean useAntClassLoader = SystemProperties.getBoolean(ClassicPluginStrategy.class.getName()+".useAntClassLoader"); - @SuppressFBWarnings("MS_SHOULD_BE_FINAL") - public static boolean DISABLE_TRANSFORMER = SystemProperties.getBoolean(ClassicPluginStrategy.class.getName()+".noBytecodeTransformer"); + @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "Accessible via System Groovy Scripts") + public static /* not final */ boolean useAntClassLoader = SystemProperties.getBoolean(ClassicPluginStrategy.class.getName() + ".useAntClassLoader", true); } diff --git a/core/src/main/java/hudson/CloseProofOutputStream.java b/core/src/main/java/hudson/CloseProofOutputStream.java index 4256d4ac75bc..0fc4aee48a5c 100644 --- a/core/src/main/java/hudson/CloseProofOutputStream.java +++ b/core/src/main/java/hudson/CloseProofOutputStream.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,10 +21,10 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson; import hudson.util.DelegatingOutputStream; - import java.io.OutputStream; /** diff --git a/core/src/main/java/hudson/CopyOnWrite.java b/core/src/main/java/hudson/CopyOnWrite.java index 891cbf04bb9f..04e737964a80 100644 --- a/core/src/main/java/hudson/CopyOnWrite.java +++ b/core/src/main/java/hudson/CopyOnWrite.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,12 +21,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson; -import java.lang.annotation.Documented; import static java.lang.annotation.ElementType.FIELD; -import java.lang.annotation.Retention; import static java.lang.annotation.RetentionPolicy.SOURCE; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; import java.lang.annotation.Target; /** diff --git a/core/src/main/java/hudson/DNSMultiCast.java b/core/src/main/java/hudson/DNSMultiCast.java index b7971e2d0a01..cfa8f664bb7a 100644 --- a/core/src/main/java/hudson/DNSMultiCast.java +++ b/core/src/main/java/hudson/DNSMultiCast.java @@ -1,32 +1,15 @@ package hudson; -import hudson.init.Initializer; -import jenkins.util.SystemProperties; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; -import java.util.logging.Logger; - -import static hudson.init.InitMilestone.COMPLETED; - /** - * Registers a DNS multi-cast service-discovery support. - * - * @author Kohsuke Kawaguchi - * @deprecated No longer does anything. + * @deprecated No longer does anything. Only here to prevent errors from old versions of tools like {@code JenkinsRule}. */ @Deprecated @Restricted(NoExternalUse.class) public class DNSMultiCast { - private static final Logger LOGGER = Logger.getLogger(DNSMultiCast.class.getName()); - - public static boolean disabled = SystemProperties.getBoolean(DNSMultiCast.class.getName()+".disabled", true); - @Initializer(before=COMPLETED) - public static void warn() { - if (!disabled) { - LOGGER.warning("DNS multicast capability has been removed from Jenkins. More information: https://jenkins.io/redirect/dns-multicast"); - } - } + public static boolean disabled = true; } diff --git a/core/src/main/java/hudson/DependencyRunner.java b/core/src/main/java/hudson/DependencyRunner.java index 68e7257bb265..b7db91fb9416 100644 --- a/core/src/main/java/hudson/DependencyRunner.java +++ b/core/src/main/java/hudson/DependencyRunner.java @@ -1,19 +1,19 @@ /* * The MIT License - * + * * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, * Brian Westrich, Jean-Baptiste Quenot - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -22,19 +22,19 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson; import hudson.model.AbstractProject; -import hudson.security.ACLContext; -import jenkins.model.Jenkins; import hudson.security.ACL; - +import hudson.security.ACLContext; import java.util.ArrayList; +import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; -import java.util.Collection; import java.util.logging.Logger; +import jenkins.model.Jenkins; /** * Runs a job on all projects in the order of dependencies @@ -42,7 +42,7 @@ public class DependencyRunner implements Runnable { private static final Logger LOGGER = Logger.getLogger(DependencyRunner.class.getName()); - + ProjectRunnable runnable; List polledProjects = new ArrayList<>(); @@ -51,6 +51,7 @@ public DependencyRunner(ProjectRunnable runnable) { this.runnable = runnable; } + @Override public void run() { try (ACLContext ctx = ACL.as2(ACL.SYSTEM2)) { Set topLevelProjects = new HashSet<>(); @@ -72,11 +73,11 @@ public void run() { } private void populate(Collection projectList) { - for (AbstractProject p : projectList) { + for (AbstractProject p : projectList) { if (polledProjects.contains(p)) { // Project will be readded at the queue, so that we always use // the longest path - LOGGER.fine("removing project " + p.getName() + " for re-add"); + LOGGER.fine("removing project " + p.getName() + " for re-add"); polledProjects.remove(p); } diff --git a/core/src/main/java/hudson/DescriptorExtensionList.java b/core/src/main/java/hudson/DescriptorExtensionList.java index 70301198cf94..7c9fbbddccac 100644 --- a/core/src/main/java/hudson/DescriptorExtensionList.java +++ b/core/src/main/java/hudson/DescriptorExtensionList.java @@ -21,36 +21,35 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson; -import hudson.model.Descriptor; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.model.Describable; +import hudson.model.Descriptor; +import hudson.model.Descriptor.FormException; import hudson.model.Hudson; -import jenkins.ExtensionComponentSet; -import jenkins.model.Jenkins; import hudson.model.ViewDescriptor; -import hudson.model.Descriptor.FormException; -import hudson.util.AdaptedIterator; -import hudson.util.Iterators.FlattenIterator; import hudson.slaves.NodeDescriptor; import hudson.tasks.Publisher; - -import java.util.Collection; -import java.util.List; +import hudson.util.AdaptedIterator; +import hudson.util.Iterators.FlattenIterator; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.logging.Level; import java.util.logging.Logger; -import java.util.concurrent.CopyOnWriteArrayList; -import edu.umd.cs.findbugs.annotations.CheckForNull; -import edu.umd.cs.findbugs.annotations.NonNull; - +import jenkins.ExtensionComponentSet; +import jenkins.model.Jenkins; import net.sf.json.JSONException; -import org.kohsuke.stapler.Stapler; import net.sf.json.JSONObject; +import org.kohsuke.stapler.Stapler; /** * {@link ExtensionList} for holding a set of {@link Descriptor}s, which is a group of descriptors for @@ -73,8 +72,8 @@ public class DescriptorExtensionList, D extends Descrip * Creates a new instance. */ @SuppressWarnings({"unchecked", "rawtypes"}) - public static ,D extends Descriptor> - DescriptorExtensionList createDescriptorList(Jenkins jenkins, Class describableType) { + public static , D extends Descriptor> + DescriptorExtensionList createDescriptorList(Jenkins jenkins, Class describableType) { if (describableType == Publisher.class) { return (DescriptorExtensionList) new Publisher.DescriptorExtensionListImpl(jenkins); } @@ -86,9 +85,9 @@ DescriptorExtensionList createDescriptorList(Jenkins jenkins, Class desc * Use {@link #create(Jenkins, Class)} */ @Deprecated - public static ,D extends Descriptor> - DescriptorExtensionList createDescriptorList(Hudson hudson, Class describableType) { - return (DescriptorExtensionList)createDescriptorList((Jenkins)hudson,describableType); + public static , D extends Descriptor> + DescriptorExtensionList createDescriptorList(Hudson hudson, Class describableType) { + return (DescriptorExtensionList) createDescriptorList((Jenkins) hudson, describableType); } /** @@ -102,11 +101,11 @@ DescriptorExtensionList createDescriptorList(Hudson hudson, Class descri */ @Deprecated protected DescriptorExtensionList(Hudson hudson, Class describableType) { - this((Jenkins)hudson,describableType); + this((Jenkins) hudson, describableType); } protected DescriptorExtensionList(Jenkins jenkins, Class describableType) { - super(jenkins, (Class)Descriptor.class, (CopyOnWriteArrayList)getLegacyDescriptors(describableType)); + super(jenkins, (Class) Descriptor.class, (CopyOnWriteArrayList) getLegacyDescriptors(describableType)); this.describableType = describableType; } @@ -119,7 +118,7 @@ protected DescriptorExtensionList(Jenkins jenkins, Class describableType) { */ @Deprecated public D find(String fqcn) { - return Descriptor.find(this,fqcn); + return Descriptor.find(this, fqcn); } /** @@ -128,7 +127,7 @@ public D find(String fqcn) { */ public D find(Class type) { for (D d : this) - if (d.clazz==type) + if (d.clazz == type) return d; return null; } @@ -143,10 +142,10 @@ public D find(Class type) { */ @CheckForNull public T newInstanceFromRadioList(JSONObject config) throws FormException { - if(config.isNullObject()) + if (config.isNullObject()) return null; // none was selected int idx = config.getInt("value"); - return get(idx).newInstance(Stapler.getCurrentRequest(),config); + return get(idx).newInstance(Stapler.getCurrentRequest(), config); } /** @@ -173,7 +172,7 @@ public T newInstanceFromRadioList(@NonNull JSONObject parent, @NonNull String na */ public @CheckForNull D findByName(String id) { for (D d : this) - if(d.getId().equals(id)) + if (d.getId().equals(id)) return d; return null; } @@ -221,11 +220,11 @@ protected Collection> load(ExtensionComponentSet delta) { private List> _load(Iterable> set) { List> r = new ArrayList<>(); - for( ExtensionComponent c : set ) { + for (ExtensionComponent c : set) { Descriptor d = c.getInstance(); try { - if(d.getT()==describableType) - r.add((ExtensionComponent)c); + if (d.getT() == describableType) + r.add((ExtensionComponent) c); } catch (IllegalStateException e) { LOGGER.log(Level.SEVERE, d.getClass() + " doesn't extend Descriptor with a type parameter", e); // skip this one } @@ -253,14 +252,17 @@ private static > CopyOnWriteArrayList listLegacyInstances() { return new Iterable() { + @Override public Iterator iterator() { - return new AdaptedIterator,Descriptor>( - new FlattenIterator,CopyOnWriteArrayList>>(legacyDescriptors.values()) { + return new AdaptedIterator, Descriptor>( + new FlattenIterator, CopyOnWriteArrayList>>(legacyDescriptors.values()) { + @Override protected Iterator> expand(CopyOnWriteArrayList> v) { return v.iterator(); } }) { + @Override protected Descriptor adapt(ExtensionComponent item) { return item.getInstance(); } diff --git a/core/src/main/java/hudson/EnvVars.java b/core/src/main/java/hudson/EnvVars.java index a323c4d39fa3..cce69ede9ee8 100644 --- a/core/src/main/java/hudson/EnvVars.java +++ b/core/src/main/java/hudson/EnvVars.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Red Hat, Inc. - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,30 +21,29 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.remoting.VirtualChannel; -import hudson.util.CaseInsensitiveComparator; import hudson.util.CyclicGraphDetector; import hudson.util.CyclicGraphDetector.CycleDetectedException; import hudson.util.VariableResolver; -import jenkins.security.MasterToSlaveCallable; - import java.io.File; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; -import java.util.Arrays; import java.util.TreeSet; import java.util.UUID; import java.util.logging.Logger; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.CheckForNull; +import jenkins.security.MasterToSlaveCallable; /** * Environment variables. @@ -65,7 +64,7 @@ * *

* In Jenkins, often we need to build up "environment variable overrides" - * on master, then to execute the process on agents. This causes a problem + * on the controller, then to execute the process on agents. This causes a problem * when working with variables like {@code PATH}. So to make this work, * we introduce a special convention {@code PATH+FOO} — all entries * that starts with {@code PATH+} are merged and prepended to the inherited @@ -73,7 +72,7 @@ * * @author Kohsuke Kawaguchi */ -public class EnvVars extends TreeMap { +public class EnvVars extends TreeMap { private static final long serialVersionUID = 4320331661987259022L; private static Logger LOGGER = Logger.getLogger(EnvVars.class.getName()); /** @@ -86,7 +85,7 @@ public class EnvVars extends TreeMap { * So this property remembers that information. */ private Platform platform; - + /** * Gets the platform for which these env vars targeted. * @since 2.144 @@ -104,11 +103,12 @@ public class EnvVars extends TreeMap { public void setPlatform(@NonNull Platform platform) { this.platform = platform; } + public EnvVars() { - super(CaseInsensitiveComparator.INSTANCE); + super(String.CASE_INSENSITIVE_ORDER); } - public EnvVars(@NonNull Map m) { + public EnvVars(@NonNull Map m) { this(); putAll(m); @@ -123,7 +123,7 @@ public EnvVars(@NonNull Map m) { @SuppressWarnings("CopyConstructorMissesField") // does not set #platform, see its Javadoc public EnvVars(@NonNull EnvVars m) { // this constructor is so that in future we can get rid of the downcasting. - this((Map)m); + this((Map) m); } /** @@ -131,10 +131,10 @@ public EnvVars(@NonNull EnvVars m) { */ public EnvVars(String... keyValuePairs) { this(); - if(keyValuePairs.length%2!=0) + if (keyValuePairs.length % 2 != 0) throw new IllegalArgumentException(Arrays.asList(keyValuePairs).toString()); - for( int i=0; i0) { - String realKey = key.substring(0,idx); + if (idx > 0) { + String realKey = key.substring(0, idx); String v = get(realKey); - if(v==null) v=value; + if (v == null) v = value; else { // we might be handling environment variables for a agent that can have different path separator - // than the master, so the following is an attempt to get it right. + // than the controller, so the following is an attempt to get it right. // it's still more error prone that I'd like. - char ch = platform==null ? File.pathSeparatorChar : platform.pathSeparator; - v=value+ch+v; + char ch = platform == null ? File.pathSeparatorChar : platform.pathSeparator; + v = value + ch + v; } - put(realKey,v); + put(realKey, v); return; } - put(key,value); + put(key, value); } /** @@ -173,18 +173,18 @@ public void override(String key, String value) { * See {@link #override(String, String)}. * @return this */ - public EnvVars overrideAll(Map all) { + public EnvVars overrideAll(Map all) { for (Map.Entry e : all.entrySet()) { - override(e.getKey(),e.getValue()); + override(e.getKey(), e.getValue()); } return this; } /** * Calculates the order to override variables. - * + * * Sort variables with topological sort with their reference graph. - * + * * This is package accessible for testing purpose. */ static class OverrideOrderCalculator { @@ -194,30 +194,31 @@ static class OverrideOrderCalculator { private static class TraceResolver implements VariableResolver { private final Comparator comparator; public Set referredVariables; - + TraceResolver(Comparator comparator) { this.comparator = comparator; clear(); } - + public void clear() { referredVariables = new TreeSet<>(comparator); } - + + @Override public String resolve(String name) { referredVariables.add(name); return ""; } } - + private static class VariableReferenceSorter extends CyclicGraphDetector { // map from a variable to a set of variables that variable refers. private final Map> refereeSetMap; - + VariableReferenceSorter(Map> refereeSetMap) { this.refereeSetMap = refereeSetMap; } - + @Override protected Iterable getEdges(String n) { // return variables referred from the variable. @@ -230,40 +231,40 @@ protected Iterable getEdges(String n) { } private final Comparator comparator; - + @NonNull private final EnvVars target; @NonNull - private final Map overrides; - + private final Map overrides; + private Map> refereeSetMap; private List orderedVariableNames; - - OverrideOrderCalculator(@NonNull EnvVars target, @NonNull Map overrides) { + + OverrideOrderCalculator(@NonNull EnvVars target, @NonNull Map overrides) { comparator = target.comparator(); this.target = target; this.overrides = overrides; scan(); } - + public List getOrderedVariableNames() { return orderedVariableNames; } - + // Cut the reference to the variable in a cycle. private void cutCycleAt(String referee, List cycle) { // cycle contains variables in referrer-to-referee order. // This should not be negative, for the first and last one is same. int refererIndex = cycle.lastIndexOf(referee) - 1; - - assert(refererIndex >= 0); + + assert refererIndex >= 0; String referrer = cycle.get(refererIndex); boolean removed = refereeSetMap.get(referrer).remove(referee); - assert(removed); - LOGGER.warning(String.format("Cyclic reference detected: %s", Util.join(cycle," -> "))); + assert removed; + LOGGER.warning(String.format("Cyclic reference detected: %s", String.join(" -> ", cycle))); LOGGER.warning(String.format("Cut the reference %s -> %s", referrer, referee)); } - + // Cut the variable reference in a cycle. private void cutCycle(List cycle) { // if an existing variable is contained in that cycle, @@ -274,27 +275,27 @@ private void cutCycle(List cycle) { // PATH1=/usr/local/bin:${PATH} // PATH=/opt/something/bin:${PATH1} // then consider reference PATH1 -> PATH can be ignored. - for (String referee: cycle) { + for (String referee : cycle) { if (target.containsKey(referee)) { cutCycleAt(referee, cycle); return; } } - + // if not, cut the reference to the first one. cutCycleAt(cycle.get(0), cycle); } - + /** * Scan all variables and list all referring variables. */ public void scan() { refereeSetMap = new TreeMap<>(comparator); List extendingVariableNames = new ArrayList<>(); - + TraceResolver resolver = new TraceResolver(comparator); - - for (Map.Entry entry: overrides.entrySet()) { + + for (Map.Entry entry : overrides.entrySet()) { if (entry.getKey().indexOf('+') > 0) { // XYZ+AAA variables should be always processed in last. extendingVariableNames.add(entry.getKey()); @@ -302,20 +303,20 @@ public void scan() { } resolver.clear(); Util.replaceMacro(entry.getValue(), resolver); - + // Variables directly referred from the current scanning variable. Set refereeSet = resolver.referredVariables; // Ignore self reference. refereeSet.remove(entry.getKey()); refereeSetMap.put(entry.getKey(), refereeSet); } - + VariableReferenceSorter sorter; - while(true) { + while (true) { sorter = new VariableReferenceSorter(refereeSetMap); try { sorter.run(refereeSetMap.keySet()); - } catch(CycleDetectedException e) { + } catch (CycleDetectedException e) { // cyclic reference found. // cut the cycle and retry. @SuppressWarnings("unchecked") @@ -325,15 +326,15 @@ public void scan() { } break; } - + // When A refers B, the last appearance of B always comes after // the last appearance of A. List reversedDuplicatedOrder = new ArrayList<>(sorter.getSorted()); Collections.reverse(reversedDuplicatedOrder); - + orderedVariableNames = new ArrayList<>(overrides.size()); - for(String key: reversedDuplicatedOrder) { - if(overrides.containsKey(key) && !orderedVariableNames.contains(key)) { + for (String key : reversedDuplicatedOrder) { + if (overrides.containsKey(key) && !orderedVariableNames.contains(key)) { orderedVariableNames.add(key); } } @@ -341,14 +342,14 @@ public void scan() { orderedVariableNames.addAll(extendingVariableNames); } } - + /** * Overrides all values in the map by the given map. Expressions in values will be expanded. * See {@link #override(String, String)}. * @return {@code this} */ - public EnvVars overrideExpandingAll(@NonNull Map all) { + public EnvVars overrideExpandingAll(@NonNull Map all) { for (String key : new OverrideOrderCalculator(this, all).getOrderedVariableNames()) { override(key, expand(all.get(key))); } @@ -358,11 +359,11 @@ public EnvVars overrideExpandingAll(@NonNull Map all) { /** * Resolves environment variables against each other. */ - public static void resolve(Map env) { - for (Map.Entry entry: env.entrySet()) { - entry.setValue(Util.replaceMacro(entry.getValue(), env)); - } - } + public static void resolve(Map env) { + for (Map.Entry entry : env.entrySet()) { + entry.setValue(Util.replaceMacro(entry.getValue(), env)); + } + } /** * Convenience message @@ -370,14 +371,14 @@ public static void resolve(Map env) { **/ public String get(String key, String defaultValue) { String v = get(key); - if (v==null) v=defaultValue; + if (v == null) v = defaultValue; return v; } @Override public String put(String key, String value) { - if (value==null) throw new IllegalArgumentException("Null value not allowed as an environment variable: "+key); - return super.put(key,value); + if (value == null) throw new IllegalArgumentException("Null value not allowed as an environment variable: " + key); + return super.put(key, value); } /** @@ -385,8 +386,8 @@ public String put(String key, String value) { * @since 1.556 */ public void putIfNotNull(String key, String value) { - if (value!=null) - put(key,value); + if (value != null) + put(key, value); } /** @@ -397,14 +398,14 @@ public void putAllNonNull(Map map) { map.forEach(this::putIfNotNull); } - + /** * Takes a string that looks like "a=b" and adds that to this map. */ public void addLine(String line) { int sep = line.indexOf('='); - if(sep > 0) { - put(line.substring(0,sep),line.substring(sep+1)); + if (sep > 0) { + put(line.substring(0, sep), line.substring(sep + 1)); } } @@ -432,15 +433,17 @@ public static EnvVars createCookie() { * A fresh copy that can be owned and modified by the caller. */ public static EnvVars getRemote(VirtualChannel channel) throws IOException, InterruptedException { - if(channel==null) - return new EnvVars("N/A","N/A"); + if (channel == null) + return new EnvVars("N/A", "N/A"); return channel.call(new GetEnvVars()); } - private static final class GetEnvVars extends MasterToSlaveCallable { + private static final class GetEnvVars extends MasterToSlaveCallable { + @Override public EnvVars call() { return new EnvVars(EnvVars.masterEnvVars); } + private static final long serialVersionUID = 1L; } @@ -449,19 +452,19 @@ public EnvVars call() { * *

* Despite what the name might imply, this is the environment variable - * of the current JVM process. And therefore, it is Jenkins master's environment - * variables only when you access this from the master. + * of the current JVM process. And therefore, it is the Jenkins controller's + * environment variables only when you access this from the controller. * *

* If you access this field from agents, then this is the environment * variable of the agent. */ - public static final Map masterEnvVars = initMaster(); + public static final Map masterEnvVars = initMaster(); private static EnvVars initMaster() { EnvVars vars = new EnvVars(System.getenv()); vars.platform = Platform.current(); - if(Main.isUnitTest || Main.isDevelopmentMode) + if (Main.isUnitTest || Main.isDevelopmentMode) // if unit test is launched with maven debug switch, // we need to prevent forked Maven processes from seeing it, or else // they'll hang diff --git a/core/src/main/java/hudson/ExpressionFactory2.java b/core/src/main/java/hudson/ExpressionFactory2.java index a3bd134319c2..7fcec22e7604 100644 --- a/core/src/main/java/hudson/ExpressionFactory2.java +++ b/core/src/main/java/hudson/ExpressionFactory2.java @@ -1,17 +1,16 @@ package hudson; +import java.util.Collection; +import java.util.Map; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; import org.apache.commons.jelly.JellyContext; import org.apache.commons.jelly.JellyException; import org.apache.commons.jelly.expression.Expression; import org.apache.commons.jelly.expression.ExpressionFactory; import org.apache.commons.jelly.expression.ExpressionSupport; import org.apache.commons.jexl.JexlContext; - -import java.util.Collection; -import java.util.Map; -import java.util.Set; -import java.util.logging.Level; -import java.util.logging.Logger; import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.StaplerRequest; import org.springframework.security.access.AccessDeniedException; @@ -22,6 +21,7 @@ * @author Kohsuke Kawaguchi */ final class ExpressionFactory2 implements ExpressionFactory { + @Override public Expression createExpression(String text) throws JellyException { try { return new JexlExpression( @@ -63,21 +63,23 @@ public String toString() { // Expression interface //------------------------------------------------------------------------- + @Override public String getExpressionText() { return "${" + expression.getExpression() + "}"; } + @Override public Object evaluate(JellyContext context) { try { CURRENT_CONTEXT.set(context); - JexlContext jexlContext = new JellyJexlContext( context ); + JexlContext jexlContext = new JellyJexlContext(context); return expression.evaluate(jexlContext); } catch (AccessDeniedException e) { // let the security exception pass through throw e; } catch (Exception e) { StaplerRequest currentRequest = Stapler.getCurrentRequest(); - LOGGER.log(Level.WARNING,"Caught exception evaluating: " + expression + " in " + (currentRequest != null ? currentRequest.getOriginalRequestURI() : "?") + ". Reason: " + e, e); + LOGGER.log(Level.WARNING, "Caught exception evaluating: " + expression + " in " + (currentRequest != null ? currentRequest.getOriginalRequestURI() : "?") + ". Reason: " + e, e); return null; } finally { CURRENT_CONTEXT.set(null); @@ -91,14 +93,16 @@ static final class JellyJexlContext implements JexlContext { private Map vars; JellyJexlContext(JellyContext context) { - this.vars = new JellyMap( context ); + this.vars = new JellyMap(context); } + @Override public void setVars(Map vars) { this.vars.clear(); - this.vars.putAll( vars ); + this.vars.putAll(vars); } + @Override public Map getVars() { return this.vars; } @@ -113,50 +117,62 @@ static final class JellyMap implements Map { this.context = context; } + @Override public Object get(Object key) { - return context.getVariable( (String) key ); + return context.getVariable((String) key); } + @Override public void clear() { // not implemented } + @Override public boolean containsKey(Object key) { - return ( get( key ) != null ); + return get(key) != null; } + @Override public boolean containsValue(Object value) { return false; } + @Override public Set entrySet() { return null; } + @Override public boolean isEmpty() { return false; } + @Override public Set keySet() { return null; } + @Override public Object put(Object key, Object value) { return null; } + @Override public void putAll(Map t) { // not implemented } + @Override public Object remove(Object key) { return null; } + @Override public int size() { return -1; } + @Override public Collection values() { return null; } diff --git a/core/src/main/java/hudson/Extension.java b/core/src/main/java/hudson/Extension.java index 1ca863d2f4f5..b240e37f87db 100644 --- a/core/src/main/java/hudson/Extension.java +++ b/core/src/main/java/hudson/Extension.java @@ -21,18 +21,20 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson; -import jenkins.YesNoMaybe; -import net.java.sezpoz.Indexable; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import static jenkins.YesNoMaybe.MAYBE; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; - -import static java.lang.annotation.ElementType.*; -import static java.lang.annotation.RetentionPolicy.RUNTIME; -import static jenkins.YesNoMaybe.MAYBE; +import jenkins.YesNoMaybe; +import net.java.sezpoz.Indexable; /** * Marks a field, a method, or a class for automatic discovery, so that Hudson can locate diff --git a/core/src/main/java/hudson/ExtensionComponent.java b/core/src/main/java/hudson/ExtensionComponent.java index e4e35ebe1d45..4ef48d08008d 100644 --- a/core/src/main/java/hudson/ExtensionComponent.java +++ b/core/src/main/java/hudson/ExtensionComponent.java @@ -50,11 +50,11 @@ public ExtensionComponent(T instance, double ordinal) { } public ExtensionComponent(T instance, Extension annotation) { - this(instance,annotation.ordinal()); + this(instance, annotation.ordinal()); } public ExtensionComponent(T instance) { - this(instance,0); + this(instance, 0); } /** @@ -79,12 +79,13 @@ public T getInstance() { * For example, {@code component.isDescriptorOf(Builder.class)} */ public boolean isDescriptorOf(Class c) { - return instance instanceof Descriptor && ((Descriptor)instance).isSubTypeOf(c); + return instance instanceof Descriptor && ((Descriptor) instance).isSubTypeOf(c); } /** * Sort {@link ExtensionComponent}s in the descending order of {@link #ordinal()}. */ + @Override public int compareTo(ExtensionComponent that) { double a = this.ordinal(); double b = that.ordinal(); diff --git a/core/src/main/java/hudson/ExtensionFinder.java b/core/src/main/java/hudson/ExtensionFinder.java index 048e69bc9fef..5bddd008f5f0 100644 --- a/core/src/main/java/hudson/ExtensionFinder.java +++ b/core/src/main/java/hudson/ExtensionFinder.java @@ -21,10 +21,9 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Iterables; import com.google.inject.AbstractModule; import com.google.inject.Binding; import com.google.inject.Guice; @@ -40,18 +39,7 @@ import hudson.init.InitMilestone; import hudson.model.Descriptor; import hudson.model.Hudson; -import jenkins.ExtensionComponentSet; -import jenkins.ExtensionFilter; -import jenkins.ExtensionRefreshException; -import jenkins.ProxyInjector; -import jenkins.model.Jenkins; -import net.java.sezpoz.Index; -import net.java.sezpoz.IndexItem; -import org.kohsuke.accmod.Restricted; -import org.kohsuke.accmod.restrictions.NoExternalUse; -import org.springframework.util.ClassUtils; - -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import java.lang.annotation.Annotation; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Field; @@ -62,13 +50,23 @@ import java.util.Collections; import java.util.HashMap; import java.util.HashSet; -import java.util.LinkedList; import java.util.List; import java.util.Map; -import java.util.Map.Entry; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; +import jenkins.ExtensionComponentSet; +import jenkins.ExtensionFilter; +import jenkins.ExtensionRefreshException; +import jenkins.ProxyInjector; +import jenkins.model.Jenkins; +import net.java.sezpoz.Index; +import net.java.sezpoz.IndexItem; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.springframework.util.ClassUtils; /** * Discovers the implementations of an extension point. @@ -101,7 +99,7 @@ public Collection findExtensions(Class type, Hudson hudson) { */ public boolean isRefreshable() { try { - return getClass().getMethod("refresh").getDeclaringClass()!=ExtensionFinder.class; + return getClass().getMethod("refresh").getDeclaringClass() != ExtensionFinder.class; } catch (NoSuchMethodException e) { return false; } @@ -156,7 +154,7 @@ public Collection> _find(Class type, Hudson hudson) } /** - * Performs class initializations without creating instances. + * Performs class initializations without creating instances. * * If two threads try to initialize classes in the opposite order, a dead lock will ensue, * and we can get into a similar situation with {@link ExtensionFinder}s. @@ -230,7 +228,7 @@ protected GuiceExtensionAnnotation(Class annotationType) { protected abstract boolean isOptional(T annotation); } - + /** * Discovers components via sezpoz but instantiates them by using Guice. */ @@ -249,15 +247,15 @@ public static class GuiceFinder extends ExtensionFinder { * Sezpoz index we are currently using in {@link #container} (and its ancestors.) * Needed to compute delta. */ - private List> sezpozIndex; + private List> sezpozIndex; - private final Map annotations = new HashMap<>(); + private final Map annotations = new HashMap<>(); private final Sezpoz moduleFinder = new Sezpoz(); /** * Map from {@link GuiceExtensionAnnotation#annotationType} to {@link GuiceExtensionAnnotation} */ - private Map,GuiceExtensionAnnotation> extensionAnnotations = new HashMap<>(); + private Map, GuiceExtensionAnnotation> extensionAnnotations = new HashMap<>(); public GuiceFinder() { refreshExtensionAnnotations(); @@ -283,14 +281,15 @@ protected void configure() { container = Guice.createInjector(modules); sezpozIndex = extensions.getLoadedIndex(); } catch (Throwable e) { - LOGGER.log(Level.SEVERE, "Failed to create Guice container from all the plugins",e); + LOGGER.log(Level.SEVERE, "Failed to create Guice container from all the plugins", e); // failing to load all bindings are disastrous, so recover by creating minimum that works // by just including the core container = Guice.createInjector(new SezpozModule(loadSezpozIndices(Jenkins.class.getClassLoader()))); } // expose Injector via lookup mechanism for interop with non-Guice clients - Jenkins.get().lookup.set(Injector.class,new ProxyInjector() { + Jenkins.get().lookup.set(Injector.class, new ProxyInjector() { + @Override protected Injector resolve() { return getContainer(); } @@ -300,16 +299,18 @@ protected Injector resolve() { private void refreshExtensionAnnotations() { for (ExtensionComponent ec : moduleFinder.find(GuiceExtensionAnnotation.class, Hudson.getInstance())) { GuiceExtensionAnnotation gea = ec.getInstance(); - extensionAnnotations.put(gea.annotationType,gea); + extensionAnnotations.put(gea.annotationType, gea); } } - private ImmutableList> loadSezpozIndices(ClassLoader classLoader) { - List> indices = new ArrayList<>(); + private List> loadSezpozIndices(ClassLoader classLoader) { + List> indices = new ArrayList<>(); for (GuiceExtensionAnnotation gea : extensionAnnotations.values()) { - Iterables.addAll(indices, Index.load(gea.annotationType, Object.class, classLoader)); + for (IndexItem indexItem : Index.load(gea.annotationType, Object.class, classLoader)) { + indices.add(indexItem); + } } - return ImmutableList.copyOf(indices); + return Collections.unmodifiableList(indices); } public Injector getContainer() { @@ -330,7 +331,7 @@ public synchronized ExtensionComponentSet refresh() throws ExtensionRefreshExcep // figure out newly discovered sezpoz components List> delta = new ArrayList<>(); for (Class annotationType : extensionAnnotations.keySet()) { - delta.addAll(Sezpoz.listDelta(annotationType,sezpozIndex)); + delta.addAll(Sezpoz.listDelta(annotationType, sezpozIndex)); } SezpozModule deltaExtensions = new SezpozModule(delta); @@ -357,19 +358,19 @@ public Collection> find(Class type) { } }; } catch (Throwable e) { - LOGGER.log(Level.SEVERE, "Failed to create Guice container from newly added plugins",e); + LOGGER.log(Level.SEVERE, "Failed to create Guice container from newly added plugins", e); throw new ExtensionRefreshException(e); } } - private Object instantiate(IndexItem item) { + private Object instantiate(IndexItem item) { try { return item.instance(); } catch (LinkageError | Exception e) { // sometimes the instantiation fails in an indirect classloading failure, // which results in a LinkageError LOGGER.log(isOptional(item.annotation()) ? Level.FINE : Level.WARNING, - "Failed to load "+item.className(), e); + "Failed to load " + item.className(), e); } return null; } @@ -384,22 +385,23 @@ private boolean isActive(Annotation annotation, AnnotatedElement e) { return gea.isActive(e); } + @Override public Collection> find(Class type, Hudson jenkins) { // the find method contract requires us to traverse all known components List> result = new ArrayList<>(); - for (Injector i=container; i!=null; i=i.getParent()) { + for (Injector i = container; i != null; i = i.getParent()) { _find(type, result, i); } return result; } private void _find(Class type, List> result, Injector container) { - for (Entry, Binding> e : container.getBindings().entrySet()) { + for (Map.Entry, Binding> e : container.getBindings().entrySet()) { if (type.isAssignableFrom(e.getKey().getTypeLiteral().getRawType())) { Annotation a = annotations.get(e.getKey()); Object o = e.getValue().getProvider().get(); - if (o!=null) { - GuiceExtensionAnnotation gea = a!=null ? extensionAnnotations.get(a.annotationType()) : null; + if (o != null) { + GuiceExtensionAnnotation gea = a != null ? extensionAnnotations.get(a.annotationType()) : null; result.add(new ExtensionComponent<>(type.cast(o), gea != null ? gea.getOrdinal(a) : 0)); } } @@ -424,15 +426,19 @@ public void scout(Class extensionType, Hudson hudson) { */ public static final Scope FAULT_TOLERANT_SCOPE = new FaultTolerantScope(true); private static final Scope QUIET_FAULT_TOLERANT_SCOPE = new FaultTolerantScope(false); - + private static final class FaultTolerantScope implements Scope { private final boolean verbose; + FaultTolerantScope(boolean verbose) { this.verbose = verbose; } + + @Override public Provider scope(final Key key, final Provider unscoped) { - final Provider base = Scopes.SINGLETON.scope(key,unscoped); + final Provider base = Scopes.SINGLETON.scope(key, unscoped); return new Provider() { + @Override public T get() { try { return base.get(); @@ -441,6 +447,7 @@ public T get() { return null; } } + void error(Key key, Throwable x) { LOGGER.log(verbose ? Level.WARNING : Level.FINE, "Failed to instantiate " + key + "; skipping this component", x); } @@ -456,10 +463,10 @@ void error(Key key, Throwable x) { * so that we can take advantage of dependency injection. */ private class SezpozModule extends AbstractModule implements ProvisionListener { - private final List> index; - private final List> loadedIndex; + private final List> index; + private final List> loadedIndex; - SezpozModule(List> index) { + SezpozModule(List> index) { this.index = index; this.loadedIndex = new ArrayList<>(); } @@ -479,6 +486,7 @@ private class SezpozModule extends AbstractModule implements ProvisionListener { private void resolve(Class c) { resolve(c, new HashSet<>()); } + private void resolve(Class c, Set> encountered) { if (!encountered.add(c)) { return; @@ -499,8 +507,8 @@ private void resolve(Class c, Set> encountered) { } } LOGGER.log(Level.FINER, "{0} looks OK", c); - } catch (Exception x) { - throw new LinkageError("Failed to resolve "+c, x); + } catch (RuntimeException x) { + throw new LinkageError("Failed to resolve " + c, x); } } @@ -510,26 +518,26 @@ protected void configure() { bindListener(Matchers.any(), this); - for (final IndexItem item : index) { + for (final IndexItem item : index) { boolean optional = isOptional(item.annotation()); try { AnnotatedElement e = item.element(); Annotation a = item.annotation(); - if (!isActive(a,e)) continue; + if (!isActive(a, e)) continue; Scope scope = optional ? QUIET_FAULT_TOLERANT_SCOPE : FAULT_TOLERANT_SCOPE; if (e instanceof Class) { - Key key = Key.get((Class)e); - resolve((Class)e); - annotations.put(key,a); + Key key = Key.get((Class) e); + resolve((Class) e); + annotations.put(key, a); bind(key).in(scope); } else { Class extType; if (e instanceof Field) { - extType = ((Field)e).getType(); + extType = ((Field) e).getType(); } else if (e instanceof Method) { - extType = ((Method)e).getReturnType(); + extType = ((Method) e).getReturnType(); } else { throw new AssertionError(); } @@ -538,32 +546,28 @@ protected void configure() { // make unique key, because Guice wants that. Key key = Key.get(extType, Names.named(item.className() + "." + item.memberName())); - annotations.put(key,a); - bind(key).toProvider(new Provider() { - public Object get() { - return instantiate(item); - } - }).in(scope); + annotations.put(key, a); + bind(key).toProvider(() -> instantiate(item)).in(scope); } loadedIndex.add(item); - } catch (Exception|LinkageError e) { + } catch (Exception | LinkageError e) { // sometimes the instantiation fails in an indirect classloading failure, // which results in a LinkageError LOGGER.log(optional ? Level.FINE : Level.WARNING, - "Failed to load "+item.className(), e); + "Failed to load " + item.className(), e); } } } public List> getLoadedIndex() { - return Collections.unmodifiableList(loadedIndex); + return Collections.unmodifiableList(new ArrayList<>(loadedIndex)); } @Override public void onProvision(ProvisionInvocation provision) { final T instance = provision.provision(); if (instance == null) return; - List methods = new LinkedList<>(); + List methods = new ArrayList<>(); Class c = instance.getClass(); // find PostConstruct methods in class hierarchy, the one from parent class being first in list @@ -576,7 +580,7 @@ public void onProvision(ProvisionInvocation provision) { Arrays.stream(c.getDeclaredMethods()) .map(m -> getMethodAndInterfaceDeclarations(m, interfaces)) .flatMap(Collection::stream) - .filter(m -> m.getAnnotation(PostConstruct.class) != null) + .filter(m -> m.getAnnotation(PostConstruct.class) != null || m.getAnnotation(javax.annotation.PostConstruct.class) != null) .findFirst() .ifPresent(method -> methods.add(0, method)); c = c.getSuperclass(); @@ -624,7 +628,7 @@ Collection getMethodAndInterfaceDeclarations(Method method, Collection> indices; + private volatile List> indices; /** * Loads indices (ideally once but as few times as possible), then reuse them later. @@ -632,16 +636,16 @@ public static final class Sezpoz extends ExtensionFinder { * {@link InitMilestone#PLUGINS_PREPARED} is attained, so this method is guaranteed to * see all the classes and indices. */ - private List> getIndices() { + private List> getIndices() { // this method cannot be synchronized because of a dead lock possibility in the following order of events: // 1. thread X can start listing indices, locking this object 'SZ' // 2. thread Y starts loading a class, locking a classloader 'CL' // 3. thread X needs to load a class, now blocked on CL // 4. thread Y decides to load extensions, now blocked on SZ. // 5. dead lock - if (indices==null) { + if (indices == null) { ClassLoader cl = Jenkins.get().getPluginManager().uberClassLoader; - indices = ImmutableList.copyOf(Index.load(Extension.class, Object.class, cl)); + indices = Collections.unmodifiableList(StreamSupport.stream(Index.load(Extension.class, Object.class, cl).spliterator(), false).collect(Collectors.toList())); } return indices; } @@ -654,28 +658,28 @@ private List> getIndices() { */ @Override public synchronized ExtensionComponentSet refresh() { - final List> old = indices; - if (old==null) return ExtensionComponentSet.EMPTY; // we haven't loaded anything + final List> old = indices; + if (old == null) return ExtensionComponentSet.EMPTY; // we haven't loaded anything - final List> delta = listDelta(Extension.class,old); + final List> delta = listDelta(Extension.class, old); - List> r = new ArrayList<>(old); + List> r = new ArrayList<>(old); r.addAll(delta); - indices = ImmutableList.copyOf(r); + indices = Collections.unmodifiableList(r); return new ExtensionComponentSet() { @Override public Collection> find(Class type) { - return _find(type,delta); + return _find(type, delta); } }; } - static List> listDelta(Class annotationType, List> old) { + static List> listDelta(Class annotationType, List> old) { // list up newly discovered components - final List> delta = new ArrayList<>(); + final List> delta = new ArrayList<>(); ClassLoader cl = Jenkins.get().getPluginManager().uberClassLoader; - for (IndexItem ii : Index.load(annotationType, Object.class, cl)) { + for (IndexItem ii : Index.load(annotationType, Object.class, cl)) { if (!old.contains(ii)) { delta.add(ii); } @@ -683,29 +687,30 @@ static List> listDelta(Class annot return delta; } + @Override public Collection> find(Class type, Hudson jenkins) { - return _find(type,getIndices()); + return _find(type, getIndices()); } /** * Finds all the matching {@link IndexItem}s that match the given type and instantiate them. */ - private Collection> _find(Class type, List> indices) { + private Collection> _find(Class type, List> indices) { List> result = new ArrayList<>(); - for (IndexItem item : indices) { + for (IndexItem item : indices) { try { Class extType = getClassFromIndex(item); - if(type.isAssignableFrom(extType)) { + if (type.isAssignableFrom(extType)) { Object instance = item.instance(); - if(instance!=null) - result.add(new ExtensionComponent<>(type.cast(instance),item.annotation())); + if (instance != null) + result.add(new ExtensionComponent<>(type.cast(instance), item.annotation())); } - } catch (LinkageError|Exception e) { + } catch (LinkageError | Exception e) { // sometimes the instantiation fails in an indirect classloading failure, // which results in a LinkageError - LOGGER.log(logLevel(item), "Failed to load "+item.className(), e); + LOGGER.log(logLevel(item), "Failed to load " + item.className(), e); } } @@ -714,7 +719,7 @@ private Collection> _find(Class type, List item : getIndices()) { + for (IndexItem item : getIndices()) { try { // we might end up having multiple threads concurrently calling into element(), // but we can't synchronize this --- if we do, the one thread that's supposed to load a class @@ -722,9 +727,9 @@ public void scout(Class extensionType, Hudson hudson) { // looking at the sezpoz code, it should be safe to do so Class extType = getClassFromIndex(item); // according to JDK-4993813 this is the only way to force class initialization - Class.forName(extType.getName(),true,extType.getClassLoader()); + Class.forName(extType.getName(), true, extType.getClassLoader()); } catch (Exception | LinkageError e) { - LOGGER.log(logLevel(item), "Failed to scout "+item.className(), e); + LOGGER.log(logLevel(item), "Failed to scout " + item.className(), e); } } } diff --git a/core/src/main/java/hudson/ExtensionList.java b/core/src/main/java/hudson/ExtensionList.java index c7826937c79f..7bae8ff5d83b 100644 --- a/core/src/main/java/hudson/ExtensionList.java +++ b/core/src/main/java/hudson/ExtensionList.java @@ -21,17 +21,17 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; +import hudson.ExtensionPoint.LegacyInstancesAreScopedToHudson; import hudson.init.InitMilestone; import hudson.model.Hudson; -import jenkins.ExtensionComponentSet; -import jenkins.model.Jenkins; import hudson.util.AdaptedIterator; import hudson.util.DescriptorList; import hudson.util.Iterators; -import hudson.ExtensionPoint.LegacyInstancesAreScopedToHudson; - import java.util.AbstractList; import java.util.ArrayList; import java.util.Collection; @@ -39,13 +39,14 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Vector; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.logging.Level; import java.util.logging.Logger; -import edu.umd.cs.findbugs.annotations.CheckForNull; -import edu.umd.cs.findbugs.annotations.NonNull; +import jenkins.ExtensionComponentSet; +import jenkins.model.Jenkins; import jenkins.util.io.OnMaster; /** @@ -62,7 +63,7 @@ * and {@link jenkins.model.Jenkins#getDescriptorList(Class)} to obtain the instances. * * @param - * Type of the extension point. This class holds instances of the subtypes of 'T'. + * Type of the extension point. This class holds instances of the subtypes of 'T'. * * @author Kohsuke Kawaguchi * @since 1.286 @@ -99,11 +100,11 @@ public class ExtensionList extends AbstractList implements OnMaster { */ @Deprecated protected ExtensionList(Hudson hudson, Class extensionType) { - this((Jenkins)hudson,extensionType); + this((Jenkins) hudson, extensionType); } protected ExtensionList(Jenkins jenkins, Class extensionType) { - this(jenkins,extensionType, new CopyOnWriteArrayList<>()); + this(jenkins, extensionType, new CopyOnWriteArrayList<>()); } /** @@ -112,7 +113,7 @@ protected ExtensionList(Jenkins jenkins, Class extensionType) { */ @Deprecated protected ExtensionList(Hudson hudson, Class extensionType, CopyOnWriteArrayList> legacyStore) { - this((Jenkins)hudson,extensionType,legacyStore); + this((Jenkins) hudson, extensionType, legacyStore); } /** @@ -120,10 +121,10 @@ protected ExtensionList(Hudson hudson, Class extensionType, CopyOnWriteArrayL * @param legacyStore * Place to store manually registered instances. The version of the constructor that * omits this uses a new {@link Vector}, making the storage lifespan tied to the life of {@link ExtensionList}. - * If the manually registered instances are scoped to VM level, the caller should pass in a static list. + * If the manually registered instances are scoped to VM level, the caller should pass in a static list. */ protected ExtensionList(Jenkins jenkins, Class extensionType, CopyOnWriteArrayList> legacyStore) { - this.hudson = (Hudson)jenkins; + this.hudson = (Hudson) jenkins; this.jenkins = jenkins; this.extensionType = extensionType; this.legacyInstances = legacyStore; @@ -146,7 +147,7 @@ public void addListener(@NonNull ExtensionListListener listener) { */ public @CheckForNull U get(@NonNull Class type) { for (T ext : this) - if(ext.getClass()==type) + if (ext.getClass() == type) return type.cast(ext); return null; } @@ -154,21 +155,22 @@ public void addListener(@NonNull ExtensionListListener listener) { /** * Looks for the extension instance of the given type (subclasses excluded), * or throws an IllegalStateException. - * + * * Meant to simplify call inside @Extension annotated class to retrieve their own instance. */ public @NonNull U getInstance(@NonNull Class type) throws IllegalStateException { for (T ext : this) - if(ext.getClass()==type) + if (ext.getClass() == type) return type.cast(ext); - + throw new IllegalStateException("The class " + type.getName() + " was not found, potentially not yet loaded"); } @Override public @NonNull Iterator iterator() { - // we need to intercept mutation, so for now don't allow Iterator.remove - return new AdaptedIterator,T>(Iterators.readOnly(ensureLoaded().iterator())) { + // we need to intercept mutation, so for now don't allow Iterator.remove + return new AdaptedIterator, T>(Iterators.readOnly(ensureLoaded().iterator())) { + @Override protected T adapt(ExtensionComponent item) { return item.getInstance(); } @@ -182,10 +184,12 @@ public List> getComponents() { return Collections.unmodifiableList(ensureLoaded()); } + @Override public T get(int index) { return ensureLoaded().get(index).getInstance(); } - + + @Override public int size() { return ensureLoaded().size(); } @@ -197,7 +201,7 @@ public List reverseView() { return new AbstractList() { @Override public T get(int index) { - return ExtensionList.this.get(size()-index-1); + return ExtensionList.this.get(size() - index - 1); } @Override @@ -212,7 +216,7 @@ public boolean remove(Object o) { try { return removeSync(o); } finally { - if(extensions!=null) { + if (extensions != null) { fireOnChangeListeners(); } } @@ -235,15 +239,15 @@ public boolean removeAll(Collection c) { private synchronized boolean removeSync(Object o) { boolean removed = removeComponent(legacyInstances, o); - if(extensions!=null) { + if (extensions != null) { List> r = new ArrayList<>(extensions); - removed |= removeComponent(r,o); + removed |= removeComponent(r, o); extensions = sort(r); } return removed; } - private boolean removeComponent(Collection> collection, Object t) { + private boolean removeComponent(Collection> collection, Object t) { for (ExtensionComponent c : collection) { if (c.getInstance().equals(t)) { return collection.remove(c); @@ -271,7 +275,7 @@ public boolean add(T t) { try { return addSync(t); } finally { - if(extensions!=null) { + if (extensions != null) { fireOnChangeListeners(); } } @@ -280,7 +284,7 @@ public boolean add(T t) { private synchronized boolean addSync(T t) { legacyInstances.add(new ExtensionComponent<>(t)); // if we've already filled extensions, add it - if(extensions!=null) { + if (extensions != null) { List> r = new ArrayList<>(extensions); r.add(new ExtensionComponent<>(t)); extensions = sort(r); @@ -306,13 +310,13 @@ public T getDynamic(String className) { } private List> ensureLoaded() { - if(extensions!=null) + if (extensions != null) return extensions; // already loaded if (jenkins == null || jenkins.getInitLevel().compareTo(InitMilestone.PLUGINS_PREPARED) < 0) return legacyInstances; // can't perform the auto discovery until all plugins are loaded, so just make the legacy instances visible synchronized (getLoadLock()) { - if(extensions==null) { + if (extensions == null) { List> r = load(); r.addAll(legacyInstances); extensions = sort(r); @@ -325,7 +329,7 @@ private List> ensureLoaded() { * Chooses the object that locks the loading of the extension instances. */ protected Object getLoadLock() { - return jenkins.lookup.setIfNull(Lock.class,new Lock()); + return Objects.requireNonNull(jenkins).lookup.setIfNull(Lock.class, new Lock()); } /** @@ -335,7 +339,7 @@ protected Object getLoadLock() { public void refresh(ExtensionComponentSet delta) { boolean fireOnChangeListeners = false; synchronized (getLoadLock()) { - if (extensions==null) + if (extensions == null) return; // not yet loaded. when we load it, we'll load everything visible by then, so no work needed Collection> found = load(delta); @@ -355,7 +359,7 @@ private void fireOnChangeListeners() { for (ExtensionListListener listener : listeners) { try { listener.onChange(); - } catch (Exception e) { + } catch (Throwable e) { LOGGER.log(Level.SEVERE, "Error firing ExtensionListListener.onChange().", e); } } @@ -377,7 +381,7 @@ protected List> load() { LOGGER.log(Level.FINER, String.format("Loading ExtensionList '%s' from", extensionType.getName()), new Throwable("Only present for stacktrace information")); } - return jenkins.getPluginManager().getPluginStrategy().findComponents(extensionType, hudson); + return Objects.requireNonNull(jenkins).getPluginManager().getPluginStrategy().findComponents(extensionType, hudson); } /** @@ -407,12 +411,12 @@ protected List> sort(List> r) { */ @Deprecated public static ExtensionList create(Hudson hudson, Class type) { - return create((Jenkins)hudson,type); + return create((Jenkins) hudson, type); } @SuppressWarnings({"unchecked", "rawtypes"}) public static ExtensionList create(Jenkins jenkins, Class type) { - if(type.getAnnotation(LegacyInstancesAreScopedToHudson.class)!=null) + if (type.getAnnotation(LegacyInstancesAreScopedToHudson.class) != null) return new ExtensionList<>(jenkins, type); else { return new ExtensionList(jenkins, type, staticLegacyInstances.computeIfAbsent(type, key -> new CopyOnWriteArrayList())); diff --git a/core/src/main/java/hudson/ExtensionListListener.java b/core/src/main/java/hudson/ExtensionListListener.java index f5c8528add39..af3c0e18b7f4 100644 --- a/core/src/main/java/hudson/ExtensionListListener.java +++ b/core/src/main/java/hudson/ExtensionListListener.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson; /** @@ -35,7 +36,7 @@ public abstract class ExtensionListListener { * {@link ExtensionList} contents has changed. *

* This would be called when an entry gets added to or removed from the list for any reason e.g. - * when a dynamically loaded plugin introduces a new {@link ExtensionPoint} implementation + * when a dynamically loaded plugin introduces a new {@link ExtensionPoint} implementation * that adds an entry to the {@link ExtensionList} being listened to. */ public abstract void onChange(); diff --git a/core/src/main/java/hudson/ExtensionListView.java b/core/src/main/java/hudson/ExtensionListView.java index e3689ccf616a..0127752e46bd 100644 --- a/core/src/main/java/hudson/ExtensionListView.java +++ b/core/src/main/java/hudson/ExtensionListView.java @@ -21,16 +21,16 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson; import hudson.tasks.UserNameResolver; -import jenkins.model.Jenkins; import hudson.util.CopyOnWriteList; - import java.util.AbstractList; +import java.util.Collection; import java.util.Iterator; import java.util.List; -import java.util.Collection; +import jenkins.model.Jenkins; /** * Compatibility layer for legacy manual registration of extension points. @@ -66,10 +66,12 @@ public Iterator iterator() { return storage().iterator(); } + @Override public T get(int index) { return storage().get(index); } + @Override public int size() { return storage().size(); } @@ -142,7 +144,7 @@ public void clear() { } @Override - public T[] toArray(T[] array) { + public X[] toArray(X[] array) { return storage().toArray(array); } diff --git a/core/src/main/java/hudson/ExtensionPoint.java b/core/src/main/java/hudson/ExtensionPoint.java index f49a5a096cc7..e04581798fc6 100644 --- a/core/src/main/java/hudson/ExtensionPoint.java +++ b/core/src/main/java/hudson/ExtensionPoint.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,14 +21,15 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package hudson; -import jenkins.model.Jenkins; +package hudson; import static java.lang.annotation.ElementType.TYPE; -import java.lang.annotation.Retention; import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; import java.lang.annotation.Target; +import jenkins.model.Jenkins; /** * Marker interface that designates extensible components @@ -51,7 +52,7 @@ public interface ExtensionPoint { /** * Used by designers of extension points (direct subtypes of {@link ExtensionPoint}) to indicate that * the legacy instances are scoped to {@link Jenkins} instance. By default, legacy instances are - * static scope. + * static scope. */ @Target(TYPE) @Retention(RUNTIME) diff --git a/core/src/main/java/hudson/FeedAdapter.java b/core/src/main/java/hudson/FeedAdapter.java index 981c5cfe8816..632001ae360a 100644 --- a/core/src/main/java/hudson/FeedAdapter.java +++ b/core/src/main/java/hudson/FeedAdapter.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson; import java.util.Calendar; diff --git a/core/src/main/java/hudson/FilePath.java b/core/src/main/java/hudson/FilePath.java index 3fb9ba4e1bb3..e4172a306a91 100644 --- a/core/src/main/java/hudson/FilePath.java +++ b/core/src/main/java/hudson/FilePath.java @@ -1,20 +1,20 @@ /* * The MIT License - * + * * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, * Eric Lefevre-Ardant, Erik Ramfelt, Michael B. Donohue, Alan Harder, * Manufacture Francaise des Pneumatiques Michelin, Romain Seguy - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,11 +23,18 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson; +import static hudson.FilePath.TarCompression.GZIP; +import static hudson.Util.fileToPath; +import static hudson.Util.fixEmpty; + import com.google.common.annotations.VisibleForTesting; import com.jcraft.jzlib.GZIPInputStream; import com.jcraft.jzlib.GZIPOutputStream; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.Launcher.LocalLauncher; import hudson.Launcher.RemoteLauncher; @@ -35,8 +42,6 @@ import hudson.model.Computer; import hudson.model.Item; import hudson.model.TaskListener; -import hudson.os.PosixAPI; -import hudson.os.PosixException; import hudson.remoting.Callable; import hudson.remoting.Channel; import hudson.remoting.DelegatingCallable; @@ -60,15 +65,14 @@ import hudson.util.NamingThreadFactory; import hudson.util.io.Archiver; import hudson.util.io.ArchiverFactory; - import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileFilter; -import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InterruptedIOException; +import java.io.NotSerializableException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; @@ -81,6 +85,7 @@ import java.net.URI; import java.net.URL; import java.net.URLConnection; +import java.nio.charset.Charset; import java.nio.file.FileSystemException; import java.nio.file.FileSystems; import java.nio.file.Files; @@ -90,10 +95,12 @@ import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.nio.file.attribute.FileAttribute; +import java.nio.file.attribute.FileTime; import java.nio.file.attribute.PosixFilePermission; import java.nio.file.attribute.PosixFilePermissions; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.Comparator; import java.util.EnumSet; import java.util.Enumeration; @@ -111,22 +118,19 @@ import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; -import edu.umd.cs.findbugs.annotations.CheckForNull; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import jenkins.FilePathFilter; import jenkins.MasterToSlaveFileCallable; import jenkins.SlaveToMasterFileCallable; -import jenkins.SoloFilePathFilter; import jenkins.model.Jenkins; import jenkins.security.MasterToSlaveCallable; import jenkins.util.ContextResettingExecutorService; +import jenkins.util.SystemProperties; import jenkins.util.VirtualFile; import org.apache.commons.compress.archivers.tar.TarArchiveEntry; import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; import org.apache.commons.fileupload.FileItem; import org.apache.commons.io.input.CountingInputStream; import org.apache.commons.lang.StringUtils; +import org.apache.tools.ant.BuildException; import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.Project; import org.apache.tools.ant.types.FileSet; @@ -139,20 +143,12 @@ import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.Stapler; -import static hudson.FilePath.TarCompression.GZIP; -import static hudson.Util.fileToPath; -import static hudson.Util.fixEmpty; -import java.io.NotSerializableException; - -import java.util.Collections; -import org.apache.tools.ant.BuildException; - /** * {@link File} like object with remoting support. * *

* Unlike {@link File}, which always implies a file path on the current computer, - * {@link FilePath} represents a file path on a specific agent or the master. + * {@link FilePath} represents a file path on a specific agent or the controller. * * Despite that, {@link FilePath} can be used much like {@link File}. It exposes * a bunch of operations (and we should add more operations as long as they are @@ -171,7 +167,7 @@ * it makes more sense to move some computation closer to the data, as opposed to * move the data to the computation. For example, if you are just computing a MD5 * digest of a file, then it would make sense to do the digest on the host where - * the file is located, as opposed to send the whole data to the master and do MD5 + * the file is located, as opposed to send the whole data to the controller and do MD5 * digesting there. * *

@@ -201,7 +197,7 @@ *

* When {@link FileCallable} is transferred to a remote node, it will be done so * by using the same Java serialization scheme that the remoting module uses. - * See {@link Channel} for more about this. + * See {@link Channel} for more about this. * *

* {@link FilePath} itself can be sent over to a remote node as a part of {@link Callable} @@ -220,39 +216,27 @@ public final class FilePath implements SerializableOnlyOverRemoting { /** * When this {@link FilePath} represents the remote path, - * this field is always non-null on master (the field represents + * this field is always non-null on the controller (the field represents * the channel to the remote agent.) When transferred to a agent via remoting, * this field reverts back to null, since it's transient. * - * When this {@link FilePath} represents a path on the master, - * this field is null on master. When transferred to a agent via remoting, + * When this {@link FilePath} represents a path on the controller, + * this field is null on the controller. When transferred to a agent via remoting, * this field becomes non-null, representing the {@link Channel} - * back to the master. + * back to the controller. * - * This is used to determine whether we are running on the master or the agent. + * This is used to determine whether we are running on the controller / the built-in node, or an agent. */ private transient VirtualChannel channel; - + /** - * Represent the path to the file in the master or the agent + * Represent the path to the file in the controller or the agent * Since the platform of the agent might be different, can't use java.io.File * * The field could not be final since it's modified in {@link #readResolve()} */ private /*final*/ String remote; - /** - * If this {@link FilePath} is deserialized to handle file access request from a remote computer, - * this field is set to the filter that performs access control. - * - *

- * If null, no access control is needed. - * - * @see #filterNonNull() - */ - private transient @Nullable - SoloFilePathFilter filter; - /** * Creates a {@link FilePath} that represents a path on the given node. * @@ -293,14 +277,14 @@ private Object readResolve() { } private String resolvePathIfRelative(@NonNull FilePath base, @NonNull String rel) { - if(isAbsolute(rel)) return rel; - if(base.isUnix()) { + if (isAbsolute(rel)) return rel; + if (base.isUnix()) { // shouldn't need this replace, but better safe than sorry - return base.remote+'/'+rel.replace('\\','/'); + return base.remote + '/' + rel.replace('\\', '/'); } else { // need this replace, see Slave.getWorkspaceFor and AbstractItem.getFullName, nested jobs on Windows // agents will always have a rel containing at least one '/' character. JENKINS-13649 - return base.remote+'\\'+rel.replace('/','\\'); + return base.remote + '\\' + rel.replace('/', '\\'); } } @@ -342,7 +326,7 @@ public static String normalize(@NonNull String path) { while (++i < end && ((c = path.charAt(i)) == '/' || c == '\\')) ; // Add token for separator unless we reached the end - if (i < end) tokens.add(path.substring(s, s+1)); + if (i < end) tokens.add(path.substring(s, s + 1)); s = i; } } @@ -365,7 +349,7 @@ public static String normalize(@NonNull String path) { // Normalize: remove something/.. plus separator before/after i -= 2; for (int j = 0; j < 3; j++) tokens.remove(i); - if (i > 0) tokens.remove(i-1); + if (i > 0) tokens.remove(i - 1); else if (tokens.size() > 0) tokens.remove(0); } } else @@ -382,14 +366,14 @@ public static String normalize(@NonNull String path) { */ boolean isUnix() { // if the path represents a local path, there' no need to guess. - if(!isRemote()) - return File.pathSeparatorChar!=';'; - + if (!isRemote()) + return File.pathSeparatorChar != ';'; + // note that we can't use the usual File.pathSeparator and etc., as the OS of // the machine where this code runs and the OS that this FilePath refers to may be different. // Windows absolute path is 'X:\...', so this is usually a good indication of Windows path - if(remote.length()>3 && remote.charAt(1)==':' && remote.charAt(2)=='\\') + if (remote.length() > 3 && remote.charAt(1) == ':' && remote.charAt(2) == '\\') return false; // Windows can handle '/' as a path separator but Unix can't, // so err on Unix side @@ -418,7 +402,7 @@ public void createZipArchive(OutputStream os) throws IOException, InterruptedExc * Creates a zip file from this directory or a file and sends that to the given output stream. */ public void zip(OutputStream os) throws IOException, InterruptedException { - zip(os,(FileFilter)null); + zip(os, (FileFilter) null); } public void zip(FilePath dst) throws IOException, InterruptedException { @@ -426,7 +410,7 @@ public void zip(FilePath dst) throws IOException, InterruptedException { zip(os); } } - + /** * Creates a zip file from this directory by using the specified filter, * and sends the result to the given output stream. @@ -437,7 +421,7 @@ public void zip(FilePath dst) throws IOException, InterruptedException { * @since 1.315 */ public void zip(OutputStream os, FileFilter filter) throws IOException, InterruptedException { - archive(ArchiverFactory.ZIP,os,filter); + archive(ArchiverFactory.ZIP, os, filter); } /** @@ -453,7 +437,7 @@ public void zip(OutputStream os, FileFilter filter) throws IOException, Interrup */ @Deprecated public void createZipArchive(OutputStream os, final String glob) throws IOException, InterruptedException { - archive(ArchiverFactory.ZIP,os,glob); + archive(ArchiverFactory.ZIP, os, glob); } /** @@ -466,7 +450,7 @@ public void createZipArchive(OutputStream os, final String glob) throws IOExcept * @since 1.315 */ public void zip(OutputStream os, final String glob) throws IOException, InterruptedException { - archive(ArchiverFactory.ZIP,os,glob); + archive(ArchiverFactory.ZIP, os, glob); } /** @@ -526,10 +510,11 @@ public int archive(final ArchiverFactory factory, OutputStream os, final DirScan @Restricted(NoExternalUse.class) public int archive(final ArchiverFactory factory, OutputStream os, final DirScanner scanner, String verificationRoot, boolean noFollowLinks) throws IOException, InterruptedException { - final OutputStream out = (channel!=null)?new RemoteOutputStream(os):os; + final OutputStream out = channel != null ? new RemoteOutputStream(os) : os; return act(new Archive(factory, out, scanner, verificationRoot, noFollowLinks)); } - private class Archive extends SecureFileCallable { + + private static class Archive extends MasterToSlaveFileCallable { private final ArchiverFactory factory; private final OutputStream out; private final DirScanner scanner; @@ -543,11 +528,12 @@ private class Archive extends SecureFileCallable { this.verificationRoot = verificationRoot; this.noFollowLinks = noFollowLinks; } + @Override public Integer invoke(File f, VirtualChannel channel) throws IOException { Archiver a = factory.create(out); try { - scanner.scan(f, ignoringSymlinks(reading(a), verificationRoot, noFollowLinks)); + scanner.scan(f, ignoringSymlinks(a, verificationRoot, noFollowLinks)); } finally { a.close(); } @@ -558,11 +544,11 @@ public Integer invoke(File f, VirtualChannel channel) throws IOException { } public int archive(final ArchiverFactory factory, OutputStream os, final FileFilter filter) throws IOException, InterruptedException { - return archive(factory,os,new DirScanner.Filter(filter)); + return archive(factory, os, new DirScanner.Filter(filter)); } public int archive(final ArchiverFactory factory, OutputStream os, final String glob) throws IOException, InterruptedException { - return archive(factory,os,new DirScanner.Glob(glob,null)); + return archive(factory, os, new DirScanner.Glob(glob, null)); } /** @@ -575,32 +561,47 @@ public int archive(final ArchiverFactory factory, OutputStream os, final String */ public void unzip(final FilePath target) throws IOException, InterruptedException { // TODO: post release, re-unite two branches by introducing FileStreamCallable that resolves InputStream - if (this.channel!=target.channel) {// local -> remote or remote->local + if (channel != target.channel) { // local -> remote or remote->local final RemoteInputStream in = new RemoteInputStream(read(), Flag.GREEDY); target.act(new UnzipRemote(in)); - } else {// local -> local or remote->remote - target.act(new UnzipLocal()); + } else { // local -> local or remote->remote + target.act(new UnzipLocal(this)); } } - private class UnzipRemote extends SecureFileCallable { + + private static class UnzipRemote extends MasterToSlaveFileCallable { private final RemoteInputStream in; + UnzipRemote(RemoteInputStream in) { this.in = in; } + @Override public Void invoke(File dir, VirtualChannel channel) throws IOException, InterruptedException { unzip(dir, in); return null; } + private static final long serialVersionUID = 1L; } - private class UnzipLocal extends SecureFileCallable { + + private static class UnzipLocal extends MasterToSlaveFileCallable { + + private final FilePath filePath; + + private UnzipLocal(FilePath filePath) { + this.filePath = filePath; + } + @Override public Void invoke(File dir, VirtualChannel channel) throws IOException, InterruptedException { - assert !FilePath.this.isRemote(); // this.channel==target.channel above - unzip(dir, reading(new File(FilePath.this.getRemote()))); // shortcut to local file + if (this.filePath.isRemote()) { + throw new IllegalStateException("Expected local path for file: " + filePath); // this.channel==target.channel above + } + unzip(dir, new File(this.filePath.getRemote())); // shortcut to local file return null; } + private static final long serialVersionUID = 1L; } @@ -615,38 +616,51 @@ public Void invoke(File dir, VirtualChannel channel) throws IOException, Interru * @see #untarFrom(InputStream, TarCompression) */ public void untar(final FilePath target, final TarCompression compression) throws IOException, InterruptedException { + final FilePath source = FilePath.this; // TODO: post release, re-unite two branches by introducing FileStreamCallable that resolves InputStream - if (this.channel!=target.channel) {// local -> remote or remote->local - final RemoteInputStream in = new RemoteInputStream(read(), Flag.GREEDY); - target.act(new UntarRemote(compression, in)); - } else {// local -> local or remote->remote - target.act(new UntarLocal(compression)); + if (source.channel != target.channel) { // local -> remote or remote->local + final RemoteInputStream in = new RemoteInputStream(source.read(), Flag.GREEDY); + target.act(new UntarRemote(source.getName(), compression, in)); + } else { // local -> local or remote->remote + target.act(new UntarLocal(source, compression)); } } - private class UntarRemote extends SecureFileCallable { + + private static class UntarRemote extends MasterToSlaveFileCallable { private final TarCompression compression; private final RemoteInputStream in; - UntarRemote(TarCompression compression, RemoteInputStream in) { + private final String name; + + UntarRemote(String name, TarCompression compression, RemoteInputStream in) { this.compression = compression; this.in = in; + this.name = name; } + @Override public Void invoke(File dir, VirtualChannel channel) throws IOException, InterruptedException { - readFromTar(FilePath.this.getName(), dir, compression.extract(in)); + readFromTar(name, dir, compression.extract(in)); return null; } + private static final long serialVersionUID = 1L; } - private class UntarLocal extends SecureFileCallable { + + private static class UntarLocal extends MasterToSlaveFileCallable { private final TarCompression compression; - UntarLocal(TarCompression compression) { + private final FilePath filePath; + + UntarLocal(FilePath source, TarCompression compression) { + this.filePath = source; this.compression = compression; } + @Override public Void invoke(File dir, VirtualChannel channel) throws IOException, InterruptedException { - readFromTar(FilePath.this.getName(), dir, compression.extract(FilePath.this.read())); + readFromTar(this.filePath.getName(), dir, compression.extract(this.filePath.read())); return null; } + private static final long serialVersionUID = 1L; } @@ -662,32 +676,36 @@ public void unzipFrom(InputStream _in) throws IOException, InterruptedException final InputStream in = new RemoteInputStream(_in, Flag.GREEDY); act(new UnzipFrom(in)); } - private class UnzipFrom extends SecureFileCallable { + + private static class UnzipFrom extends MasterToSlaveFileCallable { private final InputStream in; + UnzipFrom(InputStream in) { this.in = in; } + @Override public Void invoke(File dir, VirtualChannel channel) throws IOException { unzip(dir, in); return null; } + private static final long serialVersionUID = 1L; } - private void unzip(File dir, InputStream in) throws IOException { + private static void unzip(File dir, InputStream in) throws IOException { File tmpFile = File.createTempFile("tmpzip", null); // uses java.io.tmpdir try { // TODO why does this not simply use ZipInputStream? IOUtils.copy(in, tmpFile); - unzip(dir,tmpFile); + unzip(dir, tmpFile); } finally { - tmpFile.delete(); + Files.delete(Util.fileToPath(tmpFile)); } } - private void unzip(File dir, File zipFile) throws IOException { + private static void unzip(File dir, File zipFile) throws IOException { dir = dir.getAbsoluteFile(); // without absolutization, getParentFile below seems to fail ZipFile zip = new ZipFile(zipFile); Enumeration entries = zip.getEntries(); @@ -696,7 +714,7 @@ private void unzip(File dir, File zipFile) throws IOException { while (entries.hasMoreElements()) { ZipEntry e = entries.nextElement(); File f = new File(dir, e.getName()); - if (!f.getCanonicalPath().startsWith(dir.getCanonicalPath())) { + if (!f.getCanonicalFile().toPath().startsWith(dir.getCanonicalPath())) { throw new IOException( "Zip " + zipFile.getPath() + " contains illegal file name that breaks out of the target directory: " + e.getName()); } @@ -708,17 +726,17 @@ private void unzip(File dir, File zipFile) throws IOException { mkdirs(p); } try (InputStream input = zip.getInputStream(e)) { - IOUtils.copy(input, writing(f)); + IOUtils.copy(input, f); } try { FilePath target = new FilePath(f); int mode = e.getUnixMode(); - if (mode!=0) // Ant returns 0 if the archive doesn't record the access mode + if (mode != 0) // Ant returns 0 if the archive doesn't record the access mode target.chmod(mode); } catch (InterruptedException ex) { LOGGER.log(Level.WARNING, "unable to set permissions", ex); } - f.setLastModified(e.getTime()); + Files.setLastModifiedTime(Util.fileToPath(f), e.getLastModifiedTime()); } } } finally { @@ -732,8 +750,11 @@ private void unzip(File dir, File zipFile) throws IOException { public FilePath absolutize() throws IOException, InterruptedException { return new FilePath(channel, act(new Absolutize())); } - private static class Absolutize extends SecureFileCallable { + + private static class Absolutize extends MasterToSlaveFileCallable { private static final long serialVersionUID = 1L; + + @Override public String invoke(File f, VirtualChannel channel) throws IOException { return f.getAbsolutePath(); } @@ -743,7 +764,8 @@ public String invoke(File f, VirtualChannel channel) throws IOException { public boolean hasSymlink(FilePath verificationRoot, boolean noFollowLinks) throws IOException, InterruptedException { return act(new HasSymlink(verificationRoot == null ? null : verificationRoot.remote, noFollowLinks)); } - private static class HasSymlink extends SecureFileCallable { + + private static class HasSymlink extends MasterToSlaveFileCallable { private static final long serialVersionUID = 1L; private final String verificationRoot; private final boolean noFollowLinks; @@ -753,6 +775,7 @@ private static class HasSymlink extends SecureFileCallable { this.noFollowLinks = noFollowLinks; } + @Override public Boolean invoke(File f, VirtualChannel channel) throws IOException { return isSymlink(f, verificationRoot, noFollowLinks); } @@ -773,9 +796,11 @@ private static class SymlinkRetainingFileFilter implements FileFilter, Serializa this.noFollowLinks = noFollowLinks; } + @Override public boolean accept(File file) { return isSymlink(file, verificationRoot, noFollowLinks); } + private static final long serialVersionUID = 1L; } @@ -791,22 +816,25 @@ public boolean accept(File file) { public void symlinkTo(final String target, final TaskListener listener) throws IOException, InterruptedException { act(new SymlinkTo(target, listener)); } - private class SymlinkTo extends SecureFileCallable { + + private static class SymlinkTo extends MasterToSlaveFileCallable { private final String target; private final TaskListener listener; + SymlinkTo(String target, TaskListener listener) { this.target = target; this.listener = listener; } + private static final long serialVersionUID = 1L; + @Override public Void invoke(File f, VirtualChannel channel) throws IOException, InterruptedException { - symlinking(f); Util.createSymlink(f.getParentFile(), target, f.getName(), listener); return null; } } - + /** * Resolves symlink, if the given file is a symlink. Otherwise return null. *

@@ -817,11 +845,13 @@ public Void invoke(File f, VirtualChannel channel) throws IOException, Interrupt public String readLink() throws IOException, InterruptedException { return act(new ReadLink()); } - private class ReadLink extends SecureFileCallable { + + private static class ReadLink extends MasterToSlaveFileCallable { private static final long serialVersionUID = 1L; + @Override public String invoke(File f, VirtualChannel channel) throws IOException, InterruptedException { - return Util.resolveSymlink(reading(f)); + return Util.resolveSymlink(f); } } @@ -841,36 +871,43 @@ public boolean equals(Object o) { public int hashCode() { return 31 * (channel != null ? channel.hashCode() : 0) + remote.hashCode(); } - + /** * Supported tar file compression methods. */ public enum TarCompression { NONE { + @Override public InputStream extract(InputStream in) { return new BufferedInputStream(in); } + + @Override public OutputStream compress(OutputStream out) { return new BufferedOutputStream(out); } }, GZIP { + @Override public InputStream extract(InputStream _in) throws IOException { - HeadBufferingStream in = new HeadBufferingStream(_in,SIDE_BUFFER_SIZE); + HeadBufferingStream in = new HeadBufferingStream(_in, SIDE_BUFFER_SIZE); try { return new GZIPInputStream(in, 8192, true); } catch (IOException e) { // various people reported "java.io.IOException: Not in GZIP format" here, so diagnose this problem better in.fillSide(); - throw new IOException(e.getMessage()+"\nstream="+Util.toHexString(in.getSideBuffer()),e); + throw new IOException(e.getMessage() + "\nstream=" + Util.toHexString(in.getSideBuffer()), e); } } + + @Override public OutputStream compress(OutputStream out) throws IOException { return new GZIPOutputStream(new BufferedOutputStream(out)); } }; public abstract InputStream extract(InputStream in) throws IOException; + public abstract OutputStream compress(OutputStream in) throws IOException; } @@ -891,18 +928,22 @@ public void untarFrom(InputStream _in, final TarCompression compression) throws _in.close(); } } - private class UntarFrom extends SecureFileCallable { + + private static class UntarFrom extends MasterToSlaveFileCallable { private final TarCompression compression; private final InputStream in; + UntarFrom(TarCompression compression, InputStream in) { this.compression = compression; this.in = in; } + @Override public Void invoke(File dir, VirtualChannel channel) throws IOException { - readFromTar("input stream",dir, compression.extract(in)); + readFromTar("input stream", dir, compression.extract(in)); return null; } + private static final long serialVersionUID = 1L; } @@ -988,7 +1029,7 @@ private boolean installIfNecessaryFrom(@NonNull URL archive, @NonNull TaskListen long sourceTimestamp = con.getLastModified(); - if(this.exists()) { + if (this.exists()) { if (lastModified != 0 && sourceTimestamp == lastModified) return false; // already up to date this.deleteContents(); @@ -1005,7 +1046,7 @@ private boolean installIfNecessaryFrom(@NonNull URL archive, @NonNull TaskListen timestamp.touch(sourceTimestamp); return true; } catch (IOException x) { - Functions.printStackTrace(x, listener.error("Failed to download " + archive + " from agent; will retry from master")); + Functions.printStackTrace(x, listener.error("Failed to download " + archive + " from agent; will retry from controller")); } } @@ -1013,27 +1054,29 @@ private boolean installIfNecessaryFrom(@NonNull URL archive, @NonNull TaskListen InputStream in = archive.getProtocol().startsWith("http") ? ProxyConfiguration.getInputStream(archive) : con.getInputStream(); CountingInputStream cis = new CountingInputStream(in); try { - if(archive.toExternalForm().endsWith(".zip")) + if (archive.toExternalForm().endsWith(".zip")) unzipFrom(cis); else - untarFrom(cis,GZIP); + untarFrom(cis, GZIP); } catch (IOException e) { throw new IOException(String.format("Failed to unpack %s (%d bytes read of total %d)", - archive,cis.getByteCount(),con.getContentLength()),e); + archive, cis.getByteCount(), con.getContentLength()), e); } timestamp.touch(sourceTimestamp); return true; } catch (IOException e) { - throw new IOException("Failed to install "+archive+" to "+remote,e); + throw new IOException("Failed to install " + archive + " to " + remote, e); } } // this reads from arbitrary URL - private final class Unpack extends MasterToSlaveFileCallable { + private static final class Unpack extends MasterToSlaveFileCallable { private final URL archive; + Unpack(URL archive) { this.archive = archive; } + @Override public Void invoke(File dir, VirtualChannel channel) throws IOException, InterruptedException { try (InputStream in = archive.openStream()) { CountingInputStream cis = new CountingInputStream(in); @@ -1077,7 +1120,7 @@ public void copyFrom(InputStream in) throws IOException, InterruptedException { /** * Convenience method to call {@link FilePath#copyTo(FilePath)}. - * + * * @since 1.311 */ public void copyFrom(FilePath src) throws IOException, InterruptedException { @@ -1088,9 +1131,9 @@ public void copyFrom(FilePath src) throws IOException, InterruptedException { * Place the data from {@link FileItem} into the file location specified by this {@link FilePath} object. */ public void copyFrom(FileItem file) throws IOException, InterruptedException { - if(channel==null) { + if (channel == null) { try { - file.write(writing(new File(remote))); + file.write(new File(remote)); } catch (IOException e) { throw e; } catch (Exception e) { @@ -1099,7 +1142,7 @@ public void copyFrom(FileItem file) throws IOException, InterruptedException { } else { try (InputStream i = file.getInputStream(); OutputStream o = write()) { - org.apache.commons.io.IOUtils.copy(i,o); + org.apache.commons.io.IOUtils.copy(i, o); } } } @@ -1131,34 +1174,25 @@ public interface FileCallable extends Serializable, RoleSensitive { T invoke(File f, VirtualChannel channel) throws IOException, InterruptedException; } - /** - * {@link FileCallable}s that can be executed anywhere, including the master. - * - * The code is the same as {@link SlaveToMasterFileCallable}, but used as a marker to - * designate those impls that use {@link FilePathFilter}. - */ - /*package*/ abstract static class SecureFileCallable extends SlaveToMasterFileCallable { - } - /** * Executes some program on the machine that this {@link FilePath} exists, * so that one can perform local file operations. */ public T act(final FileCallable callable) throws IOException, InterruptedException { - return act(callable,callable.getClass().getClassLoader()); + return act(callable, callable.getClass().getClassLoader()); } private T act(final FileCallable callable, ClassLoader cl) throws IOException, InterruptedException { - if(channel!=null) { + if (channel != null) { // run this on a remote system try { - DelegatingCallable wrapper = new FileCallableWrapper<>(callable, cl); + DelegatingCallable wrapper = new FileCallableWrapper<>(callable, cl, this); for (FileCallableWrapperFactory factory : ExtensionList.lookup(FileCallableWrapperFactory.class)) { wrapper = factory.wrap(wrapper); } return channel.call(wrapper); } catch (TunneledInterruptedException e) { - throw (InterruptedException)new InterruptedException(e.getMessage()).initCause(e); + throw (InterruptedException) new InterruptedException(e.getMessage()).initCause(e); } } else { // the file is on the local machine. @@ -1169,7 +1203,7 @@ private T act(final FileCallable callable, ClassLoader cl) throws IOExcep /** * This extension point allows to contribute a wrapper around a fileCallable so that a plugin can "intercept" a * call. - *

The {@link #wrap(hudson.remoting.DelegatingCallable)} method itself will be executed on master + *

The {@link #wrap(hudson.remoting.DelegatingCallable)} method itself will be executed on the controller * (and may collect contextual data if needed) and the returned wrapper will be executed on remote. * * @since 1.482 @@ -1177,7 +1211,7 @@ private T act(final FileCallable callable, ClassLoader cl) throws IOExcep */ public abstract static class FileCallableWrapperFactory implements ExtensionPoint { - public abstract DelegatingCallable wrap(DelegatingCallable callable); + public abstract DelegatingCallable wrap(DelegatingCallable callable); } @@ -1191,7 +1225,7 @@ public abstract static class AbstractInterceptorCallableWrapper implements De private final DelegatingCallable callable; - public AbstractInterceptorCallableWrapper(DelegatingCallable callable) { + protected AbstractInterceptorCallableWrapper(DelegatingCallable callable) { this.callable = callable; } @@ -1200,6 +1234,7 @@ public final ClassLoader getClassLoader() { return callable.getClassLoader(); } + @Override public final T call() throws IOException { before(); try { @@ -1227,15 +1262,15 @@ protected void after() {} */ public Future actAsync(final FileCallable callable) throws IOException, InterruptedException { try { - DelegatingCallable wrapper = new FileCallableWrapper<>(callable); + DelegatingCallable wrapper = new FileCallableWrapper<>(callable, this); for (FileCallableWrapperFactory factory : ExtensionList.lookup(FileCallableWrapperFactory.class)) { wrapper = factory.wrap(wrapper); } - return (channel!=null ? channel : localChannel) + return (channel != null ? channel : localChannel) .callAsync(wrapper); } catch (IOException e) { // wrap it into a new IOException so that we get the caller's stack trace as well. - throw new IOException("remote file operation failed",e); + throw new IOException("remote file operation failed", e); } } @@ -1243,8 +1278,8 @@ public Future actAsync(final FileCallable callable) throws IOException * Executes some program on the machine that this {@link FilePath} exists, * so that one can perform local file operations. */ - public V act(Callable callable) throws IOException, InterruptedException, E { - if(channel!=null) { + public V act(Callable callable) throws IOException, InterruptedException, E { + if (channel != null) { // run this on a remote system return channel.call(callable); } else { @@ -1260,20 +1295,23 @@ public V act(Callable callable) throws IOException, * * @since 1.522 */ - public Callable asCallableWith(final FileCallable task) { + public Callable asCallableWith(final FileCallable task) { return new CallableWith<>(task); } + private class CallableWith implements Callable { private final FileCallable task; + CallableWith(FileCallable task) { this.task = task; } + @Override public V call() throws IOException { try { return act(task); } catch (InterruptedException e) { - throw (IOException)new InterruptedIOException().initCause(e); + throw (IOException) new InterruptedIOException().initCause(e); } } @@ -1292,8 +1330,10 @@ public void checkRoles(RoleChecker checker) throws SecurityException { public URI toURI() throws IOException, InterruptedException { return act(new ToURI()); } - private static class ToURI extends SecureFileCallable { + + private static class ToURI extends MasterToSlaveFileCallable { private static final long serialVersionUID = 1L; + @Override public URI invoke(File f, VirtualChannel channel) { return f.toURI(); @@ -1318,7 +1358,7 @@ public VirtualFile toVirtualFile() { Jenkins j = Jenkins.getInstanceOrNull(); if (j != null) { for (Computer c : j.getComputers()) { - if (getChannel()==c.getChannel()) { + if (getChannel() == c.getChannel()) { return c; } } @@ -1334,11 +1374,13 @@ public void mkdirs() throws IOException, InterruptedException { throw new IOException("Failed to mkdirs: " + remote); } } - private class Mkdirs extends SecureFileCallable { + + private static class Mkdirs extends MasterToSlaveFileCallable { private static final long serialVersionUID = 1L; + @Override public Boolean invoke(File f, VirtualChannel channel) throws IOException, InterruptedException { - if(mkdirs(f) || f.exists()) + if (mkdirs(f) || f.exists()) return true; // OK // following Ant task to avoid possible race condition. @@ -1347,7 +1389,7 @@ public Boolean invoke(File f, VirtualChannel channel) throws IOException, Interr return mkdirs(f) || f.exists(); } } - + /** * Deletes all suffixes recursively. * @throws IOException if it exists but could not be successfully deleted @@ -1360,17 +1402,17 @@ public void deleteSuffixesRecursive() throws IOException, InterruptedException { /** * Deletes all suffixed directories that are separated by {@link WorkspaceList#COMBINATOR}, including all its contents recursively. */ - private class DeleteSuffixesRecursive extends SecureFileCallable { + private static class DeleteSuffixesRecursive extends MasterToSlaveFileCallable { private static final long serialVersionUID = 1L; @Override public Void invoke(File f, VirtualChannel channel) throws IOException { for (File file : listParentFiles(f)) { if (file.getName().startsWith(f.getName() + WorkspaceList.COMBINATOR)) { - Util.deleteRecursive(file.toPath(), path -> deleting(path.toFile())); + Util.deleteRecursive(file.toPath(), path -> path.toFile()); } } - + return null; } } @@ -1392,11 +1434,13 @@ private static File[] listParentFiles(File f) { public void deleteRecursive() throws IOException, InterruptedException { act(new DeleteRecursive()); } - private class DeleteRecursive extends SecureFileCallable { + + private static class DeleteRecursive extends MasterToSlaveFileCallable { private static final long serialVersionUID = 1L; + @Override public Void invoke(File f, VirtualChannel channel) throws IOException { - Util.deleteRecursive(fileToPath(f), path -> deleting(path.toFile())); + Util.deleteRecursive(fileToPath(f), path -> path.toFile()); return null; } } @@ -1407,11 +1451,13 @@ public Void invoke(File f, VirtualChannel channel) throws IOException { public void deleteContents() throws IOException, InterruptedException { act(new DeleteContents()); } - private class DeleteContents extends SecureFileCallable { + + private static class DeleteContents extends MasterToSlaveFileCallable { private static final long serialVersionUID = 1L; + @Override public Void invoke(File f, VirtualChannel channel) throws IOException { - Util.deleteContentsRecursive(fileToPath(f), path -> deleting(path.toFile())); + Util.deleteContentsRecursive(fileToPath(f), path -> path.toFile()); return null; } } @@ -1424,28 +1470,29 @@ public Void invoke(File f, VirtualChannel channel) throws IOException { public String getBaseName() { String n = getName(); int idx = n.lastIndexOf('.'); - if (idx<0) return n; - return n.substring(0,idx); + if (idx < 0) return n; + return n.substring(0, idx); } /** * Gets just the file name portion without directories. * * For example, "foo.txt" for "../abc/foo.txt" */ + public String getName() { String r = remote; - if(r.endsWith("\\") || r.endsWith("/")) - r = r.substring(0,r.length()-1); + if (r.endsWith("\\") || r.endsWith("/")) + r = r.substring(0, r.length() - 1); - int len = r.length()-1; - while(len>=0) { + int len = r.length() - 1; + while (len >= 0) { char ch = r.charAt(len); - if(ch=='\\' || ch=='/') + if (ch == '\\' || ch == '/') break; len--; } - return r.substring(len+1); + return r.substring(len + 1); } /** @@ -1462,7 +1509,7 @@ public FilePath sibling(String rel) { * Returns a {@link FilePath} by adding the given suffix to this path name. */ public FilePath withSuffix(String suffix) { - return new FilePath(channel,remote+suffix); + return new FilePath(channel, remote + suffix); } /** @@ -1471,7 +1518,7 @@ public FilePath withSuffix(String suffix) { * @return a file on the same channel */ public @NonNull FilePath child(String relOrAbsolute) { - return new FilePath(this,relOrAbsolute); + return new FilePath(this, relOrAbsolute); } /** @@ -1483,11 +1530,11 @@ public FilePath getParent() { int i = remote.length() - 2; for (; i >= 0; i--) { char ch = remote.charAt(i); - if(ch=='\\' || ch=='/') + if (ch == '\\' || ch == '/') break; } - return i >= 0 ? new FilePath( channel, remote.substring(0,i+1) ) : null; + return i >= 0 ? new FilePath(channel, remote.substring(0, i + 1)) : null; } /** @@ -1507,20 +1554,24 @@ public FilePath createTempFile(final String prefix, final String suffix) throws try { return new FilePath(this, act(new CreateTempFile(prefix, suffix))); } catch (IOException e) { - throw new IOException("Failed to create a temp file on "+remote,e); + throw new IOException("Failed to create a temp file on " + remote, e); } } - private class CreateTempFile extends SecureFileCallable { + + private static class CreateTempFile extends MasterToSlaveFileCallable { private final String prefix; private final String suffix; + CreateTempFile(String prefix, String suffix) { this.prefix = prefix; this.suffix = suffix; } + private static final long serialVersionUID = 1L; + @Override public String invoke(File dir, VirtualChannel channel) throws IOException { - File f = writing(File.createTempFile(prefix, suffix, dir)); + File f = File.createTempFile(prefix, suffix, dir); return f.getName(); } } @@ -1542,7 +1593,7 @@ public String invoke(File dir, VirtualChannel channel) throws IOException { * @see File#createTempFile(String, String) */ public FilePath createTextTempFile(final String prefix, final String suffix, final String contents) throws IOException, InterruptedException { - return createTextTempFile(prefix,suffix,contents,true); + return createTextTempFile(prefix, suffix, contents, true); } /** @@ -1571,36 +1622,39 @@ public FilePath createTextTempFile(final String prefix, final String suffix, fin try { return new FilePath(channel, act(new CreateTextTempFile(inThisDirectory, prefix, suffix, contents))); } catch (IOException e) { - throw new IOException("Failed to create a temp file on "+remote,e); + throw new IOException("Failed to create a temp file on " + remote, e); } } - private final class CreateTextTempFile extends SecureFileCallable { + + private static class CreateTextTempFile extends MasterToSlaveFileCallable { private static final long serialVersionUID = 1L; private final boolean inThisDirectory; private final String prefix; private final String suffix; private final String contents; + CreateTextTempFile(boolean inThisDirectory, String prefix, String suffix, String contents) { this.inThisDirectory = inThisDirectory; this.prefix = prefix; this.suffix = suffix; this.contents = contents; } + @Override public String invoke(File dir, VirtualChannel channel) throws IOException { - if(!inThisDirectory) + if (!inThisDirectory) dir = new File(System.getProperty("java.io.tmpdir")); else mkdirs(dir); File f; try { - f = creating(File.createTempFile(prefix, suffix, dir)); + f = File.createTempFile(prefix, suffix, dir); } catch (IOException e) { - throw new IOException("Failed to create a temporary directory in "+dir,e); + throw new IOException("Failed to create a temporary directory in " + dir, e); } - try (Writer w = new FileWriter(writing(f))) { + try (Writer w = Files.newBufferedWriter(Util.fileToPath(f), Charset.defaultCharset())) { w.write(contents); } @@ -1630,18 +1684,22 @@ public FilePath createTempDir(final String prefix, final String suffix) throws I } else { s = new String[]{prefix, suffix}; } - String name = StringUtils.join(s, "."); + String name = String.join(".", s); return new FilePath(this, act(new CreateTempDir(name))); } catch (IOException e) { - throw new IOException("Failed to create a temp directory on "+remote,e); + throw new IOException("Failed to create a temp directory on " + remote, e); } } - private class CreateTempDir extends SecureFileCallable { + + private static class CreateTempDir extends MasterToSlaveFileCallable { private final String name; + CreateTempDir(String name) { this.name = name; } + private static final long serialVersionUID = 1L; + @Override public String invoke(File dir, VirtualChannel channel) throws IOException { @@ -1656,7 +1714,7 @@ public String invoke(File dir, VirtualChannel channel) throws IOException { } if (tempPath.toFile() == null) { - throw new IOException("Failed to obtain file from path " + dir + " on " + remote); + throw new IOException("Failed to obtain file from path " + dir); } return tempPath.toFile().getName(); } @@ -1664,18 +1722,20 @@ public String invoke(File dir, VirtualChannel channel) throws IOException { /** * Deletes this file. - * @throws IOException if it exists but could not be successfully deleted * @return true, for a modicum of compatibility + * @throws IOException if it exists but could not be successfully deleted */ public boolean delete() throws IOException, InterruptedException { act(new Delete()); return true; } - private class Delete extends SecureFileCallable { + + private static class Delete extends MasterToSlaveFileCallable { private static final long serialVersionUID = 1L; + @Override public Void invoke(File f, VirtualChannel channel) throws IOException { - Util.deleteFile(deleting(f)); + Util.deleteFile(f); return null; } } @@ -1686,11 +1746,13 @@ public Void invoke(File f, VirtualChannel channel) throws IOException { public boolean exists() throws IOException, InterruptedException { return act(new Exists()); } - private class Exists extends SecureFileCallable { + + private static class Exists extends MasterToSlaveFileCallable { private static final long serialVersionUID = 1L; + @Override public Boolean invoke(File f, VirtualChannel channel) throws IOException { - return stating(f).exists(); + return f.exists(); } } @@ -1704,11 +1766,13 @@ public Boolean invoke(File f, VirtualChannel channel) throws IOException { public long lastModified() throws IOException, InterruptedException { return act(new LastModified()); } - private class LastModified extends SecureFileCallable { + + private static class LastModified extends MasterToSlaveFileCallable { private static final long serialVersionUID = 1L; + @Override public Long invoke(File f, VirtualChannel channel) throws IOException { - return stating(f).lastModified(); + return f.lastModified(); } } @@ -1720,45 +1784,53 @@ public Long invoke(File f, VirtualChannel channel) throws IOException { public void touch(final long timestamp) throws IOException, InterruptedException { act(new Touch(timestamp)); } - private class Touch extends SecureFileCallable { + + private static class Touch extends MasterToSlaveFileCallable { private final long timestamp; + Touch(long timestamp) { this.timestamp = timestamp; } + private static final long serialVersionUID = -5094638816500738429L; + @Override public Void invoke(File f, VirtualChannel channel) throws IOException { - if(!f.exists()) { - Files.newOutputStream(fileToPath(creating(f))).close(); + if (!f.exists()) { + Files.newOutputStream(fileToPath(f)).close(); } - if(!stating(f).setLastModified(timestamp)) - throw new IOException("Failed to set the timestamp of "+f+" to "+timestamp); + if (!f.setLastModified(timestamp)) + throw new IOException("Failed to set the timestamp of " + f + " to " + timestamp); return null; } } - + private void setLastModifiedIfPossible(final long timestamp) throws IOException, InterruptedException { String message = act(new SetLastModified(timestamp)); - if (message!=null) { + if (message != null) { LOGGER.warning(message); } } - private class SetLastModified extends SecureFileCallable { + + private static class SetLastModified extends MasterToSlaveFileCallable { private final long timestamp; + SetLastModified(long timestamp) { this.timestamp = timestamp; } + private static final long serialVersionUID = -828220335793641630L; + @Override public String invoke(File f, VirtualChannel channel) throws IOException { - if(!writing(f).setLastModified(timestamp)) { + if (!f.setLastModified(timestamp)) { if (Functions.isWindows()) { // On Windows this seems to fail often. See JENKINS-11073 // Therefore don't fail, but just log a warning - return "Failed to set the timestamp of "+f+" to "+timestamp; + return "Failed to set the timestamp of " + f + " to " + timestamp; } else { - throw new IOException("Failed to set the timestamp of "+f+" to "+timestamp); + throw new IOException("Failed to set the timestamp of " + f + " to " + timestamp); } } return null; @@ -1771,14 +1843,16 @@ public String invoke(File f, VirtualChannel channel) throws IOException { public boolean isDirectory() throws IOException, InterruptedException { return act(new IsDirectory()); } - private final class IsDirectory extends SecureFileCallable { + + private static class IsDirectory extends MasterToSlaveFileCallable { private static final long serialVersionUID = 1L; + @Override public Boolean invoke(File f, VirtualChannel channel) throws IOException { - return stating(f).isDirectory(); + return f.isDirectory(); } } - + /** * Returns the file size in bytes. * @@ -1787,11 +1861,13 @@ public Boolean invoke(File f, VirtualChannel channel) throws IOException { public long length() throws IOException, InterruptedException { return act(new Length()); } - private class Length extends SecureFileCallable { + + private static class Length extends MasterToSlaveFileCallable { private static final long serialVersionUID = 1L; + @Override public Long invoke(File f, VirtualChannel channel) throws IOException { - return stating(f).length(); + return f.length(); } } @@ -1802,8 +1878,10 @@ public Long invoke(File f, VirtualChannel channel) throws IOException { public long getFreeDiskSpace() throws IOException, InterruptedException { return act(new GetFreeDiskSpace()); } - private static class GetFreeDiskSpace extends SecureFileCallable { + + private static class GetFreeDiskSpace extends MasterToSlaveFileCallable { private static final long serialVersionUID = 1L; + @Override public Long invoke(File f, VirtualChannel channel) throws IOException { return f.getFreeSpace(); @@ -1817,8 +1895,10 @@ public Long invoke(File f, VirtualChannel channel) throws IOException { public long getTotalDiskSpace() throws IOException, InterruptedException { return act(new GetTotalDiskSpace()); } - private static class GetTotalDiskSpace extends SecureFileCallable { + + private static class GetTotalDiskSpace extends MasterToSlaveFileCallable { private static final long serialVersionUID = 1L; + @Override public Long invoke(File f, VirtualChannel channel) throws IOException { return f.getTotalSpace(); @@ -1832,8 +1912,10 @@ public Long invoke(File f, VirtualChannel channel) throws IOException { public long getUsableDiskSpace() throws IOException, InterruptedException { return act(new GetUsableDiskSpace()); } - private static class GetUsableDiskSpace extends SecureFileCallable { + + private static class GetUsableDiskSpace extends MasterToSlaveFileCallable { private static final long serialVersionUID = 1L; + @Override public Long invoke(File f, VirtualChannel channel) throws IOException { return f.getUsableSpace(); @@ -1861,18 +1943,21 @@ public Long invoke(File f, VirtualChannel channel) throws IOException { * @see #mode() */ public void chmod(final int mask) throws IOException, InterruptedException { - if(!isUnix() || mask==-1) return; + if (!isUnix() || mask == -1) return; act(new Chmod(mask)); } - private class Chmod extends SecureFileCallable { + + private static class Chmod extends MasterToSlaveFileCallable { private static final long serialVersionUID = 1L; private final int mask; + Chmod(int mask) { this.mask = mask; } + @Override public Void invoke(File f, VirtualChannel channel) throws IOException { - _chmod(writing(f), mask); + _chmod(f, mask); return null; } @@ -1884,13 +1969,9 @@ public Void invoke(File f, VirtualChannel channel) throws IOException { private static void _chmod(File f, int mask) throws IOException { // TODO WindowsPosix actually does something here (WindowsLibC._wchmod); should we let it? // Anyway the existing calls already skip this method if on Windows. - if (File.pathSeparatorChar==';') return; // noop + if (File.pathSeparatorChar == ';') return; // noop - if (Util.NATIVE_CHMOD_MODE) { - PosixAPI.jnr().chmod(f.getAbsolutePath(), mask); - } else { - Files.setPosixFilePermissions(fileToPath(f), Util.modeToPermissions(mask)); - } + Files.setPosixFilePermissions(fileToPath(f), Util.modeToPermissions(mask)); } private static boolean CHMOD_WARNED = false; @@ -1903,15 +1984,17 @@ private static void _chmod(File f, int mask) throws IOException { * @since 1.311 * @see #chmod(int) */ - public int mode() throws IOException, InterruptedException, PosixException { - if(!isUnix()) return -1; + public int mode() throws IOException, InterruptedException { + if (!isUnix()) return -1; return act(new Mode()); } - private class Mode extends SecureFileCallable { + + private static class Mode extends MasterToSlaveFileCallable { private static final long serialVersionUID = 1L; + @Override public Integer invoke(File f, VirtualChannel channel) throws IOException { - return IOUtils.mode(stating(f)); + return IOUtils.mode(f); } } @@ -1923,7 +2006,7 @@ public Integer invoke(File f, VirtualChannel channel) throws IOException { */ @NonNull public List list() throws IOException, InterruptedException { - return list((FileFilter)null); + return list((FileFilter) null); } /** @@ -1954,9 +2037,11 @@ public List listDirectories() throws IOException, InterruptedException } private static final class DirectoryFilter implements FileFilter, Serializable { + @Override public boolean accept(File f) { return f.isDirectory(); } + private static final long serialVersionUID = 1L; } @@ -1976,15 +2061,19 @@ public List list(final FileFilter filter) throws IOException, Interrup } return act(new ListFilter(filter), (filter != null ? filter : this).getClass().getClassLoader()); } - private class ListFilter extends SecureFileCallable> { + + private static class ListFilter extends MasterToSlaveFileCallable> { private final FileFilter filter; + ListFilter(FileFilter filter) { this.filter = filter; } + private static final long serialVersionUID = 1L; + @Override public List invoke(File f, VirtualChannel channel) throws IOException { - File[] children = reading(f).listFiles(filter); + File[] children = f.listFiles(filter); if (children == null) { return Collections.emptyList(); } @@ -2014,6 +2103,7 @@ public FilePath[] list(final String includes) throws IOException, InterruptedExc * List up files in this directory that matches the given Ant-style filter. * * @param includes + * See {@link FileSet} for the syntax. String like "foo/*.zip" or "foo/**/*.xml" * @param excludes * See {@link FileSet} for the syntax. String like "foo/*.zip" or "foo/**/*.xml" * @return @@ -2029,6 +2119,7 @@ public FilePath[] list(final String includes, final String excludes) throws IOEx * List up files in this directory that matches the given Ant-style filter. * * @param includes + * See {@link FileSet} for the syntax. String like "foo/*.zip" or "foo/**/*.xml" * @param excludes * See {@link FileSet} for the syntax. String like "foo/*.zip" or "foo/**/*.xml" * @param defaultExcludes whether to use the ant default excludes @@ -2040,23 +2131,27 @@ public FilePath[] list(final String includes, final String excludes) throws IOEx public FilePath[] list(final String includes, final String excludes, final boolean defaultExcludes) throws IOException, InterruptedException { return act(new ListGlob(includes, excludes, defaultExcludes)); } - private class ListGlob extends SecureFileCallable { + + private static class ListGlob extends MasterToSlaveFileCallable { private final String includes; private final String excludes; private final boolean defaultExcludes; + ListGlob(String includes, String excludes, boolean defaultExcludes) { this.includes = includes; this.excludes = excludes; this.defaultExcludes = defaultExcludes; } + private static final long serialVersionUID = 1L; + @Override public FilePath[] invoke(File f, VirtualChannel channel) throws IOException { - String[] files = glob(reading(f), includes, excludes, defaultExcludes); + String[] files = glob(f, includes, excludes, defaultExcludes); FilePath[] r = new FilePath[files.length]; - for( int i=0; i { + private static class Read extends MasterToSlaveFileCallable { private static final long serialVersionUID = 1L; private final Pipe p; private String verificationRoot; @@ -2190,9 +2285,10 @@ private class Read extends SecureFileCallable { this.verificationRoot = verificationRoot; this.noFollowLinks = noFollowLinks; } + @Override public Void invoke(File f, VirtualChannel channel) throws IOException, InterruptedException { - try (InputStream fis = newInputStreamDenyingSymlinkAsNeeded(reading(f), verificationRoot, noFollowLinks); OutputStream out = p.getOut()) { + try (InputStream fis = newInputStreamDenyingSymlinkAsNeeded(f, verificationRoot, noFollowLinks); OutputStream out = p.getOut()) { org.apache.commons.io.IOUtils.copy(fis, out); } catch (Exception x) { p.error(x); @@ -2206,7 +2302,7 @@ public Void invoke(File f, VirtualChannel channel) throws IOException, Interrupt * @since 1.586 */ public InputStream readFromOffset(final long offset) throws IOException, InterruptedException { - if(channel ==null) { + if (channel == null) { final RandomAccessFile raf = new RandomAccessFile(new File(remote), "r"); try { raf.seek(offset); @@ -2245,23 +2341,23 @@ public int read(byte[] b) throws IOException { actAsync(new OffsetPipeSecureFileCallable(p, offset)); return new java.util.zip.GZIPInputStream(p.getIn()); } - - private class OffsetPipeSecureFileCallable extends SecureFileCallable { + + private static class OffsetPipeSecureFileCallable extends MasterToSlaveFileCallable { private static final long serialVersionUID = 1L; - + private Pipe p; private long offset; - + private OffsetPipeSecureFileCallable(Pipe p, long offset) { this.p = p; this.offset = offset; } - + @Override public Void invoke(File f, VirtualChannel channel) throws IOException { try (OutputStream os = p.getOut(); OutputStream out = new java.util.zip.GZIPOutputStream(os, 8192); - RandomAccessFile raf = new RandomAccessFile(reading(f), "r")) { + RandomAccessFile raf = new RandomAccessFile(f, "r")) { raf.seek(offset); byte[] buf = new byte[8192]; int len; @@ -2278,12 +2374,14 @@ public Void invoke(File f, VirtualChannel channel) throws IOException { */ public String readToString() throws IOException, InterruptedException { return act(new ReadToString()); - } - private final class ReadToString extends SecureFileCallable { - private static final long serialVersionUID = 1L; + } + + private static class ReadToString extends MasterToSlaveFileCallable { + private static final long serialVersionUID = 1L; + @Override public String invoke(File f, VirtualChannel channel) throws IOException, InterruptedException { - return new String(Files.readAllBytes(fileToPath(reading(f)))); + return new String(Files.readAllBytes(fileToPath(f)), Charset.defaultCharset()); } } @@ -2298,26 +2396,25 @@ public String invoke(File f, VirtualChannel channel) throws IOException, Interru * I/O operations also happens asynchronously from the {@link Channel#call(Callable)} operations, so if * you write to a remote file and then execute {@link Channel#call(Callable)} and try to access the newly copied * file, it might not be fully written yet. - * - *

- * */ public OutputStream write() throws IOException, InterruptedException { - if(channel==null) { + if (channel == null) { File f = new File(remote).getAbsoluteFile(); mkdirs(f.getParentFile()); - return Files.newOutputStream(fileToPath(writing(f))); + return Files.newOutputStream(fileToPath(f)); } return act(new WritePipe()); } - private class WritePipe extends SecureFileCallable { + + private static class WritePipe extends MasterToSlaveFileCallable { private static final long serialVersionUID = 1L; + @Override public OutputStream invoke(File f, VirtualChannel channel) throws IOException, InterruptedException { f = f.getAbsoluteFile(); mkdirs(f.getParentFile()); - return new RemoteOutputStream(Files.newOutputStream(fileToPath(writing(f)))); + return new RemoteOutputStream(Files.newOutputStream(fileToPath(f))); } } @@ -2331,19 +2428,22 @@ public OutputStream invoke(File f, VirtualChannel channel) throws IOException, I public void write(final String content, final String encoding) throws IOException, InterruptedException { act(new Write(encoding, content)); } - private class Write extends SecureFileCallable { + + private static class Write extends MasterToSlaveFileCallable { private static final long serialVersionUID = 1L; private final String encoding; private final String content; + Write(String encoding, String content) { this.encoding = encoding; this.content = content; } + @Override public Void invoke(File f, VirtualChannel channel) throws IOException { mkdirs(f.getParentFile()); - try (OutputStream fos = Files.newOutputStream(fileToPath(writing(f))); - Writer w = encoding != null ? new OutputStreamWriter(fos, encoding) : new OutputStreamWriter(fos)) { + try (OutputStream fos = Files.newOutputStream(fileToPath(f)); + Writer w = encoding != null ? new OutputStreamWriter(fos, encoding) : new OutputStreamWriter(fos, Charset.defaultCharset())) { w.write(content); } return null; @@ -2357,11 +2457,13 @@ public Void invoke(File f, VirtualChannel channel) throws IOException { public String digest() throws IOException, InterruptedException { return act(new Digest()); } - private class Digest extends SecureFileCallable { + + private static class Digest extends MasterToSlaveFileCallable { private static final long serialVersionUID = 1L; + @Override public String invoke(File f, VirtualChannel channel) throws IOException { - return Util.getDigestOf(reading(f)); + return Util.getDigestOf(f); } } @@ -2370,20 +2472,24 @@ public String invoke(File f, VirtualChannel channel) throws IOException { * be on the some host */ public void renameTo(final FilePath target) throws IOException, InterruptedException { - if(this.channel != target.channel) { - throw new IOException("renameTo target must be on the same host"); - } + if (this.channel != target.channel) { + throw new IOException("renameTo target must be on the same host"); + } act(new RenameTo(target)); } - private class RenameTo extends SecureFileCallable { + + private static class RenameTo extends MasterToSlaveFileCallable { private final FilePath target; + RenameTo(FilePath target) { this.target = target; } + private static final long serialVersionUID = 1L; + @Override public Void invoke(File f, VirtualChannel channel) throws IOException { - Files.move(fileToPath(reading(f)), fileToPath(creating(new File(target.remote))), LinkOption.NOFOLLOW_LINKS); + Files.move(fileToPath(f), fileToPath(new File(target.remote)), LinkOption.NOFOLLOW_LINKS); return null; } } @@ -2394,33 +2500,37 @@ public Void invoke(File f, VirtualChannel channel) throws IOException { * @since 1.308. */ public void moveAllChildrenTo(final FilePath target) throws IOException, InterruptedException { - if(this.channel != target.channel) { + if (this.channel != target.channel) { throw new IOException("pullUpTo target must be on the same host"); } act(new MoveAllChildrenTo(target)); } - private class MoveAllChildrenTo extends SecureFileCallable { + + private static class MoveAllChildrenTo extends MasterToSlaveFileCallable { private final FilePath target; + MoveAllChildrenTo(FilePath target) { this.target = target; } + private static final long serialVersionUID = 1L; + @Override public Void invoke(File f, VirtualChannel channel) throws IOException { // JENKINS-16846: if f.getName() is the same as one of the files/directories in f, // then the rename op will fail - File tmp = new File(f.getAbsolutePath()+".__rename"); + File tmp = new File(f.getAbsolutePath() + ".__rename"); if (!f.renameTo(tmp)) - throw new IOException("Failed to rename "+f+" to "+tmp); + throw new IOException("Failed to rename " + f + " to " + tmp); File t = new File(target.getRemote()); - for(File child : reading(tmp).listFiles()) { + for (File child : tmp.listFiles()) { File target = new File(t, child.getName()); - if(!stating(child).renameTo(creating(target))) - throw new IOException("Failed to rename "+child+" to "+target); + if (!child.renameTo(target)) + throw new IOException("Failed to rename " + child + " to " + target); } - deleting(tmp).delete(); + Files.deleteIfExists(Util.fileToPath(tmp)); return null; } } @@ -2434,7 +2544,7 @@ public void copyTo(FilePath target) throws IOException, InterruptedException { copyTo(out); } } catch (IOException e) { - throw new IOException("Failed to copy "+this+" to "+target,e); + throw new IOException("Failed to copy " + this + " to " + target, e); } } @@ -2454,18 +2564,20 @@ public void copyToWithPermission(FilePath target) throws IOException, Interrupte target.chmod(mode()); target.setLastModifiedIfPossible(lastModified()); } - private class CopyToWithPermission extends SecureFileCallable { + + private static class CopyToWithPermission extends MasterToSlaveFileCallable { private final FilePath target; + CopyToWithPermission(FilePath target) { this.target = target; } + @Override public Void invoke(File f, VirtualChannel channel) throws IOException { File targetFile = new File(target.remote); File targetDir = targetFile.getParentFile(); - filterNonNull().mkdirs(targetDir); Files.createDirectories(fileToPath(targetDir)); - Files.copy(fileToPath(reading(f)), fileToPath(writing(targetFile)), StandardCopyOption.COPY_ATTRIBUTES, StandardCopyOption.REPLACE_EXISTING); + Files.copy(fileToPath(f), fileToPath(targetFile), StandardCopyOption.COPY_ATTRIBUTES, StandardCopyOption.REPLACE_EXISTING); return null; } } @@ -2482,15 +2594,18 @@ public void copyTo(OutputStream os) throws IOException, InterruptedException { // this is needed because I/O operation is asynchronous syncIO(); } - private class CopyTo extends SecureFileCallable { + + private static class CopyTo extends MasterToSlaveFileCallable { private static final long serialVersionUID = 4088559042349254141L; private final OutputStream out; + CopyTo(OutputStream out) { this.out = out; } + @Override public Void invoke(File f, VirtualChannel channel) throws IOException { - try (InputStream fis = Files.newInputStream(fileToPath(reading(f)))) { + try (InputStream fis = Files.newInputStream(fileToPath(f))) { org.apache.commons.io.IOUtils.copy(fis, out); return null; } finally { @@ -2506,12 +2621,12 @@ public Void invoke(File f, VirtualChannel channel) throws IOException { */ private void syncIO() throws InterruptedException { try { - if (channel!=null) + if (channel != null) channel.syncLocalIO(); } catch (AbstractMethodError e) { // legacy agent.jar. Handle this gracefully try { - LOGGER.log(Level.WARNING,"Looks like an old agent.jar. Please update "+ Which.jarFile(Channel.class)+" to the new version",e); + LOGGER.log(Level.WARNING, "Looks like an old agent.jar. Please update " + Which.jarFile(Channel.class) + " to the new version", e); } catch (IOException ignored) { // really ignore this time } @@ -2537,19 +2652,21 @@ interface RemoteCopier { * relative path name to the output file. Path separator must be '/'. */ void open(String fileName) throws IOException; + void write(byte[] buf, int len) throws IOException; + void close() throws IOException; } /** * Copies the contents of this directory recursively into the specified target directory. - * + * * @return * the number of files copied. - * @since 1.312 + * @since 1.312 */ public int copyRecursiveTo(FilePath target) throws IOException, InterruptedException { - return copyRecursiveTo("**/*",target); + return copyRecursiveTo("**/*", target); } /** @@ -2564,7 +2681,7 @@ public int copyRecursiveTo(FilePath target) throws IOException, InterruptedExcep * the number of files copied. */ public int copyRecursiveTo(String fileMask, FilePath target) throws IOException, InterruptedException { - return copyRecursiveTo(fileMask,null,target); + return copyRecursiveTo(fileMask, null, target); } /** @@ -2606,15 +2723,15 @@ public int copyRecursiveTo(final DirScanner scanner, final FilePath target, fina * @since 2.196 */ public int copyRecursiveTo(final DirScanner scanner, final FilePath target, final String description, @NonNull TarCompression compression) throws IOException, InterruptedException { - if(this.channel==target.channel) { + if (this.channel == target.channel) { // local to local copy. return act(new CopyRecursiveLocal(target, scanner)); } else - if(this.channel==null) { + if (this.channel == null) { // local -> remote copy final Pipe pipe = Pipe.createLocalToRemote(); - Future future = target.actAsync(new ReadToTar(pipe, description, compression)); + Future future = target.actAsync(new ReadFromTar(target, pipe, description, compression)); Future future2 = actAsync(new WriteToTar(scanner, pipe, compression)); try { // JENKINS-9540 in case the reading side failed, report that error first @@ -2629,10 +2746,10 @@ public int copyRecursiveTo(final DirScanner scanner, final FilePath target, fina Future future = actAsync(new CopyRecursiveRemoteToLocal(pipe, scanner, compression)); try { - readFromTar(remote + '/' + description,new File(target.remote),compression.extract(pipe.getIn())); - } catch (IOException e) {// BuildException or IOException + readFromTar(remote + '/' + description, new File(target.remote), compression.extract(pipe.getIn())); + } catch (IOException e) { // BuildException or IOException try { - future.get(3,TimeUnit.SECONDS); + future.get(3, TimeUnit.SECONDS); throw e; // the remote side completed successfully, so the error must be local } catch (ExecutionException x) { // report both errors @@ -2660,37 +2777,43 @@ private IOException ioWithCause(ExecutionException e) { ; } - private class CopyRecursiveLocal extends SecureFileCallable { + private static class CopyRecursiveLocal extends MasterToSlaveFileCallable { private final FilePath target; private final DirScanner scanner; + CopyRecursiveLocal(FilePath target, DirScanner scanner) { this.target = target; this.scanner = scanner; } + private static final long serialVersionUID = 1L; + @Override public Integer invoke(File base, VirtualChannel channel) throws IOException { if (!base.exists()) { return 0; } - assert target.channel == null; + if (target.channel != null) { + throw new IllegalStateException("Expected null channel for " + target); + } final File dest = new File(target.remote); final AtomicInteger count = new AtomicInteger(); - scanner.scan(base, reading(new FileVisitor() { + scanner.scan(base, new FileVisitor() { private boolean exceptionEncountered; private boolean logMessageShown; + @SuppressFBWarnings(value = "PATH_TRAVERSAL_IN", justification = "TODO needs triage") @Override public void visit(File f, String relativePath) throws IOException { if (f.isFile()) { File target = new File(dest, relativePath); mkdirsE(target.getParentFile()); - Path targetPath = fileToPath(writing(target)); + Path targetPath = fileToPath(target); exceptionEncountered = exceptionEncountered || !tryCopyWithAttributes(f, targetPath); if (exceptionEncountered) { Files.copy(fileToPath(f), targetPath, StandardCopyOption.REPLACE_EXISTING); if (!logMessageShown) { - LOGGER.log(Level.INFO, - "JENKINS-52325: Jenkins failed to retain attributes when copying to {0}, so proceeding without attributes.", + LOGGER.log(Level.INFO, + "JENKINS-52325: Jenkins failed to retain attributes when copying to {0}, so proceeding without attributes.", dest.getAbsolutePath()); logMessageShown = true; } @@ -2698,79 +2821,94 @@ public void visit(File f, String relativePath) throws IOException { count.incrementAndGet(); } } + private boolean tryCopyWithAttributes(File f, Path targetPath) { - try { + try { Files.copy(fileToPath(f), targetPath, StandardCopyOption.COPY_ATTRIBUTES, StandardCopyOption.REPLACE_EXISTING); } catch (IOException e) { LOGGER.log(Level.FINE, "Unable to copy: {0}", e.getMessage()); return false; } - return true; + return true; } + @Override public boolean understandsSymlink() { return true; } + + @SuppressFBWarnings(value = "PATH_TRAVERSAL_IN", justification = "TODO needs triage") @Override public void visitSymlink(File link, String target, String relativePath) throws IOException { try { mkdirsE(new File(dest, relativePath).getParentFile()); - writing(new File(dest, target)); Util.createSymlink(dest, target, relativePath, TaskListener.NULL); } catch (InterruptedException x) { throw new IOException(x); } count.incrementAndGet(); } - })); + }); return count.get(); } } - private class ReadToTar extends SecureFileCallable { + + private static class ReadFromTar extends MasterToSlaveFileCallable { private final Pipe pipe; private final String description; private final TarCompression compression; + private final FilePath target; - ReadToTar(Pipe pipe, String description, @NonNull TarCompression compression) { + ReadFromTar(FilePath target, Pipe pipe, String description, @NonNull TarCompression compression) { + this.target = target; this.pipe = pipe; this.description = description; this.compression = compression; } + private static final long serialVersionUID = 1L; + @Override public Void invoke(File f, VirtualChannel channel) throws IOException { try (InputStream in = pipe.getIn()) { - readFromTar(remote + '/' + description, f, compression.extract(in)); + readFromTar(target.remote + '/' + description, f, compression.extract(in)); return null; } } } - private class WriteToTar extends SecureFileCallable { + + private static class WriteToTar extends MasterToSlaveFileCallable { private final DirScanner scanner; private final Pipe pipe; private final TarCompression compression; + WriteToTar(DirScanner scanner, Pipe pipe, @NonNull TarCompression compression) { this.scanner = scanner; this.pipe = pipe; this.compression = compression; } + private static final long serialVersionUID = 1L; + @Override public Integer invoke(File f, VirtualChannel channel) throws IOException, InterruptedException { - return writeToTar(new File(remote), scanner, compression.compress(pipe.getOut())); + return writeToTar(f, scanner, compression.compress(pipe.getOut())); } } - private class CopyRecursiveRemoteToLocal extends SecureFileCallable { + + private static class CopyRecursiveRemoteToLocal extends MasterToSlaveFileCallable { private static final long serialVersionUID = 1L; private final Pipe pipe; private final DirScanner scanner; private final TarCompression compression; + CopyRecursiveRemoteToLocal(Pipe pipe, DirScanner scanner, @NonNull TarCompression compression) { this.pipe = pipe; this.scanner = scanner; this.compression = compression; } + @Override public Integer invoke(File f, VirtualChannel channel) throws IOException { try (OutputStream out = pipe.getOut()) { @@ -2806,10 +2944,10 @@ public int tar(OutputStream out, DirScanner scanner) throws IOException, Interru * @return * number of files/directories that are written. */ - private Integer writeToTar(File baseDir, DirScanner scanner, OutputStream out) throws IOException { + private static Integer writeToTar(File baseDir, DirScanner scanner, OutputStream out) throws IOException { Archiver tw = ArchiverFactory.TAR.create(out); try { - scanner.scan(baseDir,reading(tw)); + scanner.scan(baseDir, tw); } finally { tw.close(); } @@ -2820,7 +2958,7 @@ private Integer writeToTar(File baseDir, DirScanner scanner, OutputStream out) t * Reads from a tar stream and stores obtained files to the base dir. * Supports large files > 10 GB since 1.627 when this was migrated to use commons-compress. */ - private void readFromTar(String name, File baseDir, InputStream in) throws IOException { + private static void readFromTar(String name, File baseDir, InputStream in) throws IOException { // TarInputStream t = new TarInputStream(in); try (TarArchiveInputStream t = new TarArchiveInputStream(in)) { @@ -2836,14 +2974,13 @@ private void readFromTar(String name, File baseDir, InputStream in) throws IOExc } else { File parent = f.getParentFile(); if (parent != null) mkdirs(parent); - writing(f); if (te.isSymbolicLink()) { new FilePath(f).symlinkTo(te.getLinkName(), TaskListener.NULL); } else { IOUtils.copy(t, f); - f.setLastModified(te.getModTime().getTime()); + Files.setLastModifiedTime(Util.fileToPath(f), FileTime.from(te.getModTime().toInstant())); int mode = te.getMode() & 0777; if (mode != 0 && !Functions.isWindows()) // be defensive _chmod(f, mode); @@ -2864,26 +3001,24 @@ private void readFromTar(String name, File baseDir, InputStream in) throws IOExc * @since 1.89 */ public Launcher createLauncher(TaskListener listener) throws IOException, InterruptedException { - if(channel==null) + if (channel == null) return new LocalLauncher(listener); else - return new RemoteLauncher(listener,channel,channel.call(new IsUnix())); + return new RemoteLauncher(listener, channel, channel.call(new IsUnix())); } - private static final class IsUnix extends MasterToSlaveCallable { + private static final class IsUnix extends MasterToSlaveCallable { + @Override @NonNull public Boolean call() throws IOException { - return File.pathSeparatorChar==':'; + return File.pathSeparatorChar == ':'; } + private static final long serialVersionUID = 1L; } /** - * Validates the ant file mask (like "foo/bar/*.txt, zot/*.jar") - * against this directory, and try to point out the problem. - * - *

- * This is useful in conjunction with {@link FormValidation}. + * Same as {@link #validateAntFileMask(String, int)} with (practically) unbounded number of operations. * * @return * null if no error was found. Otherwise returns a human readable error message. @@ -2897,28 +3032,45 @@ public String validateAntFileMask(final String fileMasks) throws IOException, In } /** - * Same as {@link #validateAntFileMask(String, int, boolean)} with caseSensitive set to true + * Same as {@link #validateAntFileMask(String, int, boolean)} with caseSensitive set to true. */ public String validateAntFileMask(final String fileMasks, final int bound) throws IOException, InterruptedException { return validateAntFileMask(fileMasks, bound, true); } + /** + * Same as {@link #validateAntFileMask(String, int, boolean)} with the default number of operations. + * @see #VALIDATE_ANT_FILE_MASK_BOUND + * @since 2.325 + */ + public String validateAntFileMask(final String fileMasks, final boolean caseSensitive) throws IOException, InterruptedException { + return validateAntFileMask(fileMasks, VALIDATE_ANT_FILE_MASK_BOUND, caseSensitive); + } + /** * Default bound for {@link #validateAntFileMask(String, int, boolean)}. * @since 1.592 */ - @SuppressFBWarnings("MS_SHOULD_BE_FINAL") - public static int VALIDATE_ANT_FILE_MASK_BOUND = Integer.getInteger(FilePath.class.getName() + ".VALIDATE_ANT_FILE_MASK_BOUND", 10000); + @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "for script console") + public static int VALIDATE_ANT_FILE_MASK_BOUND = SystemProperties.getInteger(FilePath.class.getName() + ".VALIDATE_ANT_FILE_MASK_BOUND", 10000); /** - * Like {@link #validateAntFileMask(String)} but performing only a bounded number of operations. + * Validates the ant file mask (like "foo/bar/*.txt, zot/*.jar") against this directory, and try to point out the problem. + * This performs only a bounded number of operations. + * *

Whereas the unbounded overload is appropriate for calling from cancelable, long-running tasks such as build steps, * this overload should be used when an answer is needed quickly, such as for {@link #validateFileMask(String)} * or anything else returning {@link FormValidation}. + * *

If a positive match is found, {@code null} is returned immediately. * A message is returned in case the file pattern can definitely be determined to not match anything in the directory within the alloted time. * If the time runs out without finding a match but without ruling out the possibility that there might be one, {@link InterruptedException} is thrown, * in which case the calling code should give the user the benefit of the doubt and use {@link hudson.util.FormValidation.Kind#OK} (with or without a message). + * + *

While this can be used in conjunction with {@link FormValidation}, it's generally better to use {@link #validateFileMask(String)} and + * its overloads for use in {@code doCheck} form validation methods related to workspaces, as that performs an appropriate permission check. + * Callers of this method or its overloads from web methods should ensure permissions are checked before this method is invoked. + * * @param bound a maximum number of negative operations (deliberately left vague) to perform before giving up on a precise answer; try {@link #VALIDATE_ANT_FILE_MASK_BOUND} * @throws InterruptedException not only in case of a channel failure, but also if too many operations were performed without finding any matches * @since 1.484 @@ -2926,28 +3078,32 @@ public String validateAntFileMask(final String fileMasks, final int bound) throw public @CheckForNull String validateAntFileMask(final String fileMasks, final int bound, final boolean caseSensitive) throws IOException, InterruptedException { return act(new ValidateAntFileMask(fileMasks, caseSensitive, bound)); } - private class ValidateAntFileMask extends MasterToSlaveFileCallable { + + private static class ValidateAntFileMask extends MasterToSlaveFileCallable { private final String fileMasks; private final boolean caseSensitive; private final int bound; + ValidateAntFileMask(String fileMasks, boolean caseSensitive, int bound) { this.fileMasks = fileMasks; this.caseSensitive = caseSensitive; this.bound = bound; } + private static final long serialVersionUID = 1; + @Override public String invoke(File dir, VirtualChannel channel) throws IOException, InterruptedException { - if(fileMasks.startsWith("~")) + if (fileMasks.startsWith("~")) return Messages.FilePath_TildaDoesntWork(); - StringTokenizer tokens = new StringTokenizer(fileMasks,","); + StringTokenizer tokens = new StringTokenizer(fileMasks, ","); - while(tokens.hasMoreTokens()) { + while (tokens.hasMoreTokens()) { final String fileMask = tokens.nextToken().trim(); - if(hasMatch(dir,fileMask,caseSensitive)) + if (hasMatch(dir, fileMask, caseSensitive)) continue; // no error on this portion - + // JENKINS-5253 - if we can get some match in case insensitive mode // and user requested case sensitive match, notify the user if (caseSensitive && hasMatch(dir, fileMask, false)) { @@ -2956,11 +3112,11 @@ public String invoke(File dir, VirtualChannel channel) throws IOException, Inter // in 1.172 we introduced an incompatible change to stop using ' ' as the separator // so see if we can match by using ' ' as the separator - if(fileMask.contains(" ")) { + if (fileMask.contains(" ")) { boolean matched = true; for (String token : Util.tokenize(fileMask)) - matched &= hasMatch(dir,token,caseSensitive); - if(matched) + matched &= hasMatch(dir, token, caseSensitive); + if (matched) return Messages.FilePath_validateAntFileMask_whitespaceSeparator(); } @@ -2968,28 +3124,28 @@ public String invoke(File dir, VirtualChannel channel) throws IOException, Inter // to this: (1) the user gave us aa/bb/cc/dd where cc/dd was correct // and (2) the user gave us cc/dd where aa/bb/cc/dd was correct. - {// check the (1) above first - String f=fileMask; - while(true) { + { // check the (1) above first + String f = fileMask; + while (true) { int idx = findSeparator(f); - if(idx==-1) break; - f=f.substring(idx+1); + if (idx == -1) break; + f = f.substring(idx + 1); - if(hasMatch(dir,f,caseSensitive)) - return Messages.FilePath_validateAntFileMask_doesntMatchAndSuggest(fileMask,f); + if (hasMatch(dir, f, caseSensitive)) + return Messages.FilePath_validateAntFileMask_doesntMatchAndSuggest(fileMask, f); } } - {// check the (2) above next as this is more expensive. + { // check the (2) above next as this is more expensive. // Try prepending "**/" to see if that results in a match - FileSet fs = Util.createFileSet(reading(dir),"**/"+fileMask); + FileSet fs = Util.createFileSet(dir, "**/" + fileMask); fs.setCaseSensitive(caseSensitive); DirectoryScanner ds = fs.getDirectoryScanner(new Project()); - if(ds.getIncludedFilesCount()!=0) { + if (ds.getIncludedFilesCount() != 0) { // try shorter name first so that the suggestion results in least amount of changes String[] names = ds.getIncludedFiles(); - Arrays.sort(names,SHORTER_STRING_FIRST); - for( String f : names) { + Arrays.sort(names, SHORTER_STRING_FIRST); + for (String f : names) { // now we want to decompose f to the leading portion that matched "**" // and the trailing portion that matched the file mask, so that // we can suggest the user error. @@ -2997,43 +3153,43 @@ public String invoke(File dir, VirtualChannel channel) throws IOException, Inter // this is not a very efficient/clever way to do it, but it's relatively simple StringBuilder prefix = new StringBuilder(); - while(true) { + while (true) { int idx = findSeparator(f); - if(idx==-1) break; + if (idx == -1) break; prefix.append(f, 0, idx).append('/'); - f=f.substring(idx+1); - if(hasMatch(dir,prefix+fileMask,caseSensitive)) - return Messages.FilePath_validateAntFileMask_doesntMatchAndSuggest(fileMask, prefix+fileMask); + f = f.substring(idx + 1); + if (hasMatch(dir, prefix + fileMask, caseSensitive)) + return Messages.FilePath_validateAntFileMask_doesntMatchAndSuggest(fileMask, prefix + fileMask); } } } } - {// finally, see if we can identify any sub portion that's valid. Otherwise bail out + { // finally, see if we can identify any sub portion that's valid. Otherwise bail out String previous = null; String pattern = fileMask; - while(true) { - if(hasMatch(dir,pattern,caseSensitive)) { + while (true) { + if (hasMatch(dir, pattern, caseSensitive)) { // found a match - if(previous==null) - return Messages.FilePath_validateAntFileMask_portionMatchAndSuggest(fileMask,pattern); + if (previous == null) + return Messages.FilePath_validateAntFileMask_portionMatchAndSuggest(fileMask, pattern); else - return Messages.FilePath_validateAntFileMask_portionMatchButPreviousNotMatchAndSuggest(fileMask,pattern,previous); + return Messages.FilePath_validateAntFileMask_portionMatchButPreviousNotMatchAndSuggest(fileMask, pattern, previous); } int idx = findSeparator(pattern); - if(idx<0) {// no more path component left to go back - if(pattern.equals(fileMask)) + if (idx < 0) { // no more path component left to go back + if (pattern.equals(fileMask)) return Messages.FilePath_validateAntFileMask_doesntMatchAnything(fileMask); else - return Messages.FilePath_validateAntFileMask_doesntMatchAnythingAndSuggest(fileMask,pattern); + return Messages.FilePath_validateAntFileMask_doesntMatchAnythingAndSuggest(fileMask, pattern); } // cut off the trailing component and try again previous = pattern; - pattern = pattern.substring(0,idx); + pattern = pattern.substring(0, idx); } } } @@ -3043,6 +3199,7 @@ public String invoke(File dir, VirtualChannel channel) throws IOException, Inter private boolean hasMatch(File dir, String pattern, boolean bCaseSensitive) throws InterruptedException { class Cancel extends RuntimeException {} + DirectoryScanner ds = bound == Integer.MAX_VALUE ? new DirectoryScanner() : new DirectoryScanner() { int ticks; long start = System.currentTimeMillis(); @@ -3057,19 +3214,19 @@ class Cancel extends RuntimeException {} return super.isCaseSensitive(); } }; - ds.setBasedir(reading(dir)); + ds.setBasedir(dir); ds.setIncludes(new String[] {pattern}); ds.setCaseSensitive(bCaseSensitive); try { ds.scan(); } catch (Cancel c) { - if (ds.getIncludedFilesCount()!=0 || ds.getIncludedDirsCount()!=0) { + if (ds.getIncludedFilesCount() != 0 || ds.getIncludedDirsCount() != 0) { return true; } else { - throw new InterruptedException("no matches found within " + bound); + throw (InterruptedException) new InterruptedException("no matches found within " + bound).initCause(c); } } - return ds.getIncludedFilesCount()!=0 || ds.getIncludedDirsCount()!=0; + return ds.getIncludedFilesCount() != 0 || ds.getIncludedDirsCount() != 0; } /** @@ -3078,9 +3235,9 @@ class Cancel extends RuntimeException {} private int findSeparator(String pattern) { int idx1 = pattern.indexOf('\\'); int idx2 = pattern.indexOf('/'); - if(idx1==-1) return idx2; - if(idx2==-1) return idx1; - return Math.min(idx1,idx2); + if (idx1 == -1) return idx2; + if (idx2 == -1) return idx1; + return Math.min(idx1, idx2); } } @@ -3115,24 +3272,24 @@ private UrlFactory getUrlFactory() { public static FormValidation validateFileMask(@CheckForNull FilePath path, String value) throws IOException { return FilePath.validateFileMask(path, value, true); } - + /** * Shortcut for {@link #validateFileMask(String,boolean,boolean)} with {@code errorIfNotExist} true, as the left-hand side can be null. */ public static FormValidation validateFileMask(@CheckForNull FilePath path, String value, boolean caseSensitive) throws IOException { - if(path==null) return FormValidation.ok(); + if (path == null) return FormValidation.ok(); return path.validateFileMask(value, true, caseSensitive); } /** - * Short for {@code validateFileMask(value, true, true)} + * Short for {@code validateFileMask(value, true, true)} */ public FormValidation validateFileMask(String value) throws IOException { return validateFileMask(value, true, true); } - + /** - * Short for {@code validateFileMask(value, errorIfNotExist, true)} + * Short for {@code validateFileMask(value, errorIfNotExist, true)} */ public FormValidation validateFileMask(String value, boolean errorIfNotExist) throws IOException { return validateFileMask(value, errorIfNotExist, true); @@ -3140,23 +3297,28 @@ public FormValidation validateFileMask(String value, boolean errorIfNotExist) th /** * Checks the GLOB-style file mask. See {@link #validateAntFileMask(String)}. - * Requires configure permission on ancestor AbstractProject object in request, - * or admin permission if no such ancestor is found. + * Requires configure permission on ancestor {@link AbstractProject} object in request, + * or {@link Jenkins#MANAGE} permission if no such ancestor is found. + * + *

Note that this permission check may not always make sense based on the directory provided; + * callers should consider using {@link #validateFileMask(FilePath, String, boolean)} and its overloads instead + * (once appropriate permission checks have succeeded). + * * @since 1.294 */ public FormValidation validateFileMask(String value, boolean errorIfNotExist, boolean caseSensitive) throws IOException { checkPermissionForValidate(); value = fixEmpty(value); - if(value==null) + if (value == null) return FormValidation.ok(); try { - if(!exists()) // no workspace. can't check + if (!exists()) // no workspace. can't check return FormValidation.ok(); String msg = validateAntFileMask(value, VALIDATE_ANT_FILE_MASK_BOUND, caseSensitive); - if(errorIfNotExist) return FormValidation.error(msg); + if (errorIfNotExist) return FormValidation.error(msg); else return FormValidation.warning(msg); } catch (InterruptedException e) { return FormValidation.ok(Messages.FilePath_did_not_manage_to_validate_may_be_too_sl(value)); @@ -3165,8 +3327,12 @@ public FormValidation validateFileMask(String value, boolean errorIfNotExist, bo /** * Validates a relative file path from this {@link FilePath}. - * Requires configure permission on ancestor AbstractProject object in request, - * or admin permission if no such ancestor is found. + * Requires configure permission on ancestor {@link AbstractProject} object in request, + * or {@link Jenkins#MANAGE} permission if no such ancestor is found. + * + *

Note that this permission check may not always make sense based on the directory provided; + * callers should consider using {@link #validateFileMask(FilePath, String, boolean)} and its overloads instead + * (once appropriate permission checks have succeeded). * * @param value * The relative path being validated. @@ -3182,33 +3348,33 @@ public FormValidation validateRelativePath(String value, boolean errorIfNotExist value = fixEmpty(value); // none entered yet, or something is seriously wrong - if(value==null) return FormValidation.ok(); + if (value == null) return FormValidation.ok(); // a common mistake is to use wildcard - if(value.contains("*")) return FormValidation.error(Messages.FilePath_validateRelativePath_wildcardNotAllowed()); + if (value.contains("*")) return FormValidation.error(Messages.FilePath_validateRelativePath_wildcardNotAllowed()); try { - if(!exists()) // no base directory. can't check + if (!exists()) // no base directory. can't check return FormValidation.ok(); FilePath path = child(value); - if(path.exists()) { + if (path.exists()) { if (expectingFile) { - if(!path.isDirectory()) + if (!path.isDirectory()) return FormValidation.ok(); else return FormValidation.error(Messages.FilePath_validateRelativePath_notFile(value)); } else { - if(path.isDirectory()) + if (path.isDirectory()) return FormValidation.ok(); else return FormValidation.error(Messages.FilePath_validateRelativePath_notDirectory(value)); } } - String msg = expectingFile ? Messages.FilePath_validateRelativePath_noSuchFile(value) : + String msg = expectingFile ? Messages.FilePath_validateRelativePath_noSuchFile(value) : Messages.FilePath_validateRelativePath_noSuchDirectory(value); - if(errorIfNotExist) return FormValidation.error(msg); + if (errorIfNotExist) return FormValidation.error(msg); else return FormValidation.warning(msg); } catch (InterruptedException e) { return FormValidation.ok(); @@ -3227,11 +3393,11 @@ private static void checkPermissionForValidate() { * A convenience method over {@link #validateRelativePath(String, boolean, boolean)}. */ public FormValidation validateRelativeDirectory(String value, boolean errorIfNotExist) throws IOException { - return validateRelativePath(value,errorIfNotExist,false); + return validateRelativePath(value, errorIfNotExist, false); } public FormValidation validateRelativeDirectory(String value) throws IOException { - return validateRelativeDirectory(value,true); + return validateRelativeDirectory(value, true); } @Deprecated @Override @@ -3241,15 +3407,15 @@ public String toString() { } public VirtualChannel getChannel() { - if(channel!=null) return channel; + if (channel != null) return channel; else return localChannel; } /** - * Returns true if this {@link FilePath} represents a remote file. + * Returns true if this {@link FilePath} represents a remote file. */ public boolean isRemote() { - return channel!=null; + return channel != null; } private void writeObject(ObjectOutputStream oos) throws IOException { @@ -3259,14 +3425,14 @@ private void writeObject(ObjectOutputStream oos) throws IOException { } oos.defaultWriteObject(); - oos.writeBoolean(channel==null); + oos.writeBoolean(channel == null); } private Channel _getChannelForSerialization() { try { return getChannelForSerialization(); } catch (NotSerializableException x) { - LOGGER.log(Level.WARNING, "A FilePath object is being serialized when it should not be, indicating a bug in a plugin. See https://jenkins.io/redirect/filepath-serialization for details.", x); + LOGGER.log(Level.WARNING, "A FilePath object is being serialized when it should not be, indicating a bug in a plugin. See https://www.jenkins.io/redirect/filepath-serialization for details.", x); return null; } } @@ -3275,46 +3441,49 @@ private void readObject(ObjectInputStream ois) throws IOException, ClassNotFound Channel channel = _getChannelForSerialization(); ois.defaultReadObject(); - if(ois.readBoolean()) { + if (ois.readBoolean()) { this.channel = channel; - this.filter = null; } else { this.channel = null; // If the remote channel wants us to create a FilePath that points to a local file, // we need to make sure the access control takes place. - // This covers the immediate case of FileCallables taking FilePath into reference closure implicitly, - // but it also covers more general case of FilePath sent as a return value or argument. - this.filter = SoloFilePathFilter.wrap(FilePathFilter.current()); + // Any FileCallables acting on a deserialized FilePath need to ensure they're subjecting it to + // access control checks like #reading(File) etc. } } private static final long serialVersionUID = 1L; - @SuppressFBWarnings("MS_SHOULD_BE_FINAL") - public static int SIDE_BUFFER_SIZE = 1024; + @Restricted(NoExternalUse.class) + @RestrictedSince("2.328") + public static final int SIDE_BUFFER_SIZE = 1024; private static final Logger LOGGER = Logger.getLogger(FilePath.class.getName()); /** * Adapts {@link FileCallable} to {@link Callable}. */ - private class FileCallableWrapper implements DelegatingCallable { + private static class FileCallableWrapper implements DelegatingCallable { private final FileCallable callable; private transient ClassLoader classLoader; + private final FilePath filePath; - FileCallableWrapper(FileCallable callable) { + FileCallableWrapper(FileCallable callable, FilePath filePath) { this.callable = callable; this.classLoader = callable.getClass().getClassLoader(); + this.filePath = filePath; } - private FileCallableWrapper(FileCallable callable, ClassLoader classLoader) { + private FileCallableWrapper(FileCallable callable, ClassLoader classLoader, FilePath filePath) { this.callable = callable; this.classLoader = classLoader; + this.filePath = filePath; } + @Override public T call() throws IOException { try { - return callable.invoke(new File(remote), Channel.current()); + return callable.invoke(new File(filePath.remote), filePath.channel); } catch (InterruptedException e) { throw new TunneledInterruptedException(e); } @@ -3328,6 +3497,7 @@ public void checkRoles(RoleChecker checker) throws SecurityException { callable.checkRoles(checker); } + @Override public ClassLoader getClassLoader() { return classLoader; } @@ -3347,14 +3517,11 @@ private static class TunneledInterruptedException extends IOException { private TunneledInterruptedException(InterruptedException cause) { super(cause); } + private static final long serialVersionUID = 1L; } - private static final Comparator SHORTER_STRING_FIRST = new Comparator() { - public int compare(String o1, String o2) { - return o1.length()-o2.length(); - } - }; + private static final Comparator SHORTER_STRING_FIRST = Comparator.comparingInt(String::length); /** * Gets the {@link FilePath} representation of the "~" directory @@ -3363,6 +3530,7 @@ public int compare(String o1, String o2) { public static FilePath getHomeDirectory(VirtualChannel ch) throws InterruptedException, IOException { return ch.call(new GetHomeDirectory()); } + private static class GetHomeDirectory extends MasterToSlaveCallable { @Override public FilePath call() throws IOException { @@ -3378,18 +3546,18 @@ public static final class ExplicitlySpecifiedDirScanner extends DirScanner { private static final long serialVersionUID = 1; - private final Map files; + private final Map files; /** * Create a “scanner” (it actually does no scanning). * @param files a map from logical relative paths as per {@link FileVisitor#visit}, to actual relative paths within the scanned directory */ - public ExplicitlySpecifiedDirScanner(Map files) { + public ExplicitlySpecifiedDirScanner(Map files) { this.files = files; } @Override public void scan(File dir, FileVisitor visitor) throws IOException { - for (Map.Entry entry : files.entrySet()) { + for (Map.Entry entry : files.entrySet()) { String archivedPath = entry.getKey(); assert archivedPath.indexOf('\\') == -1; String workspacePath = entry.getValue(); @@ -3405,44 +3573,13 @@ public ExplicitlySpecifiedDirScanner(Map files) { new NamingThreadFactory(new DaemonThreadFactory(), "FilePath.localPool")) )); - + /** * Channel to the current instance. */ @NonNull public static final LocalChannel localChannel = new LocalChannel(threadPoolForRemoting); - private @NonNull SoloFilePathFilter filterNonNull() { - return filter!=null ? filter : UNRESTRICTED; - } - - /** - * Wraps {@link FileVisitor} to notify read access to {@link FilePathFilter}. - */ - private FileVisitor reading(final FileVisitor v) { - final FilePathFilter filter = FilePathFilter.current(); - if (filter==null) return v; - - return new FileVisitor() { - @Override - public void visit(File f, String relativePath) throws IOException { - filter.read(f); - v.visit(f,relativePath); - } - - @Override - public void visitSymlink(File link, String target, String relativePath) throws IOException { - filter.read(link); - v.visitSymlink(link, target, relativePath); - } - - @Override - public boolean understandsSymlink() { - return v.understandsSymlink(); - } - }; - } - /** * Wraps {@link FileVisitor} to ignore symlinks. */ @@ -3466,73 +3603,16 @@ public boolean understandsSymlink() { return v; } - /** - * Pass through 'f' after ensuring that we can read that file. - */ - private File reading(File f) { - filterNonNull().read(f); - return f; - } - - /** - * Pass through 'f' after ensuring that we can access the file attributes. - */ - private File stating(File f) { - filterNonNull().stat(f); - return f; - } - - /** - * Pass through 'f' after ensuring that we can create that file/dir. - */ - private File creating(File f) { - filterNonNull().create(f); - return f; - } - - /** - * Pass through 'f' after ensuring that we can write to that file. - */ - private File writing(File f) { - FilePathFilter filter = filterNonNull(); - if (!f.exists()) - filter.create(f); - filter.write(f); - return f; - } - - /** - * Pass through 'f' after ensuring that we can create that symlink. - */ - private File symlinking(File f) { - FilePathFilter filter = filterNonNull(); - if (!f.exists()) - filter.create(f); - filter.symlink(f); - return f; - } - - /** - * Pass through 'f' after ensuring that we can delete that file. - */ - private File deleting(File f) { - filterNonNull().delete(f); - return f; - } - - private boolean mkdirs(File dir) throws IOException { + private static boolean mkdirs(File dir) throws IOException { if (dir.exists()) return false; - - filterNonNull().mkdirs(dir); Files.createDirectories(fileToPath(dir)); return true; } - private File mkdirsE(File dir) throws IOException { + private static File mkdirsE(File dir) throws IOException { if (dir.exists()) { return dir; } - filterNonNull().mkdirs(dir); return IOUtils.mkdirs(dir); } @@ -3546,11 +3626,11 @@ public boolean isDescendant(@NonNull String potentialChildRelativePath) throws I return act(new IsDescendant(potentialChildRelativePath)); } - private static class IsDescendant extends SecureFileCallable { + private static class IsDescendant extends MasterToSlaveFileCallable { private static final long serialVersionUID = 1L; private String potentialChildRelativePath; - private IsDescendant(@NonNull String potentialChildRelativePath){ + private IsDescendant(@NonNull String potentialChildRelativePath) { this.potentialChildRelativePath = potentialChildRelativePath; } @@ -3559,7 +3639,7 @@ public Boolean invoke(@NonNull File parentFile, @NonNull VirtualChannel channel) if (new File(potentialChildRelativePath).isAbsolute()) { throw new IllegalArgumentException("Only a relative path is supported, the given path is absolute: " + potentialChildRelativePath); } - + Path parentAbsolutePath = Util.fileToPath(parentFile.getAbsoluteFile()); Path parentRealPath; try { @@ -3599,7 +3679,7 @@ public Boolean invoke(@NonNull File parentFile, @NonNull VirtualChannel channel) } Path currentFileAbsolutePath = currentFilePath.toAbsolutePath(); - try{ + try { Path child = currentFileAbsolutePath.toRealPath(); if (!child.startsWith(parentRealPath)) { LOGGER.log(Level.FINE, "Child [{0}] does not start with parent [{1}] => not descendant", new Object[]{ child, parentRealPath }); @@ -3607,13 +3687,13 @@ public Boolean invoke(@NonNull File parentFile, @NonNull VirtualChannel channel) } } catch (NoSuchFileException e) { // nonexistent file / Windows Server 2016 + MSFT docker - // in case this folder / file will be copied somewhere else, + // in case this folder / file will be copied somewhere else, // it becomes the responsibility of that system to check the isDescendant with the existing links // we are not taking the parentRealPath to avoid possible problem Path child = currentFileAbsolutePath.normalize(); Path parent = parentAbsolutePath.normalize(); return child.startsWith(parent); - } catch(FileSystemException e) { + } catch (FileSystemException e) { LOGGER.log(Level.WARNING, String.format("Problem during call to the method toRealPath on %s", currentFileAbsolutePath), e); return false; } @@ -3622,14 +3702,14 @@ public Boolean invoke(@NonNull File parentFile, @NonNull VirtualChannel channel) return true; } - private @CheckForNull Path getDirectChild(Path parentPath, String childPath){ + private @CheckForNull Path getDirectChild(Path parentPath, String childPath) { Path current = parentPath.resolve(childPath); while (current != null && !parentPath.equals(current.getParent())) { current = current.getParent(); } return current; } - + private @NonNull Path windowsToRealPath(@NonNull Path path) throws IOException { try { return path.toRealPath(); @@ -3665,8 +3745,6 @@ private static Path getRealPath(Path path) throws IOException { return path.toRealPath(LinkOption.NOFOLLOW_LINKS); } - private static final SoloFilePathFilter UNRESTRICTED = SoloFilePathFilter.wrap(FilePathFilter.UNRESTRICTED); - private static class SymlinkDiscardingFileFilter implements FileFilter, Serializable { private final String verificationRoot; @@ -3677,10 +3755,11 @@ private static class SymlinkDiscardingFileFilter implements FileFilter, Serializ this.noFollowLinks = noFollowLinks; } + @Override public boolean accept(File file) { return !isSymlink(file, verificationRoot, noFollowLinks); } + private static final long serialVersionUID = 1L; } - } diff --git a/core/src/main/java/hudson/FileSystemProvisioner.java b/core/src/main/java/hudson/FileSystemProvisioner.java index 9e338bed8cbf..d93f2c8e8b76 100644 --- a/core/src/main/java/hudson/FileSystemProvisioner.java +++ b/core/src/main/java/hudson/FileSystemProvisioner.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson; import hudson.model.AbstractBuild; @@ -36,12 +37,13 @@ */ @Deprecated public abstract class FileSystemProvisioner implements Describable { - public abstract void prepareWorkspace(AbstractBuild build, FilePath ws, TaskListener listener) throws IOException, InterruptedException; + public abstract void prepareWorkspace(AbstractBuild build, FilePath ws, TaskListener listener) throws IOException, InterruptedException; public abstract void discardWorkspace(AbstractProject project, FilePath ws) throws IOException, InterruptedException; - public abstract WorkspaceSnapshot snapshot(AbstractBuild build, FilePath ws, String glob, TaskListener listener) throws IOException, InterruptedException; + public abstract WorkspaceSnapshot snapshot(AbstractBuild build, FilePath ws, String glob, TaskListener listener) throws IOException, InterruptedException; + @Override public Descriptor getDescriptor() { return Jenkins.get().getDescriptorOrDie(getClass()); } @@ -49,12 +51,15 @@ public Descriptor getDescriptor() { public static final FileSystemProvisioner DEFAULT = new Default(); public static final class Default extends FileSystemProvisioner { + @Override public void prepareWorkspace(AbstractBuild build, FilePath ws, TaskListener listener) throws IOException, InterruptedException { } + @Override public void discardWorkspace(AbstractProject project, FilePath ws) throws IOException, InterruptedException { } + @Override public WorkspaceSnapshot snapshot(AbstractBuild build, FilePath ws, String glob, TaskListener listener) throws IOException, InterruptedException { throw new IOException("unimplemented"); } diff --git a/core/src/main/java/hudson/Functions.java b/core/src/main/java/hudson/Functions.java index 3fca0f0afdf0..879791296ac7 100644 --- a/core/src/main/java/hudson/Functions.java +++ b/core/src/main/java/hudson/Functions.java @@ -1,20 +1,20 @@ /* * The MIT License - * + * * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, * Yahoo! Inc., Stephen Connolly, Tom Huybrechts, Alan Harder, Manufacture * Francaise des Pneumatiques Michelin, Romain Seguy - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,22 +23,20 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.Nullable; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import hudson.model.Computer; -import hudson.model.Slave; -import hudson.security.*; - -import java.text.SimpleDateFormat; -import java.util.function.Predicate; -import jenkins.util.SystemProperties; import hudson.cli.CLICommand; import hudson.console.ConsoleAnnotationDescriptor; import hudson.console.ConsoleAnnotatorFactory; import hudson.init.InitMilestone; import hudson.model.AbstractProject; import hudson.model.Action; +import hudson.model.Computer; import hudson.model.Describable; import hudson.model.Descriptor; import hudson.model.DescriptorVisibilityFilter; @@ -52,11 +50,12 @@ import hudson.model.ModelObject; import hudson.model.Node; import hudson.model.PageDecorator; -import jenkins.model.SimplePageDecorator; import hudson.model.PaneStatusProperties; import hudson.model.ParameterDefinition; import hudson.model.ParameterDefinition.ParameterDescriptor; +import hudson.model.PasswordParameterDefinition; import hudson.model.Run; +import hudson.model.Slave; import hudson.model.TimeZoneProperty; import hudson.model.TopLevelItem; import hudson.model.User; @@ -64,6 +63,12 @@ import hudson.scm.SCM; import hudson.scm.SCMDescriptor; import hudson.search.SearchableModelObject; +import hudson.security.ACL; +import hudson.security.AccessControlled; +import hudson.security.AuthorizationStrategy; +import hudson.security.GlobalSecurityConfiguration; +import hudson.security.Permission; +import hudson.security.SecurityRealm; import hudson.security.captcha.CaptchaSupport; import hudson.security.csrf.CrumbIssuer; import hudson.slaves.Cloud; @@ -82,13 +87,12 @@ import hudson.util.HudsonIsLoading; import hudson.util.HudsonIsRestarting; import hudson.util.Iterators; -import hudson.util.jna.GNUCLibrary; +import hudson.util.RunList; import hudson.util.Secret; +import hudson.util.jna.GNUCLibrary; import hudson.views.MyViewsTabBar; import hudson.views.ViewsTabBar; import hudson.widgets.RenderOnDemandClosure; - - import java.io.File; import java.io.IOException; import java.io.PrintStream; @@ -110,6 +114,7 @@ import java.net.URLDecoder; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; +import java.text.DateFormat; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Arrays; @@ -121,31 +126,34 @@ import java.util.Date; import java.util.Enumeration; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Set; import java.util.SortedMap; import java.util.TimeZone; import java.util.TreeMap; +import java.util.concurrent.atomic.AtomicLong; +import java.util.function.Predicate; import java.util.logging.Level; import java.util.logging.LogManager; import java.util.logging.LogRecord; import java.util.logging.Logger; import java.util.logging.SimpleFormatter; import java.util.regex.Pattern; - -import edu.umd.cs.findbugs.annotations.Nullable; +import java.util.stream.Collectors; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; - import jenkins.model.GlobalConfiguration; import jenkins.model.GlobalConfigurationCategory; import jenkins.model.Jenkins; import jenkins.model.ModelObjectWithChildren; import jenkins.model.ModelObjectWithContextMenu; - +import jenkins.model.SimplePageDecorator; +import jenkins.util.SystemProperties; import org.apache.commons.jelly.JellyContext; import org.apache.commons.jelly.JellyTagException; import org.apache.commons.jelly.Script; @@ -153,26 +161,17 @@ import org.apache.commons.jexl.parser.ASTSizeFunction; import org.apache.commons.jexl.util.Introspector; import org.apache.commons.lang.StringUtils; +import org.jenkins.ui.icon.Icon; import org.jenkins.ui.icon.IconSet; import org.jvnet.tiger_types.Types; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.DoNotUse; +import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.Ancestor; +import org.kohsuke.stapler.RawHtmlArgument; import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; -import org.kohsuke.stapler.RawHtmlArgument; - -import hudson.model.PasswordParameterDefinition; -import hudson.util.RunList; - -import java.util.HashSet; -import java.util.Set; -import java.util.concurrent.atomic.AtomicLong; -import java.util.stream.Collectors; -import edu.umd.cs.findbugs.annotations.CheckForNull; -import edu.umd.cs.findbugs.annotations.NonNull; -import org.kohsuke.accmod.Restricted; -import org.kohsuke.accmod.restrictions.NoExternalUse; -import org.kohsuke.accmod.restrictions.DoNotUse; import org.springframework.security.access.AccessDeniedException; /** @@ -190,7 +189,7 @@ public class Functions { private static Logger LOGGER = Logger.getLogger(Functions.class.getName()); @Restricted(NoExternalUse.class) - @SuppressFBWarnings("MS_SHOULD_BE_FINAL") + @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "for script console") public static /* non-final */ boolean UI_REFRESH = SystemProperties.getBoolean("jenkins.ui.refresh"); public Functions() { @@ -214,7 +213,7 @@ public static boolean isModelWithContextMenu(Object o) { public static boolean isModelWithChildren(Object o) { return o instanceof ModelObjectWithChildren; } - + @Deprecated public static boolean isMatrixProject(Object o) { return o != null && o.getClass().getName().equals("hudson.matrix.MatrixProject"); @@ -231,12 +230,10 @@ public static String iso8601DateTime(Date date) { /** * Returns a localized string for the specified date, not including time. - * @param date - * @return */ @Restricted(NoExternalUse.class) public static String localDate(Date date) { - return SimpleDateFormat.getDateInstance(SimpleDateFormat.SHORT).format(date); + return DateFormat.getDateInstance(DateFormat.SHORT).format(date); } public static String rfc822Date(Calendar cal) { @@ -245,9 +242,6 @@ public static String rfc822Date(Calendar cal) { /** * Returns a human-readable string describing the time difference between now and the specified date. - * - * @param date - * @return */ @Restricted(NoExternalUse.class) public static String getTimeSpanString(Date date) { @@ -301,8 +295,8 @@ public static void initPageVariables(JellyContext context) { see https://wiki.jenkins-ci.org/display/JENKINS/Hyperlinks+in+HTML */ - context.setVariable("resURL",rootURL+getResourcePath()); - context.setVariable("imagesURL",rootURL+getResourcePath()+"/images"); + context.setVariable("resURL", rootURL + getResourcePath()); + context.setVariable("imagesURL", rootURL + getResourcePath() + "/images"); context.setVariable("divBasedFormLayout", true); context.setVariable("userAgent", currentRequest.getHeader("User-Agent")); IconSet.initPageVariables(context); @@ -320,12 +314,12 @@ public static void initPageVariables(JellyContext context) { * if c' is not parameterized. */ public static Class getTypeParameter(Class c, Class base, int n) { - Type parameterization = Types.getBaseClass(c,base); + Type parameterization = Types.getBaseClass(c, base); if (parameterization instanceof ParameterizedType) { ParameterizedType pt = (ParameterizedType) parameterization; - return Types.erasure(Types.getTypeArgument(pt,n)); + return Types.erasure(Types.getTypeArgument(pt, n)); } else { - throw new AssertionError(c+" doesn't properly parameterize "+base); + throw new AssertionError(c + " doesn't properly parameterize " + base); } } @@ -338,9 +332,9 @@ public JDK.DescriptorImpl getJDKDescriptor() { * like "-5", "+/-0", "+3". */ public static String getDiffString(int i) { - if(i==0) return "±0"; + if (i == 0) return "±0"; String s = Integer.toString(i); - if(i>0) return "+"+s; + if (i > 0) return "+" + s; else return s; } @@ -348,9 +342,9 @@ public static String getDiffString(int i) { * {@link #getDiffString(int)} that doesn't show anything for +/-0 */ public static String getDiffString2(int i) { - if(i==0) return ""; + if (i == 0) return ""; String s = Integer.toString(i); - if(i>0) return "+"+s; + if (i > 0) return "+" + s; else return s; } @@ -359,10 +353,10 @@ public static String getDiffString2(int i) { * if there's something to print */ public static String getDiffString2(String prefix, int i, String suffix) { - if(i==0) return ""; + if (i == 0) return ""; String s = Integer.toString(i); - if(i>0) return prefix+"+"+s+suffix; - else return prefix+s+suffix; + if (i > 0) return prefix + "+" + s + suffix; + else return prefix + s + suffix; } /** @@ -371,7 +365,7 @@ public static String getDiffString2(String prefix, int i, String suffix) { public static String addSuffix(int n, String singular, String plural) { StringBuilder buf = new StringBuilder(); buf.append(n).append(' '); - if(n==1) + if (n == 1) buf.append(singular); else buf.append(plural); @@ -382,16 +376,16 @@ public static RunUrl decompose(StaplerRequest req) { List ancestors = req.getAncestors(); // find the first and last Run instances - Ancestor f=null,l=null; + Ancestor f = null, l = null; for (Ancestor anc : ancestors) { - if(anc.getObject() instanceof Run) { - if(f==null) f=anc; - l=anc; + if (anc.getObject() instanceof Run) { + if (f == null) f = anc; + l = anc; } } - if(l==null) return null; // there was no Run object + if (l == null) return null; // there was no Run object - String head = f.getPrev().getUrl()+'/'; + String head = f.getPrev().getUrl() + '/'; String base = l.getUrl(); String reqUri = req.getOriginalRequestURI(); @@ -408,7 +402,7 @@ public static RunUrl decompose(StaplerRequest req) { // Remove that many from request URL, ignoring extra slashes String rest = reqUri.replaceFirst("(?:/+[^/]*){" + slashCount + "}", ""); - return new RunUrl( (Run) f.getObject(), head, base, rest); + return new RunUrl((Run) f.getObject(), head, base, rest); } /** @@ -416,8 +410,8 @@ public static RunUrl decompose(StaplerRequest req) { * @since 1.213 */ public static Area getScreenResolution() { - Cookie res = Functions.getCookie(Stapler.getCurrentRequest(),"screenResolution"); - if(res!=null) + Cookie res = Functions.getCookie(Stapler.getCurrentRequest(), "screenResolution"); + if (res != null) return Area.parse(res.getValue()); return null; } @@ -482,10 +476,10 @@ public String getPreviousBuildUrl() { } private String getUrl(Run n) { - if(n ==null) + if (n == null) return null; else { - return head+n.getNumber()+rest; + return head + n.getNumber() + rest; } } } @@ -518,7 +512,7 @@ public static Map getSystemProperties() { /** * Gets the system property indicated by the specified key. - * + * * Delegates to {@link SystemProperties#getString(String)}. */ @Restricted(DoNotUse.class) @@ -541,14 +535,14 @@ public static Map getEnvVars() { } public static boolean isWindows() { - return File.pathSeparatorChar==';'; + return File.pathSeparatorChar == ';'; } - + public static boolean isGlibcSupported() { try { GNUCLibrary.LIBC.getpid(); return true; - } catch(Throwable t) { + } catch (Throwable t) { return false; } } @@ -576,10 +570,11 @@ public static String[] printLogRecordHtml(LogRecord r, LogRecord prior) { * @return date, source, level, message+thrown * @see SimpleFormatter#format(LogRecord) */ + private static String[] logRecordPreformat(LogRecord r) { String source; if (r.getSourceClassName() == null) { - source = r.getLoggerName(); + source = r.getLoggerName() == null ? "" : r.getLoggerName(); } else { if (r.getSourceMethodName() == null) { source = r.getSourceClassName(); @@ -593,7 +588,7 @@ private static String[] logRecordPreformat(LogRecord r) { String.format("%1$tb %1$td, %1$tY %1$tl:%1$tM:%1$tS %1$Tp", new Date(r.getMillis())), source, r.getLevel().getLocalizedName(), - x == null ? message : message + printThrowable(x) + "\n" + x == null ? message : message + printThrowable(x) + "\n", }; } @@ -607,11 +602,11 @@ public static Iterable reverse(Collection collection) { return list; } - public static Cookie getCookie(HttpServletRequest req,String name) { + public static Cookie getCookie(HttpServletRequest req, String name) { Cookie[] cookies = req.getCookies(); - if(cookies!=null) { + if (cookies != null) { for (Cookie cookie : cookies) { - if(cookie.getName().equals(name)) { + if (cookie.getName().equals(name)) { return cookie; } } @@ -619,13 +614,14 @@ public static Cookie getCookie(HttpServletRequest req,String name) { return null; } - public static String getCookie(HttpServletRequest req,String name, String defaultValue) { + public static String getCookie(HttpServletRequest req, String name, String defaultValue) { Cookie c = getCookie(req, name); - if(c==null || c.getValue()==null) return defaultValue; + if (c == null || c.getValue() == null) return defaultValue; return c.getValue(); } private static final Pattern ICON_SIZE = Pattern.compile("\\d+x\\d+"); + @Restricted(NoExternalUse.class) public static String validateIconSize(String iconSize) throws SecurityException { if (!ICON_SIZE.matcher(iconSize).matches()) { @@ -644,34 +640,34 @@ public static String getYuiSuffix() { /** * Set to true if you need to use the debug version of YUI. */ - @SuppressFBWarnings("MS_SHOULD_BE_FINAL") + @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "for script console") public static boolean DEBUG_YUI = SystemProperties.getBoolean("debug.YUI"); /** * Creates a sub map by using the given range (both ends inclusive). */ - public static SortedMap filter(SortedMap map, String from, String to) { - if(from==null && to==null) return map; - if(to==null) - return map.headMap(Integer.parseInt(from)-1); - if(from==null) + public static SortedMap filter(SortedMap map, String from, String to) { + if (from == null && to == null) return map; + if (to == null) + return map.headMap(Integer.parseInt(from) - 1); + if (from == null) return map.tailMap(Integer.parseInt(to)); - return map.subMap(Integer.parseInt(to),Integer.parseInt(from)-1); + return map.subMap(Integer.parseInt(to), Integer.parseInt(from) - 1); } /** * Creates a sub map by using the given range (upper end inclusive). */ @Restricted(NoExternalUse.class) - public static SortedMap filterExcludingFrom(SortedMap map, String from, String to) { - if(from==null && to==null) return map; - if(to==null) + public static SortedMap filterExcludingFrom(SortedMap map, String from, String to) { + if (from == null && to == null) return map; + if (to == null) return map.headMap(Integer.parseInt(from)); - if(from==null) + if (from == null) return map.tailMap(Integer.parseInt(to)); - return map.subMap(Integer.parseInt(to),Integer.parseInt(from)); + return map.subMap(Integer.parseInt(to), Integer.parseInt(from)); } private static final SimpleFormatter formatter = new SimpleFormatter(); @@ -692,7 +688,7 @@ public static boolean isAutoRefresh(HttpServletRequest request) { } public static boolean isCollapsed(String paneId) { - return PaneStatusProperties.forCurrentUser().isCollapsed(paneId); + return PaneStatusProperties.forCurrentUser().isCollapsed(paneId); } @Restricted(NoExternalUse.class) @@ -721,11 +717,11 @@ public static String getUserTimeZonePostfix() { * This is used to determine the "current" URL assigned to the given object, * so that one can compute relative URLs from it. */ - public static String getNearestAncestorUrl(StaplerRequest req,Object it) { + public static String getNearestAncestorUrl(StaplerRequest req, Object it) { List list = req.getAncestors(); - for( int i=list.size()-1; i>=0; i-- ) { + for (int i = list.size() - 1; i >= 0; i--) { Ancestor anc = (Ancestor) list.get(i); - if(anc.getObject()==it) + if (anc.getObject() == it) return anc.getUrl(); } return null; @@ -736,17 +732,17 @@ public static String getNearestAncestorUrl(StaplerRequest req,Object it) { */ public static String getSearchURL() { List list = Stapler.getCurrentRequest().getAncestors(); - for( int i=list.size()-1; i>=0; i-- ) { + for (int i = list.size() - 1; i >= 0; i--) { Ancestor anc = (Ancestor) list.get(i); - if(anc.getObject() instanceof SearchableModelObject) - return anc.getUrl()+"/search/"; + if (anc.getObject() instanceof SearchableModelObject) + return anc.getUrl() + "/search/"; } return null; } public static String appendSpaceIfNotNull(String n) { - if(n==null) return null; - else return n+' '; + if (n == null) return null; + else return n + ' '; } /** @@ -767,8 +763,8 @@ public static String getWin32ErrorMessage(IOException e) { } public static boolean isMultiline(String s) { - if(s==null) return false; - return s.indexOf('\r')>=0 || s.indexOf('\n')>=0; + if (s == null) return false; + return s.indexOf('\r') >= 0 || s.indexOf('\n') >= 0; } public static String encode(String s) { @@ -802,26 +798,26 @@ public static String xmlEscape(String s) { } public static String xmlUnescape(String s) { - return s.replace("<","<").replace(">",">").replace("&","&"); + return s.replace("<", "<").replace(">", ">").replace("&", "&"); } public static String htmlAttributeEscape(String text) { - StringBuilder buf = new StringBuilder(text.length()+64); - for( int i=0; i') + if (ch == '>') buf.append(">"); else - if(ch=='&') + if (ch == '&') buf.append("&"); else - if(ch=='"') + if (ch == '"') buf.append("""); else - if(ch=='\'') + if (ch == '\'') buf.append("'"); else buf.append(ch); @@ -830,7 +826,7 @@ public static String htmlAttributeEscape(String text) { } public static void checkPermission(Permission permission) throws IOException, ServletException { - checkPermission(Jenkins.get(),permission); + checkPermission(Jenkins.get(), permission); } public static void checkPermission(AccessControlled object, Permission permission) throws IOException, ServletException { @@ -847,19 +843,19 @@ public static void checkPermission(AccessControlled object, Permission permissio public static void checkPermission(Object object, Permission permission) throws IOException, ServletException { if (permission == null) return; - + if (object instanceof AccessControlled) - checkPermission((AccessControlled) object,permission); + checkPermission((AccessControlled) object, permission); else { List ancs = Stapler.getCurrentRequest().getAncestors(); - for(Ancestor anc : Iterators.reverse(ancs)) { + for (Ancestor anc : Iterators.reverse(ancs)) { Object o = anc.getObject(); if (o instanceof AccessControlled) { - checkPermission((AccessControlled) o,permission); + checkPermission((AccessControlled) o, permission); return; } } - checkPermission(Jenkins.get(),permission); + checkPermission(Jenkins.get(), permission); } } @@ -870,7 +866,7 @@ public static void checkPermission(Object object, Permission permission) throws * If null, returns true. This defaulting is convenient in making the use of this method terse. */ public static boolean hasPermission(Permission permission) throws IOException, ServletException { - return hasPermission(Jenkins.get(),permission); + return hasPermission(Jenkins.get(), permission); } /** @@ -881,13 +877,13 @@ public static boolean hasPermission(Object object, Permission permission) throws if (permission == null) return true; if (object instanceof AccessControlled) - return ((AccessControlled)object).hasPermission(permission); + return ((AccessControlled) object).hasPermission(permission); else { List ancs = Stapler.getCurrentRequest().getAncestors(); - for(Ancestor anc : Iterators.reverse(ancs)) { + for (Ancestor anc : Iterators.reverse(ancs)) { Object o = anc.getObject(); if (o instanceof AccessControlled) { - return ((AccessControlled)o).hasPermission(permission); + return ((AccessControlled) o).hasPermission(permission); } } return Jenkins.get().hasPermission(permission); @@ -897,7 +893,7 @@ public static boolean hasPermission(Object object, Permission permission) throws public static void adminCheck(StaplerRequest req, StaplerResponse rsp, Object required, Permission permission) throws IOException, ServletException { // this is legacy --- all views should be eventually converted to // the permission based model. - if(required!=null && !Hudson.adminCheck(req, rsp)) { + if (required != null && !Hudson.adminCheck(req, rsp)) { // check failed. commit the FORBIDDEN response, then abort. rsp.setStatus(HttpServletResponse.SC_FORBIDDEN); rsp.getOutputStream().close(); @@ -905,7 +901,7 @@ public static void adminCheck(StaplerRequest req, StaplerResponse rsp, Object re } // make sure the user owns the necessary permission to access this page. - if(permission!=null) + if (permission != null) checkPermission(permission); } @@ -914,13 +910,13 @@ public static void adminCheck(StaplerRequest req, StaplerResponse rsp, Object re */ public static String inferHudsonURL(StaplerRequest req) { String rootUrl = Jenkins.get().getRootUrl(); - if(rootUrl !=null) + if (rootUrl != null) // prefer the one explicitly configured, to work with load-balancer, frontend, etc. return rootUrl; StringBuilder buf = new StringBuilder(); buf.append(req.getScheme()).append("://"); buf.append(req.getServerName()); - if(! (req.getScheme().equals("http") && req.getLocalPort()==80 || req.getScheme().equals("https") && req.getLocalPort()==443)) + if (! (req.getScheme().equals("http") && req.getLocalPort() == 80 || req.getScheme().equals("https") && req.getLocalPort() == 443)) buf.append(':').append(req.getLocalPort()); buf.append(req.getContextPath()).append('/'); return buf.toString(); @@ -930,14 +926,15 @@ public static String inferHudsonURL(StaplerRequest req) { * Returns the link to be displayed in the footer of the UI. */ public static String getFooterURL() { - if(footerURL == null) { + if (footerURL == null) { footerURL = SystemProperties.getString("hudson.footerURL"); - if(StringUtils.isBlank(footerURL)) { - footerURL = "https://jenkins.io/"; + if (StringUtils.isBlank(footerURL)) { + footerURL = "https://www.jenkins.io/"; } } return footerURL; } + private static String footerURL = null; public static List getJobPropertyDescriptors(Class clazz) { @@ -948,7 +945,7 @@ public static List getJobPropertyDescriptors(Job job) { return DescriptorVisibilityFilter.apply(job, JobPropertyDescriptor.getPropertyDescriptors(job.getClass())); } - public static List> getBuildWrapperDescriptors(AbstractProject project) { + public static List> getBuildWrapperDescriptors(AbstractProject project) { return BuildWrappers.getFor(project); } @@ -960,15 +957,15 @@ public static List> getAuthorizationStrategyDe return AuthorizationStrategy.all(); } - public static List> getBuilderDescriptors(AbstractProject project) { + public static List> getBuilderDescriptors(AbstractProject project) { return BuildStepDescriptor.filter(Builder.all(), project.getClass()); } - public static List> getPublisherDescriptors(AbstractProject project) { + public static List> getPublisherDescriptors(AbstractProject project) { return BuildStepDescriptor.filter(Publisher.all(), project.getClass()); } - public static List> getSCMDescriptors(AbstractProject project) { + public static List> getSCMDescriptors(AbstractProject project) { return SCM._for((Job) project); } @@ -1070,7 +1067,7 @@ public static Collection getSortedDescriptorsForGlobalConfig(com.goo for (ExtensionComponent c : exts.getComponents()) { Descriptor d = c.getInstance(); - if (d.getGlobalConfigPage()==null) continue; + if (d.getGlobalConfigPage() == null) continue; if (!Jenkins.get().hasPermission(d.getRequiredGlobalConfigPagePermission())) { continue; @@ -1085,7 +1082,7 @@ public static Collection getSortedDescriptorsForGlobalConfig(com.goo List answer = new ArrayList<>(r.size()); for (Tag d : r) answer.add(d.d); - return DescriptorVisibilityFilter.apply(Jenkins.get(),answer); + return DescriptorVisibilityFilter.apply(Jenkins.get(), answer); } /** @@ -1111,7 +1108,7 @@ public static Collection getSortedDescriptorsForGlobalConfigByDescri for (ExtensionComponent c : exts.getComponents()) { Descriptor d = c.getInstance(); - if (d.getGlobalConfigPage()==null) continue; + if (d.getGlobalConfigPage() == null) continue; if (predicate.test(d)) { r.add(new Tag(c.ordinal(), d)); @@ -1122,7 +1119,7 @@ public static Collection getSortedDescriptorsForGlobalConfigByDescri List answer = new ArrayList<>(r.size()); for (Tag d : r) answer.add(d.d); - return DescriptorVisibilityFilter.apply(Jenkins.get(),answer); + return DescriptorVisibilityFilter.apply(Jenkins.get(), answer); } /** @@ -1192,7 +1189,7 @@ public static boolean hasAnyPermission(Object object, Permission[] permissions) if (ac != null) { return hasAnyPermission(ac, permissions); } - + return hasAnyPermission(Jenkins.get(), permissions); } } @@ -1227,7 +1224,7 @@ public static void checkAnyPermission(Object object, Permission[] permissions) t checkAnyPermission((AccessControlled) object, permissions); else { List ancs = Stapler.getCurrentRequest().getAncestors(); - for(Ancestor anc : Iterators.reverse(ancs)) { + for (Ancestor anc : Iterators.reverse(ancs)) { Object o = anc.getObject(); if (o instanceof AccessControlled) { checkAnyPermission((AccessControlled) o, permissions); @@ -1251,13 +1248,14 @@ private static class Tag implements Comparable { private StringBuilder buildSuperclassHierarchy(Class c, StringBuilder buf) { Class sc = c.getSuperclass(); - if (sc!=null) buildSuperclassHierarchy(sc,buf).append(':'); + if (sc != null) buildSuperclassHierarchy(sc, buf).append(':'); return buf.append(c.getName()); } + @Override public int compareTo(Tag that) { int r = Double.compare(that.ordinal, this.ordinal); - if (r!=0) return r; // descending for ordinal by reversing the order for compare + if (r != 0) return r; // descending for ordinal by reversing the order for compare return this.hierarchy.compareTo(that.hierarchy); } } @@ -1265,13 +1263,19 @@ public int compareTo(Tag that) { * Computes the path to the icon of the given action * from the context path. */ + public static String getIconFilePath(Action a) { String name = a.getIconFileName(); - if (name==null) return null; + if (name == null) { + return null; + } + if (name.startsWith("symbol-")) { + return name; + } if (name.startsWith("/")) return name.substring(1); else - return "images/24x24/"+name; + return "images/24x24/" + name; } /** @@ -1279,70 +1283,70 @@ public static String getIconFilePath(Action a) { * but handle null gracefully. */ public static int size2(Object o) throws Exception { - if(o==null) return 0; - return ASTSizeFunction.sizeOf(o,Introspector.getUberspect()); + if (o == null) return 0; + return ASTSizeFunction.sizeOf(o, Introspector.getUberspect()); } /** * Computes the relative path from the current page to the given item. */ public static String getRelativeLinkTo(Item p) { - Map ancestors = new HashMap<>(); - View view=null; + Map ancestors = new HashMap<>(); + View view = null; StaplerRequest request = Stapler.getCurrentRequest(); - for( Ancestor a : request.getAncestors() ) { - ancestors.put(a.getObject(),a.getRelativePath()); - if(a.getObject() instanceof View) + for (Ancestor a : request.getAncestors()) { + ancestors.put(a.getObject(), a.getRelativePath()); + if (a.getObject() instanceof View) view = (View) a.getObject(); } String path = ancestors.get(p); - if(path!=null) { + if (path != null) { return normalizeURI(path + '/'); } - Item i=p; + Item i = p; String url = ""; - while(true) { + while (true) { ItemGroup ig = i.getParent(); - url = i.getShortUrl()+url; + url = i.getShortUrl() + url; - if(ig== Jenkins.get() || (view != null && ig == view.getOwner().getItemGroup())) { + if (ig == Jenkins.get() || (view != null && ig == view.getOwner().getItemGroup())) { assert i instanceof TopLevelItem; if (view != null) { // assume p and the current page belong to the same view, so return a relative path // (even if they did not, View.getItem does not by default verify ownership) - return normalizeURI(ancestors.get(view)+'/'+url); + return normalizeURI(ancestors.get(view) + '/' + url); } else { // otherwise return a path from the root Hudson - return normalizeURI(request.getContextPath()+'/'+p.getUrl()); + return normalizeURI(request.getContextPath() + '/' + p.getUrl()); } } path = ancestors.get(ig); - if(path!=null) { - return normalizeURI(path+'/'+url); + if (path != null) { + return normalizeURI(path + '/' + url); } assert ig instanceof Item; // if not, ig must have been the Hudson instance i = (Item) ig; } } - + private static String normalizeURI(String uri) { return URI.create(uri).normalize().toString(); } - + /** * Gets all the {@link TopLevelItem}s recursively in the {@link ItemGroup} tree. - * + * * @since 1.512 */ public static List getAllTopLevelItems(ItemGroup root) { return root.getAllItems(TopLevelItem.class); } - + /** * Gets the relative name or display name to the given item from the specified group. * @@ -1361,41 +1365,41 @@ public static String getRelativeNameFrom(@CheckForNull Item p, @CheckForNull Ite if (p == null) return null; if (g == null) return useDisplayName ? p.getFullDisplayName() : p.getFullName(); String separationString = useDisplayName ? " » " : "/"; - + // first list up all the parents - Map parents = new HashMap<>(); - int depth=0; - while (g!=null) { + Map parents = new HashMap<>(); + int depth = 0; + while (g != null) { parents.put(g, depth++); if (g instanceof Item) - g = ((Item)g).getParent(); + g = ((Item) g).getParent(); else g = null; } StringBuilder buf = new StringBuilder(); - Item i=p; + Item i = p; while (true) { - if (buf.length()>0) buf.insert(0,separationString); - buf.insert(0,useDisplayName ? i.getDisplayName() : i.getName()); + if (buf.length() > 0) buf.insert(0, separationString); + buf.insert(0, useDisplayName ? i.getDisplayName() : i.getName()); ItemGroup gr = i.getParent(); Integer d = parents.get(gr); - if (d!=null) { - for (int j=d; j>0; j--) { - buf.insert(0,separationString); - buf.insert(0,".."); + if (d != null) { + for (int j = d; j > 0; j--) { + buf.insert(0, separationString); + buf.insert(0, ".."); } return buf.toString(); } if (gr instanceof Item) - i = (Item)gr; + i = (Item) gr; else // Parent is a group, but not an item return null; } } - + /** * Gets the name to the given item relative to given group. * @@ -1410,9 +1414,9 @@ public static String getRelativeNameFrom(@CheckForNull Item p, @CheckForNull Ite @Nullable public static String getRelativeNameFrom(@CheckForNull Item p, @CheckForNull ItemGroup g) { return getRelativeNameFrom(p, g, false); - } - - + } + + /** * Gets the relative display name to the given item from the specified group. * @@ -1429,15 +1433,15 @@ public static String getRelativeDisplayNameFrom(@CheckForNull Item p, @CheckForN return getRelativeNameFrom(p, g, true); } - public static Map dumpAllThreads() { - Map sorted = new TreeMap<>(new ThreadSorter()); + public static Map dumpAllThreads() { + Map sorted = new TreeMap<>(new ThreadSorter()); sorted.putAll(Thread.getAllStackTraces()); return sorted; } public static ThreadInfo[] getThreadInfos() { ThreadMXBean mbean = ManagementFactory.getThreadMXBean(); - return mbean.dumpAllThreads(mbean.isObjectMonitorUsageSupported(),mbean.isSynchronizerUsageSupported()); + return mbean.dumpAllThreads(mbean.isObjectMonitorUsageSupported(), mbean.isSynchronizerUsageSupported()); } public static ThreadGroupMap sortThreadsAndGetGroupMap(ThreadInfo[] list) { @@ -1448,12 +1452,12 @@ public static ThreadGroupMap sortThreadsAndGetGroupMap(ThreadInfo[] list) { // Common code for sorting Threads/ThreadInfos by ThreadGroup private static class ThreadSorterBase { - protected Map map = new HashMap<>(); + protected Map map = new HashMap<>(); ThreadSorterBase() { ThreadGroup tg = Thread.currentThread().getThreadGroup(); while (tg.getParent() != null) tg = tg.getParent(); - Thread[] threads = new Thread[tg.activeCount()*2]; + Thread[] threads = new Thread[tg.activeCount() * 2]; int threadsLen = tg.enumerate(threads, true); for (int i = 0; i < threadsLen; i++) { ThreadGroup group = threads[i].getThreadGroup(); @@ -1463,8 +1467,8 @@ private static class ThreadSorterBase { protected int compare(long idA, long idB) { String tga = map.get(idA), tgb = map.get(idB); - int result = (tga!=null?-1:0) + (tgb!=null?1:0); // Will be non-zero if only one is null - if (result==0 && tga!=null) + int result = (tga != null ? -1 : 0) + (tgb != null ? 1 : 0); // Will be non-zero if only one is null + if (result == 0 && tga != null) result = tga.compareToIgnoreCase(tgb); return result; } @@ -1481,6 +1485,7 @@ public String getThreadGroup(ThreadInfo ti) { return map.get(ti.getThreadId()); } + @Override public int compare(ThreadInfo a, ThreadInfo b) { int result = compare(a.getThreadId(), b.getThreadId()); if (result == 0) @@ -1493,6 +1498,7 @@ private static class ThreadSorter extends ThreadSorterBase implements Comparator private static final long serialVersionUID = 5053631350439192685L; + @Override public int compare(Thread a, Thread b) { int result = compare(a.getId(), b.getId()); if (result == 0) @@ -1531,7 +1537,7 @@ public static String dumpThreadInfo(ThreadInfo ti, ThreadGroupMap map) { } sb.append('\n'); StackTraceElement[] stackTrace = ti.getStackTrace(); - for (int i=0; i < stackTrace.length; i++) { + for (int i = 0; i < stackTrace.length; i++) { StackTraceElement ste = stackTrace[i]; sb.append("\tat ").append(ste); sb.append('\n'); @@ -1579,9 +1585,9 @@ public static Collection emptyList() { public static String jsStringEscape(String s) { if (s == null) return null; StringBuilder buf = new StringBuilder(); - for( int i=0; i T defaulted(T value, T defaultValue) { - return value!=null ? value : defaultValue; + return value != null ? value : defaultValue; } /** @@ -1674,6 +1680,7 @@ public static T defaulted(T value, T defaultValue) { doPrintStackTrace(s, t, null, "", new HashSet<>()); return s.toString(); } + private static void doPrintStackTrace(@NonNull StringBuilder s, @NonNull Throwable t, @CheckForNull Throwable higher, @NonNull String prefix, @NonNull Set encountered) { if (!encountered.add(t)) { s.append("\n"); @@ -1682,7 +1689,7 @@ private static void doPrintStackTrace(@NonNull StringBuilder s, @NonNull Throwab if (Util.isOverridden(Throwable.class, t.getClass(), "printStackTrace", PrintWriter.class)) { StringWriter sw = new StringWriter(); t.printStackTrace(new PrintWriter(sw)); - s.append(sw.toString()); + s.append(sw); return; } Throwable lower = t.getCause(); @@ -1746,8 +1753,8 @@ public static void printStackTrace(@CheckForNull Throwable t, @NonNull PrintStre * Minimum 5 rows. */ public static int determineRows(String s) { - if(s==null) return 5; - return Math.max(5,LINE_END.split(s).length); + if (s == null) return 5; + return Math.max(5, LINE_END.split(s).length); } /** @@ -1781,7 +1788,7 @@ public static boolean isAnonymous() { */ public static JellyContext getCurrentJellyContext() { JellyContext context = ExpressionFactory2.CURRENT_CONTEXT.get(); - assert context!=null; + assert context != null; return context; } @@ -1801,8 +1808,8 @@ public static String runScript(Script script) throws JellyTagException { * Warning: do not call this with a {@link RunList}, or you will break lazy loading! */ public static List subList(List base, int maxSize) { - if(maxSize List subList(List base, int maxSize) { public static String joinPath(String... components) { StringBuilder buf = new StringBuilder(); for (String s : components) { - if (s.length()==0) continue; + if (s.length() == 0) continue; - if (buf.length()>0) { - if (buf.charAt(buf.length()-1)!='/') + if (buf.length() > 0) { + if (buf.charAt(buf.length() - 1) != '/') buf.append('/'); - if (s.charAt(0)=='/') s=s.substring(1); + if (s.charAt(0) == '/') s = s.substring(1); } buf.append(s); } @@ -1831,9 +1838,9 @@ public static String joinPath(String... components) { * * @return null in case the action should not be presented to the user. */ - public static @CheckForNull String getActionUrl(String itUrl,Action action) { + public static @CheckForNull String getActionUrl(String itUrl, Action action) { String urlName = action.getUrlName(); - if(urlName==null) return null; // Should not be displayed + if (urlName == null) return null; // Should not be displayed try { if (new URI(urlName).isAbsolute()) { return urlName; @@ -1842,11 +1849,11 @@ public static String joinPath(String... components) { Logger.getLogger(Functions.class.getName()).log(Level.WARNING, "Failed to parse URL for {0}: {1}", new Object[] {action, x}); return null; } - if(urlName.startsWith("/")) - return joinPath(Stapler.getCurrentRequest().getContextPath(),urlName); + if (urlName.startsWith("/")) + return joinPath(Stapler.getCurrentRequest().getContextPath(), urlName); else // relative URL name - return joinPath(Stapler.getCurrentRequest().getContextPath()+'/'+itUrl,urlName); + return joinPath(Stapler.getCurrentRequest().getContextPath() + '/' + itUrl, urlName); } /** @@ -1857,12 +1864,12 @@ public static String joinPath(String... components) { public static String toEmailSafeString(String projectName) { // TODO: escape non-ASCII characters StringBuilder buf = new StringBuilder(projectName.length()); - for( int i=0; i=0) + if (('a' <= ch && ch <= 'z') + || ('A' <= ch && ch <= 'Z') + || ('0' <= ch && ch <= '9') + || "-_.".indexOf(ch) >= 0) buf.append(ch); else buf.append('_'); // escape @@ -1881,9 +1888,9 @@ public String getServerName() { // This makes it work correctly when Hudson runs behind a reverse proxy. String url = Jenkins.get().getRootUrl(); try { - if(url!=null) { + if (url != null) { String host = new URL(url).getHost(); - if(host!=null) + if (host != null) return host; } } catch (MalformedURLException e) { @@ -1900,7 +1907,7 @@ public String getServerName() { */ @Deprecated public String getCheckUrl(String userDefined, Object descriptor, String field) { - if(userDefined!=null || field==null) return userDefined; + if (userDefined != null || field == null) return userDefined; if (descriptor instanceof Descriptor) { Descriptor d = (Descriptor) descriptor; return d.getCheckUrl(field); @@ -1913,13 +1920,13 @@ public String getCheckUrl(String userDefined, Object descriptor, String field) { * @since 1.528 */ public void calcCheckUrl(Map attributes, String userDefined, Object descriptor, String field) { - if(userDefined!=null || field==null) return; + if (userDefined != null || field == null) return; if (descriptor instanceof Descriptor) { Descriptor d = (Descriptor) descriptor; CheckMethod m = d.getCheckMethod(field); - attributes.put("checkUrl",m.toStemUrl()); - attributes.put("checkDependsOn",m.getDependsOn()); + attributes.put("checkUrl", m.toStemUrl()); + attributes.put("checkDependsOn", m.getDependsOn()); } } @@ -1931,8 +1938,8 @@ public void calcCheckUrl(Map attributes, String userDefined, Object descriptor, public boolean hyperlinkMatchesCurrentPage(String href) throws UnsupportedEncodingException { String url = Stapler.getCurrentRequest().getRequestURL().toString(); if (href == null || href.length() <= 1) return ".".equals(href) && url.endsWith("/"); - url = URLDecoder.decode(url,"UTF-8"); - href = URLDecoder.decode(href,"UTF-8"); + url = URLDecoder.decode(url, "UTF-8"); + href = URLDecoder.decode(href, "UTF-8"); if (url.endsWith("/")) url = url.substring(0, url.length() - 1); if (href.endsWith("/")) href = href.substring(0, href.length() - 1); @@ -1947,14 +1954,15 @@ public List singletonList(T t) { * Gets all the {@link PageDecorator}s. */ public static List getPageDecorators() { - // this method may be called to render start up errors, at which point Hudson doesn't exist yet. see HUDSON-3608 - if(Jenkins.getInstanceOrNull()==null) return Collections.emptyList(); + // this method may be called to render start up errors, at which point Hudson doesn't exist yet. see JENKINS-3608 + if (Jenkins.getInstanceOrNull() == null) return Collections.emptyList(); return PageDecorator.all(); } /** * Gets only one {@link SimplePageDecorator}. * @since 2.128 */ + public static SimplePageDecorator getSimplePageDecorator() { return SimplePageDecorator.first(); } @@ -1971,8 +1979,8 @@ public static List> getCloudDescriptors() { * Prepend a prefix only when there's the specified body. */ public String prepend(String prefix, String body) { - if(body!=null && body.length()>0) - return prefix+body; + if (body != null && body.length() > 0) + return prefix + body; return body; } @@ -1997,11 +2005,11 @@ public static Date getCurrentTime() { } public static Locale getCurrentLocale() { - Locale locale=null; + Locale locale = null; StaplerRequest req = Stapler.getCurrentRequest(); - if(req!=null) + if (req != null) locale = req.getLocale(); - if(locale==null) + if (locale == null) locale = Locale.getDefault(); return locale; } @@ -2021,7 +2029,7 @@ public static String generateConsoleAnnotationScriptAndStylesheet() { buf.append(""); } for (ConsoleAnnotationDescriptor d : ConsoleAnnotationDescriptor.all()) { - String path = cp+"/descriptor/"+d.clazz.getName(); + String path = cp + "/descriptor/" + d.clazz.getName(); if (d.hasScript()) buf.append(""); if (d.hasStylesheet()) @@ -2086,7 +2094,7 @@ public String getPasswordValue(Object o) { /* Log a warning if we're in development mode (core or plugin): There's an f:password backed by a non-Secret */ if (req != null && (Boolean.getBoolean("hudson.hpi.run") || Boolean.getBoolean("hudson.Main.development"))) { LOGGER.log(Level.WARNING, () -> " form control in " + getJellyViewsInformationForCurrentRequest() + - " is not backed by hudson.util.Secret. Learn more: https://jenkins.io/redirect/hudson.util.Secret"); + " is not backed by hudson.util.Secret. Learn more: https://www.jenkins.io/redirect/hudson.util.Secret"); } /* Return plain value if it's not a Secret and the escape hatch is set */ @@ -2118,9 +2126,9 @@ private String getJellyViewsInformationForCurrentRequest() { } public List filterDescriptors(Object context, Iterable descriptors) { - return DescriptorVisibilityFilter.apply(context,descriptors); + return DescriptorVisibilityFilter.apply(context, descriptors); } - + /** * Returns true if we are running unit tests. */ @@ -2159,13 +2167,13 @@ public static boolean isWipeOutPermissionEnabled() { } public static String createRenderOnDemandProxy(JellyContext context, String attributesToCapture) { - return Stapler.getCurrentRequest().createJavaScriptProxy(new RenderOnDemandClosure(context,attributesToCapture)); + return Stapler.getCurrentRequest().createJavaScriptProxy(new RenderOnDemandClosure(context, attributesToCapture)); } public static String getCurrentDescriptorByNameUrl() { return Descriptor.getCurrentDescriptorByNameUrl(); } - + public static String setCurrentDescriptorByNameUrl(String value) { String o = getCurrentDescriptorByNameUrl(); Stapler.getCurrentRequest().setAttribute("currentDescriptorByNameUrl", value); @@ -2190,7 +2198,7 @@ public static List getRequestHeaders(String name) { * Used for arguments to internationalized expressions to avoid escape */ public static Object rawHtml(Object o) { - return o==null ? null : new RawHtmlArgument(o); + return o == null ? null : new RawHtmlArgument(o); } public static ArrayList getCLICommands() { @@ -2216,30 +2224,30 @@ public static String getAvatar(User user, String avatarSize) { */ @Deprecated public String getUserAvatar(User user, String avatarSize) { - return getAvatar(user,avatarSize); + return getAvatar(user, avatarSize); } - - + + /** * Returns human readable information about file size - * + * * @param size file size in bytes * @return file size in appropriate unit */ - public static String humanReadableByteSize(long size){ + public static String humanReadableByteSize(long size) { String measure = "B"; - if(size < 1024){ + if (size < 1024) { return size + " " + measure; } double number = size; - if(number>=1024){ - number = number/1024; + if (number >= 1024) { + number = number / 1024; measure = "KB"; - if(number>=1024){ - number = number/1024; + if (number >= 1024) { + number = number / 1024; measure = "MB"; - if(number>=1024){ - number=number/1024; + if (number >= 1024) { + number = number / 1024; measure = "GB"; } } @@ -2272,19 +2280,10 @@ public static String breakableString(final String plain) { */ public static void advertiseHeaders(HttpServletResponse rsp) { Jenkins j = Jenkins.getInstanceOrNull(); - if (j!=null) { - rsp.setHeader("X-Hudson","1.395"); + if (j != null) { + rsp.setHeader("X-Hudson", "1.395"); rsp.setHeader("X-Jenkins", Jenkins.VERSION); rsp.setHeader("X-Jenkins-Session", Jenkins.SESSION_HASH); - - TcpSlaveAgentListener tal = j.tcpSlaveAgentListener; - if (tal != null) { // headers used only by deprecated Remoting-based CLI - int p = tal.getAdvertisedPort(); - rsp.setIntHeader("X-Hudson-CLI-Port", p); - rsp.setIntHeader("X-Jenkins-CLI-Port", p); - rsp.setIntHeader("X-Jenkins-CLI2-Port", p); - rsp.setHeader("X-Jenkins-CLI-Host", TcpSlaveAgentListener.CLI_HOST_NAME); - } } } @@ -2296,4 +2295,92 @@ public static boolean isContextMenuVisible(Action a) { return true; } } + + @Restricted(NoExternalUse.class) + public static Icon tryGetIcon(String iconGuess) { + // Jenkins Symbols don't have metadata so return null + if (iconGuess == null || iconGuess.startsWith("symbol-")) { + return null; + } + + StaplerRequest currentRequest = Stapler.getCurrentRequest(); + currentRequest.getWebApp().getDispatchValidator().allowDispatch(currentRequest, Stapler.getCurrentResponse()); + Icon iconMetadata = IconSet.icons.getIconByClassSpec(iconGuess); + + if (iconMetadata == null) { + // Icon could be provided as a simple iconFileName e.g. "settings.png" + iconMetadata = IconSet.icons.getIconByClassSpec(IconSet.toNormalizedIconNameClass(iconGuess) + " icon-md"); + } + + if (iconMetadata == null) { + // Icon could be provided as an absolute iconFileName e.g. "/plugin/foo/abc.png" + iconMetadata = IconSet.icons.getIconByUrl(iconGuess); + } + + return iconMetadata; + } + + @Restricted(NoExternalUse.class) + public static String extractPluginNameFromIconSrc(String iconSrc) { + if (iconSrc == null) { + return ""; + } + + if (!iconSrc.contains("plugin-")) { + return ""; + } + + String[] arr = iconSrc.split(" "); + for (String element : arr) { + if (element.startsWith("plugin-")) { + return element.replace("plugin-", ""); + } + } + + return ""; + } + + @Restricted(NoExternalUse.class) + public static String tryGetIconPath(String iconGuess, JellyContext context) { + if (iconGuess == null) { + return null; + } + + if (iconGuess.startsWith("symbol-")) { + return iconGuess; + } + + StaplerRequest currentRequest = Stapler.getCurrentRequest(); + currentRequest.getWebApp().getDispatchValidator().allowDispatch(currentRequest, Stapler.getCurrentResponse()); + String rootURL = currentRequest.getContextPath(); + Icon iconMetadata = tryGetIcon(iconGuess); + String iconSource = null; + + if (iconMetadata != null) { + iconSource = iconMetadata.getQualifiedUrl(context); + } + + if (iconMetadata == null) { + if (!iconGuess.startsWith("/") && !iconGuess.startsWith("http")) { + iconGuess = "/" + iconGuess; + } + + iconSource = rootURL + (iconGuess.startsWith("/images/") || iconGuess.startsWith("/plugin/") ? getResourcePath() : "") + iconGuess; + } + + if (iconMetadata != null && iconMetadata.getClassSpec() != null) { + String translatedIcon = IconSet.tryTranslateTangoIconToSymbol(iconMetadata.getClassSpec()); + if (translatedIcon != null) { + return translatedIcon; + } + } + + return iconSource; + } + + @SuppressFBWarnings(value = "PREDICTABLE_RANDOM", justification = "True randomness isn't necessary for form item IDs") + @Restricted(NoExternalUse.class) + public static String generateItemId() { + return String.valueOf(Math.floor(Math.random() * 3000)); + } } diff --git a/core/src/main/java/hudson/Indenter.java b/core/src/main/java/hudson/Indenter.java index aa4348b57a9b..90a1d403e225 100644 --- a/core/src/main/java/hudson/Indenter.java +++ b/core/src/main/java/hudson/Indenter.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson; import hudson.model.Job; @@ -34,12 +35,12 @@ public abstract class Indenter { protected abstract int getNestLevel(J job); public final String getCss(J job) { - return "padding-left: "+getNestLevel(job)*2+"em"; + return "padding-left: " + getNestLevel(job) * 2 + "em"; } public final String getRelativeShift(J job) { int i = getNestLevel(job); - if(i==0) return null; - return "position:relative; left: "+ i *2+"em"; + if (i == 0) return null; + return "position:relative; left: " + i * 2 + "em"; } } diff --git a/core/src/main/java/hudson/Launcher.java b/core/src/main/java/hudson/Launcher.java index 70aa04301884..6ea7375ff5a9 100644 --- a/core/src/main/java/hudson/Launcher.java +++ b/core/src/main/java/hudson/Launcher.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Stephen Connolly, CloudBees, Inc. - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,34 +21,29 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson; +import static org.apache.commons.io.output.NullOutputStream.NULL_OUTPUT_STREAM; + +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.Proc.LocalProc; +import hudson.Proc.ProcWithJenkins23271Patch; import hudson.model.Computer; -import jenkins.util.MemoryReductionUtil; +import hudson.model.Node; import hudson.model.Run; -import hudson.util.QuotedStringTokenizer; -import jenkins.model.Jenkins; import hudson.model.TaskListener; -import hudson.model.Node; import hudson.remoting.Channel; import hudson.remoting.Pipe; import hudson.remoting.RemoteInputStream; import hudson.remoting.RemoteOutputStream; import hudson.remoting.VirtualChannel; -import hudson.util.StreamCopyThread; import hudson.util.ArgumentListBuilder; import hudson.util.ProcessTree; -import jenkins.security.MasterToSlaveCallable; -import jenkins.tasks.filters.EnvVarsFilterRuleWrapper; -import jenkins.tasks.filters.EnvVarsFilterLocalRule; -import jenkins.tasks.filters.EnvVarsFilterableBuilder; -import org.apache.commons.io.input.NullInputStream; -import org.kohsuke.accmod.Restricted; -import org.kohsuke.accmod.restrictions.Beta; -import org.kohsuke.accmod.restrictions.NoExternalUse; - -import edu.umd.cs.findbugs.annotations.CheckForNull; +import hudson.util.QuotedStringTokenizer; +import hudson.util.StreamCopyThread; import java.io.BufferedOutputStream; import java.io.File; import java.io.IOException; @@ -56,16 +51,22 @@ import java.io.InterruptedIOException; import java.io.OutputStream; import java.io.Serializable; +import java.util.ArrayList; import java.util.Arrays; -import java.util.Map; import java.util.List; -import java.util.ArrayList; +import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; - -import static org.apache.commons.io.output.NullOutputStream.NULL_OUTPUT_STREAM; -import hudson.Proc.ProcWithJenkins23271Patch; -import edu.umd.cs.findbugs.annotations.NonNull; +import jenkins.model.Jenkins; +import jenkins.security.MasterToSlaveCallable; +import jenkins.tasks.filters.EnvVarsFilterLocalRule; +import jenkins.tasks.filters.EnvVarsFilterRuleWrapper; +import jenkins.tasks.filters.EnvVarsFilterableBuilder; +import jenkins.util.MemoryReductionUtil; +import org.apache.commons.io.input.NullInputStream; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.Beta; +import org.kohsuke.accmod.restrictions.NoExternalUse; /** * Starts a process. @@ -85,7 +86,7 @@ * * * @author Kohsuke Kawaguchi - * @see FilePath#createLauncher(TaskListener) + * @see FilePath#createLauncher(TaskListener) */ public abstract class Launcher { @@ -98,7 +99,7 @@ public abstract class Launcher { @Restricted(Beta.class) protected EnvVarsFilterRuleWrapper envVarsFilterRuleWrapper; - public Launcher(@NonNull TaskListener listener, @CheckForNull VirtualChannel channel) { + protected Launcher(@NonNull TaskListener listener, @CheckForNull VirtualChannel channel) { this.listener = listener; this.channel = channel; } @@ -119,7 +120,7 @@ protected Launcher(@NonNull Launcher launcher) { * @since 2.246 */ @Restricted(Beta.class) - public void prepareFilterRules(@CheckForNull Run run, @NonNull EnvVarsFilterableBuilder builder){ + public void prepareFilterRules(@CheckForNull Run run, @NonNull EnvVarsFilterableBuilder builder) { List specificRuleList = builder.buildEnvVarsFilterRules(); EnvVarsFilterRuleWrapper ruleWrapper = EnvVarsFilterRuleWrapper.createRuleWrapper(run, builder, this, specificRuleList); this.setEnvVarsFilterRuleWrapper(ruleWrapper); @@ -136,7 +137,7 @@ protected void setEnvVarsFilterRuleWrapper(EnvVarsFilterRuleWrapper envVarsFilte * @return * {@code null} if the target node is not configured to support this. * this is a transitional measure. - * Note that a launcher for the master is always non-null. + * Note that a launcher for the built-in node is always non-null. */ @CheckForNull public VirtualChannel getChannel() { @@ -146,7 +147,7 @@ public VirtualChannel getChannel() { /** * Gets the {@link TaskListener} that this launcher uses to * report the commands that it's executing. - * + * * @return Task listener */ @NonNull @@ -173,8 +174,8 @@ public TaskListener getListener() { @Deprecated @CheckForNull public Computer getComputer() { - for( Computer c : Jenkins.get().getComputers() ) - if(c.getChannel()==channel) + for (Computer c : Jenkins.get().getComputers()) + if (c.getChannel() == channel) return c; return null; } @@ -289,7 +290,7 @@ public boolean quiet() { /** * Sets the current directory. - * + * * @param workDir Work directory to be used. * If {@code null}, the default/current directory will be used by the process starter * @return {@code this} @@ -314,8 +315,8 @@ public FilePath pwd() { /** * Sets STDOUT destination. - * - * @param out Output stream. + * + * @param out Output stream. * Use {@code null} to send STDOUT to {@code /dev/null}. * @return {@code this} */ @@ -327,7 +328,7 @@ public ProcStarter stdout(@CheckForNull OutputStream out) { /** * Sends the stdout to the given {@link TaskListener}. - * + * * @param out Task listener (must be safely remotable) * @return {@code this} */ @@ -339,7 +340,7 @@ public ProcStarter stdout(@NonNull TaskListener out) { /** * Gets current STDOUT destination. - * + * * @return STDOUT output stream. {@code null} if STDOUT is suppressed or undefined. */ @CheckForNull @@ -358,7 +359,7 @@ public ProcStarter stderr(@CheckForNull OutputStream err) { /** * Gets current STDERR destination. - * + * * @return STDERR output stream. {@code null} if suppressed or undefined. */ @CheckForNull @@ -369,7 +370,7 @@ public OutputStream stderr() { /** * Controls where the stdin of the process comes from. * By default, {@code /dev/null}. - * + * * @return {@code this} */ @NonNull @@ -380,7 +381,7 @@ public ProcStarter stdin(@CheckForNull InputStream in) { /** * Gets current STDIN destination. - * + * * @return STDIN output stream. {@code null} if suppressed or undefined. */ @CheckForNull @@ -395,7 +396,7 @@ public InputStream stdin() { * In addition to what the current process * is inherited (if this is going to be launched from a agent agent, that * becomes the "current" process), these variables will be also set. - * + * * @param overrides Environment variables to be overridden * @return {@code this} */ @@ -407,7 +408,7 @@ public ProcStarter envs(@NonNull Map overrides) { /** * @param overrides * List of "VAR=VALUE". See {@link #envs(Map)} for the semantics. - * + * * @return {@code this} */ public ProcStarter envs(@CheckForNull String... overrides) { @@ -425,7 +426,7 @@ public ProcStarter envs(@CheckForNull String... overrides) { /** * Gets a list of environment variables to be set. * Returns an empty array if envs field has not been initialized. - * + * * @return If initialized, returns a copy of internal envs array. Otherwise - a new empty array. */ @NonNull @@ -470,7 +471,7 @@ public ProcStarter readStderr() { * Indicates that the caller will directly write to the child process {@link #stdin()} via {@link Proc#getStdin()}. * (Whereas by default you call {@link #stdin(InputStream)} * and let Jenkins pump your {@link InputStream} of choosing to stdin.) - * + * * @return {@code this} * @since 1.399 */ @@ -486,7 +487,7 @@ public ProcStarter writeStdin() { * @since 2.246 */ @Restricted(Beta.class) - public ProcStarter buildStep(EnvVarsFilterableBuilder envVarsFilterableBuilder){ + public ProcStarter buildStep(EnvVarsFilterableBuilder envVarsFilterableBuilder) { this.envVarsFilterableBuilder = envVarsFilterableBuilder; return this; } @@ -518,7 +519,7 @@ public int join() throws IOException, InterruptedException { // The logging around procHolderForJoin prevents the preliminary object deallocation we saw in JENKINS-23271 final Proc procHolderForJoin = start(); LOGGER.log(Level.FINER, "Started the process {0}", procHolderForJoin); - + if (procHolderForJoin instanceof ProcWithJenkins23271Patch) { return procHolderForJoin.join(); } else { @@ -571,8 +572,8 @@ public final ProcStarter launch() { * Use {@link #launch()} and its associated builder pattern */ @Deprecated - public final Proc launch(String cmd, Map env, OutputStream out, FilePath workDir) throws IOException { - return launch(cmd,Util.mapToEnv(env),out,workDir); + public final Proc launch(String cmd, Map env, OutputStream out, FilePath workDir) throws IOException { + return launch(cmd, Util.mapToEnv(env), out, workDir); } /** @@ -642,8 +643,8 @@ public final Proc launch(String[] cmd, boolean[] mask, Map env, * Use {@link #launch()} and its associated builder pattern */ @Deprecated - public final Proc launch(String cmd,String[] env,OutputStream out, FilePath workDir) throws IOException { - return launch(Util.tokenize(cmd),env,out,workDir); + public final Proc launch(String cmd, String[] env, OutputStream out, FilePath workDir) throws IOException { + return launch(Util.tokenize(cmd), env, out, workDir); } /** @@ -762,7 +763,7 @@ public Proc launch(String[] cmd, boolean[] mask, String[] env, InputStream in, O *

* When the returned channel is terminated, the process will be killed. * - * @param cmd + * @param cmd * The commands. * @param out * Where the stderr from the launched process will be sent. @@ -774,20 +775,20 @@ public Proc launch(String[] cmd, boolean[] mask, String[] env, InputStream in, O * is inherited (if this is going to be launched from an agent, that * becomes the "current" process), these variables will be also set. */ - public abstract Channel launchChannel(@NonNull String[] cmd, @NonNull OutputStream out, - @CheckForNull FilePath workDir, @NonNull Map envVars) throws IOException, InterruptedException; + public abstract Channel launchChannel(@NonNull String[] cmd, @NonNull OutputStream out, + @CheckForNull FilePath workDir, @NonNull Map envVars) throws IOException, InterruptedException; /** * Returns true if this {@link Launcher} is going to launch on Unix. */ public boolean isUnix() { - return File.pathSeparatorChar==':'; + return File.pathSeparatorChar == ':'; } /** * Calls {@link ProcessTree#killAll(Map)} to kill processes. */ - public abstract void kill(Map modelEnvVars) throws IOException, InterruptedException; + public abstract void kill(Map modelEnvVars) throws IOException, InterruptedException; /** * Prints out the command line to the listener so that users know what we are doing. @@ -796,7 +797,7 @@ protected final void printCommandLine(@NonNull String[] cmd, @CheckForNull FileP StringBuilder buf = new StringBuilder(); if (workDir != null) { buf.append('['); - if(showFullPath) + if (showFullPath) buf.append(workDir.getRemote()); else buf.append(workDir.getRemote().replaceFirst("^.+[/\\\\]", "")); @@ -805,15 +806,15 @@ protected final void printCommandLine(@NonNull String[] cmd, @CheckForNull FileP buf.append('$'); for (String c : cmd) { buf.append(' '); - if(c.indexOf(' ')>=0) { - if(c.indexOf('"')>=0) + if (c.indexOf(' ') >= 0) { + if (c.indexOf('"') >= 0) buf.append('\'').append(c).append('\''); else buf.append('"').append(c).append('"'); } else buf.append(c); } - listener.getLogger().println(buf.toString()); + listener.getLogger().println(buf); listener.getLogger().flush(); } @@ -827,11 +828,11 @@ protected final void printCommandLine(@NonNull String[] cmd, @CheckForNull FileP * @param workDir The work dir. */ protected final void maskedPrintCommandLine(@NonNull List cmd, @CheckForNull boolean[] mask, @CheckForNull FilePath workDir) { - if(mask==null) { - printCommandLine(cmd.toArray(new String[0]),workDir); + if (mask == null) { + printCommandLine(cmd.toArray(new String[0]), workDir); return; } - + assert mask.length == cmd.size(); final String[] masked = new String[cmd.size()]; for (int i = 0; i < cmd.size(); i++) { @@ -843,14 +844,14 @@ protected final void maskedPrintCommandLine(@NonNull List cmd, @CheckFor } printCommandLine(masked, workDir); } - + protected final void maskedPrintCommandLine(@NonNull String[] cmd, @NonNull boolean[] mask, @CheckForNull FilePath workDir) { - maskedPrintCommandLine(Arrays.asList(cmd),mask,workDir); + maskedPrintCommandLine(Arrays.asList(cmd), mask, workDir); } /** * Returns a decorated {@link Launcher} for the given node. - * + * * @param node Node for which this launcher is created. * @return Decorated instance of the Launcher. */ @@ -858,7 +859,7 @@ protected final void maskedPrintCommandLine(@NonNull String[] cmd, @NonNull bool public final Launcher decorateFor(@NonNull Node node) { Launcher l = this; for (LauncherDecorator d : LauncherDecorator.all()) - l = d.decorate(l,node); + l = d.decorate(l, node); return l; } @@ -877,10 +878,10 @@ public final Launcher decorateByPrefix(final String... prefix) { public boolean isUnix() { return outer.isUnix(); } - + @Override public Proc launch(ProcStarter starter) throws IOException { - starter.commands.addAll(0,Arrays.asList(prefix)); + starter.commands.addAll(0, Arrays.asList(prefix)); boolean[] masks = starter.masks; if (masks != null) { starter.masks = prefix(masks); @@ -890,7 +891,7 @@ public Proc launch(ProcStarter starter) throws IOException { @Override public Channel launchChannel(String[] cmd, OutputStream out, FilePath workDir, Map envVars) throws IOException, InterruptedException { - return outer.launchChannel(prefix(cmd),out,workDir,envVars); + return outer.launchChannel(prefix(cmd), out, workDir, envVars); } @Override @@ -899,15 +900,15 @@ public void kill(Map modelEnvVars) throws IOException, Interrupt } private String[] prefix(@NonNull String[] args) { - String[] newArgs = new String[args.length+prefix.length]; - System.arraycopy(prefix,0,newArgs,0,prefix.length); - System.arraycopy(args,0,newArgs,prefix.length,args.length); + String[] newArgs = new String[args.length + prefix.length]; + System.arraycopy(prefix, 0, newArgs, 0, prefix.length); + System.arraycopy(args, 0, newArgs, prefix.length, args.length); return newArgs; } private boolean[] prefix(@NonNull boolean[] args) { - boolean[] newArgs = new boolean[args.length+prefix.length]; - System.arraycopy(args,0,newArgs,prefix.length,args.length); + boolean[] newArgs = new boolean[args.length + prefix.length]; + System.arraycopy(args, 0, newArgs, prefix.length, args.length); return newArgs; } }; @@ -935,7 +936,7 @@ public boolean isUnix() { @Override public Proc launch(ProcStarter starter) throws IOException { EnvVars e = new EnvVars(env); - if (starter.envs!=null) { + if (starter.envs != null) { for (String env : starter.envs) { e.addLine(env); } @@ -948,7 +949,7 @@ public Proc launch(ProcStarter starter) throws IOException { public Channel launchChannel(String[] cmd, OutputStream out, FilePath workDir, Map envVars) throws IOException, InterruptedException { EnvVars e = new EnvVars(env); e.putAll(envVars); - return outer.launchChannel(cmd,out,workDir,e); + return outer.launchChannel(cmd, out, workDir, e); } @Override @@ -986,26 +987,27 @@ public Proc launch(ProcStarter ps) throws IOException { // replace variables in command line String[] jobCmd = new String[ps.commands.size()]; - for ( int idx = 0 ; idx < jobCmd.length; idx++ ) - jobCmd[idx] = jobEnv.expand(ps.commands.get(idx)); + for (int idx = 0; idx < jobCmd.length; idx++) + jobCmd[idx] = jobEnv.expand(ps.commands.get(idx)); return new LocalProc(jobCmd, Util.mapToEnv(jobEnv), - ps.reverseStdin ?LocalProc.SELFPUMP_INPUT:ps.stdin, - ps.reverseStdout?LocalProc.SELFPUMP_OUTPUT:ps.stdout, - ps.reverseStderr?LocalProc.SELFPUMP_OUTPUT:ps.stderr, + ps.reverseStdin ? LocalProc.SELFPUMP_INPUT : ps.stdin, + ps.reverseStdout ? LocalProc.SELFPUMP_OUTPUT : ps.stdout, + ps.reverseStderr ? LocalProc.SELFPUMP_OUTPUT : ps.stderr, toFile(ps.pwd)); } private File toFile(FilePath f) { - return f==null ? null : new File(f.getRemote()); + return f == null ? null : new File(f.getRemote()); } - public Channel launchChannel(String[] cmd, OutputStream out, FilePath workDir, Map envVars) throws IOException { + @Override + public Channel launchChannel(String[] cmd, OutputStream out, FilePath workDir, Map envVars) throws IOException { printCommandLine(cmd, workDir); ProcessBuilder pb = new ProcessBuilder(cmd); pb.directory(toFile(workDir)); - if (envVars!=null) pb.environment().putAll(envVars); + if (envVars != null) pb.environment().putAll(envVars); return launchChannel(out, pb); } @@ -1025,10 +1027,10 @@ public Channel launchChannel(OutputStream out, ProcessBuilder pb) throws IOExcep final Process proc = pb.start(); - final Thread t2 = new StreamCopyThread(pb.command()+": stderr copier", proc.getErrorStream(), out); + final Thread t2 = new StreamCopyThread(pb.command() + ": stderr copier", proc.getErrorStream(), out); t2.start(); - return new Channel("locally launched channel on "+ pb.command(), + return new Channel("locally launched channel on " + pb.command(), Computer.threadPoolForRemoting, proc.getInputStream(), proc.getOutputStream(), out) { /** @@ -1039,7 +1041,7 @@ public synchronized void terminate(IOException e) { super.terminate(e); ProcessTree pt = ProcessTree.get(); try { - pt.killAll(proc,cookie); + pt.killAll(proc, cookie); } catch (InterruptedException x) { LOGGER.log(Level.INFO, "Interrupted", x); } @@ -1105,13 +1107,14 @@ public VirtualChannel getChannel() { return super.getChannel(); } + @Override public Proc launch(ProcStarter ps) throws IOException { final OutputStream out = ps.stdout == null || ps.stdoutListener != null ? null : new RemoteOutputStream(new CloseProofOutputStream(ps.stdout)); - final OutputStream err = ps.stderr==null ? null : new RemoteOutputStream(new CloseProofOutputStream(ps.stderr)); - final InputStream in = (ps.stdin==null || ps.stdin==NULL_INPUT_STREAM) ? null : new RemoteInputStream(ps.stdin,false); - + final OutputStream err = ps.stderr == null ? null : new RemoteOutputStream(new CloseProofOutputStream(ps.stderr)); + final InputStream in = ps.stdin == null || ps.stdin == NULL_INPUT_STREAM ? null : new RemoteInputStream(ps.stdin, false); + final FilePath psPwd = ps.pwd; - final String workDir = psPwd==null ? null : psPwd.getRemote(); + final String workDir = psPwd == null ? null : psPwd.getRemote(); try { RemoteLaunchCallable remote = new RemoteLaunchCallable(ps.commands, ps.masks, ps.envs, in, ps.reverseStdin, out, ps.reverseStdout, err, ps.reverseStderr, ps.quiet, workDir, listener, ps.stdoutListener); @@ -1120,20 +1123,20 @@ public Proc launch(ProcStarter ps) throws IOException { envVarsFilterRuleWrapper = null; return new ProcImpl(getChannel().call(remote)); } catch (InterruptedException e) { - throw (IOException)new InterruptedIOException().initCause(e); + throw (IOException) new InterruptedIOException().initCause(e); } } @Override - public Channel launchChannel(String[] cmd, OutputStream err, FilePath _workDir, Map envOverrides) throws IOException, InterruptedException { + public Channel launchChannel(String[] cmd, OutputStream err, FilePath _workDir, Map envOverrides) throws IOException, InterruptedException { printCommandLine(cmd, _workDir); Pipe out = Pipe.createRemoteToLocal(); - final String workDir = _workDir==null ? null : _workDir.getRemote(); + final String workDir = _workDir == null ? null : _workDir.getRemote(); OutputStream os = getChannel().call(new RemoteChannelLaunchCallable(cmd, out, err, workDir, envOverrides)); - return new Channel("remotely launched channel on "+channel, + return new Channel("remotely launched channel on " + channel, Computer.threadPoolForRemoting, out.getIn(), new BufferedOutputStream(os)); } @@ -1143,7 +1146,7 @@ public boolean isUnix() { } @Override - public void kill(final Map modelEnvVars) throws IOException, InterruptedException { + public void kill(final Map modelEnvVars) throws IOException, InterruptedException { getChannel().call(new KillTask(modelEnvVars)); } @@ -1152,13 +1155,14 @@ public String toString() { return "RemoteLauncher[" + getChannel() + "]"; } - private static final class KillTask extends MasterToSlaveCallable { + private static final class KillTask extends MasterToSlaveCallable { private final Map modelEnvVars; KillTask(Map modelEnvVars) { this.modelEnvVars = modelEnvVars; } + @Override public Void call() throws RuntimeException { try { ProcessTree.get().killAll(modelEnvVars); @@ -1227,14 +1231,14 @@ public OutputStream getStdin() { } } } - + /** - * A launcher which delegates to a provided inner launcher. + * A launcher which delegates to a provided inner launcher. * Allows subclasses to only implement methods they want to override. - * Originally, this launcher has been implemented in + * Originally, this launcher has been implemented in * * Custom Tools Plugin. - * + * * @author rcampbell * @author Oleg Nenashev, Synopsys Inc. * @since 1.568 @@ -1298,9 +1302,9 @@ public VirtualChannel getChannel() { @Override public Proc launch(String[] cmd, String[] env, InputStream in, OutputStream out, FilePath workDir) throws IOException { - return inner.launch(cmd, env, in, out, workDir); + return inner.launch(cmd, env, in, out, workDir); } - + /** * Gets nested launcher. * @return Inner launcher @@ -1308,12 +1312,12 @@ public Proc launch(String[] cmd, String[] env, InputStream in, OutputStream out, @NonNull public Launcher getInner() { return inner; - } + } } public static class IOTriplet implements Serializable { @CheckForNull - InputStream stdout,stderr; + InputStream stdout, stderr; @CheckForNull OutputStream stdin; private static final long serialVersionUID = 1L; @@ -1321,16 +1325,19 @@ public static class IOTriplet implements Serializable { /** * Remoting interface of a remote process */ + public interface RemoteProcess { int join() throws InterruptedException, IOException; + void kill() throws IOException, InterruptedException; + boolean isAlive() throws IOException, InterruptedException; - + @NonNull IOTriplet getIOtriplet(); } - private static class RemoteLaunchCallable extends MasterToSlaveCallable { + private static class RemoteLaunchCallable extends MasterToSlaveCallable { private final @NonNull List cmd; private final @CheckForNull boolean[] masks; private final @CheckForNull String[] env; @@ -1347,8 +1354,8 @@ private static class RemoteLaunchCallable extends MasterToSlaveCallable cmd, @CheckForNull boolean[] masks, @CheckForNull String[] env, @CheckForNull InputStream in, boolean reverseStdin, - @CheckForNull OutputStream out, boolean reverseStdout, - @CheckForNull OutputStream err, boolean reverseStderr, + @CheckForNull OutputStream out, boolean reverseStdout, + @CheckForNull OutputStream err, boolean reverseStderr, boolean quiet, @CheckForNull String workDir, @NonNull TaskListener listener, @CheckForNull TaskListener stdoutListener) { this.cmd = new ArrayList<>(cmd); this.masks = masks; @@ -1370,6 +1377,7 @@ public void setEnvVarsFilterRuleWrapper(EnvVarsFilterRuleWrapper envVarsFilterRu this.envVarsFilterRuleWrapper = envVarsFilterRuleWrapper; } + @Override public RemoteProcess call() throws IOException { final Channel channel = getOpenChannelOrFail(); LocalLauncher localLauncher = new LocalLauncher(listener); @@ -1382,14 +1390,15 @@ public RemoteProcess call() throws IOException { } else { ps.stdout(out); } - if(workDir!=null) ps.pwd(workDir); + if (workDir != null) ps.pwd(workDir); if (reverseStdin) ps.writeStdin(); if (reverseStdout) ps.readStdout(); if (reverseStderr) ps.readStderr(); final Proc p = ps.start(); - return channel.export(RemoteProcess.class,new RemoteProcess() { + return channel.export(RemoteProcess.class, new RemoteProcess() { + @Override public int join() throws InterruptedException, IOException { try { return p.join(); @@ -1407,14 +1416,17 @@ public int join() throws InterruptedException, IOException { } } + @Override public void kill() throws IOException, InterruptedException { p.kill(); } + @Override public boolean isAlive() throws IOException, InterruptedException { return p.isAlive(); } + @Override public IOTriplet getIOtriplet() { IOTriplet r = new IOTriplet(); if (reverseStdout) r.stdout = new RemoteInputStream(p.getStdout()); @@ -1428,7 +1440,7 @@ public IOTriplet getIOtriplet() { private static final long serialVersionUID = 1L; } - private static class RemoteChannelLaunchCallable extends MasterToSlaveCallable { + private static class RemoteChannelLaunchCallable extends MasterToSlaveCallable { @NonNull private final String[] cmd; @NonNull @@ -1438,10 +1450,10 @@ private static class RemoteChannelLaunchCallable extends MasterToSlaveCallable envOverrides; + private final Map envOverrides; - RemoteChannelLaunchCallable(@NonNull String[] cmd, @NonNull Pipe out, @NonNull OutputStream err, - @CheckForNull String workDir, @NonNull Map envOverrides) { + RemoteChannelLaunchCallable(@NonNull String[] cmd, @NonNull Pipe out, @NonNull OutputStream err, + @CheckForNull String workDir, @NonNull Map envOverrides) { this.cmd = cmd; this.out = out; this.err = new RemoteOutputStream(err); @@ -1449,15 +1461,16 @@ private static class RemoteChannelLaunchCallable extends MasterToSlaveCallable cmdLines = Arrays.asList(cmd); - new StreamCopyThread("stdin copier for remote agent on "+cmdLines, + new StreamCopyThread("stdin copier for remote agent on " + cmdLines, p.getInputStream(), out.getOut()).start(); - new StreamCopyThread("stderr copier for remote agent on "+cmdLines, + new StreamCopyThread("stderr copier for remote agent on " + cmdLines, p.getErrorStream(), err).start(); // TODO: don't we need to join? @@ -1474,10 +1487,10 @@ public OutputStream call() throws IOException { private static EnvVars inherit(@CheckForNull String[] env) { // convert String[] to Map first EnvVars m = new EnvVars(); - if(env!=null) { + if (env != null) { for (String e : env) { int index = e.indexOf('='); - m.put(e.substring(0,index), e.substring(index+1)); + m.put(e.substring(0, index), e.substring(index + 1)); } } // then do the inheritance @@ -1487,15 +1500,16 @@ private static EnvVars inherit(@CheckForNull String[] env) { /** * Expands the list of environment variables by inheriting current env variables. */ - private static EnvVars inherit(@NonNull Map overrides) { + private static EnvVars inherit(@NonNull Map overrides) { EnvVars m = new EnvVars(EnvVars.masterEnvVars); m.overrideExpandingAll(overrides); return m; } - + /** * Debug option to display full current path instead of just the last token. */ + @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "for debugging") public static boolean showFullPath = false; private static final NullInputStream NULL_INPUT_STREAM = new NullInputStream(0); diff --git a/core/src/main/java/hudson/LauncherDecorator.java b/core/src/main/java/hudson/LauncherDecorator.java index 372f8200b9ef..79001e7f7ac3 100644 --- a/core/src/main/java/hudson/LauncherDecorator.java +++ b/core/src/main/java/hudson/LauncherDecorator.java @@ -1,12 +1,12 @@ package hudson; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.model.AbstractBuild; import hudson.model.BuildListener; -import hudson.model.Node; import hudson.model.Executor; +import hudson.model.Node; import hudson.model.TaskListener; import hudson.tasks.BuildWrapper; -import edu.umd.cs.findbugs.annotations.NonNull; /** * Decorates {@link Launcher} so that one can intercept executions of commands diff --git a/core/src/main/java/hudson/LocalPluginManager.java b/core/src/main/java/hudson/LocalPluginManager.java index 4bfccf9e40a8..d1fcfd678e3a 100644 --- a/core/src/main/java/hudson/LocalPluginManager.java +++ b/core/src/main/java/hudson/LocalPluginManager.java @@ -24,16 +24,15 @@ package hudson; -import jenkins.util.SystemProperties; -import jenkins.model.Jenkins; - import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.NonNull; -import javax.servlet.ServletContext; import java.io.File; import java.util.Collection; import java.util.Collections; import java.util.logging.Logger; +import javax.servlet.ServletContext; +import jenkins.model.Jenkins; +import jenkins.util.SystemProperties; /** * Default implementation of {@link PluginManager}. @@ -47,7 +46,7 @@ public class LocalPluginManager extends PluginManager { * @param rootDir Jenkins home directory. */ public LocalPluginManager(@CheckForNull ServletContext context, @NonNull File rootDir) { - super(context, new File(rootDir,"plugins")); + super(context, new File(rootDir, "plugins")); } /** diff --git a/core/src/main/java/hudson/Lookup.java b/core/src/main/java/hudson/Lookup.java index b0b40ba89151..ba051f72a633 100644 --- a/core/src/main/java/hudson/Lookup.java +++ b/core/src/main/java/hudson/Lookup.java @@ -32,14 +32,14 @@ * @author Kohsuke Kawaguchi */ public class Lookup { - private final ConcurrentHashMap data = new ConcurrentHashMap<>(); + private final ConcurrentHashMap data = new ConcurrentHashMap<>(); public T get(Class type) { return type.cast(data.get(type)); } public T set(Class type, T instance) { - return type.cast(data.put(type,instance)); + return type.cast(data.put(type, instance)); } /** @@ -51,7 +51,7 @@ public T set(Class type, T instance) { */ public T setIfNull(Class type, T instance) { Object o = data.putIfAbsent(type, instance); - if (o!=null) return type.cast(o); + if (o != null) return type.cast(o); return instance; } } diff --git a/core/src/main/java/hudson/Main.java b/core/src/main/java/hudson/Main.java index 96db6cd7ae34..625fef0c52ee 100644 --- a/core/src/main/java/hudson/Main.java +++ b/core/src/main/java/hudson/Main.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,30 +21,31 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.InvalidPathException; -import jenkins.util.SystemProperties; +import com.thoughtworks.xstream.core.util.Base64Encoder; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.util.DualOutputStream; import hudson.util.EncodingStream; -import com.thoughtworks.xstream.core.util.Base64Encoder; import hudson.util.IOUtils; - import java.io.File; import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.net.HttpRetryException; import java.net.HttpURLConnection; import java.net.URL; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.InvalidPathException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.nio.charset.Charset; +import jenkins.util.SystemProperties; /** * Entry point to Hudson from command line. @@ -69,7 +70,7 @@ public static void main(String[] args) { /** @see #remotePost */ public static int run(String[] args) throws Exception { String home = getHudsonHome(); - if (home==null) { + if (home == null) { System.err.println("JENKINS_HOME is not set."); return -1; } @@ -83,7 +84,7 @@ public static int run(String[] args) throws Exception { private static String getHudsonHome() { String home = EnvVars.masterEnvVars.get("JENKINS_HOME"); - if (home!=null) return home; + if (home != null) return home; return EnvVars.masterEnvVars.get("HUDSON_HOME"); } @@ -95,30 +96,30 @@ public static int remotePost(String[] args) throws Exception { String projectName = args[0]; String home = getHudsonHome(); - if(!home.endsWith("/")) home = home + '/'; // make sure it ends with '/' + if (!home.endsWith("/")) home = home + '/'; // make sure it ends with '/' // check for authentication info String auth = new URL(home).getUserInfo(); - if(auth != null) auth = "Basic " + new Base64Encoder().encode(auth.getBytes(StandardCharsets.UTF_8)); + if (auth != null) auth = "Basic " + new Base64Encoder().encode(auth.getBytes(StandardCharsets.UTF_8)); - {// check if the home is set correctly + { // check if the home is set correctly HttpURLConnection con = open(new URL(home)); if (auth != null) con.setRequestProperty("Authorization", auth); con.connect(); - if(con.getResponseCode()!=200 - || con.getHeaderField("X-Hudson")==null) { - System.err.println(home+" is not Hudson ("+con.getResponseMessage()+")"); + if (con.getResponseCode() != 200 + || con.getHeaderField("X-Hudson") == null) { + System.err.println(home + " is not Hudson (" + con.getResponseMessage() + ")"); return -1; } } URL jobURL = new URL(home + "job/" + Util.encode(projectName).replace("/", "/job/") + "/"); - {// check if the job name is correct + { // check if the job name is correct HttpURLConnection con = open(new URL(jobURL, "acceptBuildResult")); if (auth != null) con.setRequestProperty("Authorization", auth); con.connect(); - if(con.getResponseCode()!=200) { + if (con.getResponseCode() != 200) { System.err.println(jobURL + " is not a valid external job (" + con.getResponseCode() + " " + con.getResponseMessage() + ")"); return -1; } @@ -130,7 +131,7 @@ public static int remotePost(String[] args) throws Exception { HttpURLConnection con = open(new URL(home + "crumbIssuer/api/xml?xpath=concat(//crumbRequestField,\":\",//crumb)'")); if (auth != null) con.setRequestProperty("Authorization", auth); - String line = IOUtils.readFirstLine(con.getInputStream(),"UTF-8"); + String line = IOUtils.readFirstLine(con.getInputStream(), "UTF-8"); String[] components = line.split(":"); if (components.length == 2) { crumbField = components[0]; @@ -141,31 +142,31 @@ public static int remotePost(String[] args) throws Exception { } // write the output to a temporary file first. - File tmpFile = File.createTempFile("jenkins","log"); + File tmpFile = File.createTempFile("jenkins", "log"); try { int ret; try (OutputStream os = Files.newOutputStream(tmpFile.toPath()); Writer w = new OutputStreamWriter(os, StandardCharsets.UTF_8)) { w.write(""); - w.write(""); + w.write(""); w.flush(); // run the command long start = System.currentTimeMillis(); List cmd = new ArrayList<>(Arrays.asList(args).subList(1, args.length)); - Proc proc = new Proc.LocalProc(cmd.toArray(new String[0]),(String[])null,System.in, - new DualOutputStream(System.out,new EncodingStream(os))); + Proc proc = new Proc.LocalProc(cmd.toArray(new String[0]), (String[]) null, System.in, + new DualOutputStream(System.out, new EncodingStream(os))); ret = proc.join(); - w.write(""+ret+""+(System.currentTimeMillis()-start)+""); + w.write("" + ret + "" + (System.currentTimeMillis() - start) + ""); } catch (InvalidPathException e) { throw new IOException(e); } URL location = new URL(jobURL, "postBuildResult"); - while(true) { + while (true) { try { // start a remote connection HttpURLConnection con = open(location); @@ -175,7 +176,7 @@ public static int remotePost(String[] args) throws Exception { } con.setDoOutput(true); // this tells HttpURLConnection not to buffer the whole thing - con.setFixedLengthStreamingMode((int)tmpFile.length()); + con.setFixedLengthStreamingMode((int) tmpFile.length()); con.connect(); // send the data try (InputStream in = Files.newInputStream(tmpFile.toPath())) { @@ -184,13 +185,13 @@ public static int remotePost(String[] args) throws Exception { throw new IOException(e); } - if(con.getResponseCode()!=200) { + if (con.getResponseCode() != 200) { org.apache.commons.io.IOUtils.copy(con.getErrorStream(), System.err); } return ret; } catch (HttpRetryException e) { - if(e.getLocation()!=null) { + if (e.getLocation() != null) { // retry with the new location location = new URL(e.getLocation()); continue; @@ -200,7 +201,7 @@ public static int remotePost(String[] args) throws Exception { } } } finally { - tmpFile.delete(); + Files.delete(Util.fileToPath(tmpFile)); } } @@ -208,7 +209,7 @@ public static int remotePost(String[] args) throws Exception { * Connects to the given HTTP URL and configure time out, to avoid infinite hang. */ private static HttpURLConnection open(URL url) throws IOException { - HttpURLConnection c = (HttpURLConnection)url.openConnection(); + HttpURLConnection c = (HttpURLConnection) url.openConnection(); c.setReadTimeout(TIMEOUT); c.setConnectTimeout(TIMEOUT); return c; @@ -217,16 +218,18 @@ private static HttpURLConnection open(URL url) throws IOException { /** * Set to true if we are running unit tests. */ + @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "for debugging") public static boolean isUnitTest = false; /** * Set to true if we are running inside {@code mvn jetty:run}. * This is also set if running inside {@code mvn hpi:run} since plugins parent POM 2.30. */ - public static boolean isDevelopmentMode = SystemProperties.getBoolean(Main.class.getName()+".development"); + @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "for debugging") + public static boolean isDevelopmentMode = SystemProperties.getBoolean(Main.class.getName() + ".development"); /** * Time out for socket connection to Hudson. */ - public static final int TIMEOUT = SystemProperties.getInteger(Main.class.getName()+".timeout",15000); + public static final int TIMEOUT = SystemProperties.getInteger(Main.class.getName() + ".timeout", 15000); } diff --git a/core/src/main/java/hudson/MarkupText.java b/core/src/main/java/hudson/MarkupText.java index 17a4d4a80a76..182565205ecf 100644 --- a/core/src/main/java/hudson/MarkupText.java +++ b/core/src/main/java/hudson/MarkupText.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson; import java.util.ArrayList; @@ -64,8 +65,9 @@ private static final class Tag implements Comparable { this.markup = markup; } + @Override public int compareTo(Tag that) { - return this.pos-that.pos; + return this.pos - that.pos; } } @@ -73,7 +75,7 @@ public int compareTo(Tag that) { * Represents a substring of a {@link MarkupText}. */ public final class SubText extends AbstractMarkupText { - private final int start,end; + private final int start, end; private final int[] groups; public SubText(Matcher m, int textOffset) { @@ -81,10 +83,10 @@ public SubText(Matcher m, int textOffset) { end = m.end() + textOffset; int cnt = m.groupCount(); - groups = new int[cnt*2]; - for( int i=0; i…}. */ public void href(String url) { - addHyperlink(0,length(),url); + addHyperlink(0, length(), url); } /** @@ -145,8 +147,8 @@ public void href(String url) { * groups captured by '(...)' in the regexp. */ public int start(int groupIndex) { - if(groupIndex==0) return start; - return groups[groupIndex*2-2]; + if (groupIndex == 0) return start; + return groups[groupIndex * 2 - 2]; } /** @@ -160,8 +162,8 @@ public int start() { * Gets the end index of the captured group within {@link MarkupText#getText()}. */ public int end(int groupIndex) { - if(groupIndex==0) return end; - return groups[groupIndex*2-1]; + if (groupIndex == 0) return end; + return groups[groupIndex * 2 - 1]; } /** @@ -175,9 +177,9 @@ public int end() { * Gets the text that represents the captured group. */ public String group(int groupIndex) { - if(start(groupIndex)==-1) + if (start(groupIndex) == -1) return null; - return text.substring(start(groupIndex),end(groupIndex)); + return text.substring(start(groupIndex), end(groupIndex)); } /** @@ -194,24 +196,24 @@ public int groupCount() { public String replace(String s) { StringBuilder buf = new StringBuilder(s.length() + 10); - for( int i=0; i 9) { - buf.append('$').append(ch); + buf.append('$').append(ch); } else { - // add the group text - String group = group(groupId); - if (group != null) - buf.append(group); + // add the group text + String group = group(groupId); + if (group != null) + buf.append(group); } } else { @@ -225,7 +227,7 @@ public String replace(String s) { @Override protected SubText createSubText(Matcher m) { - return new SubText(m,start); + return new SubText(m, start); } } @@ -249,30 +251,31 @@ public String getText() { * @param end * If negative, -N means "trim the last N-1 chars". That is, (s,-1) is the same as (s,length) */ + @Override public SubText subText(int start, int end) { - return new SubText(start, end<0 ? text.length()+1+end : end); + return new SubText(start, end < 0 ? text.length() + 1 + end : end); } @Override - public void addMarkup( int startPos, int endPos, String startTag, String endTag ) { + public void addMarkup(int startPos, int endPos, String startTag, String endTag) { rangeCheck(startPos); rangeCheck(endPos); - if(startPos>endPos) throw new IndexOutOfBoundsException(); + if (startPos > endPos) throw new IndexOutOfBoundsException(); // when multiple tags are added to the same range, we want them to show up like // abc, not abc. Also, we'd like abcdef, // not abcdef. Do this by inserting them to different places. tags.add(new Tag(startPos, startTag)); - tags.add(0,new Tag(endPos,endTag)); + tags.add(0, new Tag(endPos, endTag)); } public void addMarkup(int pos, String tag) { rangeCheck(pos); - tags.add(new Tag(pos,tag)); + tags.add(new Tag(pos, tag)); } private void rangeCheck(int pos) { - if(pos<0 || pos>text.length()) + if (pos < 0 || pos > text.length()) throw new IndexOutOfBoundsException(); } @@ -296,8 +299,8 @@ public String toString() { * If false, the escape is for the normal HTML, thus SP becomes &nbsp; and CR/LF becomes {@code
} */ public String toString(boolean preEscape) { - if(tags.isEmpty()) - return preEscape? Util.xmlEscape(text) : Util.escape(text); // the most common case + if (tags.isEmpty()) + return preEscape ? Util.xmlEscape(text) : Util.escape(text); // the most common case Collections.sort(tags); @@ -305,14 +308,14 @@ public String toString(boolean preEscape) { int copied = 0; // # of chars already copied from text to buf for (Tag tag : tags) { - if (copied findTokens(Pattern pattern) { @Override protected SubText createSubText(Matcher m) { - return new SubText(m,0); + return new SubText(m, 0); } } diff --git a/core/src/main/java/hudson/PermalinkList.java b/core/src/main/java/hudson/PermalinkList.java index caffd8baf0fe..6c97c54a00b2 100644 --- a/core/src/main/java/hudson/PermalinkList.java +++ b/core/src/main/java/hudson/PermalinkList.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,11 +21,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson; import hudson.model.PermalinkProjectAction.Permalink; import hudson.util.EditDistance; - import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -51,7 +51,7 @@ public PermalinkList() { */ public Permalink get(String id) { for (Permalink p : this) - if(p.getId().equals(id)) + if (p.getId().equals(id)) return p; return null; } @@ -64,7 +64,7 @@ public Permalink findNearest(String id) { for (Permalink p : this) ids.add(p.getId()); String nearest = EditDistance.findNearest(id, ids); - if(nearest==null) return null; + if (nearest == null) return null; return get(nearest); } } diff --git a/core/src/main/java/hudson/Platform.java b/core/src/main/java/hudson/Platform.java index 080538693da4..23ab0caa6653 100644 --- a/core/src/main/java/hudson/Platform.java +++ b/core/src/main/java/hudson/Platform.java @@ -21,10 +21,10 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson; import hudson.util.VersionNumber; - import java.io.File; import java.util.Locale; @@ -37,10 +37,10 @@ * @author Kohsuke Kawaguchi */ public enum Platform { - WINDOWS(';'),UNIX(':'); + WINDOWS(';'), UNIX(':'); /** - * The character that separates paths in environment variables like PATH and CLASSPATH. + * The character that separates paths in environment variables like PATH and CLASSPATH. * On Windows ';' and on Unix ':'. * * @see File#pathSeparator @@ -52,7 +52,7 @@ public enum Platform { } public static Platform current() { - if(File.pathSeparatorChar==':') return UNIX; + if (File.pathSeparatorChar == ':') return UNIX; return WINDOWS; } @@ -66,7 +66,7 @@ public static boolean isDarwin() { */ public static boolean isSnowLeopardOrLater() { try { - return isDarwin() && new VersionNumber(System.getProperty("os.version")).compareTo(new VersionNumber("10.6"))>=0; + return isDarwin() && new VersionNumber(System.getProperty("os.version")).compareTo(new VersionNumber("10.6")) >= 0; } catch (IllegalArgumentException e) { // failed to parse the version return false; diff --git a/core/src/main/java/hudson/Plugin.java b/core/src/main/java/hudson/Plugin.java index 6919577086eb..41eafeabf545 100644 --- a/core/src/main/java/hudson/Plugin.java +++ b/core/src/main/java/hudson/Plugin.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,37 +21,36 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package hudson; -import java.util.concurrent.TimeUnit; +package hudson; +import com.thoughtworks.xstream.XStream; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import jenkins.model.Jenkins; +import hudson.init.Initializer; +import hudson.init.Terminator; import hudson.model.Descriptor; +import hudson.model.Descriptor.FormException; import hudson.model.Saveable; import hudson.model.listeners.ItemListener; import hudson.model.listeners.SaveableListener; -import hudson.model.Descriptor.FormException; -import org.kohsuke.accmod.Restricted; -import org.kohsuke.accmod.restrictions.NoExternalUse; -import org.kohsuke.stapler.StaplerProxy; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; - -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; import java.io.File; - -import net.sf.json.JSONObject; -import com.thoughtworks.xstream.XStream; -import hudson.init.Initializer; -import hudson.init.Terminator; +import java.io.IOException; import java.net.URL; import java.util.Locale; +import java.util.concurrent.TimeUnit; import java.util.logging.Logger; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletResponse; import jenkins.model.GlobalConfiguration; +import jenkins.model.Jenkins; +import jenkins.util.SystemProperties; +import net.sf.json.JSONObject; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.stapler.StaplerProxy; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; /** * Base class of Hudson plugin. @@ -59,8 +58,8 @@ *

* A plugin may {@linkplain #Plugin derive from this class}, or it may directly define extension * points annotated with {@link hudson.Extension}. For a list of extension - * points, see - * https://jenkins.io/redirect/developer/extension-points. + * points, see + * https://www.jenkins.io/redirect/developer/extension-points. * *

* One instance of a plugin is created by Hudson, and used as the entry point @@ -268,7 +267,7 @@ public void doDynamic(StaplerRequest req, StaplerResponse rsp) throws IOExceptio */ protected void load() throws IOException { XmlFile xml = getConfigXml(); - if(xml.exists()) + if (xml.exists()) xml.unmarshal(this); } @@ -277,8 +276,9 @@ protected void load() throws IOException { * * @since 1.245 */ + @Override public void save() throws IOException { - if(BulkChange.contains(this)) return; + if (BulkChange.contains(this)) return; XmlFile config = getConfigXml(); config.write(this); SaveableListener.fireOnChange(this, config); @@ -295,7 +295,7 @@ public void save() throws IOException { */ protected XmlFile getConfigXml() { return new XmlFile(Jenkins.XSTREAM, - new File(Jenkins.get().getRootDir(),wrapper.getShortName()+".xml")); + new File(Jenkins.get().getRootDir(), wrapper.getShortName() + ".xml")); } @Override @@ -311,8 +311,8 @@ public Object getTarget() { * Escape hatch for StaplerProxy-based access control */ @Restricted(NoExternalUse.class) - @SuppressFBWarnings("MS_SHOULD_BE_FINAL") - public static /* Script Console modifiable */ boolean SKIP_PERMISSION_CHECK = Boolean.getBoolean(Plugin.class.getName() + ".skipPermissionCheck"); + @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "for script console") + public static /* Script Console modifiable */ boolean SKIP_PERMISSION_CHECK = SystemProperties.getBoolean(Plugin.class.getName() + ".skipPermissionCheck"); /** * Dummy instance of {@link Plugin} to be used when a plugin didn't diff --git a/core/src/main/java/hudson/PluginFirstClassLoader.java b/core/src/main/java/hudson/PluginFirstClassLoader.java index ee87947a28ea..a990ea329e5a 100644 --- a/core/src/main/java/hudson/PluginFirstClassLoader.java +++ b/core/src/main/java/hudson/PluginFirstClassLoader.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Olivier Lamy - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,19 +21,18 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson; -import java.io.Closeable; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.URL; -import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; import java.util.List; - -import jenkins.util.AntWithFindResourceClassLoader; +import java.util.concurrent.CopyOnWriteArrayList; +import jenkins.util.AntClassLoader; /** * classLoader which use first /WEB-INF/lib/*.jar and /WEB-INF/classes before core classLoader @@ -42,64 +41,56 @@ * @since 1.371 */ public class PluginFirstClassLoader - extends AntWithFindResourceClassLoader - implements Closeable + extends AntClassLoader { - public PluginFirstClassLoader() { super(null, false); } - private List urls = new ArrayList<>(); + private List urls = new CopyOnWriteArrayList<>(); @Override - public void addPathFiles( Collection paths ) + public void addPathFiles(Collection paths) throws IOException { - for ( File f : paths ) + for (File f : paths) { - urls.add( f.toURI().toURL() ); - addPathFile( f ); + urls.add(f.toURI().toURL()); + addPathFile(f); } } /** * @return List of jar used by the plugin /WEB-INF/lib/*.jar and classes directory /WEB-INF/classes */ - public List getURLs() + public List getURLs() { return urls; } - - public void close() - throws IOException - { - cleanup(); - } @Override - protected Enumeration findResources( String arg0, boolean arg1 ) + protected Enumeration findResources(String name, boolean skipParent) throws IOException { - return super.findResources( arg0, arg1 ); + return super.findResources(name, skipParent); } @Override - public Enumeration findResources( String name ) + public Enumeration findResources(String name) throws IOException { - return super.findResources( name ); + return super.findResources(name); } @Override - public URL getResource( String arg0 ) + public URL getResource(String name) { - return super.getResource( arg0 ); + return super.getResource(name); } @Override - public InputStream getResourceAsStream( String name ) + public InputStream getResourceAsStream(String name) { - return super.getResourceAsStream( name ); + return super.getResourceAsStream(name); } } diff --git a/core/src/main/java/hudson/PluginFirstClassLoader2.java b/core/src/main/java/hudson/PluginFirstClassLoader2.java new file mode 100644 index 000000000000..974939d53acb --- /dev/null +++ b/core/src/main/java/hudson/PluginFirstClassLoader2.java @@ -0,0 +1,135 @@ +package hudson; + +import edu.umd.cs.findbugs.annotations.NonNull; +import hudson.util.CompoundEnumeration; +import java.io.IOException; +import java.net.URL; +import java.util.Enumeration; +import java.util.Objects; +import jenkins.util.URLClassLoader2; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; + +/** + * Class loader that consults the plugin's {@code WEB-INF/lib/*.jar} and {@code WEB-INF/classes} + * directories and the Jenkins core class loader (in that order). + * + *

To use this class loader, set {@code pluginFirstClassLoader} to {@code true} in the {@code + * maven-hpi-plugin} configuration. + * + * @author Basil Crow + */ +@Restricted(NoExternalUse.class) +public class PluginFirstClassLoader2 extends URLClassLoader2 { + static { + registerAsParallelCapable(); + } + + public PluginFirstClassLoader2(@NonNull URL[] urls, @NonNull ClassLoader parent) { + super(Objects.requireNonNull(urls), Objects.requireNonNull(parent)); + } + + /** + * Load the class with the specified binary name. This method searches for classes in the + * following order: + * + *

    + *
  1. + *

    Invoke {@link #findLoadedClass(String)} to check if the class has already been + * loaded. + *

  2. + *

    Invoke {@link #findClass(String)} to find the class. + *

  3. + *

    Invoke {@link #loadClass(String)} on the parent class loader. + *

+ * + *

If the class was found using the above steps and the {@code resolve} flag is true, this + * method will then invoke {@link #resolveClass(Class)} on the resulting {@link Class} object. + * + *

This method synchronizes on the result of {@link #getClassLoadingLock(String)} during the + * entire class loading process. + * + * @param name The binary name of the class + * @param resolve If {@code true} then resolve the class + * @return The resulting {@link Class} object + * @throws ClassNotFoundException If the class could not be found + */ + @Override + protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { + synchronized (getClassLoadingLock(name)) { + Class c = findLoadedClass(name); + if (c == null) { + try { + c = findClass(name); + } catch (ClassNotFoundException e) { + // ignore + } + } + if (c == null) { + c = getParent().loadClass(name); + } + if (resolve) { + resolveClass(c); + } + return c; + } + } + + /** + * Find the resource with the given name. A resource is some data (images, audio, text, etc) + * that can be accessed by class code in a way that is independent of the location of the code. + * + *

The name of a resource is a '{@code /}'-separated path name that identifies the resource. + * This method searches for resources in the following order: + * + *

    + *
  1. + *

    Invoke {@link #findResource(String)} to find the resource. + *

  2. + *

    Invoke {@link #getResource(String)} on the parent class loader. + *

+ * + * @param name The resource name + * @return {@link URL} object for reading the resource; {@code null} if the resource could not + * be found, a {@link URL} could not be constructed to locate the resource, the resource is + * in a package that is not opened unconditionally, or access to the resource is denied by + * the security manager. + * @throws NullPointerException If {@code name} is {@code null} + */ + @Override + public URL getResource(String name) { + Objects.requireNonNull(name); + URL url = findResource(name); + if (url == null) { + url = getParent().getResource(name); + } + return url; + } + + /** + * Find all the resources with the given name. A resource is some data (images, audio, text, + * etc) that can be accessed by class code in a way that is independent of the location of the + * code. + * + *

The name of a resource is a {@code /}-separated path name that identifies the resource. + * This method first invokes {@link #findResources(String)} to find the resources with the name + * in this class loader. Finally, it invokes {@link #getResources(String)} on the parent class + * loader. It returns an enumeration whose elements are the {@link URL}s found by searching the + * {@link URL}s found with {@link #findResources(String)}, followed by the {@link URL}s found by + * searching the parent class loader. + * + * @param name The resource name + * @return An enumeration of {@link URL} objects for the resource. If no resources could be + * found, the enumeration will be empty. Resources for which a {@link URL} cannot be + * constructed, which are in a package that is not opened unconditionally, or for which + * access to the resource is denied by the security manager, are not returned in the + * enumeration. + * @throws IOException If I/O errors occur + * @throws NullPointerException If {@code name} is {@code null} + */ + @Override + public Enumeration getResources(String name) throws IOException { + Objects.requireNonNull(name); + return new CompoundEnumeration<>(findResources(name), getParent().getResources(name)); + } +} diff --git a/core/src/main/java/hudson/PluginManager.java b/core/src/main/java/hudson/PluginManager.java index eb4a5dee22b5..e4575086d9fb 100644 --- a/core/src/main/java/hudson/PluginManager.java +++ b/core/src/main/java/hudson/PluginManager.java @@ -21,8 +21,21 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson; +import static hudson.init.InitMilestone.COMPLETED; +import static hudson.init.InitMilestone.PLUGINS_LISTED; +import static hudson.init.InitMilestone.PLUGINS_PREPARED; +import static hudson.init.InitMilestone.PLUGINS_STARTED; +import static java.util.logging.Level.FINE; +import static java.util.logging.Level.INFO; +import static java.util.logging.Level.WARNING; +import static java.util.stream.Collectors.toList; + +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.Nullable; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.PluginWrapper.Dependency; import hudson.init.InitMilestone; @@ -52,6 +65,55 @@ import hudson.util.Service; import hudson.util.VersionNumber; import hudson.util.XStream2; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.InputStream; +import java.io.UncheckedIOException; +import java.lang.reflect.Method; +import java.net.JarURLConnection; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLClassLoader; +import java.net.URLConnection; +import java.nio.file.Files; +import java.nio.file.attribute.FileTime; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.ServiceLoader; +import java.util.Set; +import java.util.TreeMap; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.Future; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.jar.Manifest; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Collectors; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.xml.XMLConstants; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParserFactory; import jenkins.ClassLoaderReflectionToolkit; import jenkins.ExtensionRefreshException; import jenkins.InitReactorRunner; @@ -63,7 +125,6 @@ import jenkins.model.Jenkins; import jenkins.plugins.DetachedPluginsUtil; import jenkins.security.CustomClassFilter; -import jenkins.telemetry.impl.java11.MissingClassTelemetry; import jenkins.util.SystemProperties; import jenkins.util.io.OnMaster; import jenkins.util.xml.RestrictiveEntityResolver; @@ -79,7 +140,6 @@ import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.LogFactory; import org.jenkinsci.Symbol; -import org.jenkinsci.bytecode.Transformer; import org.jvnet.hudson.reactor.Executable; import org.jvnet.hudson.reactor.Reactor; import org.jvnet.hudson.reactor.TaskBuilder; @@ -99,65 +159,12 @@ import org.kohsuke.stapler.export.ExportedBean; import org.kohsuke.stapler.interceptor.RequirePOST; import org.kohsuke.stapler.verb.POST; +import org.springframework.security.core.Authentication; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; -import edu.umd.cs.findbugs.annotations.CheckForNull; -import edu.umd.cs.findbugs.annotations.NonNull; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParserFactory; -import java.io.ByteArrayInputStream; -import java.io.Closeable; -import java.io.File; -import java.io.FilenameFilter; -import java.io.IOException; -import java.io.InputStream; -import java.lang.ref.WeakReference; -import java.lang.reflect.Method; -import java.net.JarURLConnection; -import java.net.MalformedURLException; -import java.net.URISyntaxException; -import java.net.URL; -import java.net.URLClassLoader; -import java.net.URLConnection; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.ServiceLoader; -import java.util.Set; -import java.util.TreeMap; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.Future; -import java.util.function.Function; -import java.util.function.Supplier; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; -import java.util.jar.Manifest; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.stream.Collectors; - -import static hudson.init.InitMilestone.*; -import static java.util.logging.Level.*; -import static java.util.stream.Collectors.toList; - -import org.springframework.security.core.Authentication; - /** * Manages {@link PluginWrapper}s. * @@ -201,7 +208,7 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas // Secure initialization CHECK_UPDATE_SLEEP_TIME_MILLIS = SystemProperties.getInteger(PluginManager.class.getName() + ".checkUpdateSleepTimeMillis", 1000); CHECK_UPDATE_ATTEMPTS = SystemProperties.getInteger(PluginManager.class.getName() + ".checkUpdateAttempts", 1); - } catch(Exception e) { + } catch (RuntimeException e) { LOGGER.warning(String.format("There was an error initializing the PluginManager. Exception: %s", e)); } finally { CHECK_UPDATE_ATTEMPTS = CHECK_UPDATE_ATTEMPTS > 0 ? CHECK_UPDATE_ATTEMPTS : 1; @@ -213,7 +220,7 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas private enum PMConstructor { JENKINS { @Override - @NonNull + @NonNull PluginManager doCreate(@NonNull Class klass, @NonNull Jenkins jenkins) throws ReflectiveOperationException { return klass.getConstructor(Jenkins.class).newInstance(jenkins); @@ -238,7 +245,7 @@ PluginManager doCreate(@NonNull Class klass, @NonNull Jenkins jenkins) throws ReflectiveOperationException { try { return doCreate(klass, jenkins); - } catch(NoSuchMethodException e) { + } catch (NoSuchMethodException e) { // Constructor not found. Will try the remaining ones. return null; } @@ -269,13 +276,9 @@ PluginManager doCreate(@NonNull Class klass, } } LOGGER.log(WARNING, String.format("Provided custom plugin manager [%s] does not provide any of the suitable constructors. Using default.", pmClassName)); - } catch(NullPointerException e) { - // Class.forName and Class.getConstructor are supposed to never return null though a broken ClassLoader - // could break the contract. Just in case we introduce this specific catch to avoid polluting the logs with NPEs. - LOGGER.log(WARNING, String.format("Unable to instantiate custom plugin manager [%s]. Using default.", pmClassName)); - } catch(ClassCastException e) { + } catch (ClassCastException e) { LOGGER.log(WARNING, String.format("Provided class [%s] does not extend PluginManager. Using default.", pmClassName)); - } catch(Exception e) { + } catch (Exception e) { LOGGER.log(WARNING, String.format("Unable to instantiate custom plugin manager [%s]. Using default.", pmClassName), e); } } @@ -327,9 +330,7 @@ PluginManager doCreate(@NonNull Class klass, */ // implementation is minimal --- just enough to run XStream // and load plugin-contributed classes. - public final ClassLoader uberClassLoader = new UberClassLoader(); - - private final Transformer compatibilityTransformer = new Transformer(); + public final ClassLoader uberClassLoader = new UberClassLoader(activePlugins); /** * Once plugin is uploaded, this flag becomes true. @@ -351,27 +352,19 @@ PluginManager doCreate(@NonNull Class klass, */ private final PluginStrategy strategy; - public PluginManager(ServletContext context, File rootDir) { + protected PluginManager(ServletContext context, File rootDir) { this.context = context; this.rootDir = rootDir; - if(!rootDir.exists()) - rootDir.mkdirs(); - String workDir = SystemProperties.getString(PluginManager.class.getName()+".workDir"); - this.workDir = StringUtils.isBlank(workDir) ? null : new File(workDir); - - strategy = createPluginStrategy(); - - // load up rules for the core first try { - compatibilityTransformer.loadRules(getClass().getClassLoader()); + Util.createDirectories(rootDir.toPath()); } catch (IOException e) { - LOGGER.log(Level.WARNING, "Failed to load compatibility rewrite rules",e); + throw new UncheckedIOException(e); } - } + String workDir = SystemProperties.getString(PluginManager.class.getName() + ".workDir"); + this.workDir = StringUtils.isBlank(workDir) ? null : new File(workDir); - public Transformer getCompatibilityTransformer() { - return compatibilityTransformer; + strategy = createPluginStrategy(); } public Api getApi() { @@ -412,26 +405,30 @@ public TaskBuilder initTasks(final InitStrategy initStrategy) { { Handle loadBundledPlugins = add("Loading bundled plugins", new Executable() { + @Override public void run(Reactor session) throws Exception { bundledPlugins = loadBundledPlugins(); } }); Handle listUpPlugins = requires(loadBundledPlugins).add("Listing up plugins", new Executable() { + @Override public void run(Reactor session) throws Exception { archives = initStrategy.listPluginArchives(PluginManager.this); } }); - requires(listUpPlugins).attains(PLUGINS_LISTED).add("Preparing plugins",new Executable() { + requires(listUpPlugins).attains(PLUGINS_LISTED).add("Preparing plugins", new Executable() { + @Override public void run(Reactor session) throws Exception { // once we've listed plugins, we can fill in the reactor with plugin-specific initialization tasks TaskGraphBuilder g = new TaskGraphBuilder(); - final Map inspectedShortNames = new HashMap<>(); + final Map inspectedShortNames = new HashMap<>(); - for( final File arc : archives ) { + for (final File arc : archives) { g.followedBy().notFatal().attains(PLUGINS_LISTED).add("Inspecting plugin " + arc, new Executable() { + @Override public void run(Reactor session1) throws Exception { try { PluginWrapper p = strategy.createPluginWrapper(arc); @@ -440,7 +437,7 @@ public void run(Reactor session1) throws Exception { p.isBundled = containsHpiJpi(bundledPlugins, arc.getName()); plugins.add(p); } catch (IOException e) { - failedPlugins.add(new FailedPlugin(arc.getName(),e)); + failedPlugins.add(new FailedPlugin(arc.getName(), e)); throw e; } } @@ -452,11 +449,11 @@ public void run(Reactor session1) throws Exception { private boolean isDuplicate(PluginWrapper p) { String shortName = p.getShortName(); if (inspectedShortNames.containsKey(shortName)) { - LOGGER.info("Ignoring "+arc+" because "+inspectedShortNames.get(shortName)+" is already loaded"); + LOGGER.info("Ignoring " + arc + " because " + inspectedShortNames.get(shortName) + " is already loaded"); return true; } - inspectedShortNames.put(shortName,arc); + inspectedShortNames.put(shortName, arc); return false; } }); @@ -466,6 +463,7 @@ private boolean isDuplicate(PluginWrapper p) { /** * Makes sure there's no cycle in dependencies. */ + @Override public void run(Reactor reactor) throws Exception { try { CyclicGraphDetector cgd = new CyclicGraphDetector() { @@ -486,13 +484,12 @@ private void addTo(List dependencies, List r) { } @Override - protected void reactOnCycle(PluginWrapper q, List cycle) - throws hudson.util.CyclicGraphDetector.CycleDetectedException { + protected void reactOnCycle(PluginWrapper q, List cycle) { - LOGGER.log(Level.SEVERE, "found cycle in plugin dependencies: (root="+q+", deactivating all involved) "+Util.join(cycle," -> ")); + LOGGER.log(Level.SEVERE, "found cycle in plugin dependencies: (root=" + q + ", deactivating all involved) " + cycle.stream().map(Object::toString).collect(Collectors.joining(" -> "))); for (PluginWrapper pluginWrapper : cycle) { pluginWrapper.setHasCycleDependency(true); - failedPlugins.add(new FailedPlugin(pluginWrapper.getShortName(), new CycleDetectedException(cycle))); + failedPlugins.add(new FailedPlugin(pluginWrapper, new CycleDetectedException(cycle))); } } @@ -501,7 +498,7 @@ protected void reactOnCycle(PluginWrapper q, List cycle) // obtain topologically sorted list and overwrite the list for (PluginWrapper p : cgd.getSorted()) { - if(p.isActive()) + if (p.isActive()) activePlugins.add(p); } } catch (CycleDetectedException e) { // TODO this should be impossible, since we override reactOnCycle to not throw the exception @@ -511,13 +508,6 @@ protected void reactOnCycle(PluginWrapper q, List cycle) } }); - // Let's see for a while until we open this functionality up to plugins -// g.followedBy().attains(PLUGINS_LISTED).add("Load compatibility rules", new Executable() { -// public void run(Reactor reactor) throws Exception { -// compatibilityTransformer.loadRules(uberClassLoader); -// } -// }); - session.addAll(g.discoverTasks(session)); pluginListed = true; // technically speaking this is still too early, as at this point tasks are merely scheduled, not necessarily executed. @@ -538,6 +528,7 @@ builder, new TaskGraphBuilder() {{ /** * Once the plugins are listed, schedule their initialization. */ + @Override public void run(Reactor session) throws Exception { Jenkins.get().lookup.set(PluginInstanceStore.class, new PluginInstanceStore()); TaskGraphBuilder g = new TaskGraphBuilder(); @@ -545,19 +536,22 @@ public void run(Reactor session) throws Exception { // schedule execution of loading plugins for (final PluginWrapper p : activePlugins.toArray(new PluginWrapper[0])) { g.followedBy().notFatal().attains(PLUGINS_PREPARED).add(String.format("Loading plugin %s v%s (%s)", p.getLongName(), p.getVersion(), p.getShortName()), new Executable() { + @Override public void run(Reactor session) throws Exception { try { p.resolvePluginDependencies(); strategy.load(p); } catch (MissingDependencyException e) { - failedPlugins.add(new FailedPlugin(p.getShortName(), e)); + failedPlugins.add(new FailedPlugin(p, e)); activePlugins.remove(p); plugins.remove(p); + p.releaseClassLoader(); LOGGER.log(Level.SEVERE, "Failed to install {0}: {1}", new Object[] { p.getShortName(), e.getMessage() }); } catch (IOException e) { - failedPlugins.add(new FailedPlugin(p.getShortName(), e)); + failedPlugins.add(new FailedPlugin(p, e)); activePlugins.remove(p); plugins.remove(p); + p.releaseClassLoader(); throw e; } } @@ -567,6 +561,7 @@ public void run(Reactor session) throws Exception { // schedule execution of initializing plugins for (final PluginWrapper p : activePlugins.toArray(new PluginWrapper[0])) { g.followedBy().notFatal().attains(PLUGINS_STARTED).add("Initializing plugin " + p.getShortName(), new Executable() { + @Override public void run(Reactor session) throws Exception { if (!activePlugins.contains(p)) { return; @@ -574,9 +569,10 @@ public void run(Reactor session) throws Exception { try { p.getPluginOrFail().postInitialize(); } catch (Exception e) { - failedPlugins.add(new FailedPlugin(p.getShortName(), e)); + failedPlugins.add(new FailedPlugin(p, e)); activePlugins.remove(p); plugins.remove(p); + p.releaseClassLoader(); throw e; } } @@ -584,6 +580,7 @@ public void run(Reactor session) throws Exception { } g.followedBy().attains(PLUGINS_STARTED).add("Discovering plugin initialization tasks", new Executable() { + @Override public void run(Reactor reactor) throws Exception { // rescan to find plugin-contributed @Initializer reactor.addAll(initializerFinder.discoverTasks(reactor)); @@ -634,16 +631,16 @@ void considerDetachedPlugin(String shortName) { //TODO: Consider refactoring in order to avoid DMI_COLLECTION_OF_URLS @SuppressFBWarnings(value = "DMI_COLLECTION_OF_URLS", justification = "Plugin loading happens only once on Jenkins startup") protected @NonNull Set loadPluginsFromWar(@NonNull String fromPath, @CheckForNull FilenameFilter filter) { - Set names = new HashSet(); + Set names = new HashSet<>(); ServletContext context = Jenkins.get().servletContext; Set plugins = Util.fixNull(context.getResourcePaths(fromPath)); Set copiedPlugins = new HashSet<>(); Set dependencies = new HashSet<>(); - for( String pluginPath : plugins) { - String fileName = pluginPath.substring(pluginPath.lastIndexOf('/')+1); - if(fileName.length()==0) { + for (String pluginPath : plugins) { + String fileName = pluginPath.substring(pluginPath.lastIndexOf('/') + 1); + if (fileName.length() == 0) { // see http://www.nabble.com/404-Not-Found-error-when-clicking-on-help-td24508544.html // I suspect some containers are returning directory names. continue; @@ -657,7 +654,7 @@ void considerDetachedPlugin(String shortName) { } names.add(fileName); - copyBundledPlugin(url, fileName); + copyBundledPlugin(Objects.requireNonNull(url), fileName); copiedPlugins.add(url); try { addDependencies(url, fromPath, dependencies); @@ -665,7 +662,7 @@ void considerDetachedPlugin(String shortName) { LOGGER.log(Level.SEVERE, "Failed to resolve dependencies for the bundled plugin " + fileName, e); } } catch (IOException e) { - LOGGER.log(Level.SEVERE, "Failed to extract the bundled plugin "+fileName,e); + LOGGER.log(Level.SEVERE, "Failed to extract the bundled plugin " + fileName, e); } } @@ -858,12 +855,13 @@ private String normalisePluginName(@NonNull String name) { * this is necessary since the bundled plugins are still called *.hpi */ private boolean containsHpiJpi(Collection bundledPlugins, String name) { - return bundledPlugins.contains(name.replaceAll("\\.hpi",".jpi")) - || bundledPlugins.contains(name.replaceAll("\\.jpi",".hpi")); + return bundledPlugins.contains(name.replaceAll("\\.hpi", ".jpi")) + || bundledPlugins.contains(name.replaceAll("\\.jpi", ".hpi")); } /** * Returns the manifest of a bundled but not-extracted plugin. + * @deprecated removed without replacement */ @Deprecated // See https://groups.google.com/d/msg/jenkinsci-dev/kRobm-cxFw8/6V66uhibAwAJ public @CheckForNull Manifest getBundledPluginManifest(String shortName) { @@ -894,11 +892,11 @@ public void dynamicLoad(File arc, boolean removeExisting, @CheckForNull List i = plugins.iterator(); i.hasNext();) { pw = i.next(); - if(sn.equals(pw.getShortName())) { + if (sn.equals(pw.getShortName())) { i.remove(); break; } @@ -910,7 +908,7 @@ public void dynamicLoad(File arc, boolean removeExisting, @CheckForNull List plugins) throws Exception { Map pluginsByName = plugins.stream().collect(Collectors.toMap(PluginWrapper::getShortName, p -> p)); // recalculate dependencies of plugins optionally depending the newly deployed ones. - for (PluginWrapper depender: this.plugins) { + for (PluginWrapper depender : this.plugins) { if (plugins.contains(depender)) { // skip itself. continue; } - for (Dependency d: depender.getOptionalDependencies()) { + for (Dependency d : depender.getOptionalDependencies()) { PluginWrapper dependee = pluginsByName.get(d.shortName); if (dependee != null) { // this plugin depends on the newly loaded one! @@ -1004,7 +1001,7 @@ public synchronized void resolveDependentPlugins() { Set dependents = new HashSet<>(); for (PluginWrapper possibleDependent : plugins) { // No need to check if plugin is dependent of itself - if(possibleDependent.getShortName().equals(plugin.getShortName())) { + if (possibleDependent.getShortName().equals(plugin.getShortName())) { continue; } @@ -1053,20 +1050,20 @@ public synchronized void resolveDependentPlugins() { */ protected void copyBundledPlugin(URL src, String fileName) throws IOException { LOGGER.log(FINE, "Copying {0}", src); - fileName = fileName.replace(".hpi",".jpi"); // normalize fileNames to have the correct suffix - String legacyName = fileName.replace(".jpi",".hpi"); + fileName = fileName.replace(".hpi", ".jpi"); // normalize fileNames to have the correct suffix + String legacyName = fileName.replace(".jpi", ".hpi"); long lastModified = getModificationDate(src); File file = new File(rootDir, fileName); // normalization first, if the old file exists. - rename(new File(rootDir,legacyName),file); + rename(new File(rootDir, legacyName), file); // update file if: // - no file exists today // - bundled version and current version differs (by timestamp). if (!file.exists() || file.lastModified() != lastModified) { FileUtils.copyURLToFile(src, file); - file.setLastModified(getModificationDate(src)); + Files.setLastModifiedTime(Util.fileToPath(file), FileTime.fromMillis(getModificationDate(src))); // lastModified is set for two reasons: // - to avoid unpacking as much as possible, but still do it on both upgrade and downgrade // - to make sure the value is not changed after each restart, so we can avoid @@ -1078,26 +1075,23 @@ protected void copyBundledPlugin(URL src, String fileName) throws IOException { } /*package*/ static @CheckForNull Manifest parsePluginManifest(URL bundledJpi) { - try { - URLClassLoader cl = new URLClassLoader(new URL[]{bundledJpi}); - InputStream in=null; + try (URLClassLoader cl = new URLClassLoader(new URL[]{bundledJpi})) { + InputStream in = null; try { URL res = cl.findResource(PluginWrapper.MANIFEST_FILENAME); - if (res!=null) { + if (res != null) { in = getBundledJpiManifestStream(res); return new Manifest(in); } } finally { Util.closeAndLogFailures(in, LOGGER, PluginWrapper.MANIFEST_FILENAME, bundledJpi.toString()); - if (cl instanceof Closeable) - ((Closeable)cl).close(); } } catch (IOException e) { - LOGGER.log(WARNING, "Failed to parse manifest of "+bundledJpi, e); + LOGGER.log(WARNING, "Failed to parse manifest of " + bundledJpi, e); } return null; } - + /** * Retrieves input stream for the Manifest url. * The method intelligently handles the case of {@link JarURLConnection} pointing to files within JAR. @@ -1110,15 +1104,15 @@ protected void copyBundledPlugin(URL src, String fileName) throws IOException { URLConnection uc = url.openConnection(); InputStream in = null; // Magic, which allows to avoid using stream generated for JarURLConnection. - // It prevents getting into JENKINS-37332 due to the file descriptor leak + // It prevents getting into JENKINS-37332 due to the file descriptor leak if (uc instanceof JarURLConnection) { final JarURLConnection jarURLConnection = (JarURLConnection) uc; final String entryName = jarURLConnection.getEntryName(); - - try(JarFile jarFile = jarURLConnection.getJarFile()) { - final JarEntry entry = (entryName != null && jarFile != null) ? jarFile.getJarEntry(entryName) : null; + + try (JarFile jarFile = jarURLConnection.getJarFile()) { + final JarEntry entry = entryName != null && jarFile != null ? jarFile.getJarEntry(entryName) : null; if (entry != null) { - try(InputStream i = jarFile.getInputStream(entry)) { + try (InputStream i = jarFile.getInputStream(entry)) { byte[] manifestBytes = IOUtils.toByteArray(i); in = new ByteArrayInputStream(manifestBytes); } @@ -1128,16 +1122,16 @@ protected void copyBundledPlugin(URL src, String fileName) throws IOException { url); } } - } + } // If input stream is undefined, use the default implementation if (in == null) { in = url.openStream(); } - + return in; } - + /** * Retrieves modification date of the specified file. * The method intelligently handles the case of {@link JarURLConnection} pointing to files within JAR. @@ -1148,7 +1142,7 @@ protected void copyBundledPlugin(URL src, String fileName) throws IOException { @NonNull /*package*/ static long getModificationDate(@NonNull URL url) throws IOException { URLConnection uc = url.openConnection(); - + // It prevents file descriptor leak if the URL references a file within JAR // See JENKINS-37332 for more info // The code idea is taken from https://github.com/jknack/handlebars.java/pull/394 @@ -1167,7 +1161,7 @@ protected void copyBundledPlugin(URL src, String fileName) throws IOException { } } } - + // Fallbak to the default implementation return uc.getLastModified(); } @@ -1190,31 +1184,31 @@ private void rename(File legacyFile, File newFile) throws IOException { * Creates a hudson.PluginStrategy, looking at the corresponding system property. */ protected PluginStrategy createPluginStrategy() { - String strategyName = SystemProperties.getString(PluginStrategy.class.getName()); - if (strategyName != null) { - try { - Class klazz = getClass().getClassLoader().loadClass(strategyName); - Object strategy = klazz.getConstructor(PluginManager.class) - .newInstance(this); - if (strategy instanceof PluginStrategy) { - LOGGER.info("Plugin strategy: " + strategyName); - return (PluginStrategy) strategy; - } else { - LOGGER.warning("Plugin strategy (" + strategyName + - ") is not an instance of hudson.PluginStrategy"); - } - } catch (ClassNotFoundException e) { - LOGGER.warning("Plugin strategy class not found: " - + strategyName); - } catch (Exception e) { - LOGGER.log(WARNING, "Could not instantiate plugin strategy: " - + strategyName + ". Falling back to ClassicPluginStrategy", e); - } - LOGGER.info("Falling back to ClassicPluginStrategy"); - } - - // default and fallback - return new ClassicPluginStrategy(this); + String strategyName = SystemProperties.getString(PluginStrategy.class.getName()); + if (strategyName != null) { + try { + Class klazz = getClass().getClassLoader().loadClass(strategyName); + Object strategy = klazz.getConstructor(PluginManager.class) + .newInstance(this); + if (strategy instanceof PluginStrategy) { + LOGGER.info("Plugin strategy: " + strategyName); + return (PluginStrategy) strategy; + } else { + LOGGER.warning("Plugin strategy (" + strategyName + + ") is not an instance of hudson.PluginStrategy"); + } + } catch (ClassNotFoundException e) { + LOGGER.warning("Plugin strategy class not found: " + + strategyName); + } catch (Exception e) { + LOGGER.log(WARNING, "Could not instantiate plugin strategy: " + + strategyName + ". Falling back to ClassicPluginStrategy", e); + } + LOGGER.info("Falling back to ClassicPluginStrategy"); + } + + // default and fallback + return new ClassicPluginStrategy(this); } public PluginStrategy getPluginStrategy() { @@ -1250,7 +1244,7 @@ public List getFailedPlugins() { @CheckForNull public PluginWrapper getPlugin(String shortName) { for (PluginWrapper p : getPlugins()) { - if(p.getShortName().equals(shortName)) + if (p.getShortName().equals(shortName)) return p; } return null; @@ -1267,7 +1261,7 @@ public PluginWrapper getPlugin(String shortName) { @CheckForNull public PluginWrapper getPlugin(Class pluginClazz) { for (PluginWrapper p : getPlugins()) { - if(pluginClazz.isInstance(p.getPlugin())) + if (pluginClazz.isInstance(p.getPlugin())) return p; } return null; @@ -1282,16 +1276,18 @@ public PluginWrapper getPlugin(Class pluginClazz) { public List getPlugins(Class pluginSuperclass) { List result = new ArrayList<>(); for (PluginWrapper p : getPlugins()) { - if(pluginSuperclass.isInstance(p.getPlugin())) + if (pluginSuperclass.isInstance(p.getPlugin())) result.add(p); } return Collections.unmodifiableList(result); } + @Override public String getDisplayName() { return Messages.PluginManager_DisplayName(); } + @Override public String getSearchUrl() { return "pluginManager"; } @@ -1302,7 +1298,7 @@ public String getSearchUrl() { * @deprecated Use {@link ServiceLoader} instead, or (more commonly) {@link ExtensionList}. */ @Deprecated - public Collection> discover( Class spi ) { + public Collection> discover(Class spi) { Set> result = new HashSet<>(); for (PluginWrapper p : activePlugins) { @@ -1321,8 +1317,8 @@ public PluginWrapper whichPlugin(Class c) { PluginWrapper oneAndOnly = null; ClassLoader cl = c.getClassLoader(); for (PluginWrapper p : activePlugins) { - if (p.classLoader==cl) { - if (oneAndOnly!=null) + if (p.classLoader == cl) { + if (oneAndOnly != null) return null; // ambiguous oneAndOnly = p; } @@ -1333,12 +1329,16 @@ public PluginWrapper whichPlugin(Class c) { /** * Orderly terminates all the plugins. */ - public void stop() { + public synchronized void stop() { for (PluginWrapper p : activePlugins) { p.stop(); + } + List pluginsCopy = new ArrayList<>(plugins); + for (PluginWrapper p : pluginsCopy) { + activePlugins.remove(p); + plugins.remove(p); p.releaseClassLoader(); } - activePlugins.clear(); // Work around a bug in commons-logging. // See http://www.szegedi.org/articles/memleak.html LogFactory.release(uberClassLoader); @@ -1348,7 +1348,7 @@ public void stop() { public static boolean isNonMetaLabel(String label) { return !("adopt-this-plugin".equals(label) || "deprecated".equals(label)); } - + @Restricted(NoExternalUse.class) public HttpResponse doPluginsSearch(@QueryParameter String query, @QueryParameter Integer limit) { List plugins = new ArrayList<>(); @@ -1459,10 +1459,10 @@ public HttpResponse doPluginsSearch(@QueryParameter String query, @QueryParamete JSONArray mappedPlugins = new JSONArray(); mappedPlugins.addAll(plugins); - + return hudson.util.HttpResponses.okJSON(mappedPlugins); } - + /** * Get the list of all plugins - available and installed. * @return The list of all plugins - available and installed. @@ -1471,7 +1471,7 @@ public HttpResponse doPluginsSearch(@QueryParameter String query, @QueryParamete public HttpResponse doPlugins() { Jenkins.get().checkPermission(Jenkins.ADMINISTER); JSONArray response = new JSONArray(); - Map allPlugins = new HashMap<>(); + Map allPlugins = new HashMap<>(); for (PluginWrapper plugin : plugins) { JSONObject pluginInfo = new JSONObject(); pluginInfo.put("installed", true); @@ -1496,11 +1496,11 @@ public HttpResponse doPlugins() { response.add(pluginInfo); } for (UpdateSite site : Jenkins.get().getUpdateCenter().getSiteList()) { - for (UpdateSite.Plugin plugin: site.getAvailables()) { + for (UpdateSite.Plugin plugin : site.getAvailables()) { JSONObject pluginInfo = allPlugins.get(plugin.name); - if(pluginInfo == null) { - pluginInfo = new JSONObject(); - pluginInfo.put("installed", false); + if (pluginInfo == null) { + pluginInfo = new JSONObject(); + pluginInfo.put("installed", false); } pluginInfo.put("name", plugin.name); pluginInfo.put("title", plugin.getDisplayName()); @@ -1533,9 +1533,9 @@ public HttpResponse doUpdateSources(StaplerRequest req) throws IOException { return new HttpRedirect("./sites"); } - + /** - * Called to progress status beyond installing plugins, e.g. if + * Called to progress status beyond installing plugins, e.g. if * there were failures that prevented installation from naturally proceeding */ @RequirePOST @@ -1557,13 +1557,13 @@ public void doInstall(StaplerRequest req, StaplerResponse rsp) throws IOExceptio Enumeration en = req.getParameterNames(); while (en.hasMoreElements()) { String n = en.nextElement(); - if(n.startsWith("plugin.")) { + if (n.startsWith("plugin.")) { n = n.substring(7); plugins.add(n); } } - boolean dynamicLoad = req.getParameter("dynamicLoad")!=null; + boolean dynamicLoad = req.getParameter("dynamicLoad") != null; install(plugins, dynamicLoad); rsp.sendRedirect("../updateCenter/"); @@ -1599,7 +1599,7 @@ public HttpResponse doInstallPlugins(StaplerRequest req) throws IOException { responseData.put("correlationId", correlationId.toString()); return hudson.util.HttpResponses.okJSON(responseData); - } catch (Exception e) { + } catch (RuntimeException e) { return hudson.util.HttpResponses.errorJSON(e.getMessage()); } } @@ -1652,7 +1652,7 @@ private List> install(@NonNull Collection jobFuture : installJobs) { - if(!jobFuture.isDone() && !jobFuture.isCancelled()) { + if (!jobFuture.isDone() && !jobFuture.isCancelled()) { continue INSTALLING; } UpdateCenter.UpdateCenterJob job = jobFuture.get(); - if(job instanceof InstallationJob && ((InstallationJob)job).status instanceof DownloadJob.Failure) { + if (job instanceof InstallationJob && ((InstallationJob) job).status instanceof DownloadJob.Failure) { failures = true; } } @@ -1696,7 +1696,7 @@ public void run() { break; } updateCenter.persistInstallStatus(); - if(!failures) { + if (!failures) { try (ACLContext acl = ACL.as2(currentAuth)) { InstallUtil.proceedToNextStateFrom(InstallState.INITIAL_PLUGINS_INSTALLING); } @@ -1738,7 +1738,7 @@ public HttpResponse doProxyConfigure(StaplerRequest req) throws IOException, Ser jenkins.checkPermission(Jenkins.ADMINISTER); ProxyConfiguration pc = req.bindJSON(ProxyConfiguration.class, req.getSubmittedForm()); - if (pc.name==null) { + if (pc.name == null) { jenkins.proxy = null; ProxyConfiguration.getXmlFile().delete(); } else { @@ -1748,6 +1748,50 @@ public HttpResponse doProxyConfigure(StaplerRequest req) throws IOException, Ser return new HttpRedirect("advanced"); } + interface PluginCopier { + void copy(File target) throws Exception; + + void cleanup(); + } + + static class FileUploadPluginCopier implements PluginCopier { + private FileItem fileItem; + + FileUploadPluginCopier(FileItem fileItem) { + this.fileItem = fileItem; + } + + @Override + public void copy(File target) throws Exception { + fileItem.write(target); + } + + @Override + public void cleanup() { + fileItem.delete(); + } + } + + static class UrlPluginCopier implements PluginCopier { + private String url; + + UrlPluginCopier(String url) { + this.url = url; + } + + @Override + public void copy(File target) throws Exception { + try (InputStream input = ProxyConfiguration.getInputStream(new URL(url))) { + Files.copy(input, target.toPath()); + } + } + + @Override + public void cleanup() { + + } + } + /** * Uploads a plugin. */ @@ -1756,32 +1800,41 @@ public HttpResponse doUploadPlugin(StaplerRequest req) throws IOException, Servl try { Jenkins.get().checkPermission(Jenkins.ADMINISTER); + String fileName = ""; + PluginCopier copier; ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory()); + List items = upload.parseRequest(req); + if (StringUtils.isNotBlank(items.get(1).getString())) { + // this is a URL deployment + fileName = items.get(1).getString(); + copier = new UrlPluginCopier(fileName); + } else { + // this is a file upload + FileItem fileItem = items.get(0); + fileName = Util.getFileName(fileItem.getName()); + copier = new FileUploadPluginCopier(fileItem); + } - // Parse the request - FileItem fileItem = upload.parseRequest(req).get(0); - String fileName = Util.getFileName(fileItem.getName()); - if("".equals(fileName)){ + if ("".equals(fileName)) { return new HttpRedirect("advanced"); } // we allow the upload of the new jpi's and the legacy hpi's - if(!fileName.endsWith(".jpi") && !fileName.endsWith(".hpi")){ + if (!fileName.endsWith(".jpi") && !fileName.endsWith(".hpi")) { throw new Failure(hudson.model.Messages.Hudson_NotAPlugin(fileName)); } // first copy into a temporary file name File t = File.createTempFile("uploaded", ".jpi"); t.deleteOnExit(); + // TODO Remove this workaround after FILEUPLOAD-293 is resolved. + Files.delete(Util.fileToPath(t)); try { - // TODO Remove this workaround after FILEUPLOAD-293 is resolved. - t.delete(); - - fileItem.write(t); + copier.copy(t); } catch (Exception e) { // Exception thrown is too generic so at least limit the scope where it can occur throw new ServletException(e); } - fileItem.delete(); + copier.cleanup(); final String baseName = identifyPluginShortName(t); @@ -1807,7 +1860,7 @@ public HttpResponse doUploadPlugin(StaplerRequest req) throws IOException, Servl .element("optional", p.contains("resolution:=optional"))); } } - } catch(IOException e) { + } catch (IOException e) { LOGGER.log(WARNING, "Unable to setup dependency list for plugin upload", e); } @@ -1824,6 +1877,25 @@ public HttpResponse doUploadPlugin(StaplerRequest req) throws IOException, Servl } } + @Restricted(NoExternalUse.class) + @RequirePOST public FormValidation doCheckPluginUrl(StaplerRequest request, @QueryParameter String value) throws IOException { + if (StringUtils.isNotBlank(value)) { + try { + URL url = new URL(value); + if (!url.getProtocol().startsWith("http")) { + return FormValidation.error(Messages.PluginManager_invalidUrl()); + } + + if (!url.getProtocol().equals("https")) { + return FormValidation.warning(Messages.PluginManager_insecureUrl()); + } + } catch (MalformedURLException e) { + return FormValidation.error(e.getMessage()); + } + } + return FormValidation.ok(); + } + @Restricted(NoExternalUse.class) @RequirePOST public HttpResponse doCheckUpdatesServer() throws IOException { Jenkins.get().checkPermission(Jenkins.SYSTEM_READ); @@ -1849,7 +1921,7 @@ public HttpResponse doUploadPlugin(StaplerRequest req) throws IOException, Servl .withDuringActionExceptions(new Class[] {Exception.class}) // what we do with a failed attempt due to an allowed exception, return an FormValidation.error with the message - .withDuringActionExceptionListener( (attempt, e) -> FormValidation.errorWithMarkup(e.getClass().getSimpleName() + ": " + e.getLocalizedMessage())) + .withDuringActionExceptionListener((attempt, e) -> FormValidation.errorWithMarkup(e.getClass().getSimpleName() + ": " + e.getLocalizedMessage())) // lets get our retrier object .build(); @@ -1916,7 +1988,7 @@ protected String identifyPluginShortName(File t) { if (name != null) return name; } } catch (IOException e) { - LOGGER.log(WARNING, "Failed to identify the short name from "+t,e); + LOGGER.log(WARNING, "Failed to identify the short name from " + t, e); } return FilenameUtils.getBaseName(t.getName()); // fall back to the base name of what's uploaded } @@ -1948,7 +2020,7 @@ public List> prevalidateConfig(InputStream List> jobs = new ArrayList<>(); UpdateCenter uc = Jenkins.get().getUpdateCenter(); // TODO call uc.updateAllSites() when available? perhaps not, since we should not block on network here - for (Map.Entry requestedPlugin : parseRequestedPlugins(configXml).entrySet()) { + for (Map.Entry requestedPlugin : parseRequestedPlugins(configXml).entrySet()) { PluginWrapper pw = getPlugin(requestedPlugin.getKey()); if (pw == null) { // install new UpdateSite.Plugin toInstall = uc.getPlugin(requestedPlugin.getKey(), requestedPlugin.getValue()); @@ -2006,7 +2078,7 @@ public JSONArray doPrevalidateConfig(StaplerRequest req) throws IOException { JSONArray response = new JSONArray(); - for (Map.Entry p : parseRequestedPlugins(req.getInputStream()).entrySet()) { + for (Map.Entry p : parseRequestedPlugins(req.getInputStream()).entrySet()) { PluginWrapper pw = getPlugin(p.getKey()); JSONObject j = new JSONObject() .accumulate("name", p.getKey()) @@ -2034,10 +2106,13 @@ public HttpResponse doInstallNecessaryPlugins(StaplerRequest req) throws IOExcep /** * Parses configuration XML files and picks up references to XML files. */ - public Map parseRequestedPlugins(InputStream configXml) throws IOException { - final Map requestedPlugins = new TreeMap<>(); + public Map parseRequestedPlugins(InputStream configXml) throws IOException { + final Map requestedPlugins = new TreeMap<>(); try { - SAXParserFactory.newInstance().newSAXParser().parse(configXml, new DefaultHandler() { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + spf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); + spf.newSAXParser().parse(configXml, new DefaultHandler() { @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { String plugin = attributes.getValue("plugin"); if (plugin == null) { @@ -2062,7 +2137,7 @@ public Map parseRequestedPlugins(InputStream configXml) th }); } catch (SAXException x) { - throw new IOException("Failed to parse XML",x); + throw new IOException("Failed to parse XML", x); } catch (ParserConfigurationException e) { throw new AssertionError(e); // impossible since we don't tweak XMLParser } @@ -2102,6 +2177,7 @@ public MetadataCache createCache() { @Restricted(NoExternalUse.class) // table.jelly public static final class MetadataCache { private final Map data = new HashMap<>(); + public T of(String key, Class type, Supplier func) { return type.cast(data.computeIfAbsent(key, _ignored -> func.get())); } @@ -2110,96 +2186,56 @@ public T of(String key, Class type, Supplier func) { /** * {@link ClassLoader} that can see all plugins. */ - public final class UberClassLoader extends ClassLoader { - /** - * Make generated types visible. - * Keyed by the generated class name. - */ - private ConcurrentMap> generatedClasses = new ConcurrentHashMap<>(); + public static final class UberClassLoader extends ClassLoader { + private final List activePlugins; + /** Cache of loaded, or known to be unloadable, classes. */ - private final Map> loaded = new HashMap<>(); + private final ConcurrentMap>> loaded = new ConcurrentHashMap<>(); - public UberClassLoader() { - super(PluginManager.class.getClassLoader()); + static { + registerAsParallelCapable(); } - public void addNamedClass(String className, Class c) { - generatedClasses.put(className, new WeakReference<>(c)); + public UberClassLoader(List activePlugins) { + super(PluginManager.class.getClassLoader()); + this.activePlugins = activePlugins; } @Override protected Class findClass(String name) throws ClassNotFoundException { - WeakReference wc = generatedClasses.get(name); - if (wc!=null) { - Class c = wc.get(); - if (c!=null) return c; - else generatedClasses.remove(name,wc); - } - if (name.startsWith("SimpleTemplateScript")) { // cf. groovy.text.SimpleTemplateEngine throw new ClassNotFoundException("ignoring " + name); } - synchronized (loaded) { - if (loaded.containsKey(name)) { - Class c = loaded.get(name); - if (c != null) { - return c; + return loaded.computeIfAbsent(name, this::computeValue).orElseThrow(() -> new ClassNotFoundException(name)); + } + + private Optional> computeValue(String name) { + for (PluginWrapper p : activePlugins) { + try { + if (FAST_LOOKUP) { + return Optional.of(ClassLoaderReflectionToolkit.loadClass(p.classLoader, name)); } else { - throw new ClassNotFoundException("cached miss for " + name); - } - } - } - if (FAST_LOOKUP) { - for (PluginWrapper p : activePlugins) { - try { - Class c = ClassLoaderReflectionToolkit._findLoadedClass(p.classLoader, name); - if (c != null) { - synchronized (loaded) { - loaded.put(name, c); - } - return c; - } - // calling findClass twice appears to cause LinkageError: duplicate class def - c = ClassLoaderReflectionToolkit._findClass(p.classLoader, name); - synchronized (loaded) { - loaded.put(name, c); - } - return c; - } catch (ClassNotFoundException e) { - //not found. try next - } - } - } else { - for (PluginWrapper p : activePlugins) { - try { - return p.classLoader.loadClass(name); - } catch (ClassNotFoundException e) { - //not found. try next + return Optional.of(p.classLoader.loadClass(name)); } + } catch (ClassNotFoundException e) { + // Not found. Try the next class loader. } } - synchronized (loaded) { - loaded.put(name, null); - } - // not found in any of the classloader. delegate. - ClassNotFoundException cnfe = new ClassNotFoundException(name); - MissingClassTelemetry.reportException(name, cnfe); - throw cnfe; + // Not found in any of the class loaders. Delegate. + return Optional.empty(); } @Override protected URL findResource(String name) { - if (FAST_LOOKUP) { - for (PluginWrapper p : activePlugins) { - URL url = ClassLoaderReflectionToolkit._findResource(p.classLoader, name); - if(url!=null) - return url; - } - } else { - for (PluginWrapper p : activePlugins) { - URL url = p.classLoader.getResource(name); - if(url!=null) - return url; + for (PluginWrapper p : activePlugins) { + URL url; + if (FAST_LOOKUP) { + url = ClassLoaderReflectionToolkit._findResource(p.classLoader, name); + } else { + url = p.classLoader.getResource(name); + } + if (url != null) { + return url; } } return null; @@ -2208,12 +2244,10 @@ protected URL findResource(String name) { @Override protected Enumeration findResources(String name) throws IOException { List resources = new ArrayList<>(); - if (FAST_LOOKUP) { - for (PluginWrapper p : activePlugins) { - resources.addAll(Collections.list(ClassLoaderReflectionToolkit._findResources(p.classLoader, name))); - } - } else { - for (PluginWrapper p : activePlugins) { + for (PluginWrapper p : activePlugins) { + if (FAST_LOOKUP) { + resources.addAll(Collections.list(ClassLoaderReflectionToolkit._findResources(p.classLoader, name))); + } else { resources.addAll(Collections.list(p.classLoader.getResources(name))); } } @@ -2226,16 +2260,17 @@ public String toString() { return "classLoader " + getClass().getName(); } } - @SuppressFBWarnings("MS_SHOULD_BE_FINAL") - public static boolean FAST_LOOKUP = !SystemProperties.getBoolean(PluginManager.class.getName()+".noFastLookup"); + + @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "for script console") + public static boolean FAST_LOOKUP = !SystemProperties.getBoolean(PluginManager.class.getName() + ".noFastLookup"); /** @deprecated in Jenkins 2.222 use {@link Jenkins#ADMINISTER} instead */ @Deprecated - public static final Permission UPLOAD_PLUGINS = new Permission(Jenkins.PERMISSIONS, "UploadPlugins", Messages._PluginManager_UploadPluginsPermission_Description(),Jenkins.ADMINISTER,PermissionScope.JENKINS); + public static final Permission UPLOAD_PLUGINS = new Permission(Jenkins.PERMISSIONS, "UploadPlugins", Messages._PluginManager_UploadPluginsPermission_Description(), Jenkins.ADMINISTER, PermissionScope.JENKINS); /** @deprecated in Jenkins 2.222 use {@link Jenkins#ADMINISTER} instead */ @Deprecated - public static final Permission CONFIGURE_UPDATECENTER = new Permission(Jenkins.PERMISSIONS, "ConfigureUpdateCenter", Messages._PluginManager_ConfigureUpdateCenterPermission_Description(),Jenkins.ADMINISTER,PermissionScope.JENKINS); + public static final Permission CONFIGURE_UPDATECENTER = new Permission(Jenkins.PERMISSIONS, "ConfigureUpdateCenter", Messages._PluginManager_ConfigureUpdateCenterPermission_Description(), Jenkins.ADMINISTER, PermissionScope.JENKINS); /** * Remembers why a plugin failed to deploy. @@ -2243,10 +2278,25 @@ public String toString() { public static final class FailedPlugin { public final String name; public final Exception cause; + @Nullable + public final PluginWrapper pluginWrapper; + /** + * Constructor for FailedPlugin when we do not have an associated PluginWrapper + */ public FailedPlugin(String name, Exception cause) { this.name = name; this.cause = cause; + this.pluginWrapper = null; + } + + /** + * Constructor for FailedPlugin when we know which PluginWrapper failed + */ + public FailedPlugin(PluginWrapper pluginWrapper, Exception cause) { + this.name = pluginWrapper.getShortName(); + this.cause = cause; + this.pluginWrapper = pluginWrapper; } public String getExceptionString() { @@ -2258,7 +2308,7 @@ public String getExceptionString() { * Stores {@link Plugin} instances. */ /*package*/ static final class PluginInstanceStore { - final Map store = new ConcurrentHashMap<>(); + final Map store = new ConcurrentHashMap<>(); } /** @@ -2276,11 +2326,12 @@ public String getDisplayName() { private transient volatile List pluginsWithCycle; + @Override public boolean isActivated() { - if(pluginsWithCycle == null){ + if (pluginsWithCycle == null) { pluginsWithCycle = new ArrayList<>(); for (PluginWrapper p : Jenkins.get().getPluginManager().getPlugins()) { - if(p.hasCycleDependency()){ + if (p.hasCycleDependency()) { pluginsWithCycle.add(p); isActive = true; } @@ -2318,15 +2369,16 @@ public static PluginUpdateMonitor getInstance() { * @param requiredVersion the lowest version which is OK (e.g. 2.2.2) * @param message the message to show (plain text) */ - public void ifPluginOlderThenReport(String pluginName, String requiredVersion, String message){ + public void ifPluginOlderThenReport(String pluginName, String requiredVersion, String message) { Plugin plugin = Jenkins.get().getPlugin(pluginName); - if(plugin != null){ - if(plugin.getWrapper().getVersionNumber().isOlderThan(new VersionNumber(requiredVersion))) { + if (plugin != null) { + if (plugin.getWrapper().getVersionNumber().isOlderThan(new VersionNumber(requiredVersion))) { pluginsToBeUpdated.put(pluginName, new PluginUpdateInfo(pluginName, message)); } } } + @Override public boolean isActivated() { return !pluginsToBeUpdated.isEmpty(); } @@ -2352,6 +2404,7 @@ public Collection getPluginsToBeUpdated() { public static class PluginUpdateInfo { public final String pluginName; public final String message; + private PluginUpdateInfo(String pluginName, String message) { this.pluginName = pluginName; this.message = message; @@ -2375,6 +2428,7 @@ public String getDisplayName() { return Messages.PluginManager_PluginDeprecationMonitor_DisplayName(); } + @Override public boolean isActivated() { return !getDeprecatedPlugins().isEmpty(); } @@ -2431,6 +2485,6 @@ public boolean hasAdoptThisPluginLabel(PluginWrapper plugin) { * Escape hatch for StaplerProxy-based access control */ @Restricted(NoExternalUse.class) - @SuppressFBWarnings("MS_SHOULD_BE_FINAL") - public static /* Script Console modifiable */ boolean SKIP_PERMISSION_CHECK = Boolean.getBoolean(PluginManager.class.getName() + ".skipPermissionCheck"); + @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "for script console") + public static /* Script Console modifiable */ boolean SKIP_PERMISSION_CHECK = SystemProperties.getBoolean(PluginManager.class.getName() + ".skipPermissionCheck"); } diff --git a/core/src/main/java/hudson/PluginStrategy.java b/core/src/main/java/hudson/PluginStrategy.java index 0a4a6e7968b4..2b237931c038 100644 --- a/core/src/main/java/hudson/PluginStrategy.java +++ b/core/src/main/java/hudson/PluginStrategy.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Tom Huybrechts - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,15 +21,16 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.model.Hudson; import java.io.File; import java.io.IOException; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; -import edu.umd.cs.findbugs.annotations.NonNull; /** * Pluggability point for how to create {@link PluginWrapper}. @@ -43,13 +44,13 @@ */ public interface PluginStrategy extends ExtensionPoint { - /** - * Creates a plugin wrapper, which provides a management interface for the plugin - * @param archive + /** + * Creates a plugin wrapper, which provides a management interface for the plugin + * @param archive * Either a directory that points to a pre-exploded plugin, or an jpi file, or an jpl file. - */ - PluginWrapper createPluginWrapper(File archive) - throws IOException; + */ + PluginWrapper createPluginWrapper(File archive) + throws IOException; /** * Finds the plugin name without actually unpacking anything {@link #createPluginWrapper} would. @@ -58,34 +59,32 @@ PluginWrapper createPluginWrapper(File archive) */ @NonNull String getShortName(File archive) throws IOException; - /** - * Loads the plugin and starts it. - * - *

- * This should be done after all the classloaders are constructed for all - * the plugins, so that dependencies can be properly loaded by plugins. - */ - void load(PluginWrapper wrapper) throws IOException; + /** + * Loads the plugin and starts it. + * + *

+ * This should be done after all the classloaders are constructed for all + * the plugins, so that dependencies can be properly loaded by plugins. + */ + void load(PluginWrapper wrapper) throws IOException; - /** - * Optionally start services provided by the plugin. Should be called - * when all plugins are loaded. - * - * @param plugin - */ - void initializeComponents(PluginWrapper plugin); + /** + * Optionally start services provided by the plugin. Should be called + * when all plugins are loaded. + */ + void initializeComponents(PluginWrapper plugin); - /** - * Find components of the given type using the assigned strategy. - * - * + /** + * Find components of the given type using the assigned strategy. + * + * * @param type The component type * @param hudson The Hudson scope * @return Sequence of components - * @since 1.400 - */ - List> findComponents(Class type, Hudson hudson); - + * @since 1.400 + */ + List> findComponents(Class type, Hudson hudson); + /** * Called when a plugin is installed, but there was already a plugin installed which optionally depended on that plugin. * The class loader of the existing depending plugin should be updated diff --git a/core/src/main/java/hudson/PluginWrapper.java b/core/src/main/java/hudson/PluginWrapper.java index 64a432f22589..a42596726cdb 100644 --- a/core/src/main/java/hudson/PluginWrapper.java +++ b/core/src/main/java/hudson/PluginWrapper.java @@ -1,19 +1,19 @@ /* * The MIT License - * + * * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, * Yahoo! Inc., Erik Ramfelt, Tom Huybrechts - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -22,10 +22,20 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson; -import com.google.common.collect.ImmutableSet; +import static hudson.PluginWrapper.PluginDisableStatus.ALREADY_DISABLED; +import static hudson.PluginWrapper.PluginDisableStatus.DISABLED; +import static hudson.PluginWrapper.PluginDisableStatus.ERROR_DISABLING; +import static hudson.PluginWrapper.PluginDisableStatus.NOT_DISABLED_DEPENDANTS; +import static hudson.PluginWrapper.PluginDisableStatus.NO_SUCH_PLUGIN; +import static java.util.logging.Level.WARNING; +import static org.apache.commons.io.FilenameUtils.getBaseName; + import com.google.common.collect.Sets; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.PluginManager.PluginInstanceStore; import hudson.model.AdministrativeMonitor; import hudson.model.Api; @@ -34,30 +44,12 @@ import hudson.model.UpdateSite; import hudson.util.VersionNumber; import io.jenkins.lib.versionnumber.JavaSpecificationVersion; -import jenkins.YesNoMaybe; -import jenkins.model.Jenkins; -import jenkins.security.UpdateSiteWarningsMonitor; -import jenkins.util.java.JavaUtils; -import org.apache.commons.lang.StringUtils; -import org.apache.commons.logging.LogFactory; -import org.kohsuke.accmod.Restricted; -import org.kohsuke.accmod.restrictions.DoNotUse; -import org.kohsuke.accmod.restrictions.NoExternalUse; -import org.kohsuke.stapler.HttpResponse; -import org.kohsuke.stapler.HttpResponses; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; -import org.kohsuke.stapler.export.Exported; -import org.kohsuke.stapler.export.ExportedBean; -import org.kohsuke.stapler.interceptor.RequirePOST; - -import edu.umd.cs.findbugs.annotations.CheckForNull; -import edu.umd.cs.findbugs.annotations.NonNull; import java.io.Closeable; import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.net.URL; +import java.net.URLClassLoader; import java.nio.file.Files; import java.nio.file.InvalidPathException; import java.util.ArrayList; @@ -77,15 +69,26 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; - -import static hudson.PluginWrapper.PluginDisableStatus.ALREADY_DISABLED; -import static hudson.PluginWrapper.PluginDisableStatus.DISABLED; -import static hudson.PluginWrapper.PluginDisableStatus.ERROR_DISABLING; -import static hudson.PluginWrapper.PluginDisableStatus.NOT_DISABLED_DEPENDANTS; -import static hudson.PluginWrapper.PluginDisableStatus.NO_SUCH_PLUGIN; -import static java.util.logging.Level.WARNING; +import jenkins.YesNoMaybe; +import jenkins.model.Jenkins; import jenkins.plugins.DetachedPluginsUtil; -import static org.apache.commons.io.FilenameUtils.getBaseName; +import jenkins.security.UpdateSiteWarningsMonitor; +import jenkins.util.AntClassLoader; +import jenkins.util.URLClassLoader2; +import jenkins.util.java.JavaUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.LogFactory; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.Beta; +import org.kohsuke.accmod.restrictions.DoNotUse; +import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.stapler.HttpResponse; +import org.kohsuke.stapler.HttpResponses; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.export.Exported; +import org.kohsuke.stapler.export.ExportedBean; +import org.kohsuke.stapler.interceptor.RequirePOST; /** * Represents a Jenkins plug-in and associated control information @@ -111,11 +114,12 @@ */ @ExportedBean public class PluginWrapper implements Comparable, ModelObject { + /** * A plugin won't be loaded unless his declared dependencies are present and match the required minimal version. * This can be set to false to disable the version check (legacy behaviour) */ - private static final boolean ENABLE_PLUGIN_DEPENDENCIES_VERSION_CHECK = Boolean.parseBoolean(System.getProperty(PluginWrapper.class.getName()+"." + "dependenciesVersionCheck.enabled", "true")); + private static final boolean ENABLE_PLUGIN_DEPENDENCIES_VERSION_CHECK = Boolean.parseBoolean(System.getProperty(PluginWrapper.class.getName() + "." + "dependenciesVersionCheck.enabled", "true")); /** * {@link PluginManager} to which this belongs to. @@ -165,7 +169,7 @@ public class PluginWrapper implements Comparable, ModelObject { * The snapshot of {@code disableFile.exists()} as of the start up. */ private final boolean active; - + private boolean hasCycleDependency = false; private final List dependencies; @@ -220,7 +224,7 @@ public boolean hasDerivedDependencyErrors() { * The core can depend on a plugin if it is bundled. Sometimes it's the only thing that * depends on the plugin e.g. UI support library bundle plugin. */ - private static Set CORE_ONLY_DEPENDANT = ImmutableSet.copyOf(Collections.singletonList("jenkins-core")); + private static Set CORE_ONLY_DEPENDANT = Collections.singleton("jenkins-core"); /** * Set the list of components that depend on this plugin. @@ -307,7 +311,7 @@ public void setOptionalDependants(@NonNull Set optionalDependents) { * plugin, otherwise {@code false}. */ public boolean hasDependents() { - return (isBundled || !dependents.isEmpty()); + return isBundled || !dependents.isEmpty(); } /** @@ -378,6 +382,56 @@ public boolean isDeprecated() { return !getDeprecations().isEmpty(); } + /** + * Inject the specified jar file(s) to the plugins classpath. + *

Warning: This is advanced usage that you should not be needed in 99.9% of all cases, any jar insertion + * should happen early into the plugins lifecycle to prevent classloading issues in dependent plugins. + *

+ * Rather than use this functionality it is to have co-operative behaviour between any consumer of the libraries and load the classes in a separate {@link ClassLoader}. + * you can expose third-party libraries from a dynamic location in various ways, such as: + * + *

    + *
  • You could split your plugin into two modules: + *
      + *
    • regular Jenkins plugin code, plus some interface encapsulating access to the lib via a minimal, simplified + * API + *
    • an implementation of that interface which compiles against a provided static reference copy of the library, + * and which is packaged in your plugin as a resource (not in WEB-INF/lib/*.jar) + *
    + *
  • with coordination: + *
      + *
    • dynamically find some JAR(s) on the controller (or perhaps even agent) + *
    • find the bridge JAR in your plugin’s resources area + *
    • create some {@link URLClassLoader} loading them both, parented to the plugin {@link ClassLoader} + *
    • use reflection to load & instantiate the class of the bridge implementation, casting to the interface from + * the plugin + *
    + *
+ * For a concrete example see the database + * plugin. * + * + * @throws Exception if the File could not be inserted into the classpath for some reason. + * @since 2.313 + */ + @Restricted(Beta.class) + public void injectJarsToClasspath(File... jars) throws Exception { + if (classLoader instanceof AntClassLoader) { + for (File f : jars) { + LOGGER.log(Level.CONFIG, () -> "Inserting " + f + " into " + shortName + " plugin's classpath"); + ((AntClassLoader) classLoader).addPathComponent(f); + } + } else if (classLoader instanceof URLClassLoader2) { + for (File f : jars) { + LOGGER.log(Level.CONFIG, () -> "Inserting " + f + " into " + shortName + " plugin's classpath"); + ((URLClassLoader2) classLoader).addURL(f.toURI().toURL()); + } + } else { + throw new AssertionError("PluginWrapper classloader has changed type, but this code has not been updated accordingly"); + } + + } + @ExportedBean public static final class Dependency { @Exported @@ -389,10 +443,10 @@ public static final class Dependency { public Dependency(String s) { int idx = s.indexOf(':'); - if(idx==-1) - throw new IllegalArgumentException("Illegal dependency specifier "+s); - this.shortName = Util.intern(s.substring(0,idx)); - String version = Util.intern(s.substring(idx+1)); + if (idx == -1) + throw new IllegalArgumentException("Illegal dependency specifier " + s); + this.shortName = Util.intern(s.substring(0, idx)); + String version = Util.intern(s.substring(idx + 1)); boolean isOptional = false; String[] osgiProperties = version.split("[;]"); @@ -414,41 +468,42 @@ public Dependency(String s) { @Override public String toString() { return shortName + " (" + version + ")" + (optional ? " optional" : ""); - } + } } /** * @param archive * A .jpi archive file jar file, or a .jpl linked plugin. * @param manifest - * The manifest for the plugin + * The manifest for the plugin * @param baseResourceURL - * A URL pointing to the resources for this plugin + * A URL pointing to the resources for this plugin * @param classLoader - * a classloader that loads classes from this plugin and its dependencies + * a classloader that loads classes from this plugin and its dependencies * @param disableFile - * if this file exists on startup, the plugin will not be activated + * if this file exists on startup, the plugin will not be activated * @param dependencies a list of mandatory dependencies * @param optionalDependencies a list of optional dependencies */ - public PluginWrapper(PluginManager parent, File archive, Manifest manifest, URL baseResourceURL, - ClassLoader classLoader, File disableFile, - List dependencies, List optionalDependencies) { + public PluginWrapper(PluginManager parent, File archive, Manifest manifest, URL baseResourceURL, + ClassLoader classLoader, File disableFile, + List dependencies, List optionalDependencies) { this.parent = parent; - this.manifest = manifest; - this.shortName = Util.intern(computeShortName(manifest, archive.getName())); - this.baseResourceURL = baseResourceURL; - this.classLoader = classLoader; - this.disableFile = disableFile; - this.active = !disableFile.exists(); - this.dependencies = dependencies; - this.optionalDependencies = optionalDependencies; + this.manifest = manifest; + this.shortName = Util.intern(computeShortName(manifest, archive.getName())); + this.baseResourceURL = baseResourceURL; + this.classLoader = classLoader; + this.disableFile = disableFile; + this.active = !disableFile.exists(); + this.dependencies = dependencies; + this.optionalDependencies = optionalDependencies; for (Dependency d : optionalDependencies) { assert d.optional : d + " included among optionalDependencies of " + shortName + " but was not marked optional"; } this.archive = archive; } + @Override public String getDisplayName() { return StringUtils.removeStart(getLongName(), "Jenkins "); } @@ -479,11 +534,11 @@ static String computeShortName(Manifest manifest, String fileName) { // use the name captured in the manifest, as often plugins // depend on the specific short name in its URLs. String n = manifest.getMainAttributes().getValue("Short-Name"); - if(n!=null) return n; + if (n != null) return n; // maven seems to put this automatically, so good fallback to check. n = manifest.getMainAttributes().getValue("Extension-Name"); - if(n!=null) return n; + if (n != null) return n; // otherwise infer from the file name, since older plugins don't have // this entry. @@ -554,7 +609,7 @@ public String getUrl() { List siteMetadataList = getInfoFromAllSites(); String firstSiteUrl = null; if (!siteMetadataList.isEmpty()) { - firstSiteUrl = siteMetadataList.get(0).wiki; + firstSiteUrl = siteMetadataList.get(0).wiki; if (allUrlsMatch(firstSiteUrl, siteMetadataList)) { return firstSiteUrl; } @@ -564,7 +619,7 @@ public String getUrl() { // use manifest (since maven-hpi-plugin 1.30) String url = manifest.getMainAttributes().getValue("Url"); if (url != null) { - return url; + return url; } return firstSiteUrl; } @@ -573,7 +628,7 @@ private boolean allUrlsMatch(String url, List uiList) { return uiList.stream().allMatch(k -> k.wiki != null && k.wiki.equals(url)); } - @Override + @Override public String toString() { return "Plugin:" + getShortName(); } @@ -587,7 +642,7 @@ public String toString() { @Deprecated public String getLongName() { String name = manifest.getMainAttributes().getValue("Long-Name"); - if(name!=null) return name; + if (name != null) return name; return shortName; } @@ -597,7 +652,7 @@ public String getLongName() { @Exported public YesNoMaybe supportsDynamicLoad() { String v = manifest.getMainAttributes().getValue("Support-Dynamic-Loading"); - if (v==null) return YesNoMaybe.MAYBE; + if (v == null) return YesNoMaybe.MAYBE; return Boolean.parseBoolean(v) ? YesNoMaybe.YES : YesNoMaybe.NO; } @@ -611,11 +666,11 @@ public String getVersion() { private String getVersionOf(Manifest manifest) { String v = manifest.getMainAttributes().getValue("Plugin-Version"); - if(v!=null) return v; + if (v != null) return v; // plugins generated before maven-hpi-plugin 1.3 should still have this attribute v = manifest.getMainAttributes().getValue("Implementation-Version"); - if(v!=null) return v; + if (v != null) return v; return "???"; } @@ -628,10 +683,10 @@ private String getVersionOf(Manifest manifest) { @Exported public @CheckForNull String getRequiredCoreVersion() { String v = manifest.getMainAttributes().getValue("Jenkins-Version"); - if (v!= null) return v; + if (v != null) return v; v = manifest.getMainAttributes().getValue("Hudson-Version"); - if (v!= null) return v; + if (v != null) return v; return null; } @@ -640,7 +695,7 @@ private String getVersionOf(Manifest manifest) { * Generally coming from the {@code java.level} extracted as MANIFEST's metadata with * this addition on the plugins' parent pom. * - * @see maven-hpi-plugin#PR-75. + * @see maven-hpi-plugin#PR-75 * * @since 2.158 */ @@ -664,7 +719,7 @@ public boolean isOlderThan(VersionNumber v) { return getVersionNumber().compareTo(v) < 0; } catch (IllegalArgumentException e) { // if we can't figure out our current version, it probably means it's very old, - // since the version information is missing only from the very old plugins + // since the version information is missing only from the very old plugins return true; } } @@ -694,7 +749,7 @@ public void releaseClassLoader() { try { ((Closeable) classLoader).close(); } catch (IOException e) { - LOGGER.log(WARNING, "Failed to shut down classloader",e); + LOGGER.log(WARNING, "Failed to shut down classloader", e); } } @@ -706,22 +761,22 @@ public void enable() throws IOException { LOGGER.log(Level.FINEST, "Plugin {0} has been already enabled. Skipping the enable() operation", getShortName()); return; } - if(!disableFile.delete()) - throw new IOException("Failed to delete "+disableFile); + if (!disableFile.delete()) + throw new IOException("Failed to delete " + disableFile); } /** * Disables this plugin next time Jenkins runs. As it doesn't check anything, it's recommended to use the method * {@link #disable(PluginDisableStrategy)} + * @deprecated use {@link #disable(PluginDisableStrategy)} */ - @Deprecated //see https://issues.jenkins-ci.org/browse/JENKINS-27177 + @Deprecated //see https://issues.jenkins.io/browse/JENKINS-27177 public void disable() throws IOException { disableWithoutCheck(); } /** * Disable a plugin wihout checking any dependency. Only add the disable file. - * @throws IOException */ private void disableWithoutCheck() throws IOException { try (OutputStream os = Files.newOutputStream(disableFile.toPath())) { @@ -835,12 +890,12 @@ private Set dependentsToCheck(PluginDisableStrategy strategy) { public boolean isActive() { return active && !hasCycleDependency(); } - - public boolean hasCycleDependency(){ + + public boolean hasCycleDependency() { return hasCycleDependency; } - public void setHasCycleDependency(boolean hasCycle){ + public void setHasCycleDependency(boolean hasCycle) { hasCycleDependency = hasCycle; } @@ -868,7 +923,7 @@ public Manifest getManifest() { } public void setPlugin(Plugin plugin) { - Jenkins.lookup(PluginInstanceStore.class).store.put(this,plugin); + Jenkins.lookup(PluginInstanceStore.class).store.put(this, plugin); plugin.wrapper = this; } @@ -878,7 +933,7 @@ public String getPluginClass() { public boolean hasLicensesXml() { try { - new URL(baseResourceURL,"WEB-INF/licenses.xml").openStream().close(); + new URL(baseResourceURL, "WEB-INF/licenses.xml").openStream().close(); return true; } catch (IOException e) { return false; @@ -918,7 +973,7 @@ public boolean hasLicensesXml() { if (dependency == null) { PluginWrapper failedDependency = NOTICE.getPlugin(d.shortName); if (failedDependency != null) { - dependencyErrors.put(Messages.PluginWrapper_failed_to_load_dependency(failedDependency.getLongName(), failedDependency.getVersion()), true); + dependencyErrors.put(Messages.PluginWrapper_failed_to_load_dependency_2(failedDependency.getLongName(), failedDependency.getShortName(), failedDependency.getVersion()), true); break; } else { dependencyErrors.put(Messages.PluginWrapper_missing(d.shortName, d.version), false); @@ -926,13 +981,13 @@ public boolean hasLicensesXml() { } else { if (dependency.isActive()) { if (isDependencyObsolete(d, dependency)) { - versionDependencyError(Messages.PluginWrapper_obsolete(dependency.getLongName(), dependency.getVersion(), d.version), dependency.getVersion(), d.version); + versionDependencyError(Messages.PluginWrapper_obsolete_2(dependency.getLongName(), dependency.getShortName(), dependency.getVersion(), d.version), dependency.getVersion(), d.version); } } else { if (isDependencyObsolete(d, dependency)) { - versionDependencyError(Messages.PluginWrapper_disabledAndObsolete(dependency.getLongName(), dependency.getVersion(), d.version), dependency.getVersion(), d.version); + versionDependencyError(Messages.PluginWrapper_obsolete_2(dependency.getLongName(), dependency.getShortName(), dependency.getVersion(), d.version), dependency.getVersion(), d.version); } else { - dependencyErrors.put(Messages.PluginWrapper_disabled(dependency.getLongName()), false); + dependencyErrors.put(Messages.PluginWrapper_disabled_2(dependency.getLongName(), dependency.getShortName()), false); } } @@ -943,7 +998,7 @@ public boolean hasLicensesXml() { PluginWrapper dependency = parent.getPlugin(d.shortName); if (dependency != null && dependency.isActive()) { if (isDependencyObsolete(d, dependency)) { - versionDependencyError(Messages.PluginWrapper_obsolete(dependency.getLongName(), dependency.getVersion(), d.version), dependency.getVersion(), d.version); + versionDependencyError(Messages.PluginWrapper_obsolete_2(dependency.getLongName(), dependency.getShortName(), dependency.getVersion(), d.version), dependency.getVersion(), d.version); } else { dependencies.add(d); } @@ -952,7 +1007,7 @@ public boolean hasLicensesXml() { if (!dependencyErrors.isEmpty()) { NOTICE.addPlugin(this); StringBuilder messageBuilder = new StringBuilder(); - messageBuilder.append(Messages.PluginWrapper_failed_to_load_plugin(getLongName(), getVersion())).append(System.lineSeparator()); + messageBuilder.append(Messages.PluginWrapper_failed_to_load_plugin_2(getLongName(), getShortName(), getVersion())).append(System.lineSeparator()); for (Iterator iterator = dependencyErrors.keySet().iterator(); iterator.hasNext(); ) { String dependencyError = iterator.next(); messageBuilder.append(" - ").append(dependencyError); @@ -975,7 +1030,7 @@ private boolean isDependencyObsolete(Dependency d, PluginWrapper dependency) { */ private void versionDependencyError(String message, String actual, String minimum) { if (isSnapshot(actual) || isSnapshot(minimum)) { - LOGGER.log(WARNING, "Suppressing dependency error in {0} v{1}: {2}", new Object[] {getLongName(), getVersion(), message}); + LOGGER.log(WARNING, "Suppressing dependency error in {0} v{1}: {2}", new Object[] {getShortName(), getVersion(), message}); } else { dependencyErrors.put(message, false); } @@ -999,10 +1054,10 @@ static boolean isSnapshot(@NonNull String version) { public UpdateSite.Plugin getUpdateInfo() { UpdateCenter uc = Jenkins.get().getUpdateCenter(); UpdateSite.Plugin p = uc.getPlugin(getShortName(), getVersionNumber()); - if(p!=null && p.isNewerThan(getVersion())) return p; + if (p != null && p.isNewerThan(getVersion())) return p; return null; } - + /** * returns the {@link hudson.model.UpdateSite.Plugin} object, or null. */ @@ -1027,9 +1082,9 @@ private List getInfoFromAllSites() { */ @Exported public boolean hasUpdate() { - return getUpdateInfo()!=null; + return getUpdateInfo() != null; } - + @Exported @Deprecated // See https://groups.google.com/d/msg/jenkinsci-dev/kRobm-cxFw8/6V66uhibAwAJ public boolean isPinned() { @@ -1070,9 +1125,31 @@ public boolean hasImpliedDependents() { return false; } + /** + * Get list of implied dependencies. + * @since 2.296 + */ + @Restricted(NoExternalUse.class) + public @NonNull Set getImpliedDependents() { + if (!isDetached()) { + return Collections.emptySet(); + } + + Set implied = new HashSet<>(); + for (PluginWrapper p : Jenkins.get().getPluginManager().getPlugins()) { + for (Dependency dependency : DetachedPluginsUtil.getImpliedDependencies(p.shortName, p.getRequiredCoreVersion())) { + if (dependency.shortName.equals(shortName)) { + implied.add(p.shortName); + } + } + } + return implied; + } + /** * Sort by short name. */ + @Override public int compareTo(PluginWrapper pw) { return shortName.compareToIgnoreCase(pw.shortName); } @@ -1089,7 +1166,7 @@ public boolean isDowngradable() { * Where is the backup file? */ public File getBackupFile() { - return new File(Jenkins.get().getRootDir(),"plugins/"+getShortName() + ".bak"); + return new File(Jenkins.get().getRootDir(), "plugins/" + getShortName() + ".bak"); } /** @@ -1115,6 +1192,7 @@ public String getBackupVersion() { /** * Checks if this plugin is pinned and that's forcing us to use an older version than the bundled one. + * @deprecated removed without replacement */ @Deprecated // See https://groups.google.com/d/msg/jenkinsci-dev/kRobm-cxFw8/6V66uhibAwAJ public boolean isPinningForcingOldVersion() { @@ -1134,6 +1212,7 @@ void addPlugin(PluginWrapper plugin) { plugins.put(plugin.shortName, plugin); } + @Override public boolean isActivated() { return !plugins.isEmpty(); } @@ -1160,8 +1239,8 @@ public PluginWrapper getPlugin(String shortName) { * Depending on whether the user said "dismiss" or "correct", send him to the right place. */ public void doAct(StaplerRequest req, StaplerResponse rsp) throws IOException { - if(req.hasParameter("correct")) { - rsp.sendRedirect(req.getContextPath()+"/pluginManager"); + if (req.hasParameter("correct")) { + rsp.sendRedirect(req.getContextPath() + "/pluginManager"); } } @@ -1298,9 +1377,9 @@ public HttpResponse doUnpin() throws IOException { @RequirePOST public HttpResponse doDoUninstall() throws IOException { Jenkins jenkins = Jenkins.get(); - + jenkins.checkPermission(Jenkins.ADMINISTER); - archive.delete(); + Files.deleteIfExists(Util.fileToPath(archive)); // Redo who depends on who. jenkins.getPluginManager().resolveDependentPlugins(); @@ -1333,6 +1412,24 @@ public List getDeprecations() { return deprecations; } + @Restricted(NoExternalUse.class) + public String getIssueTrackerReportUrl() { + final UpdateCenter updateCenter = Jenkins.get().getUpdateCenter(); + if (updateCenter.isSiteDataReady()) { + for (UpdateSite site : updateCenter.getSites()) { + final UpdateSite.Plugin sitePlugin = site.getPlugin(this.shortName); + if (sitePlugin != null && sitePlugin.issueTrackers != null) { + for (UpdateSite.IssueTracker issueTracker : sitePlugin.issueTrackers) { + if (issueTracker.reportUrl != null) { + return issueTracker.reportUrl; + } + } + } + } + } + return null; + } + private static final Logger LOGGER = Logger.getLogger(PluginWrapper.class.getName()); /** diff --git a/core/src/main/java/hudson/Proc.java b/core/src/main/java/hudson/Proc.java index 26d8c14c5c8c..6bcb6d416819 100644 --- a/core/src/main/java/hudson/Proc.java +++ b/core/src/main/java/hudson/Proc.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, CloudBees, Inc. - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,8 +21,10 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson; +import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.Launcher.ProcStarter; import hudson.model.TaskListener; @@ -32,14 +34,13 @@ import hudson.util.ExceptionCatchingThreadFactory; import hudson.util.NamingThreadFactory; import hudson.util.NullStream; -import hudson.util.StreamCopyThread; import hudson.util.ProcessTree; -import org.apache.commons.io.input.NullInputStream; - +import hudson.util.StreamCopyThread; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.nio.charset.Charset; import java.util.Locale; import java.util.Map; import java.util.concurrent.CancellationException; @@ -51,7 +52,7 @@ import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; -import edu.umd.cs.findbugs.annotations.CheckForNull; +import org.apache.commons.io.input.NullInputStream; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; @@ -141,7 +142,7 @@ protected Proc() {} public abstract OutputStream getStdin(); private static final ExecutorService executor = Executors.newCachedThreadPool(new ExceptionCatchingThreadFactory(new NamingThreadFactory(new ClassLoaderSanityThreadFactory(new DaemonThreadFactory()), "Proc.executor"))); - + /** * Like {@link #join} but can be given a maximum time to wait. * @param timeout number of time units @@ -157,6 +158,7 @@ public final int joinWithTimeout(final long timeout, final TimeUnit unit, final CountDownLatch latch = new CountDownLatch(1); try { executor.submit(new Runnable() { + @Override public void run() { try { if (!latch.await(timeout, unit)) { @@ -174,42 +176,42 @@ public void run() { latch.countDown(); } } - + /** * Locally launched process. */ public static final class LocalProc extends Proc { private final Process proc; - private final Thread copier,copier2; + private final Thread copier, copier2; private final OutputStream out; private final EnvVars cookie; private final String name; - private final InputStream stdout,stderr; + private final InputStream stdout, stderr; private final OutputStream stdin; - public LocalProc(String cmd, Map env, OutputStream out, File workDir) throws IOException { - this(cmd,Util.mapToEnv(env),out,workDir); + public LocalProc(String cmd, Map env, OutputStream out, File workDir) throws IOException { + this(cmd, Util.mapToEnv(env), out, workDir); } - public LocalProc(String[] cmd, Map env,InputStream in, OutputStream out) throws IOException { - this(cmd,Util.mapToEnv(env),in,out); + public LocalProc(String[] cmd, Map env, InputStream in, OutputStream out) throws IOException { + this(cmd, Util.mapToEnv(env), in, out); } - public LocalProc(String cmd,String[] env,OutputStream out, File workDir) throws IOException { - this( Util.tokenize(cmd), env, out, workDir ); + public LocalProc(String cmd, String[] env, OutputStream out, File workDir) throws IOException { + this(Util.tokenize(cmd), env, out, workDir); } - public LocalProc(String[] cmd,String[] env,OutputStream out, File workDir) throws IOException { - this(cmd,env,null,out,workDir); + public LocalProc(String[] cmd, String[] env, OutputStream out, File workDir) throws IOException { + this(cmd, env, null, out, workDir); } - public LocalProc(String[] cmd,String[] env,InputStream in,OutputStream out) throws IOException { - this(cmd,env,in,out,null); + public LocalProc(String[] cmd, String[] env, InputStream in, OutputStream out) throws IOException { + this(cmd, env, in, out, null); } - public LocalProc(String[] cmd,String[] env,InputStream in,OutputStream out, File workDir) throws IOException { - this(cmd,env,in,out,null,workDir); + public LocalProc(String[] cmd, String[] env, InputStream in, OutputStream out, File workDir) throws IOException { + this(cmd, env, in, out, null, workDir); } /** @@ -217,30 +219,30 @@ public LocalProc(String[] cmd,String[] env,InputStream in,OutputStream out, File * null to redirect stderr to stdout. */ @SuppressFBWarnings(value = "COMMAND_INJECTION", justification = "Command injection is the point of this old, barely used class.") - public LocalProc(String[] cmd,String[] env,InputStream in,OutputStream out,OutputStream err,File workDir) throws IOException { - this( calcName(cmd), - stderr(environment(new ProcessBuilder(cmd),env).directory(workDir), err==null || err== SELFPUMP_OUTPUT), - in, out, err ); + public LocalProc(String[] cmd, String[] env, InputStream in, OutputStream out, OutputStream err, File workDir) throws IOException { + this(calcName(cmd), + stderr(environment(new ProcessBuilder(cmd), env).directory(workDir), err == null || err == SELFPUMP_OUTPUT), + in, out, err); } private static ProcessBuilder stderr(ProcessBuilder pb, boolean redirectError) { - if(redirectError) pb.redirectErrorStream(true); + if (redirectError) pb.redirectErrorStream(true); return pb; } private static ProcessBuilder environment(ProcessBuilder pb, String[] env) { - if(env!=null) { + if (env != null) { Map m = pb.environment(); m.clear(); for (String e : env) { int idx = e.indexOf('='); - m.put(e.substring(0,idx),e.substring(idx+1)); + m.put(e.substring(0, idx), e.substring(idx + 1)); } } return pb; } - private LocalProc( String name, ProcessBuilder procBuilder, InputStream in, OutputStream out, OutputStream err ) throws IOException { + private LocalProc(String name, ProcessBuilder procBuilder, InputStream in, OutputStream out, OutputStream err) throws IOException { Logger.getLogger(Proc.class.getName()).log(Level.FINE, "Running: {0}", name); this.name = name; this.out = out; @@ -252,11 +254,11 @@ private LocalProc( String name, ProcessBuilder procBuilder, InputStream in, Outp this.proc = procBuilder.start(); InputStream procInputStream = proc.getInputStream(); - if (out==SELFPUMP_OUTPUT) { + if (out == SELFPUMP_OUTPUT) { stdout = procInputStream; copier = null; } else { - copier = new StreamCopyThread(name+": stdout copier", procInputStream, out); + copier = new StreamCopyThread(name + ": stdout copier", procInputStream, out); copier.start(); stdout = null; } @@ -266,21 +268,21 @@ private LocalProc( String name, ProcessBuilder procBuilder, InputStream in, Outp stdin = null; proc.getOutputStream().close(); } else - if (in==SELFPUMP_INPUT) { + if (in == SELFPUMP_INPUT) { stdin = proc.getOutputStream(); } else { - new StdinCopyThread(name+": stdin copier",in,proc.getOutputStream()).start(); + new StdinCopyThread(name + ": stdin copier", in, proc.getOutputStream()).start(); stdin = null; } InputStream procErrorStream = proc.getErrorStream(); - if(err!=null) { - if (err==SELFPUMP_OUTPUT) { + if (err != null) { + if (err == SELFPUMP_OUTPUT) { stderr = procErrorStream; copier2 = null; } else { stderr = null; - copier2 = new StreamCopyThread(name+": stderr copier", procErrorStream, err); + copier2 = new StreamCopyThread(name + ": stderr copier", procErrorStream, err); copier2.start(); } } else { @@ -289,7 +291,7 @@ private LocalProc( String name, ProcessBuilder procBuilder, InputStream in, Outp // according to the source code, Sun JREs still still returns a distinct reader end of a pipe that needs to be closed. // but apparently at least on some IBM JDK5, returned input and error streams are the same. // so try to close them smartly - if (procErrorStream!=procInputStream) { + if (procErrorStream != procInputStream) { procErrorStream.close(); } copier2 = null; @@ -297,14 +299,17 @@ private LocalProc( String name, ProcessBuilder procBuilder, InputStream in, Outp } } + @Override public InputStream getStdout() { return stdout; } + @Override public InputStream getStderr() { return stderr; } + @Override public OutputStream getStdin() { return stdin; } @@ -315,27 +320,27 @@ public OutputStream getStdin() { @Override public int join() throws InterruptedException, IOException { // show what we are waiting for in the thread title - // since this involves some native work, let's have some soak period before enabling this by default + // since this involves some native work, let's have some soak period before enabling this by default Thread t = Thread.currentThread(); String oldName = t.getName(); if (SHOW_PID) { ProcessTree.OSProcess p = ProcessTree.get().get(proc); - t.setName(oldName+" "+(p!=null?"waiting for pid="+p.getPid():"waiting for "+name)); + t.setName(oldName + " " + (p != null ? "waiting for pid=" + p.getPid() : "waiting for " + name)); } try { int r = proc.waitFor(); - // see https://jenkins.io/redirect/troubleshooting/process-leaked-file-descriptors + // see https://www.jenkins.io/redirect/troubleshooting/process-leaked-file-descriptors // problems like that shows up as infinite wait in join(), which confuses great many users. // So let's do a timed wait here and try to diagnose the problem - if (copier!=null) copier.join(TimeUnit.SECONDS.toMillis(10)); - if(copier2!=null) copier2.join(TimeUnit.SECONDS.toMillis(10)); - if((copier!=null && copier.isAlive()) || (copier2!=null && copier2.isAlive())) { + if (copier != null) copier.join(TimeUnit.SECONDS.toMillis(10)); + if (copier2 != null) copier2.join(TimeUnit.SECONDS.toMillis(10)); + if ((copier != null && copier.isAlive()) || (copier2 != null && copier2.isAlive())) { // looks like handles are leaking. // closing these handles should terminate the threads. - String msg = "Process leaked file descriptors. See https://jenkins.io/redirect/troubleshooting/process-leaked-file-descriptors for more information"; + String msg = "Process leaked file descriptors. See https://www.jenkins.io/redirect/troubleshooting/process-leaked-file-descriptors for more information"; Throwable e = new Exception().fillInStackTrace(); - LOGGER.log(Level.WARNING,msg,e); + LOGGER.log(Level.WARNING, msg, e); // doing proc.getInputStream().close() hangs in FileInputStream.close0() // it could be either because another thread is blocking on read, or @@ -351,7 +356,7 @@ public int join() throws InterruptedException, IOException { // } catch (IOException x) { // LOGGER.log(Level.FINE,"stderr termination failed",x); // } - out.write(msg.getBytes()); + out.write(msg.getBytes(Charset.defaultCharset())); out.write('\n'); } return r; @@ -384,7 +389,7 @@ public void kill() throws InterruptedException, IOException { * Destroys the child process without join. */ private void destroy() throws InterruptedException { - ProcessTree.get().killAll(proc,cookie); + ProcessTree.get().killAll(proc, cookie); } /** @@ -422,12 +427,7 @@ public void run() { } private static String calcName(String[] cmd) { - StringBuilder buf = new StringBuilder(); - for (String token : cmd) { - if(buf.length()>0) buf.append(' '); - buf.append(token); - } - return buf.toString(); + return String.join(" ", cmd); } public static final InputStream SELFPUMP_INPUT = new NullInputStream(0); @@ -468,9 +468,9 @@ public int join() throws IOException, InterruptedException { kill(); throw e; } catch (ExecutionException e) { - if(e.getCause() instanceof IOException) - throw (IOException)e.getCause(); - throw new IOException("Failed to join the process",e); + if (e.getCause() instanceof IOException) + throw (IOException) e.getCause(); + throw new IOException("Failed to join the process", e); } catch (CancellationException x) { return -1; } finally { @@ -505,13 +505,13 @@ public OutputStream getStdin() { /** * Debug switch to have the thread display the process it's waiting for. */ - @SuppressFBWarnings("MS_SHOULD_BE_FINAL") + @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "for debugging") public static boolean SHOW_PID = false; - + /** * An instance of {@link Proc}, which has an internal workaround for JENKINS-23271. * It presumes that the instance of the object is guaranteed to be used after the {@link Proc#join()} call. - * See JENKINS-23271 + * See JENKINS-23271 * @author Oleg Nenashev */ @Restricted(NoExternalUse.class) diff --git a/core/src/main/java/hudson/ProxyConfiguration.java b/core/src/main/java/hudson/ProxyConfiguration.java index d5b805995ef0..c087c00ceb8c 100644 --- a/core/src/main/java/hudson/ProxyConfiguration.java +++ b/core/src/main/java/hudson/ProxyConfiguration.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,9 +21,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson; import com.thoughtworks.xstream.XStream; +import edu.umd.cs.findbugs.annotations.CheckForNull; import hudson.model.AbstractDescribableImpl; import hudson.model.Descriptor; import hudson.model.Saveable; @@ -49,7 +51,6 @@ import java.util.List; import java.util.concurrent.TimeUnit; import java.util.regex.Pattern; -import edu.umd.cs.findbugs.annotations.CheckForNull; import jenkins.model.Jenkins; import jenkins.security.stapler.StaplerAccessibleType; import jenkins.util.JenkinsJVM; @@ -77,8 +78,8 @@ *

* Proxy authentication (including NTLM) is implemented by setting a default * {@link Authenticator} which provides a {@link PasswordAuthentication} - * (as described in the Java 6 tech note - * + * (as described in the Java 8 tech note + * * Http Authentication). * * @see jenkins.model.Jenkins#proxy @@ -89,8 +90,8 @@ public final class ProxyConfiguration extends AbstractDescribableImpl getNoProxyHostPatterns(String noProxyHost) { - if (noProxyHost==null) return Collections.emptyList(); + if (noProxyHost == null) return Collections.emptyList(); List r = new ArrayList<>(); for (String s : noProxyHost.split("[ \t\n,|]+")) { - if (s.length()==0) continue; + if (s.length() == 0) continue; r.add(Pattern.compile(s.replace(".", "\\.").replace("*", ".*"))); } return r; @@ -257,17 +258,18 @@ public Proxy createProxy(String host) { } public static Proxy createProxy(String host, String name, int port, String noProxyHost) { - if (host!=null && noProxyHost!=null) { + if (host != null && noProxyHost != null) { for (Pattern p : getNoProxyHostPatterns(noProxyHost)) { if (p.matcher(host).matches()) return Proxy.NO_PROXY; } } - return new Proxy(Proxy.Type.HTTP, new InetSocketAddress(name,port)); + return new Proxy(Proxy.Type.HTTP, new InetSocketAddress(name, port)); } + @Override public void save() throws IOException { - if(BulkChange.contains(this)) return; + if (BulkChange.contains(this)) return; XmlFile config = getXmlFile(); config.write(this); SaveableListener.fireOnChange(this, config); @@ -288,7 +290,7 @@ public static XmlFile getXmlFile() { public static ProxyConfiguration load() throws IOException { XmlFile f = getXmlFile(); - if(f.exists()) + if (f.exists()) return (ProxyConfiguration) f.read(); else return null; @@ -299,24 +301,24 @@ public static ProxyConfiguration load() throws IOException { */ public static URLConnection open(URL url) throws IOException { final ProxyConfiguration p = get(); - + URLConnection con; - if(p==null) { + if (p == null) { con = url.openConnection(); } else { Proxy proxy = p.createProxy(url.getHost()); con = url.openConnection(proxy); - if(p.getUserName()!=null) { + if (p.getUserName() != null) { // Add an authenticator which provides the credentials for proxy authentication Authenticator.setDefault(p.authenticator); p.jenkins48775workaround(proxy, url); } } - - if(DEFAULT_CONNECT_TIMEOUT_MILLIS > 0) { + + if (DEFAULT_CONNECT_TIMEOUT_MILLIS > 0) { con.setConnectTimeout(DEFAULT_CONNECT_TIMEOUT_MILLIS); } - + if (JenkinsJVM.isJenkinsJVM()) { // this code may run on an agent decorate(con); } @@ -343,7 +345,6 @@ public static InputStream getInputStream(URL url) throws IOException { /** * If the first URL we try to access with a HTTP proxy is HTTPS then the authentication cache will not have been * pre-populated, so we try to access at least one HTTP URL before the very first HTTPS url. - * @param proxy * @param url the actual URL being opened. */ private void jenkins48775workaround(Proxy proxy, URL url) { @@ -362,7 +363,7 @@ private void jenkins48775workaround(Proxy proxy, URL url) { } } authCacheSeeded = true; - } else if ("https".equals(url.getProtocol())){ + } else if ("https".equals(url.getProtocol())) { // if we access any http url using a proxy then the auth cache will have been seeded authCacheSeeded = authCacheSeeded || proxy != Proxy.NO_PROXY; } @@ -445,8 +446,8 @@ public FormValidation doValidateProxy( GetMethod method = null; try { method = new GetMethod(testUrl); - method.getParams().setParameter("http.socket.timeout", DEFAULT_CONNECT_TIMEOUT_MILLIS > 0 ? DEFAULT_CONNECT_TIMEOUT_MILLIS : (int)TimeUnit.SECONDS.toMillis(30)); - + method.getParams().setParameter("http.socket.timeout", DEFAULT_CONNECT_TIMEOUT_MILLIS > 0 ? DEFAULT_CONNECT_TIMEOUT_MILLIS : (int) TimeUnit.SECONDS.toMillis(30)); + HttpClient client = new HttpClient(); if (Util.fixEmptyAndTrim(name) != null && !isNoProxyHost(host, noProxyHost)) { client.getHostConfiguration().setProxy(name, port); @@ -454,7 +455,7 @@ public FormValidation doValidateProxy( AuthScope scope = new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT); client.getState().setProxyCredentials(scope, credentials); } - + int code = client.executeMethod(method); if (code != HttpURLConnection.HTTP_OK) { return FormValidation.error(Messages.ProxyConfiguration_FailedToConnect(testUrl, code)); @@ -466,12 +467,12 @@ public FormValidation doValidateProxy( method.releaseConnection(); } } - + return FormValidation.ok(Messages.ProxyConfiguration_Success()); } private boolean isNoProxyHost(String host, String noProxyHost) { - if (host!=null && noProxyHost!=null) { + if (host != null && noProxyHost != null) { for (Pattern p : getNoProxyHostPatterns(noProxyHost)) { if (p.matcher(host).matches()) { return true; @@ -482,7 +483,7 @@ private boolean isNoProxyHost(String host, String noProxyHost) { } private Credentials createCredentials(String userName, String password) { - if (userName.indexOf('\\') >= 0){ + if (userName.indexOf('\\') >= 0) { final String domain = userName.substring(0, userName.indexOf('\\')); final String user = userName.substring(userName.indexOf('\\') + 1); return new NTCredentials(user, Secret.fromString(password).getPlainText(), "", domain); diff --git a/core/src/main/java/hudson/RelativePath.java b/core/src/main/java/hudson/RelativePath.java index c5f562db3b61..b90d7a275bfc 100644 --- a/core/src/main/java/hudson/RelativePath.java +++ b/core/src/main/java/hudson/RelativePath.java @@ -1,13 +1,12 @@ package hudson; -import org.kohsuke.stapler.QueryParameter; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; - -import static java.lang.annotation.ElementType.*; -import static java.lang.annotation.RetentionPolicy.*; +import org.kohsuke.stapler.QueryParameter; /** * Used in conjunction with {@link QueryParameter} to refer to diff --git a/core/src/main/java/hudson/ResponseHeaderFilter.java b/core/src/main/java/hudson/ResponseHeaderFilter.java index c85bdc2502ec..90fb0be87d37 100644 --- a/core/src/main/java/hudson/ResponseHeaderFilter.java +++ b/core/src/main/java/hudson/ResponseHeaderFilter.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, id:digerata - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,10 +21,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package hudson; -import java.util.*; +package hudson; +import java.io.IOException; +import java.util.Enumeration; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; @@ -32,7 +33,6 @@ import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletResponse; -import java.io.IOException; /** * This filter allows you to modify headers set by the container or other servlets @@ -48,58 +48,61 @@ * down Hudson page load times. *

* To enable this filter, edit the web.xml file to include: - * + * *

  * <filter>
- * 		<filter-name>change-headers-filter</filter-name>
- * 		<filter-class>hudson.ResponseHeaderFilter</filter-class>
- * 		<init-param>
- * 			<param-name>Pragma</param-name>
- * 			<param-value>public</param-value>
- * 		</init-param>
- * 		<init-param>
- * 			<param-name>Cache-Control</param-name>
- * 			<param-value>max-age=86400, public</param-value>
- * 		</init-param>
+ *         <filter-name>change-headers-filter</filter-name>
+ *         <filter-class>hudson.ResponseHeaderFilter</filter-class>
+ *         <init-param>
+ *             <param-name>Pragma</param-name>
+ *             <param-value>public</param-value>
+ *         </init-param>
+ *         <init-param>
+ *             <param-name>Cache-Control</param-name>
+ *             <param-value>max-age=86400, public</param-value>
+ *         </init-param>
  * </filter>
- * 
+ *
  * And down below that:
- * 
+ *
  * <filter-mapping>
- * 		<filter-name>Headers</filter-name>
- * 		<url-pattern>/*</url-pattern>
+ *         <filter-name>Headers</filter-name>
+ *         <url-pattern>/*</url-pattern>
  * </filter-mapping>
  * 
- * + * *

- * In the case of the tomcat cache problem, it is important that the url-pattern for + * In the case of the tomcat cache problem, it is important that the url-pattern for * the filter matches the url-pattern set for the security-constraint. - * + * * @author Mike Wille */ public class ResponseHeaderFilter implements Filter { - private FilterConfig config; + private FilterConfig config; - public void init(FilterConfig filterConfig) throws ServletException { - config = filterConfig; - } + @Override + public void init(FilterConfig filterConfig) throws ServletException { + config = filterConfig; + } - public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, - ServletException { - HttpServletResponse httpResp = (HttpServletResponse) resp; + @Override + public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, + ServletException { + HttpServletResponse httpResp = (HttpServletResponse) resp; - Enumeration e = config.getInitParameterNames(); + Enumeration e = config.getInitParameterNames(); - // for each configuration element... - while(e.hasMoreElements()) { - String headerName = (String) e.nextElement(); - String headerValue = config.getInitParameter(headerName); - // set the header with the given name and value - httpResp.setHeader(headerName, headerValue); - } - chain.doFilter(req, resp); - } + // for each configuration element... + while (e.hasMoreElements()) { + String headerName = (String) e.nextElement(); + String headerValue = config.getInitParameter(headerName); + // set the header with the given name and value + httpResp.setHeader(headerName, headerValue); + } + chain.doFilter(req, resp); + } - public void destroy() { - } + @Override + public void destroy() { + } } diff --git a/core/src/main/java/hudson/RestrictedSince.java b/core/src/main/java/hudson/RestrictedSince.java index 507c1788c37d..c43568f7fb6d 100644 --- a/core/src/main/java/hudson/RestrictedSince.java +++ b/core/src/main/java/hudson/RestrictedSince.java @@ -24,9 +24,8 @@ package hudson; -import org.kohsuke.accmod.Restricted; - import java.lang.annotation.Documented; +import org.kohsuke.accmod.Restricted; /** * Accompanies {@link Restricted} annotation to indicate when the access restriction was placed. diff --git a/core/src/main/java/hudson/StructuredForm.java b/core/src/main/java/hudson/StructuredForm.java index d6a78748dabf..708d0120dc9d 100644 --- a/core/src/main/java/hudson/StructuredForm.java +++ b/core/src/main/java/hudson/StructuredForm.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,19 +21,19 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson; +import java.util.Collections; +import java.util.List; +import javax.servlet.ServletException; import net.sf.json.JSONArray; import net.sf.json.JSONObject; import org.kohsuke.stapler.StaplerRequest; -import javax.servlet.ServletException; -import java.util.Collections; -import java.util.List; - /** * Obtains the structured form data from {@link StaplerRequest}. - * See http://wiki.jenkins-ci.org/display/JENKINS/Structured+Form+Submission + * See https://www.jenkins.io/doc/developer/forms/structured-form-submission/ * * @author Kohsuke Kawaguchi */ @@ -59,15 +59,16 @@ public static JSONObject get(StaplerRequest req) throws ServletException { * Because of the way structured form submission work, this is convenient way of * handling repeated multi-value entries. * - * @since 1.233 + * @since 1.233 */ + public static List toList(JSONObject parent, String propertyName) { Object v = parent.get(propertyName); - if(v==null) + if (v == null) return Collections.emptyList(); - if(v instanceof JSONObject) - return Collections.singletonList((JSONObject)v); - if(v instanceof JSONArray) + if (v instanceof JSONObject) + return Collections.singletonList((JSONObject) v); + if (v instanceof JSONArray) return (List) v; throw new IllegalArgumentException(); diff --git a/core/src/main/java/hudson/TcpSlaveAgentListener.java b/core/src/main/java/hudson/TcpSlaveAgentListener.java index 63c224b6e897..eb6358f7a3f3 100644 --- a/core/src/main/java/hudson/TcpSlaveAgentListener.java +++ b/core/src/main/java/hudson/TcpSlaveAgentListener.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Stephen Connolly - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,46 +21,43 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson; -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import java.io.ByteArrayInputStream; -import java.io.SequenceInputStream; -import java.nio.charset.StandardCharsets; -import java.security.interfaces.RSAPublicKey; import edu.umd.cs.findbugs.annotations.Nullable; - +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.model.AperiodicWork; -import hudson.util.VersionNumber; -import jenkins.model.Jenkins; -import jenkins.model.identity.InstanceIdentityProvider; -import jenkins.security.stapler.StaplerAccessibleType; -import jenkins.slaves.RemotingVersionInfo; -import jenkins.util.SystemProperties; import hudson.slaves.OfflineCause; -import java.io.DataOutputStream; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.SocketAddress; -import java.net.URL; -import java.util.Arrays; -import java.util.Base64; -import jenkins.AgentProtocol; - +import hudson.util.VersionNumber; +import java.io.ByteArrayInputStream; import java.io.DataInputStream; +import java.io.DataOutputStream; import java.io.EOFException; import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.SequenceInputStream; import java.net.BindException; import java.net.InetSocketAddress; import java.net.MalformedURLException; import java.net.Socket; +import java.net.SocketAddress; +import java.net.URL; import java.nio.channels.ServerSocketChannel; +import java.nio.charset.StandardCharsets; +import java.security.interfaces.RSAPublicKey; +import java.util.Arrays; +import java.util.Base64; import java.util.logging.Level; import java.util.logging.Logger; - +import jenkins.AgentProtocol; +import jenkins.model.Jenkins; +import jenkins.model.identity.InstanceIdentityProvider; +import jenkins.security.stapler.StaplerAccessibleType; +import jenkins.slaves.RemotingVersionInfo; +import jenkins.util.SystemProperties; import org.apache.commons.io.IOUtils; import org.apache.commons.io.output.NullOutputStream; -import org.apache.commons.lang.StringUtils; import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; @@ -94,12 +91,12 @@ public final class TcpSlaveAgentListener extends Thread { * Use 0 to choose a random port. */ public TcpSlaveAgentListener(int port) throws IOException { - super("TCP agent listener port="+port); + super("TCP agent listener port=" + port); try { serverSocket = ServerSocketChannel.open(); serverSocket.socket().bind(new InetSocketAddress(port)); } catch (BindException e) { - throw (BindException)new BindException("Failed to listen on port "+port+" because it's already in use.").initCause(e); + throw (BindException) new BindException("Failed to listen on port " + port + " because it's already in use.").initCause(e); } this.configuredPort = port; setUncaughtExceptionHandler((t, e) -> { @@ -138,7 +135,7 @@ public String getAdvertisedHost() { } try { return new URL(Jenkins.get().getRootUrl()).getHost(); - } catch (MalformedURLException | NullPointerException e) { + } catch (MalformedURLException e) { throw new IllegalStateException("Could not get TcpSlaveAgentListener host name", e); } } @@ -162,7 +159,7 @@ public String getIdentityPublicKey() { * @since 2.16 */ public String getAgentProtocolNames() { - return StringUtils.join(Jenkins.get().getAgentProtocols(), ", "); + return String.join(", ", Jenkins.get().getAgentProtocols()); } /** @@ -197,8 +194,8 @@ public void run(Throwable cause) { }).start(); } } catch (IOException e) { - if(!shuttingDown) { - LOGGER.log(Level.SEVERE,"Failed to accept TCP connections", e); + if (!shuttingDown) { + LOGGER.log(Level.SEVERE, "Failed to accept TCP connections", e); } } } @@ -222,7 +219,7 @@ public void shutdown() { try { serverSocket.close(); } catch (IOException e) { - LOGGER.log(Level.WARNING, "Failed to close down TCP port",e); + LOGGER.log(Level.WARNING, "Failed to close down TCP port", e); } } @@ -239,10 +236,10 @@ private final class ConnectionHandler extends Thread { ConnectionHandler(Socket s, ConnectionHandlerFailureCallback parentTerminator) { this.s = s; - synchronized(getClass()) { + synchronized (getClass()) { id = iotaGen++; } - setName("TCP agent connection handler #"+id+" with "+s.getRemoteSocketAddress()); + setName("TCP agent connection handler #" + id + " with " + s.getRemoteSocketAddress()); setUncaughtExceptionHandler((t, e) -> { LOGGER.log(Level.SEVERE, "Uncaught exception in TcpSlaveAgentListener ConnectionHandler " + t, e); try { @@ -268,17 +265,17 @@ public void run() { String header = new String(head, StandardCharsets.US_ASCII); if (header.startsWith("GET ")) { // this looks like an HTTP client - respondHello(header,s); + respondHello(header, s); return; } // otherwise assume this is AgentProtocol and start from the beginning - String s = new DataInputStream(new SequenceInputStream(new ByteArrayInputStream(head),in)).readUTF(); + String s = new DataInputStream(new SequenceInputStream(new ByteArrayInputStream(head), in)).readUTF(); - if(s.startsWith("Protocol:")) { + if (s.startsWith("Protocol:")) { String protocol = s.substring(9); AgentProtocol p = AgentProtocol.of(protocol); - if (p!=null) { + if (p != null) { if (Jenkins.get().getAgentProtocols().contains(protocol)) { LOGGER.log(p instanceof PingAgentProtocol ? Level.FINE : Level.INFO, "Accepted {0} connection #{1} from {2}", new Object[] {protocol, id, this.s.getRemoteSocketAddress()}); p.handle(this.s); @@ -291,7 +288,7 @@ public void run() { error("Unrecognized protocol: " + s, this.s); } } catch (InterruptedException e) { - LOGGER.log(Level.WARNING,"Connection #"+id+" aborted",e); + LOGGER.log(Level.WARNING, "Connection #" + id + " aborted", e); try { s.close(); } catch (IOException ex) { @@ -323,7 +320,7 @@ private void respondHello(String header, Socket s) throws IOException { response = "HTTP/1.0 200 OK\r\n" + "Content-Type: text/plain;charset=UTF-8\r\n" + "\r\n" + - "Jenkins-Agent-Protocols: " + getAgentProtocolNames()+"\r\n" + + "Jenkins-Agent-Protocols: " + getAgentProtocolNames() + "\r\n" + "Jenkins-Version: " + Jenkins.VERSION + "\r\n" + "Jenkins-Session: " + Jenkins.SESSION_HASH + "\r\n" + "Client: " + s.getInetAddress().getHostAddress() + "\r\n" + @@ -371,7 +368,7 @@ public Thread getParentThread() { } /** - * This extension provides a Ping protocol that allows people to verify that the TcpSlaveAgentListener is alive. + * This extension provides a Ping protocol that allows people to verify that the {@link TcpSlaveAgentListener} is alive. * We also use this to wake the acceptor thread on termination. * * @since 1.653 @@ -432,7 +429,7 @@ public boolean connect(Socket socket) throws IOException { new String(ping, StandardCharsets.UTF_8), responseLength > 0 && responseLength <= response.length ? new String(response, 0, responseLength, StandardCharsets.UTF_8) : - "bad response length " + responseLength + "bad response length " + responseLength, }); return false; } @@ -509,7 +506,7 @@ protected void doAperiodicRun() { } public static void schedule(Thread originThread, Throwable cause) { - schedule(originThread, cause,5000); + schedule(originThread, cause, 5000); } public static void schedule(Thread originThread, Throwable cause, long approxDelay) { @@ -526,12 +523,13 @@ public static void schedule(Thread originThread, Throwable cause, long approxDel * Connection terminated because we are reconnected from the current peer. */ public static class ConnectionFromCurrentPeer extends OfflineCause { + @Override public String toString() { return "The current peer is reconnecting"; } } - private static int iotaGen=1; + private static int iotaGen = 1; private static final Logger LOGGER = Logger.getLogger(TcpSlaveAgentListener.class.getName()); @@ -544,7 +542,7 @@ public String toString() { */ @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "Accessible via System Groovy Scripts") @Restricted(NoExternalUse.class) - public static String CLI_HOST_NAME = SystemProperties.getString(TcpSlaveAgentListener.class.getName()+".hostName"); + public static String CLI_HOST_NAME = SystemProperties.getString(TcpSlaveAgentListener.class.getName() + ".hostName"); /** * Port number that we advertise protocol clients to connect to. @@ -558,5 +556,5 @@ public String toString() { */ @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "Accessible via System Groovy Scripts") @Restricted(NoExternalUse.class) - public static Integer CLI_PORT = SystemProperties.getInteger(TcpSlaveAgentListener.class.getName()+".port"); + public static Integer CLI_PORT = SystemProperties.getInteger(TcpSlaveAgentListener.class.getName() + ".port"); } diff --git a/core/src/main/java/hudson/UDPBroadcastThread.java b/core/src/main/java/hudson/UDPBroadcastThread.java deleted file mode 100644 index 4c4900585be2..000000000000 --- a/core/src/main/java/hudson/UDPBroadcastThread.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2004-2009, Sun Microsystems, Inc. - * Copyright (c) 2020, CloudBees, Inc - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package hudson; - -import hudson.init.Initializer; -import jenkins.util.SystemProperties; -import org.kohsuke.accmod.Restricted; -import org.kohsuke.accmod.restrictions.NoExternalUse; - -import java.util.logging.Logger; - -import static hudson.init.InitMilestone.COMPLETED; - -/** - * Monitors a UDP multicast broadcast and respond with the location of the Hudson service. - * - *

- * Useful for auto-discovery of Hudson in the network. - * - * @author Kohsuke Kawaguchi - * @deprecated No longer does anything. - */ -@Deprecated -@Restricted(NoExternalUse.class) -public class UDPBroadcastThread { - - // The previous default port was 33848, before the "disabled by default" change - public static final int PORT = SystemProperties.getInteger("hudson.udp", -1); - - private static final Logger LOGGER = Logger.getLogger(UDPBroadcastThread.class.getName()); - - @Initializer(before=COMPLETED) - public static void warn() { - if (PORT > 0) { - LOGGER.warning("UDP broadcast capability has been removed from Jenkins. More information: https://jenkins.io/redirect/udp-broadcast"); - } - } - -} diff --git a/core/src/main/java/hudson/URLConnectionDecorator.java b/core/src/main/java/hudson/URLConnectionDecorator.java index f3794f4e33ea..95c8a4e6bd34 100644 --- a/core/src/main/java/hudson/URLConnectionDecorator.java +++ b/core/src/main/java/hudson/URLConnectionDecorator.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson; diff --git a/core/src/main/java/hudson/Util.java b/core/src/main/java/hudson/Util.java index 6821fc4960ea..6af39fc1cb75 100644 --- a/core/src/main/java/hudson/Util.java +++ b/core/src/main/java/hudson/Util.java @@ -21,29 +21,30 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.CheckReturnValue; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.Nullable; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.model.TaskListener; -import jenkins.util.MemoryReductionUtil; import hudson.util.QuotedStringTokenizer; import hudson.util.VariableResolver; -import jenkins.util.SystemProperties; - -import jenkins.util.io.PathRemover; -import org.apache.commons.codec.digest.DigestUtils; -import org.apache.commons.io.IOUtils; -import org.apache.commons.io.output.NullOutputStream; -import org.apache.commons.lang.time.FastDateFormat; -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.Project; -import org.apache.tools.ant.taskdefs.Copy; -import org.apache.tools.ant.types.FileSet; - -import org.kohsuke.accmod.Restricted; -import org.kohsuke.accmod.restrictions.NoExternalUse; - -import java.io.*; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.Closeable; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.PrintStream; +import java.io.Reader; +import java.io.StringReader; +import java.io.Writer; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.net.InetAddress; @@ -56,6 +57,7 @@ import java.nio.charset.Charset; import java.nio.charset.CharsetEncoder; import java.nio.charset.StandardCharsets; +import java.nio.file.CopyOption; import java.nio.file.FileAlreadyExistsException; import java.nio.file.FileSystemException; import java.nio.file.FileSystems; @@ -64,8 +66,10 @@ import java.nio.file.LinkOption; import java.nio.file.Path; import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; import java.nio.file.attribute.BasicFileAttributes; import java.nio.file.attribute.DosFileAttributes; +import java.nio.file.attribute.FileAttribute; import java.nio.file.attribute.PosixFilePermission; import java.nio.file.attribute.PosixFilePermissions; import java.security.DigestInputStream; @@ -76,7 +80,20 @@ import java.time.LocalDate; import java.time.ZoneId; import java.time.temporal.ChronoUnit; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.EnumSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.MissingResourceException; +import java.util.Properties; +import java.util.ResourceBundle; +import java.util.Set; +import java.util.SimpleTimeZone; +import java.util.StringTokenizer; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Supplier; @@ -85,15 +102,22 @@ import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; - -import edu.umd.cs.findbugs.annotations.CheckForNull; -import edu.umd.cs.findbugs.annotations.CheckReturnValue; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; - +import jenkins.util.MemoryReductionUtil; +import jenkins.util.SystemProperties; +import jenkins.util.io.PathRemover; +import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.apache.commons.io.output.NullOutputStream; +import org.apache.commons.lang.time.FastDateFormat; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.taskdefs.Copy; +import org.apache.tools.ant.types.FileSet; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.StaplerRequest; /** @@ -116,10 +140,10 @@ public class Util { * @since 1.176 */ @NonNull - public static List filter( @NonNull Iterable base, @NonNull Class type ) { + public static List filter(@NonNull Iterable base, @NonNull Class type) { List r = new ArrayList<>(); for (Object i : base) { - if(type.isInstance(i)) + if (type.isInstance(i)) r.add(type.cast(i)); } return r; @@ -129,8 +153,8 @@ public static List filter( @NonNull Iterable base, @NonNull Class t * Creates a filtered sublist. */ @NonNull - public static List filter( @NonNull List base, @NonNull Class type ) { - return filter((Iterable)base,type); + public static List filter(@NonNull List base, @NonNull Class type) { + return filter((Iterable) base, type); } /** @@ -146,7 +170,7 @@ public static List filter( @NonNull List base, @NonNull Class type * */ @Nullable - public static String replaceMacro( @CheckForNull String s, @NonNull Map properties) { + public static String replaceMacro(@CheckForNull String s, @NonNull Map properties) { return replaceMacro(s, new VariableResolver.ByMap<>(properties)); } @@ -158,30 +182,30 @@ public static String replaceMacro( @CheckForNull String s, @NonNull Map resolver) { - if (s == null) { - return null; - } + if (s == null) { + return null; + } - int idx=0; - while(true) { + int idx = 0; + while (true) { Matcher m = VARIABLE.matcher(s); - if(!m.find(idx)) return s; + if (!m.find(idx)) return s; String key = m.group().substring(1); // escape the dollar sign or get the key to resolve String value; - if(key.charAt(0)=='$') { + if (key.charAt(0) == '$') { value = "$"; } else { - if(key.charAt(0)=='{') key = key.substring(1,key.length()-1); + if (key.charAt(0) == '{') key = key.substring(1, key.length() - 1); value = resolver.resolve(key); } - if(value==null) + if (value == null) idx = m.end(); // skip this else { - s = s.substring(0,m.start())+value+s.substring(m.end()); + s = s.substring(0, m.start()) + value + s.substring(m.end()); idx = m.start() + value.length(); } } @@ -216,9 +240,9 @@ public static String loadFile(@NonNull File logfile) throws IOException { @NonNull public static String loadFile(@NonNull File logfile, @NonNull Charset charset) throws IOException { // Note: Until charset handling is resolved (e.g. by implementing - // https://issues.jenkins-ci.org/browse/JENKINS-48923 ), this method + // https://issues.jenkins.io/browse/JENKINS-48923 ), this method // must be able to handle character encoding errors. As reported at - // https://issues.jenkins-ci.org/browse/JENKINS-49112 Run.getLog() calls + // https://issues.jenkins.io/browse/JENKINS-49112 Run.getLog() calls // loadFile() to fully read the generated log file. This file might // contain unmappable and/or malformed byte sequences. We need to make // sure that in such cases, no CharacterCodingException is thrown. @@ -228,7 +252,7 @@ public static String loadFile(@NonNull File logfile, @NonNull Charset charset) t // from a Charset and the reader returned by Files.newBufferedReader() // handle malformed and unmappable byte sequences for the specified // encoding; the latter is more picky and will throw an exception. - // See: https://issues.jenkins-ci.org/browse/JENKINS-49060?focusedCommentId=325989&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-325989 + // See: https://issues.jenkins.io/browse/JENKINS-49060?focusedCommentId=325989&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-325989 try { return FileUtils.readFileToString(logfile, charset); } catch (FileNotFoundException e) { @@ -393,7 +417,7 @@ public static File createTempDir() throws IOException { // by default, the permissions of the created directory are 0700&(~umask) // whereas the old approach created a temporary directory with permissions // 0777&(~umask). - // To avoid permissions problems like https://issues.jenkins-ci.org/browse/JENKINS-48407 + // To avoid permissions problems like https://issues.jenkins.io/browse/JENKINS-48407 // we can pass POSIX file permissions as an attribute (see, for example, // https://github.com/jenkinsci/jenkins/pull/3161 ) final Path tempPath; @@ -413,15 +437,15 @@ public static File createTempDir() throws IOException { * On Windows, error messages for IOException aren't very helpful. * This method generates additional user-friendly error message to the listener */ - public static void displayIOException(@NonNull IOException e, @NonNull TaskListener listener ) { + public static void displayIOException(@NonNull IOException e, @NonNull TaskListener listener) { String msg = getWin32ErrorMessage(e); - if(msg!=null) + if (msg != null) listener.getLogger().println(msg); } @CheckForNull public static String getWin32ErrorMessage(@NonNull IOException e) { - return getWin32ErrorMessage((Throwable)e); + return getWin32ErrorMessage((Throwable) e); } /** @@ -433,19 +457,19 @@ public static String getWin32ErrorMessage(@NonNull IOException e) { @CheckForNull public static String getWin32ErrorMessage(Throwable e) { String msg = e.getMessage(); - if(msg!=null) { + if (msg != null) { Matcher m = errorCodeParser.matcher(msg); - if(m.matches()) { + if (m.matches()) { try { ResourceBundle rb = ResourceBundle.getBundle("/hudson/win32errors"); - return rb.getString("error"+m.group(1)); - } catch (Exception ignored) { + return rb.getString("error" + m.group(1)); + } catch (RuntimeException ignored) { // silently recover from resource related failures } } } - if(e.getCause()!=null) + if (e.getCause() != null) return getWin32ErrorMessage(e.getCause()); return null; // no message } @@ -460,9 +484,9 @@ public static String getWin32ErrorMessage(Throwable e) { public static String getWin32ErrorMessage(int n) { try { ResourceBundle rb = ResourceBundle.getBundle("/hudson/win32errors"); - return rb.getString("error"+n); + return rb.getString("error" + n); } catch (MissingResourceException e) { - LOGGER.log(Level.WARNING,"Failed to find resource bundle",e); + LOGGER.log(Level.WARNING, "Failed to find resource bundle", e); return null; } } @@ -483,7 +507,7 @@ public static String getHostName() { * @deprecated Use {@link IOUtils#copy(InputStream, OutputStream)} */ @Deprecated - public static void copyStream(@NonNull InputStream in,@NonNull OutputStream out) throws IOException { + public static void copyStream(@NonNull InputStream in, @NonNull OutputStream out) throws IOException { IOUtils.copy(in, out); } @@ -527,23 +551,23 @@ public static void copyStreamAndClose(@NonNull Reader in, @NonNull Writer out) t */ @NonNull public static String[] tokenize(@NonNull String s, @CheckForNull String delimiter) { - return QuotedStringTokenizer.tokenize(s,delimiter); + return QuotedStringTokenizer.tokenize(s, delimiter); } @NonNull public static String[] tokenize(@NonNull String s) { - return tokenize(s," \t\n\r\f"); + return tokenize(s, " \t\n\r\f"); } /** * Converts the map format of the environment variables to the K=V format in the array. */ @NonNull - public static String[] mapToEnv(@NonNull Map m) { + public static String[] mapToEnv(@NonNull Map m) { String[] r = new String[m.size()]; - int idx=0; + int idx = 0; - for (final Map.Entry e : m.entrySet()) { + for (final Map.Entry e : m.entrySet()) { r[idx++] = e.getKey() + '=' + e.getValue(); } return r; @@ -551,8 +575,8 @@ public static String[] mapToEnv(@NonNull Map m) { public static int min(int x, @NonNull int... values) { for (int i : values) { - if(i 0) else if (seconds >= 10) return Messages.Util_second(seconds); else if (seconds >= 1) - return Messages.Util_second(seconds+(float)(millisecs/100)/10); // render "1.2 sec" - else if(millisecs>=100) - return Messages.Util_second((float)(millisecs/10)/100); // render "0.12 sec". + return Messages.Util_second(seconds + (float) (millisecs / 100) / 10); // render "1.2 sec" + else if (millisecs >= 100) + return Messages.Util_second((float) (millisecs / 10) / 100); // render "0.12 sec". else return Messages.Util_millisecond(millisecs); } @@ -787,9 +811,9 @@ public static String getPastTimeString(long duration) { @NonNull @Deprecated public static String combine(long n, @NonNull String suffix) { - String s = Long.toString(n)+' '+suffix; - if(n!=1) - // Just adding an 's' won't work in most natural languages, even English has exception to the rule (e.g. copy/copies). + String s = Long.toString(n) + ' ' + suffix; + if (n != 1) + // Just adding an 's' won't work in most natural languages, even English has exception to the rule (e.g. copy/copies). s += "s"; return s; } @@ -798,10 +822,10 @@ public static String combine(long n, @NonNull String suffix) { * Create a sub-list by only picking up instances of the specified type. */ @NonNull - public static List createSubList(@NonNull Collection source, @NonNull Class type ) { + public static List createSubList(@NonNull Collection source, @NonNull Class type) { List r = new ArrayList<>(); for (Object item : source) { - if(type.isInstance(item)) + if (type.isInstance(item)) r.add(type.cast(item)); } return r; @@ -828,7 +852,7 @@ public static String encode(@NonNull String s) { for (int i = 0; i < s.length(); i++) { int c = s.charAt(i); - if (c<128 && c!=' ') { + if (c < 128 && c != ' ') { out.append((char) c); } else { // 1 char -> UTF8 @@ -851,6 +875,7 @@ public static String encode(@NonNull String s) { } private static final boolean[] uriMap = new boolean[123]; + static { String raw = "! $ &'()*+,-. 0123456789 = @ABCDEFGHIJKLMNOPQRSTUVWXYZ _ abcdefghijklmnopqrstuvwxyz"; @@ -860,7 +885,22 @@ public static String encode(@NonNull String s) { // Encode control chars and space for (i = 0; i < 33; i++) uriMap[i] = true; for (int j = 0; j < raw.length(); i++, j++) - uriMap[i] = (raw.charAt(j) == ' '); + uriMap[i] = raw.charAt(j) == ' '; + // If we add encodeQuery() just add a 2nd map to encode &+= + // queryMap[38] = queryMap[43] = queryMap[61] = true; + } + + private static final boolean[] fullUriMap = new boolean[123]; + + static { + String raw = " 0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz"; + // !"#$%&'()*+,-./0123456789:;<=>?@ [\]^_` {|}~ + // ^--so these are encoded + int i; + // Encode control chars and space + for (i = 0; i < 33; i++) fullUriMap[i] = true; + for (int j = 0; j < raw.length(); i++, j++) + fullUriMap[i] = raw.charAt(j) == ' '; // If we add encodeQuery() just add a 2nd map to encode &+= // queryMap[38] = queryMap[43] = queryMap[61] = true; } @@ -876,6 +916,23 @@ public static String encode(@NonNull String s) { */ @NonNull public static String rawEncode(@NonNull String s) { + return encode(s, uriMap); + } + + /** + * Encode a single path component for use in an HTTP URL. + * Escapes all special characters including those outside + * of the characters specified in RFC1738. + * All characters outside numbers and letters without diacritic are encoded. + * Note that slash ({@code /}) is encoded, so the given string should be a + * single path component used in constructing a URL. + */ + @NonNull + public static String fullEncode(@NonNull String s) { + return encode(s, fullUriMap); + } + + private static String encode(String s, boolean[] map) { boolean escaped = false; StringBuilder out = null; CharsetEncoder enc = null; @@ -883,9 +940,9 @@ public static String rawEncode(@NonNull String s) { char c; for (int i = 0, m = s.length(); i < m; i++) { int codePoint = Character.codePointAt(s, i); - if((codePoint&0xffffff80)==0) { // 1 byte + if ((codePoint & 0xffffff80) == 0) { // 1 byte c = s.charAt(i); - if (c > 122 || uriMap[c]) { + if (c > 122 || map[c]) { if (!escaped) { out = new StringBuilder(i + (m - i) * 3); out.append(s, 0, i); @@ -925,7 +982,7 @@ public static String rawEncode(@NonNull String s) { out.append(toDigit(aByte & 0xF)); } - if(Character.charCount(codePoint) > 1) { + if (Character.charCount(codePoint) > 1) { i++; // we processed two characters } } @@ -934,14 +991,14 @@ public static String rawEncode(@NonNull String s) { } private static char toDigit(int n) { - return (char)(n < 10 ? '0' + n : 'A' + n - 10); + return (char) (n < 10 ? '0' + n : 'A' + n - 10); } /** * Surrounds by a single-quote. */ public static String singleQuote(String s) { - return '\''+s+'\''; + return '\'' + s + '\''; } /** @@ -949,34 +1006,34 @@ public static String singleQuote(String s) { */ @Nullable public static String escape(@CheckForNull String text) { - if (text==null) return null; - StringBuilder buf = new StringBuilder(text.length()+64); - for( int i=0; i"); else - if(ch=='<') + if (ch == '<') buf.append("<"); else - if(ch=='>') + if (ch == '>') buf.append(">"); else - if(ch=='&') + if (ch == '&') buf.append("&"); else - if(ch=='"') + if (ch == '"') buf.append("""); else - if(ch=='\'') + if (ch == '\'') buf.append("'"); else - if(ch==' ') { + if (ch == ' ') { // All spaces in a block of consecutive spaces are converted to // non-breaking space ( ) except for the last one. This allows // significant whitespace to be retained without prohibiting wrapping. - char nextCh = i+1 < text.length() ? text.charAt(i+1) : 0; - buf.append(nextCh==' ' ? " " : " "); + char nextCh = i + 1 < text.length() ? text.charAt(i + 1) : 0; + buf.append(nextCh == ' ' ? " " : " "); } else buf.append(ch); @@ -986,16 +1043,16 @@ public static String escape(@CheckForNull String text) { @NonNull public static String xmlEscape(@NonNull String text) { - StringBuilder buf = new StringBuilder(text.length()+64); - for( int i=0; i') + if (ch == '>') buf.append(">"); else - if(ch=='&') + if (ch == '&') buf.append("&"); else buf.append(ch); @@ -1015,10 +1072,15 @@ public static void touch(@NonNull File file) throws IOException { /** * Copies a single file by using Ant. + * + * @deprecated since 2.335; use {@link Files#copy(Path, Path, CopyOption...)} directly */ + @Deprecated + @Restricted(NoExternalUse.class) + @RestrictedSince("2.335") public static void copyFile(@NonNull File src, @NonNull File dst) throws BuildException { Copy cp = new Copy(); - cp.setProject(new org.apache.tools.ant.Project()); + cp.setProject(new Project()); cp.setTofile(dst); cp.setFile(src); cp.setOverwrite(true); @@ -1048,7 +1110,7 @@ public static T fixNull(@CheckForNull T s, @NonNull T defaultValue) { */ @CheckForNull public static String fixEmpty(@CheckForNull String s) { - if(s==null || s.length()==0) return null; + if (s == null || s.length() == 0) return null; return s; } @@ -1059,7 +1121,7 @@ public static String fixEmpty(@CheckForNull String s) { */ @CheckForNull public static String fixEmptyAndTrim(@CheckForNull String s) { - if(s==null) return null; + if (s == null) return null; return fixEmpty(s.trim()); } @@ -1125,23 +1187,25 @@ public static Iterable fixNull(@CheckForNull Iterable l) { @NonNull public static String getFileName(@NonNull String filePath) { int idx = filePath.lastIndexOf('\\'); - if(idx>=0) - return getFileName(filePath.substring(idx+1)); + if (idx >= 0) + return getFileName(filePath.substring(idx + 1)); idx = filePath.lastIndexOf('/'); - if(idx>=0) - return getFileName(filePath.substring(idx+1)); + if (idx >= 0) + return getFileName(filePath.substring(idx + 1)); return filePath; } /** * Concatenate multiple strings by inserting a separator. + * @deprecated since 2.292; use {@link String#join(CharSequence, Iterable)} */ + @Deprecated @NonNull public static String join(@NonNull Collection strings, @NonNull String separator) { StringBuilder buf = new StringBuilder(); - boolean first=true; + boolean first = true; for (Object s : strings) { - if(first) first=false; + if (first) first = false; else buf.append(separator); buf.append(s); } @@ -1187,14 +1251,14 @@ public static FileSet createFileSet(@NonNull File baseDir, @NonNull String inclu StringTokenizer tokens; - tokens = new StringTokenizer(includes,","); - while(tokens.hasMoreTokens()) { + tokens = new StringTokenizer(includes, ","); + while (tokens.hasMoreTokens()) { String token = tokens.nextToken().trim(); fs.createInclude().setName(token); } - if(excludes!=null) { - tokens = new StringTokenizer(excludes,","); - while(tokens.hasMoreTokens()) { + if (excludes != null) { + tokens = new StringTokenizer(excludes, ","); + while (tokens.hasMoreTokens()) { String token = tokens.nextToken().trim(); fs.createExclude().setName(token); } @@ -1204,7 +1268,7 @@ public static FileSet createFileSet(@NonNull File baseDir, @NonNull String inclu @NonNull public static FileSet createFileSet(@NonNull File baseDir, @NonNull String includes) { - return createFileSet(baseDir,includes,null); + return createFileSet(baseDir, includes, null); } private static void tryToDeleteSymlink(@NonNull File symlink) { @@ -1244,7 +1308,7 @@ private static boolean createSymlinkAtomic(@NonNull Path pathForSymlink, @NonNul Path tempSymlinkPath = symlink.toPath(); Files.createSymbolicLink(tempSymlinkPath, target); try { - Files.move(tempSymlinkPath, pathForSymlink, java.nio.file.StandardCopyOption.ATOMIC_MOVE); + Files.move(tempSymlinkPath, pathForSymlink, StandardCopyOption.ATOMIC_MOVE); return true; } catch ( UnsupportedOperationException | @@ -1321,6 +1385,7 @@ public static void createSymlink(@NonNull File baseDir, @NonNull String targetPa } private static final AtomicBoolean warnedSymlinks = new AtomicBoolean(); + private static void warnWindowsSymlink() { if (warnedSymlinks.compareAndSet(false, true)) { LOGGER.warning("Symbolic links enabled on this platform but disabled for this user; run as administrator or use Local Security Policy > Security Settings > Local Policies > User Rights Assignment > Create symbolic links"); @@ -1345,11 +1410,11 @@ public static String resolveSymlink(File link, TaskListener listener) throws Int @CheckForNull public static File resolveSymlinkToFile(@NonNull File link) throws InterruptedException, IOException { String target = resolveSymlink(link); - if (target==null) return null; + if (target == null) return null; File f = new File(target); if (f.isAbsolute()) return f; // absolute symlink - return new File(link.getParentFile(),target); // relative symlink + return new File(link.getParentFile(), target); // relative symlink } /** @@ -1375,7 +1440,7 @@ public static String resolveSymlink(@NonNull File link) throws IOException { return null; } catch (IOException x) { throw x; - } catch (Exception x) { + } catch (RuntimeException x) { throw new IOException(x); } } @@ -1387,7 +1452,7 @@ public static String resolveSymlink(@NonNull File link) throws IOException { * but don't remember it right now. * * @since 1.204 - * @deprecated since 2008-05-13. This method is broken (see ISSUE#1666). It should probably + * @deprecated since 2008-05-13. This method is broken (see JENKINS-1666). It should probably * be removed but I'm not sure if it is considered part of the public API * that needs to be maintained for backwards compatibility. * Use {@link #encode(String)} instead. @@ -1395,7 +1460,7 @@ public static String resolveSymlink(@NonNull File link) throws IOException { @Deprecated public static String encodeRFC2396(String url) { try { - return new URI(null,url,null).toASCIIString(); + return new URI(null, url, null).toASCIIString(); } catch (URISyntaxException e) { LOGGER.log(Level.WARNING, "Failed to encode {0}", url); // could this ever happen? return url; @@ -1408,7 +1473,7 @@ public static String encodeRFC2396(String url) { */ @NonNull public static String wrapToErrorSpan(@NonNull String s) { - s = ""+s+""; + s = "" + s + ""; return s; } @@ -1422,7 +1487,7 @@ public static String wrapToErrorSpan(@NonNull String s) { */ @CheckForNull public static Number tryParseNumber(@CheckForNull String numberStr, @CheckForNull Number defaultNumber) { - if ((numberStr == null) || (numberStr.length() == 0)) { + if (numberStr == null || numberStr.length() == 0) { return defaultNumber; } try { @@ -1541,8 +1606,8 @@ private static Method getMethod(@NonNull Class clazz, @Nullable Class base public static File changeExtension(@NonNull File dst, @NonNull String ext) { String p = dst.getPath(); int pos = p.lastIndexOf('.'); - if (pos<0) return new File(p+ext); - else return new File(p.substring(0,pos)+ext); + if (pos < 0) return new File(p + ext); + else return new File(p.substring(0, pos) + ext); } /** @@ -1551,7 +1616,7 @@ public static File changeExtension(@NonNull File dst, @NonNull String ext) { */ @Nullable public static String intern(@CheckForNull String s) { - return s==null ? s : s.intern(); + return s == null ? s : s.intern(); } /** @@ -1568,10 +1633,10 @@ public static String intern(@CheckForNull String s) { @Restricted(NoExternalUse.class) public static boolean isAbsoluteUri(@NonNull String uri) { int idx = uri.indexOf(':'); - if (idx<0) return false; // no ':'. can't be absolute + if (idx < 0) return false; // no ':'. can't be absolute // #, ?, and / must not be before ':' - return idx<_indexOf(uri, '#') && idx<_indexOf(uri,'?') && idx<_indexOf(uri,'/'); + return idx < _indexOf(uri, '#') && idx < _indexOf(uri, '?') && idx < _indexOf(uri, '/'); } /** @@ -1588,7 +1653,7 @@ public static boolean isSafeToRedirectTo(@NonNull String uri) { */ private static int _indexOf(@NonNull String s, char ch) { int idx = s.indexOf(ch); - if (idx<0) return s.length(); + if (idx < 0) return s.length(); return idx; } @@ -1602,7 +1667,7 @@ public static Properties loadProperties(@NonNull String properties) throws IOExc p.load(new StringReader(properties)); return p; } - + /** * Closes the item and logs error to the log in the case of error. * Logging will be performed on the {@code WARNING} level. @@ -1613,14 +1678,14 @@ public static Properties loadProperties(@NonNull String properties) throws IOExc * @since 2.19, but TODO update once un-restricted */ @Restricted(NoExternalUse.class) - public static void closeAndLogFailures(@CheckForNull Closeable toClose, @NonNull Logger logger, + public static void closeAndLogFailures(@CheckForNull Closeable toClose, @NonNull Logger logger, @NonNull String closeableName, @NonNull String closeableOwner) { if (toClose == null) { return; } try { toClose.close(); - } catch(IOException ex) { + } catch (IOException ex) { LogRecord record = new LogRecord(Level.WARNING, "Failed to close {0} of {1}"); record.setParameters(new Object[] { closeableName, closeableOwner }); record.setThrown(ex); @@ -1672,28 +1737,85 @@ public static Set modeToPermissions(int mode) throws IOExce throw new IOException(e); } } - + + /** + * Create a directory by creating all nonexistent parent directories first. + * + *

Unlike {@link Files#createDirectory}, an exception is not thrown + * if the directory could not be created because it already exists. + * Unlike {@link Files#createDirectories}, an exception is not thrown + * if the directory (or one of its parents) is a symbolic link. + * + *

The {@code attrs} parameter contains optional {@link FileAttribute file attributes} + * to set atomically when creating the nonexistent directories. + * Each file attribute is identified by its {@link FileAttribute#name}. + * If more than one attribute of the same name is included in the array, + * then all but the last occurrence is ignored. + * + *

If this method fails, + * then it may do so after creating some, but not all, of the parent directories. + * + * @param dir The directory to create. + * @param attrs An optional list of file attributes to set atomically + * when creating the directory. + * @return The directory. + * @throws UnsupportedOperationException If the array contains an attribute + * that cannot be set atomically when creating the directory. + * @throws FileAlreadyExistsException If {@code dir} exists but is not a directory. + * @throws IOException If an I/O error occurs. + * @see Files#createDirectories(Path, FileAttribute[]) + */ + @Restricted(NoExternalUse.class) + public static Path createDirectories(@NonNull Path dir, FileAttribute... attrs) throws IOException { + dir = dir.toAbsolutePath(); + + Path parent; + for (parent = dir.getParent(); parent != null; parent = parent.getParent()) { + if (Files.exists(parent)) { + break; + } + } + + if (parent == null) { + if (Files.isDirectory(dir)) { + return dir; + } else { + return Files.createDirectory(dir, attrs); + } + } + + Path child = parent; + for (Path name : parent.relativize(dir)) { + child = child.resolve(name); + if (!Files.isDirectory(child)) { + Files.createDirectory(child, attrs); + } + } + + return dir; + } + /** * Compute the number of calendar days elapsed since the given date. * As it's only the calendar days difference that matter, "11.00pm" to "2.00am the day after" returns 1, * even if there are only 3 hours between. As well as "10am" to "2pm" both on the same day, returns 0. */ @Restricted(NoExternalUse.class) - public static long daysBetween(@NonNull Date a, @NonNull Date b){ + public static long daysBetween(@NonNull Date a, @NonNull Date b) { LocalDate aLocal = a.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); LocalDate bLocal = b.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); return ChronoUnit.DAYS.between(aLocal, bLocal); } - + /** * @return positive number of days between the given date and now * @see #daysBetween(Date, Date) */ @Restricted(NoExternalUse.class) - public static long daysElapsedSince(@NonNull Date date){ + public static long daysElapsedSince(@NonNull Date date) { return Math.max(0, daysBetween(date, new Date())); } - + /** * Find the specific ancestor, or throw an exception. * Useful for an ancestor we know is inside the URL to ease readability @@ -1707,7 +1829,7 @@ public static long daysElapsedSince(@NonNull Date date){ return t; } - public static final FastDateFormat XS_DATETIME_FORMATTER = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss'Z'",new SimpleTimeZone(0,"GMT")); + public static final FastDateFormat XS_DATETIME_FORMATTER = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss'Z'", new SimpleTimeZone(0, "GMT")); // Note: RFC822 dates must not be localized! public static final FastDateFormat RFC822_DATETIME_FORMATTER @@ -1718,9 +1840,9 @@ public static long daysElapsedSince(@NonNull Date date){ /** * On Unix environment that cannot run "ln", set this to true. */ - public static boolean NO_SYMLINK = SystemProperties.getBoolean(Util.class.getName()+".noSymLink"); + public static boolean NO_SYMLINK = SystemProperties.getBoolean(Util.class.getName() + ".noSymLink"); - public static boolean SYMLINK_ESCAPEHATCH = SystemProperties.getBoolean(Util.class.getName()+".symlinkEscapeHatch"); + public static boolean SYMLINK_ESCAPEHATCH = SystemProperties.getBoolean(Util.class.getName() + ".symlinkEscapeHatch"); /** * The number of additional times we will attempt to delete files/directory trees @@ -1778,16 +1900,4 @@ public static long daysElapsedSince(@NonNull Date date){ private static PathRemover newPathRemover(@NonNull PathRemover.PathChecker pathChecker) { return PathRemover.newFilteredRobustRemover(pathChecker, DELETION_RETRIES, GC_AFTER_FAILED_DELETE, WAIT_BETWEEN_DELETION_RETRIES); } - - /** - * If this flag is true, native implementations of {@link FilePath#chmod} - * and {@link hudson.util.IOUtils#mode} are used instead of NIO. - *

- * This should only be enabled if the setgid/setuid/sticky bits are - * intentionally set on the Jenkins installation and they are being - * overwritten by Jenkins erroneously. - */ - @Restricted(value = NoExternalUse.class) - @SuppressFBWarnings("MS_SHOULD_BE_FINAL") - public static boolean NATIVE_CHMOD_MODE = SystemProperties.getBoolean(Util.class.getName() + ".useNativeChmodAndMode"); } diff --git a/core/src/main/java/hudson/WebAppMain.java b/core/src/main/java/hudson/WebAppMain.java index d96fce2e5fac..c63e1f813a96 100644 --- a/core/src/main/java/hudson/WebAppMain.java +++ b/core/src/main/java/hudson/WebAppMain.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Jean-Baptiste Quenot, Tom Huybrechts - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,64 +21,62 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson; -import hudson.security.ACLContext; -import java.io.OutputStream; -import java.nio.file.Files; -import java.nio.file.InvalidPathException; -import java.nio.file.StandardOpenOption; -import jenkins.util.SystemProperties; +import static java.util.logging.Level.FINE; +import static java.util.logging.Level.SEVERE; +import static java.util.logging.Level.WARNING; + import com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider; import com.thoughtworks.xstream.core.JVM; import hudson.model.Hudson; import hudson.security.ACL; +import hudson.security.ACLContext; +import hudson.util.AWTProblem; import hudson.util.BootFailure; -import jenkins.model.Jenkins; +import hudson.util.ChartUtil; +import hudson.util.HudsonFailedToLoad; import hudson.util.HudsonIsLoading; +import hudson.util.IncompatibleAntVersionDetected; import hudson.util.IncompatibleServletVersionDetected; import hudson.util.IncompatibleVMDetected; import hudson.util.InsufficientPermissionDetected; import hudson.util.NoHomeDir; -import hudson.util.RingBufferLogHandler; import hudson.util.NoTempDir; -import hudson.util.IncompatibleAntVersionDetected; -import hudson.util.HudsonFailedToLoad; -import hudson.util.ChartUtil; -import hudson.util.AWTProblem; -import jenkins.util.JenkinsJVM; -import org.jvnet.localizer.LocaleProvider; -import org.kohsuke.accmod.Restricted; -import org.kohsuke.accmod.restrictions.NoExternalUse; -import org.kohsuke.stapler.jelly.JellyFacet; -import org.apache.tools.ant.types.FileSet; - -import javax.naming.Context; -import javax.naming.InitialContext; -import javax.naming.NamingException; -import javax.servlet.ServletContext; -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; -import javax.servlet.ServletResponse; -import javax.servlet.SessionTrackingMode; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.TransformerFactoryConfigurationError; +import hudson.util.RingBufferLogHandler; import java.io.File; import java.io.IOException; +import java.io.OutputStream; import java.net.URL; import java.net.URLClassLoader; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.InvalidPathException; +import java.nio.file.StandardOpenOption; +import java.security.Security; import java.util.Date; import java.util.EnumSet; import java.util.Locale; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.security.Security; import java.util.logging.ConsoleHandler; import java.util.logging.Formatter; import java.util.logging.Handler; +import java.util.logging.Level; import java.util.logging.LogRecord; - -import static java.util.logging.Level.*; +import java.util.logging.Logger; +import javax.servlet.ServletContext; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; +import javax.servlet.ServletResponse; +import javax.servlet.SessionTrackingMode; +import jenkins.model.Jenkins; +import jenkins.util.JenkinsJVM; +import jenkins.util.SystemProperties; +import org.apache.tools.ant.types.FileSet; +import org.jvnet.localizer.LocaleProvider; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.stapler.jelly.JellyFacet; /** * Entry point when Hudson is used as a webapp. @@ -99,7 +97,7 @@ public class WebAppMain implements ServletContextListener { *

* The SecurityRealm should be corrected but this is a hardening in Jenkins core. *

- * As this property is read during startup, you will not be able to change it at runtime + * As this property is read during startup, you will not be able to change it at runtime * depending on your application server (not possible with Jetty nor Tomcat) *

* When running hpi:run, the default tracking is COOKIE+URL. @@ -110,7 +108,7 @@ public class WebAppMain implements ServletContextListener { public static final String FORCE_SESSION_TRACKING_BY_COOKIE_PROP = WebAppMain.class.getName() + ".forceSessionTrackingByCookie"; private final RingBufferLogHandler handler = new RingBufferLogHandler(WebAppMain.getDefaultRingBufferSize()) { - + @Override public synchronized void publish(LogRecord record) { if (record.getLevel().intValue() >= Level.INFO.intValue()) { super.publish(record); @@ -118,11 +116,12 @@ public class WebAppMain implements ServletContextListener { } }; - /**This getter returns the int DEFAULT_RING_BUFFER_SIZE from the class RingBufferLogHandler from a static context. + /** + * This getter returns the int DEFAULT_RING_BUFFER_SIZE from the class RingBufferLogHandler from a static context. * Exposes access from RingBufferLogHandler.DEFAULT_RING_BUFFER_SIZE to WebAppMain. * Written for the requirements of JENKINS-50669 * @return int This returns DEFAULT_RING_BUFFER_SIZE - * @see JENKINS-50669 + * @see JENKINS-50669 * @since 2.259 */ public static int getDefaultRingBufferSize() { @@ -142,7 +141,7 @@ public void contextInitialized(ServletContextEvent event) { if (Main.isDevelopmentMode && System.getProperty("java.util.logging.config.file") == null) { try { Formatter formatter = (Formatter) Class.forName("io.jenkins.lib.support_log_formatter.SupportLogFormatter").newInstance(); - for (Handler h : java.util.logging.Logger.getLogger("").getHandlers()) { + for (Handler h : Logger.getLogger("").getHandlers()) { if (h instanceof ConsoleHandler) { ((ConsoleHandler) h).setFormatter(formatter); } @@ -156,26 +155,27 @@ public void contextInitialized(ServletContextEvent event) { JenkinsJVMAccess._setJenkinsJVM(true); final ServletContext context = event.getServletContext(); - File home=null; + File home = null; try { // use the current request to determine the language LocaleProvider.setProvider(new LocaleProvider() { + @Override public Locale get() { return Functions.getCurrentLocale(); } }); - // quick check to see if we (seem to) have enough permissions to run. (see #719) + // quick check to see if we (seem to) have enough permissions to run. (see JENKINS-719) JVM jvm; try { jvm = new JVM(); - new URLClassLoader(new URL[0],getClass().getClassLoader()); - } catch(SecurityException e) { + new URLClassLoader(new URL[0], getClass().getClassLoader()); + } catch (SecurityException e) { throw new InsufficientPermissionDetected(e); } - try {// remove Sun PKCS11 provider if present. See http://wiki.jenkins-ci.org/display/JENKINS/Solaris+Issue+6276483 + try { // remove Sun PKCS11 provider if present. See http://wiki.jenkins-ci.org/display/JENKINS/Solaris+Issue+6276483 Security.removeProvider("SunPKCS11-Solaris"); } catch (SecurityException e) { // ignore this error. @@ -185,67 +185,36 @@ public Locale get() { final FileAndDescription describedHomeDir = getHomeDir(event); home = describedHomeDir.file.getAbsoluteFile(); - home.mkdirs(); - LOGGER.info("Jenkins home directory: "+ home +" found at: " + describedHomeDir.description); - - // check that home exists (as mkdirs could have failed silently), otherwise throw a meaningful error - if (!home.exists()) - throw new NoHomeDir(home); + try { + Util.createDirectories(home.toPath()); + } catch (IOException | InvalidPathException e) { + throw (NoHomeDir) new NoHomeDir(home).initCause(e); + } + LOGGER.info("Jenkins home directory: " + home + " found at: " + describedHomeDir.description); recordBootAttempt(home); // make sure that we are using XStream in the "enhanced" (JVM-specific) mode - if(jvm.bestReflectionProvider().getClass()==PureJavaReflectionProvider.class) { + if (jvm.bestReflectionProvider().getClass() == PureJavaReflectionProvider.class) { throw new IncompatibleVMDetected(); // nope } -// JNA is no longer a hard requirement. It's just nice to have. See HUDSON-4820 for more context. -// // make sure JNA works. this can fail if -// // - platform is unsupported -// // - JNA is already loaded in another classloader -// // see http://wiki.jenkins-ci.org/display/JENKINS/JNA+is+already+loaded -// // TODO: or shall we instead modify Hudson to work gracefully without JNA? -// try { -// /* -// java.lang.UnsatisfiedLinkError: Native Library /builds/apps/glassfish/domains/hudson-domain/generated/jsp/j2ee-modules/hudson-1.309/loader/com/sun/jna/sunos-sparc/libjnidispatch.so already loaded in another classloader -// at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1743) -// at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1674) -// at java.lang.Runtime.load0(Runtime.java:770) -// at java.lang.System.load(System.java:1005) -// at com.sun.jna.Native.loadNativeLibraryFromJar(Native.java:746) -// at com.sun.jna.Native.loadNativeLibrary(Native.java:680) -// at com.sun.jna.Native.(Native.java:108) -// at hudson.util.jna.GNUCLibrary.(GNUCLibrary.java:86) -// at hudson.Util.createSymlink(Util.java:970) -// at hudson.model.Run.run(Run.java:1174) -// at hudson.matrix.MatrixBuild.run(MatrixBuild.java:149) -// at hudson.model.ResourceController.execute(ResourceController.java:88) -// at hudson.model.Executor.run(Executor.java:123) -// */ -// String.valueOf(Native.POINTER_SIZE); // this meaningless operation forces the classloading and initialization -// } catch (LinkageError e) { -// if (e.getMessage().contains("another classloader")) -// context.setAttribute(APP,new JNADoublyLoaded(e)); -// else -// context.setAttribute(APP,new HudsonFailedToLoad(e)); -// } - // make sure this is servlet 2.4 container or above try { - ServletResponse.class.getMethod("setCharacterEncoding",String.class); + ServletResponse.class.getMethod("setCharacterEncoding", String.class); } catch (NoSuchMethodException e) { - throw new IncompatibleServletVersionDetected(ServletResponse.class); + throw (IncompatibleServletVersionDetected) new IncompatibleServletVersionDetected(ServletResponse.class).initCause(e); } // make sure that we see Ant 1.7 try { FileSet.class.getMethod("getDirectoryScanner"); } catch (NoSuchMethodException e) { - throw new IncompatibleAntVersionDetected(FileSet.class); + throw (IncompatibleAntVersionDetected) new IncompatibleAntVersionDetected(FileSet.class).initCause(e); } // make sure AWT is functioning, or else JFreeChart won't even load. - if(ChartUtil.awtProblemCause!=null) { + if (ChartUtil.awtProblemCause != null) { throw new AWTProblem(ChartUtil.awtProblemCause); } @@ -262,26 +231,9 @@ public Locale get() { throw new NoTempDir(e); } - // Tomcat breaks XSLT with JDK 5.0 and onward. Check if that's the case, and if so, - // try to correct it - try { - TransformerFactory.newInstance(); - // if this works we are all happy - } catch (TransformerFactoryConfigurationError x) { - // no it didn't. - LOGGER.log(WARNING, "XSLT not configured correctly. Hudson will try to fix this. See http://issues.apache.org/bugzilla/show_bug.cgi?id=40895 for more details",x); - System.setProperty(TransformerFactory.class.getName(),"com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl"); - try { - TransformerFactory.newInstance(); - LOGGER.info("XSLT is set to the JAXP RI in JRE"); - } catch(TransformerFactoryConfigurationError y) { - LOGGER.log(SEVERE, "Failed to correct the problem."); - } - } - installExpressionFactory(event); - context.setAttribute(APP,new HudsonIsLoading()); + context.setAttribute(APP, new HudsonIsLoading()); if (SystemProperties.getBoolean(FORCE_SESSION_TRACKING_BY_COOKIE_PROP, true)) { context.setSessionTrackingModes(EnumSet.of(SessionTrackingMode.COOKIE)); } @@ -300,19 +252,19 @@ public void run() { context.setAttribute(APP, instance); - BootFailure.getBootFailureFile(_home).delete(); + Files.deleteIfExists(BootFailure.getBootFailureFile(_home).toPath()); // at this point we are open for business and serving requests normally - LOGGER.info("Jenkins is fully up and running"); + Jenkins.get().getLifecycle().onReady(); success = true; } catch (Error e) { - new HudsonFailedToLoad(e).publish(context,_home); + new HudsonFailedToLoad(e).publish(context, _home); throw e; } catch (Exception e) { - new HudsonFailedToLoad(e).publish(context,_home); + new HudsonFailedToLoad(e).publish(context, _home); } finally { Jenkins instance = Jenkins.getInstanceOrNull(); - if(!success && instance!=null) + if (!success && instance != null) instance.cleanUp(); } } @@ -321,7 +273,7 @@ public void run() { } catch (BootFailure e) { e.publish(context, home); } catch (Error | RuntimeException e) { - LOGGER.log(SEVERE, "Failed to initialize Jenkins",e); + LOGGER.log(SEVERE, "Failed to initialize Jenkins", e); throw e; } } @@ -337,10 +289,10 @@ public void joinInit() throws InterruptedException { * @see BootFailure */ private void recordBootAttempt(File home) { - try (OutputStream o=Files.newOutputStream(BootFailure.getBootFailureFile(home).toPath(), StandardOpenOption.CREATE, StandardOpenOption.APPEND)) { - o.write((new Date().toString() + System.getProperty("line.separator", "\n")).getBytes()); + try (OutputStream o = Files.newOutputStream(BootFailure.getBootFailureFile(home).toPath(), StandardOpenOption.CREATE, StandardOpenOption.APPEND)) { + o.write((new Date() + System.getProperty("line.separator", "\n")).getBytes(Charset.defaultCharset())); } catch (IOException | InvalidPathException e) { - LOGGER.log(WARNING, "Failed to record boot attempts",e); + LOGGER.log(WARNING, "Failed to record boot attempts", e); } } @@ -348,10 +300,9 @@ public static void installExpressionFactory(ServletContextEvent event) { JellyFacet.setExpressionFactory(event, new ExpressionFactory2()); } - /** + /** * Installs log handler to monitor all Hudson logs. */ - @edu.umd.cs.findbugs.annotations.SuppressFBWarnings("LG_LOST_LOGGER_DUE_TO_WEAK_REFERENCE") private void installLogger() { Jenkins.logRecords = handler.getView(); Logger.getLogger("").addHandler(handler); @@ -361,7 +312,8 @@ private void installLogger() { public static class FileAndDescription { public final File file; public final String description; - public FileAndDescription(File file,String description) { + + public FileAndDescription(File file, String description) { this.file = file; this.description = description; } @@ -370,69 +322,50 @@ public FileAndDescription(File file,String description) { /** * Determines the home directory for Jenkins. * - *

- * We look for a setting that affects the smallest scope first, then bigger ones later. + *

We look for a setting that affects the smallest scope first, then bigger ones later. * - *

- * People makes configuration mistakes, so we are trying to be nice + *

People make configuration mistakes, so we are trying to be nice * with those by doing {@link String#trim()}. - * - *

+ * * @return the File alongside with some description to help the user troubleshoot issues */ public FileAndDescription getHomeDir(ServletContextEvent event) { - // check JNDI for the home directory first - for (String name : HOME_NAMES) { - try { - InitialContext iniCtxt = new InitialContext(); - Context env = (Context) iniCtxt.lookup("java:comp/env"); - String value = (String) env.lookup(name); - if(value!=null && value.trim().length()>0) - return new FileAndDescription(new File(value.trim()),"JNDI/java:comp/env/"+name); - // look at one more place. See issue #1314 - value = (String) iniCtxt.lookup(name); - if(value!=null && value.trim().length()>0) - return new FileAndDescription(new File(value.trim()),"JNDI/"+name); - } catch (NamingException e) { - // ignore - } - } - - // next the system property + // check the system property for the home directory first for (String name : HOME_NAMES) { String sysProp = SystemProperties.getString(name); - if(sysProp!=null) - return new FileAndDescription(new File(sysProp.trim()),"SystemProperties.getProperty(\""+name+"\")"); + if (sysProp != null) + return new FileAndDescription(new File(sysProp.trim()), "SystemProperties.getProperty(\"" + name + "\")"); } // look at the env var next for (String name : HOME_NAMES) { String env = EnvVars.masterEnvVars.get(name); - if(env!=null) - return new FileAndDescription(new File(env.trim()).getAbsoluteFile(),"EnvVars.masterEnvVars.get(\""+name+"\")"); + if (env != null) + return new FileAndDescription(new File(env.trim()).getAbsoluteFile(), "EnvVars.masterEnvVars.get(\"" + name + "\")"); } // otherwise pick a place by ourselves String root = event.getServletContext().getRealPath("/WEB-INF/workspace"); - if(root!=null) { + if (root != null) { File ws = new File(root.trim()); - if(ws.exists()) + if (ws.exists()) // Hudson <1.42 used to prefer this before ~/.hudson, so // check the existence and if it's there, use it. // otherwise if this is a new installation, prefer ~/.hudson - return new FileAndDescription(ws,"getServletContext().getRealPath(\"/WEB-INF/workspace\")"); + return new FileAndDescription(ws, "getServletContext().getRealPath(\"/WEB-INF/workspace\")"); } - File legacyHome = new File(new File(System.getProperty("user.home")),".hudson"); + File legacyHome = new File(new File(System.getProperty("user.home")), ".hudson"); if (legacyHome.exists()) { - return new FileAndDescription(legacyHome,"$user.home/.hudson"); // before rename, this is where it was stored + return new FileAndDescription(legacyHome, "$user.home/.hudson"); // before rename, this is where it was stored } - File newHome = new File(new File(System.getProperty("user.home")),".jenkins"); - return new FileAndDescription(newHome,"$user.home/.jenkins"); + File newHome = new File(new File(System.getProperty("user.home")), ".jenkins"); + return new FileAndDescription(newHome, "$user.home/.jenkins"); } + @Override public void contextDestroyed(ServletContextEvent event) { try (ACLContext old = ACL.as2(ACL.SYSTEM2)) { Jenkins instance = Jenkins.getInstanceOrNull(); @@ -440,7 +373,7 @@ public void contextDestroyed(ServletContextEvent event) { if (instance != null) { instance.cleanUp(); } - } catch (Exception e) { + } catch (Throwable e) { LOGGER.log(Level.SEVERE, "Failed to clean up. Restart will continue.", e); } @@ -467,5 +400,5 @@ private static void _setJenkinsJVM(boolean jenkinsJVM) { } } - private static final String[] HOME_NAMES = {"JENKINS_HOME","HUDSON_HOME"}; + private static final String[] HOME_NAMES = {"JENKINS_HOME", "HUDSON_HOME"}; } diff --git a/core/src/main/java/hudson/WorkspaceSnapshot.java b/core/src/main/java/hudson/WorkspaceSnapshot.java index f4a5aa0e242b..19d536700f8a 100644 --- a/core/src/main/java/hudson/WorkspaceSnapshot.java +++ b/core/src/main/java/hudson/WorkspaceSnapshot.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,12 +21,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson; +import hudson.model.AbstractBuild; import hudson.model.Action; import hudson.model.TaskListener; -import hudson.model.AbstractBuild; - import java.io.IOException; /** @@ -45,17 +45,20 @@ public abstract class WorkspaceSnapshot implements Action { * @param listener * Send the progress of the restoration to this listener. Never null. */ - public abstract void restoreTo(AbstractBuild owner, FilePath dst, TaskListener listener) throws IOException, InterruptedException; + public abstract void restoreTo(AbstractBuild owner, FilePath dst, TaskListener listener) throws IOException, InterruptedException; + @Override public String getIconFileName() { // by default, hide from the UI return null; } + @Override public String getDisplayName() { return "Workspace"; } + @Override public String getUrlName() { return "workspace"; } diff --git a/core/src/main/java/hudson/XmlFile.java b/core/src/main/java/hudson/XmlFile.java index d203806906ad..f624104df673 100644 --- a/core/src/main/java/hudson/XmlFile.java +++ b/core/src/main/java/hudson/XmlFile.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson; import com.thoughtworks.xstream.XStream; @@ -33,16 +34,6 @@ import hudson.model.Descriptor; import hudson.util.AtomicFileWriter; import hudson.util.XStream2; -import java.nio.file.Files; -import java.nio.file.InvalidPathException; -import org.xml.sax.Attributes; -import org.xml.sax.InputSource; -import org.xml.sax.Locator; -import org.xml.sax.SAXException; -import org.xml.sax.ext.Locator2; -import org.xml.sax.helpers.DefaultHandler; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParserFactory; import java.io.BufferedInputStream; import java.io.File; import java.io.IOException; @@ -50,15 +41,28 @@ import java.io.InputStreamReader; import java.io.Reader; import java.io.Serializable; -import java.io.Writer; import java.io.StringWriter; +import java.io.Writer; +import java.nio.channels.FileChannel; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.InvalidPathException; import java.util.Collections; import java.util.IdentityHashMap; import java.util.Map; import java.util.function.Supplier; import java.util.logging.Level; import java.util.logging.Logger; +import javax.xml.XMLConstants; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParserFactory; import org.apache.commons.io.IOUtils; +import org.xml.sax.Attributes; +import org.xml.sax.InputSource; +import org.xml.sax.Locator; +import org.xml.sax.SAXException; +import org.xml.sax.ext.Locator2; +import org.xml.sax.helpers.DefaultHandler; /** * Represents an XML data file that Jenkins uses as a data file. @@ -112,22 +116,34 @@ * There's a few other possibilities, such as implementing a custom * {@link Converter} for XStream, or {@link XStream#alias(String, Class) registering an alias}. * - * @see Architecture » Persistence + * @see Architecture » Persistence * @author Kohsuke Kawaguchi */ public final class XmlFile { private final XStream xs; private final File file; + private final boolean force; private static final Map beingWritten = Collections.synchronizedMap(new IdentityHashMap<>()); private static final ThreadLocal writing = new ThreadLocal<>(); public XmlFile(File file) { - this(DEFAULT_XSTREAM,file); + this(DEFAULT_XSTREAM, file); } public XmlFile(XStream xs, File file) { + this(xs, file, true); + } + + /** + * @param force Whether or not to flush the page cache to the storage device with {@link + * FileChannel#force} (i.e., {@code fsync}} or {@code FlushFileBuffers}) before this method + * returns. If you set this to {@code false}, you will lose data integrity. + * @since 2.304 + */ + public XmlFile(XStream xs, File file, boolean force) { this.xs = xs; this.file = file; + this.force = force; } public File getFile() { @@ -143,12 +159,12 @@ public XStream getXStream() { */ public Object read() throws IOException { if (LOGGER.isLoggable(Level.FINE)) { - LOGGER.fine("Reading "+file); + LOGGER.fine("Reading " + file); } try (InputStream in = new BufferedInputStream(Files.newInputStream(file.toPath()))) { return xs.fromXML(in); } catch (RuntimeException | Error e) { - throw new IOException("Unable to read "+file,e); + throw new IOException("Unable to read " + file, e); } } @@ -159,7 +175,7 @@ public Object read() throws IOException { * The unmarshalled object. Usually the same as {@code o}, but would be different * if the XML representation is completely new. */ - public Object unmarshal( Object o ) throws IOException { + public Object unmarshal(Object o) throws IOException { return unmarshal(o, false); } @@ -180,13 +196,15 @@ private Object unmarshal(Object o, boolean nullOut) throws IOException { return xs.unmarshal(DEFAULT_DRIVER.createReader(in), o); } } catch (RuntimeException | Error e) { - throw new IOException("Unable to read "+file,e); + throw new IOException("Unable to read " + file, e); } } - public void write( Object o ) throws IOException { + public void write(Object o) throws IOException { mkdirs(); - AtomicFileWriter w = new AtomicFileWriter(file); + AtomicFileWriter w = force + ? new AtomicFileWriter(file) + : new AtomicFileWriter(file.toPath(), StandardCharsets.UTF_8, false, false); try { w.write("\n"); beingWritten.put(o, null); @@ -198,7 +216,7 @@ public void write( Object o ) throws IOException { writing.set(null); } w.commit(); - } catch(RuntimeException e) { + } catch (RuntimeException e) { throw new IOException(e); } finally { w.abort(); @@ -230,12 +248,12 @@ public boolean exists() { return file.exists(); } - public void delete() { - file.delete(); + public void delete() throws IOException { + Files.deleteIfExists(Util.fileToPath(file)); } - - public void mkdirs() { - file.getParentFile().mkdirs(); + + public void mkdirs() throws IOException { + Util.createDirectories(Util.fileToPath(file.getParentFile())); } @Override @@ -247,8 +265,8 @@ public String toString() { * Opens a {@link Reader} that loads XML. * This method uses {@link #sniffEncoding() the right encoding}, * not just the system default encoding. - * @throws IOException Encoding issues * @return Reader for the file. should be close externally once read. + * @throws IOException Encoding issues */ public Reader readRaw() throws IOException { try { @@ -288,14 +306,15 @@ public void writeRawTo(Writer w) throws IOException { /** * Parses the beginning of the file and determines the encoding. * - * @throws IOException - * if failed to detect encoding. * @return * always non-null. + * @throws IOException + * if failed to detect encoding. */ public String sniffEncoding() throws IOException { class Eureka extends SAXException { final String encoding; + Eureka(String encoding) { this.encoding = encoding; } @@ -304,7 +323,11 @@ class Eureka extends SAXException { try (InputStream in = Files.newInputStream(file.toPath())) { InputSource input = new InputSource(file.toURI().toASCIIString()); input.setByteStream(in); - JAXP.newSAXParser().parse(input,new DefaultHandler() { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + spf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); + spf.setNamespaceAware(true); + spf.newSAXParser().parse(input, new DefaultHandler() { private Locator loc; @Override public void setDocumentLocator(Locator locator) { @@ -324,11 +347,11 @@ public void startElement(String uri, String localName, String qName, Attributes } private void attempt() throws Eureka { - if(loc==null) return; + if (loc == null) return; if (loc instanceof Locator2) { Locator2 loc2 = (Locator2) loc; String e = loc2.getEncoding(); - if(e!=null) + if (e != null) throw new Eureka(e); } } @@ -336,7 +359,7 @@ private void attempt() throws Eureka { // can't reach here throw new AssertionError(); } catch (Eureka e) { - if(e.encoding!=null) + if (e.encoding != null) return e.encoding; // the environment can contain old version of Xerces and others that do not support Locator2 // in such a case, assume UTF-8 rather than fail, since Jenkins internally always write XML in UTF-8 @@ -356,13 +379,7 @@ private void attempt() throws Eureka { private static final Logger LOGGER = Logger.getLogger(XmlFile.class.getName()); - private static final SAXParserFactory JAXP = SAXParserFactory.newInstance(); - private static final HierarchicalStreamDriver DEFAULT_DRIVER = XStream2.getDefaultDriver(); private static final XStream DEFAULT_XSTREAM = new XStream2(DEFAULT_DRIVER); - - static { - JAXP.setNamespaceAware(true); - } } diff --git a/core/src/main/java/hudson/cli/AbstractBuildRangeCommand.java b/core/src/main/java/hudson/cli/AbstractBuildRangeCommand.java index bef260eee0e0..ead7f267ff60 100644 --- a/core/src/main/java/hudson/cli/AbstractBuildRangeCommand.java +++ b/core/src/main/java/hudson/cli/AbstractBuildRangeCommand.java @@ -3,10 +3,9 @@ import hudson.model.AbstractBuild; import hudson.model.AbstractProject; import hudson.model.Fingerprint.RangeSet; -import org.kohsuke.args4j.Argument; - import java.io.IOException; import java.util.List; +import org.kohsuke.args4j.Argument; /** * {@link CLICommand} that acts on a series of {@link AbstractBuild}s. @@ -16,17 +15,18 @@ */ @Deprecated public abstract class AbstractBuildRangeCommand extends CLICommand { - @Argument(metaVar="JOB",usage="Name of the job to build",required=true,index=0) - public AbstractProject job; + @Argument(metaVar = "JOB", usage = "Name of the job to build", required = true, index = 0) + public AbstractProject job; - @Argument(metaVar="RANGE",usage="Range of the build records to delete. 'N-M', 'N,M', or 'N'",required=true,index=1) + @Argument(metaVar = "RANGE", usage = "Range of the build records to delete. 'N-M', 'N,M', or 'N'", required = true, index = 1) public String range; + @Override protected int run() throws Exception { - RangeSet rs = RangeSet.fromString(range,false); + RangeSet rs = RangeSet.fromString(range, false); - return act((List)job.getBuilds(rs)); + return act((List) job.getBuilds(rs)); } - protected abstract int act(List> builds) throws IOException; + protected abstract int act(List> builds) throws IOException; } diff --git a/core/src/main/java/hudson/cli/AddJobToViewCommand.java b/core/src/main/java/hudson/cli/AddJobToViewCommand.java index 3a57c9ffb50c..6bab9deeb7d1 100644 --- a/core/src/main/java/hudson/cli/AddJobToViewCommand.java +++ b/core/src/main/java/hudson/cli/AddJobToViewCommand.java @@ -21,15 +21,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package hudson.cli; -import java.util.List; +package hudson.cli; import hudson.Extension; -import hudson.model.TopLevelItem; import hudson.model.DirectlyModifiableView; +import hudson.model.TopLevelItem; import hudson.model.View; - +import java.util.List; import org.kohsuke.args4j.Argument; /** @@ -39,11 +38,11 @@ @Extension public class AddJobToViewCommand extends CLICommand { - @Argument(usage="Name of the view", required=true, index=0) + @Argument(usage = "Name of the view", required = true, index = 0) private View view; @SuppressWarnings("MismatchedQueryAndUpdateOfCollection") - @Argument(usage="Job names", required=true, index=1) + @Argument(usage = "Job names", required = true, index = 1) private List jobs; @Override @@ -58,7 +57,7 @@ protected int run() throws Exception { if (!(view instanceof DirectlyModifiableView)) throw new IllegalStateException( "'" + view.getDisplayName() + "' view can not be modified directly"); - for (TopLevelItem job: jobs) { + for (TopLevelItem job : jobs) { ((DirectlyModifiableView) view).add(job); } diff --git a/core/src/main/java/hudson/cli/BuildCommand.java b/core/src/main/java/hudson/cli/BuildCommand.java index dc6917b59690..b4f7ae15e0a1 100644 --- a/core/src/main/java/hudson/cli/BuildCommand.java +++ b/core/src/main/java/hudson/cli/BuildCommand.java @@ -21,45 +21,43 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.cli; +import hudson.AbortException; +import hudson.Extension; import hudson.Util; import hudson.console.ModelHyperlinkNote; import hudson.model.Cause.UserIdCause; import hudson.model.CauseAction; +import hudson.model.Item; import hudson.model.Job; -import hudson.model.Run; -import hudson.model.ParametersAction; +import hudson.model.ParameterDefinition; import hudson.model.ParameterValue; +import hudson.model.ParametersAction; import hudson.model.ParametersDefinitionProperty; -import hudson.model.ParameterDefinition; -import hudson.Extension; -import hudson.AbortException; import hudson.model.Queue; -import hudson.model.Item; +import hudson.model.Run; import hudson.model.TaskListener; import hudson.model.User; import hudson.model.queue.QueueTaskFuture; import hudson.util.EditDistance; import hudson.util.StreamTaskListener; - +import java.io.FileNotFoundException; +import java.io.PrintStream; import java.nio.file.NoSuchFileException; -import jenkins.scm.SCMDecisionHandler; -import org.kohsuke.args4j.Argument; -import org.kohsuke.args4j.CmdLineException; -import org.kohsuke.args4j.Option; - -import java.util.Map; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; -import java.util.ArrayList; -import java.util.Map.Entry; -import java.io.FileNotFoundException; -import java.io.PrintStream; - +import java.util.Map; +import java.util.Objects; import jenkins.model.Jenkins; import jenkins.model.ParameterizedJobMixIn; +import jenkins.scm.SCMDecisionHandler; import jenkins.triggers.SCMTriggerItem; +import org.kohsuke.args4j.Argument; +import org.kohsuke.args4j.CmdLineException; +import org.kohsuke.args4j.Option; /** * Builds a job, and optionally waits until its completion. @@ -73,48 +71,49 @@ public String getShortDescription() { return Messages.BuildCommand_ShortDescription(); } - @Argument(metaVar="JOB",usage="Name of the job to build",required=true) - public Job job; + @Argument(metaVar = "JOB", usage = "Name of the job to build", required = true) + public Job job; - @Option(name="-f", usage="Follow the build progress. Like -s only interrupts are not passed through to the build.") + @Option(name = "-f", usage = "Follow the build progress. Like -s only interrupts are not passed through to the build.") public boolean follow = false; - @Option(name="-s",usage="Wait until the completion/abortion of the command. Interrupts are passed through to the build.") + @Option(name = "-s", usage = "Wait until the completion/abortion of the command. Interrupts are passed through to the build.") public boolean sync = false; - @Option(name="-w",usage="Wait until the start of the command") + @Option(name = "-w", usage = "Wait until the start of the command") public boolean wait = false; - @Option(name="-c",usage="Check for SCM changes before starting the build, and if there's no change, exit without doing a build") + @Option(name = "-c", usage = "Check for SCM changes before starting the build, and if there's no change, exit without doing a build") public boolean checkSCM = false; - @Option(name="-p",usage="Specify the build parameters in the key=value format.") - public Map parameters = new HashMap<>(); + @Option(name = "-p", usage = "Specify the build parameters in the key=value format.") + public Map parameters = new HashMap<>(); - @Option(name="-v",usage="Prints out the console output of the build. Use with -s") + @Option(name = "-v", usage = "Prints out the console output of the build. Use with -s") public boolean consoleOutput = false; - @Option(name="-r") @Deprecated + @Option(name = "-r") @Deprecated public int retryCnt = 10; protected static final String BUILD_SCHEDULING_REFUSED = "Build scheduling Refused by an extension, hence not in Queue."; + @Override protected int run() throws Exception { job.checkPermission(Item.BUILD); ParametersAction a = null; if (!parameters.isEmpty()) { ParametersDefinitionProperty pdp = job.getProperty(ParametersDefinitionProperty.class); - if (pdp==null) - throw new IllegalStateException(job.getFullDisplayName()+" is not parameterized but the -p option was specified."); + if (pdp == null) + throw new IllegalStateException(job.getFullDisplayName() + " is not parameterized but the -p option was specified."); //TODO: switch to type annotations after the migration to Java 1.8 List values = new ArrayList<>(); - for (Entry e : parameters.entrySet()) { + for (Map.Entry e : parameters.entrySet()) { String name = e.getKey(); ParameterDefinition pd = pdp.getParameterDefinition(name); - if (pd==null) { + if (pd == null) { String nearest = EditDistance.findNearest(name, pdp.getParameterDefinitionNames()); throw new CmdLineException(null, nearest == null ? String.format("'%s' is not a valid parameter.", name) : @@ -122,20 +121,20 @@ protected int run() throws Exception { } ParameterValue val = pd.createValue(this, Util.fixNull(e.getValue())); if (val == null) { - throw new CmdLineException(null, String.format("Cannot resolve the value for the parameter '%s'.",name)); + throw new CmdLineException(null, String.format("Cannot resolve the value for the parameter '%s'.", name)); } values.add(val); } // handle missing parameters by adding as default values ISSUE JENKINS-7162 - for(ParameterDefinition pd : pdp.getParameterDefinitions()) { + for (ParameterDefinition pd : pdp.getParameterDefinitions()) { if (parameters.containsKey(pd.getName())) continue; // not passed in use default ParameterValue defaultValue = pd.getDefaultParameterValue(); if (defaultValue == null) { - throw new CmdLineException(null, String.format("No default value for the parameter '%s'.",pd.getName())); + throw new CmdLineException(null, String.format("No default value for the parameter '%s'.", pd.getName())); } values.add(defaultValue); } @@ -146,7 +145,7 @@ protected int run() throws Exception { if (checkSCM) { SCMTriggerItem item = SCMTriggerItem.SCMTriggerItems.asSCMTriggerItem(job); if (item == null) - throw new AbortException(job.getFullDisplayName()+" has no SCM trigger, but checkSCM was specified"); + throw new AbortException(job.getFullDisplayName() + " has no SCM trigger, but checkSCM was specified"); // preemptively check for a polling veto if (SCMDecisionHandler.firstShouldPollVeto(job) != null) { return 0; @@ -159,21 +158,21 @@ protected int run() throws Exception { String msg = Messages.BuildCommand_CLICause_CannotBuildUnknownReasons(job.getFullDisplayName()); if (job instanceof ParameterizedJobMixIn.ParameterizedJob && ((ParameterizedJobMixIn.ParameterizedJob) job).isDisabled()) { msg = Messages.BuildCommand_CLICause_CannotBuildDisabled(job.getFullDisplayName()); - } else if (job.isHoldOffBuildUntilSave()){ + } else if (job.isHoldOffBuildUntilSave()) { msg = Messages.BuildCommand_CLICause_CannotBuildConfigNotSaved(job.getFullDisplayName()); } throw new IllegalStateException(msg); } Queue.Item item = ParameterizedJobMixIn.scheduleBuild2(job, 0, new CauseAction(new CLICause(Jenkins.getAuthentication2().getName())), a); - QueueTaskFuture> f = item != null ? (QueueTaskFuture)item.getFuture() : null; - + QueueTaskFuture> f = item != null ? (QueueTaskFuture) item.getFuture() : null; + if (wait || sync || follow) { if (f == null) { throw new IllegalStateException(BUILD_SCHEDULING_REFUSED); } - Run b = f.waitForStart(); // wait for the start - stdout.println("Started "+b.getFullDisplayName()); + Run b = f.waitForStart(); // wait for the start + stdout.println("Started " + b.getFullDisplayName()); stdout.flush(); if (sync || follow) { @@ -184,13 +183,13 @@ protected int run() throws Exception { // exception on a slow/busy machine, if it takes // longish to create the log file int retryInterval = 100; - for (int i=0;i<=retryCnt;) { + for (int i = 0; i <= retryCnt; ) { try { b.writeWholeLogTo(stdout); break; } catch (FileNotFoundException | NoSuchFileException e) { - if ( i == retryCnt ) { + if (i == retryCnt) { Exception myException = new AbortException(); myException.initCause(e); throw myException; @@ -201,7 +200,7 @@ protected int run() throws Exception { } } f.get(); // wait for the completion - stdout.println("Completed "+b.getFullDisplayName()+" : "+b.getResult()); + stdout.println("Completed " + b.getFullDisplayName() + " : " + b.getResult()); return b.getResult().ordinal; } catch (InterruptedException e) { if (follow) { @@ -240,15 +239,15 @@ protected void printUsageSummary(PrintStream stderr) { public static class CLICause extends UserIdCause { - private String startedBy; + private String startedBy; - public CLICause(){ - startedBy = "unknown"; - } + public CLICause() { + startedBy = "unknown"; + } - public CLICause(String startedBy){ - this.startedBy = startedBy; - } + public CLICause(String startedBy) { + this.startedBy = startedBy; + } @Override public String getShortDescription() { @@ -265,12 +264,22 @@ public void print(TaskListener listener) { @Override public boolean equals(Object o) { - return o instanceof CLICause; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + if (!super.equals(o)) { + return false; + } + CLICause cliCause = (CLICause) o; + return Objects.equals(startedBy, cliCause.startedBy); } @Override public int hashCode() { - return 7; + return Objects.hash(super.hashCode(), startedBy); } } } diff --git a/core/src/main/java/hudson/cli/CLIAction.java b/core/src/main/java/hudson/cli/CLIAction.java index 03a791bf2422..d42e974452a2 100644 --- a/core/src/main/java/hudson/cli/CLIAction.java +++ b/core/src/main/java/hudson/cli/CLIAction.java @@ -21,30 +21,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package hudson.cli; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletResponse; -import hudson.model.UnprotectedRootAction; -import jenkins.model.Jenkins; - -import org.jenkinsci.Symbol; -import org.kohsuke.accmod.Restricted; -import org.kohsuke.accmod.restrictions.NoExternalUse; -import org.kohsuke.stapler.Stapler; -import org.kohsuke.stapler.StaplerProxy; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +package hudson.cli; import hudson.Extension; +import hudson.model.UnprotectedRootAction; import java.io.ByteArrayInputStream; import java.io.DataInputStream; +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PipedInputStream; @@ -54,15 +38,28 @@ import java.nio.charset.Charset; import java.nio.charset.UnsupportedCharsetException; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Locale; +import java.util.Map; +import java.util.UUID; import java.util.logging.Level; import java.util.logging.Logger; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletResponse; +import jenkins.model.Jenkins; import jenkins.util.FullDuplexHttpService; import jenkins.websocket.WebSocketSession; import jenkins.websocket.WebSockets; +import org.jenkinsci.Symbol; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.HttpResponses; +import org.kohsuke.stapler.Stapler; +import org.kohsuke.stapler.StaplerProxy; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; import org.springframework.security.core.Authentication; /** @@ -78,14 +75,17 @@ public class CLIAction implements UnprotectedRootAction, StaplerProxy { private final transient Map duplexServices = new HashMap<>(); + @Override public String getIconFileName() { return null; } + @Override public String getDisplayName() { return "Jenkins CLI"; } + @Override public String getUrlName() { return "cli"; } @@ -121,19 +121,25 @@ public HttpResponse doWs() { Authentication authentication = Jenkins.getAuthentication2(); return WebSockets.upgrade(new WebSocketSession() { ServerSideImpl connection; + long sentBytes, sentCount, receivedBytes, receivedCount; class OutputImpl implements PlainCLIProtocol.Output { @Override public void send(byte[] data) throws IOException { sendBinary(ByteBuffer.wrap(data)); + sentBytes += data.length; + sentCount++; } + @Override public void close() throws IOException { doClose(); } } + private void doClose() { close(); } + @Override protected void opened() { try { @@ -154,21 +160,27 @@ protected void opened() { } }, "CLI handler for " + authentication.getName()).start(); } + @Override protected void binary(byte[] payload, int offset, int len) { try { connection.handle(new DataInputStream(new ByteArrayInputStream(payload, offset, len))); + receivedBytes += len; + receivedCount++; } catch (IOException x) { error(x); } } + @Override protected void error(Throwable cause) { LOGGER.log(Level.WARNING, null, cause); } + @Override protected void closed(int statusCode, String reason) { LOGGER.fine(() -> "closed: " + statusCode + ": " + reason); + LOGGER.fine(() -> "received " + receivedCount + " packets of " + receivedBytes + " bytes; sent " + sentCount + " packets of " + sentBytes + " bytes"); connection.handleClose(); } }); @@ -177,7 +189,7 @@ protected void closed(int statusCode, String reason) { @Override public Object getTarget() { StaplerRequest req = Stapler.getCurrentRequest(); - if (req.getRestOfPath().length()==0 && "POST".equals(req.getMethod())) { + if (req.getRestOfPath().length() == 0 && "POST".equals(req.getMethod())) { // CLI connection request if ("false".equals(req.getParameter("remoting"))) { throw new PlainCliEndpointResponse(); @@ -199,15 +211,18 @@ static class ServerSideImpl extends PlainCLIProtocol.ServerSide { private final PipedInputStream stdin = new PipedInputStream(); private final PipedOutputStream stdinMatch = new PipedOutputStream(); private final Authentication authentication; + ServerSideImpl(PlainCLIProtocol.Output out, Authentication authentication) throws IOException { super(out); stdinMatch.connect(stdin); this.authentication = authentication; } + @Override protected void onArg(String text) { args.add(text); } + @Override protected void onLocale(String text) { for (Locale _locale : Locale.getAvailableLocales()) { @@ -218,6 +233,7 @@ protected void onLocale(String text) { } LOGGER.log(Level.WARNING, "unknown client locale {0}", text); } + @Override protected void onEncoding(String text) { try { @@ -226,18 +242,22 @@ protected void onEncoding(String text) { LOGGER.log(Level.WARNING, "unknown client charset {0}", text); } } + @Override protected void onStart() { ready(); } + @Override protected void onStdin(byte[] chunk) throws IOException { stdinMatch.write(chunk); } + @Override protected void onEndStdin() throws IOException { stdinMatch.close(); } + @Override protected void handleClose() { ready(); @@ -245,10 +265,12 @@ protected void handleClose() { runningThread.interrupt(); } } + private synchronized void ready() { ready = true; notifyAll(); } + void run() throws IOException, InterruptedException { synchronized (this) { while (!ready) { diff --git a/core/src/main/java/hudson/cli/CLICommand.java b/core/src/main/java/hudson/cli/CLICommand.java index d0c9825768e2..ab0a7266aec1 100644 --- a/core/src/main/java/hudson/cli/CLICommand.java +++ b/core/src/main/java/hudson/cli/CLICommand.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.cli; import edu.umd.cs.findbugs.annotations.CheckForNull; @@ -40,6 +41,9 @@ import java.io.IOException; import java.io.InputStream; import java.io.PrintStream; +import java.io.UncheckedIOException; +import java.io.UnsupportedEncodingException; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Type; import java.nio.charset.Charset; import java.util.List; @@ -81,7 +85,7 @@ * calls {@link #main(List, Locale, InputStream, PrintStream, PrintStream)} method. * *

Note for CLI command implementor

- * Start with this document + * Start with this document * to get the general idea of CLI. * *
    @@ -113,15 +117,15 @@ public abstract class CLICommand implements ExtensionPoint, Cloneable { * (In contrast, calling {@code System.out.println(...)} would print out * the message to the server log file, which is probably not what you want. */ - public transient PrintStream stdout,stderr; + public transient PrintStream stdout, stderr; /** - * Shared text, which is reported back to CLI if an error happens in commands + * Shared text, which is reported back to CLI if an error happens in commands * taking lists of parameters. * @since 2.26 */ static final String CLI_LISTPARAM_SUMMARY_ERROR_TEXT = "Error occurred while performing this command, see previous stderr output."; - + /** * Connected to stdin of the CLI agent. * @@ -166,13 +170,13 @@ public abstract class CLICommand implements ExtensionPoint, Cloneable { public String getName() { String name = getClass().getName(); name = name.substring(name.lastIndexOf('.') + 1); // short name - name = name.substring(name.lastIndexOf('$')+1); - if(name.endsWith("Command")) - name = name.substring(0,name.length()-7); // trim off the command + name = name.substring(name.lastIndexOf('$') + 1); + if (name.endsWith("Command")) + name = name.substring(0, name.length() - 7); // trim off the command // convert "FooBarZot" into "foo-bar-zot" // Locale is fixed so that "CreateInstance" always become "create-instance" no matter where this is run. - return name.replaceAll("([a-z0-9])([A-Z])","$1-$2").toLowerCase(Locale.ENGLISH); + return name.replaceAll("([a-z0-9])([A-Z])", "$1-$2").toLowerCase(Locale.ENGLISH); } /** @@ -183,7 +187,7 @@ public String getName() { /** * Entry point to the CLI command. - * + * *

    * The default implementation uses args4j to parse command line arguments and call {@link #run()}, * but if that processing is undesirable, subtypes can directly override this method and leave {@link #run()} @@ -205,21 +209,20 @@ public String getName() { * Connected to the stderr of the CLI client. * @return * Exit code from the CLI command execution - * - *

    - * Jenkins standard exit codes from CLI: - * 0 means everything went well. - * 1 means further unspecified exception is thrown while performing the command. - * 2 means CmdLineException is thrown while performing the command. - * 3 means IllegalArgumentException is thrown while performing the command. - * 4 mean IllegalStateException is thrown while performing the command. - * 5 means AbortException is thrown while performing the command. - * 6 means AccessDeniedException is thrown while performing the command. - * 7 means BadCredentialsException is thrown while performing the command. - * 8-15 are reserved for future usage - * 16+ mean a custom CLI exit error code (meaning defined by the CLI command itself) - * - *

    + * + * + * + * + * + * + * + * + * + * + * + * + * + *
    Jenkins standard exit codes from CLI
    CodeDefinition
    0everything went well.
    1further unspecified exception is thrown while performing the command.
    2{@link CmdLineException} is thrown while performing the command.
    3{@link IllegalArgumentException} is thrown while performing the command.
    4{@link IllegalStateException} is thrown while performing the command.
    5{@link AbortException} is thrown while performing the command.
    6{@link AccessDeniedException} is thrown while performing the command.
    7{@link BadCredentialsException} is thrown while performing the command.
    8-15are reserved for future usage.
    16+a custom CLI exit error code (meaning defined by the CLI command itself)
    * Note: For details - see JENKINS-32273 */ public int main(List args, Locale locale, InputStream stdin, PrintStream stdout, PrintStream stderr) { @@ -279,7 +282,7 @@ public int main(List args, Locale locale, InputStream stdin, PrintStream Functions.printStackTrace(e, stderr); return 1; } finally { - if(sc != null) + if (sc != null) sc.setAuthentication(old); // restore } } @@ -313,7 +316,7 @@ protected CmdLineParser getCmdLineParser() { */ @Deprecated public Channel checkChannel() throws AbortException { - throw new AbortException("This command is requesting the -remoting mode which is no longer supported. See https://jenkins.io/redirect/cli-command-requires-channel"); + throw new AbortException("This command is requesting the -remoting mode which is no longer supported. See https://www.jenkins.io/redirect/cli-command-requires-channel"); } /** @@ -334,8 +337,8 @@ public Channel checkChannel() throws AbortException { * @since 2.266 */ public Authentication getTransportAuthentication2() { - Authentication a = transportAuth; - if (a==null) a = Jenkins.ANONYMOUS2; + Authentication a = transportAuth; + if (a == null) a = Jenkins.ANONYMOUS2; return a; } @@ -364,7 +367,7 @@ public void setTransportAuth(org.acegisecurity.Authentication transportAuth) { /** * Executes the command, and return the exit code. - * + * *

    * This is an internal contract between {@link CLICommand} and its subtype. * To execute CLI method from outside, use {@link #main(List, Locale, InputStream, PrintStream, PrintStream)} @@ -404,7 +407,19 @@ protected void printUsage(PrintStream stderr, CmdLineParser p) { public final String getSingleLineSummary() { ByteArrayOutputStream out = new ByteArrayOutputStream(); getCmdLineParser().printSingleLineUsage(out); - return out.toString(); + Charset charset; + try { + charset = getClientCharset(); + } catch (IOException e) { + throw new UncheckedIOException(e); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + try { + return out.toString(charset.name()); + } catch (UnsupportedEncodingException e) { + throw new AssertionError(e); + } } /** @@ -414,7 +429,19 @@ public final String getSingleLineSummary() { public final String getUsage() { ByteArrayOutputStream out = new ByteArrayOutputStream(); getCmdLineParser().printUsage(out); - return out.toString(); + Charset charset; + try { + charset = getClientCharset(); + } catch (IOException e) { + throw new UncheckedIOException(e); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + try { + return out.toString(charset.name()); + } catch (UnsupportedEncodingException e) { + throw new AssertionError(e); + } } /** @@ -423,17 +450,34 @@ public final String getUsage() { @Restricted(NoExternalUse.class) public final String getLongDescription() { ByteArrayOutputStream out = new ByteArrayOutputStream(); - PrintStream ps = new PrintStream(out); + Charset charset; + try { + charset = getClientCharset(); + } catch (IOException e) { + throw new UncheckedIOException(e); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + PrintStream ps; + try { + ps = new PrintStream(out, false, charset.name()); + } catch (UnsupportedEncodingException e) { + throw new AssertionError(e); + } printUsageSummary(ps); ps.close(); - return out.toString(); + try { + return out.toString(charset.name()); + } catch (UnsupportedEncodingException e) { + throw new AssertionError(e); + } } /** * Called while producing usage. This is a good method to override * to render the general description of the command that goes beyond - * a single-line summary. + * a single-line summary. */ protected void printUsageSummary(PrintStream stderr) { stderr.println(getShortDescription()); @@ -481,9 +525,9 @@ protected String getClientEnvironmentVariable(String name) throws IOException, I */ protected CLICommand createClone() { try { - return getClass().newInstance(); - } catch (IllegalAccessException | InstantiationException e) { - throw new AssertionError(e); + return getClass().getDeclaredConstructor().newInstance(); + } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) { + throw new LinkageError(e.getMessage(), e); } } @@ -492,9 +536,9 @@ protected CLICommand createClone() { */ protected void registerOptionHandlers() { try { - for (Class c : Index.list(OptionHandlerExtension.class, Jenkins.get().pluginManager.uberClassLoader,Class.class)) { + for (Class c : Index.list(OptionHandlerExtension.class, Jenkins.get().pluginManager.uberClassLoader, Class.class)) { Type t = Types.getBaseClass(c, OptionHandler.class); - CmdLineParser.registerHandler(Types.erasure(Types.getTypeArgument(t,0)), c); + CmdLineParser.registerHandler(Types.erasure(Types.getTypeArgument(t, 0)), c); } } catch (IOException e) { throw new Error(e); @@ -513,7 +557,7 @@ public static ExtensionList all() { */ public static CLICommand clone(String name) { for (CLICommand cmd : all()) - if(name.equals(cmd.getName())) + if (name.equals(cmd.getName())) return cmd.createClone(); return null; } @@ -539,7 +583,7 @@ public static CLICommand getCurrent() { // register option handlers that are defined ClassLoaders cls = new ClassLoaders(); Jenkins j = Jenkins.getInstanceOrNull(); - if (j!=null) {// only when running on the master + if (j != null) { // only when running on the controller cls.put(j.getPluginManager().uberClassLoader); ResourceNameIterator servicesIter = @@ -547,10 +591,10 @@ public static CLICommand getCurrent() { final ResourceClassIterator itr = new DiscoverClasses(cls).findResourceClasses(servicesIter); - while(itr.hasNext()) { + while (itr.hasNext()) { Class h = itr.nextResourceClass().loadClass(); Class c = Types.erasure(Types.getTypeArgument(Types.getBaseClass(h, OptionHandler.class), 0)); - CmdLineParser.registerHandler(c,h); + CmdLineParser.registerHandler(c, h); } } } diff --git a/core/src/main/java/hudson/cli/CancelQuietDownCommand.java b/core/src/main/java/hudson/cli/CancelQuietDownCommand.java index a521de769b78..8947dd5b30d5 100644 --- a/core/src/main/java/hudson/cli/CancelQuietDownCommand.java +++ b/core/src/main/java/hudson/cli/CancelQuietDownCommand.java @@ -25,9 +25,8 @@ package hudson.cli; import hudson.Extension; -import jenkins.model.Jenkins; - import java.util.logging.Logger; +import jenkins.model.Jenkins; /** * Cancel previous quiet down Jenkins - preparation for a restart diff --git a/core/src/main/java/hudson/cli/ClearQueueCommand.java b/core/src/main/java/hudson/cli/ClearQueueCommand.java index 1a1b875bc5c3..f040dabc1fd3 100644 --- a/core/src/main/java/hudson/cli/ClearQueueCommand.java +++ b/core/src/main/java/hudson/cli/ClearQueueCommand.java @@ -25,9 +25,8 @@ package hudson.cli; import hudson.Extension; -import jenkins.model.Jenkins; - import java.util.logging.Logger; +import jenkins.model.Jenkins; /** * Clears the build queue diff --git a/core/src/main/java/hudson/cli/CliCrumbExclusion.java b/core/src/main/java/hudson/cli/CliCrumbExclusion.java index 12cca148f3b6..4e3064f43178 100644 --- a/core/src/main/java/hudson/cli/CliCrumbExclusion.java +++ b/core/src/main/java/hudson/cli/CliCrumbExclusion.java @@ -21,18 +21,18 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.cli; import hudson.Extension; import hudson.security.csrf.CrumbExclusion; -import org.kohsuke.accmod.Restricted; -import org.kohsuke.accmod.restrictions.DoNotUse; - +import java.io.IOException; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import java.io.IOException; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.DoNotUse; /** * Makes CLI HTTP fallback work with CSRF protection enabled (JENKINS-18114). diff --git a/core/src/main/java/hudson/cli/CliTransportAuthenticator.java b/core/src/main/java/hudson/cli/CliTransportAuthenticator.java index 1271074a7192..3e865c15adb7 100644 --- a/core/src/main/java/hudson/cli/CliTransportAuthenticator.java +++ b/core/src/main/java/hudson/cli/CliTransportAuthenticator.java @@ -30,7 +30,6 @@ public abstract class CliTransportAuthenticator implements ExtensionPoint { * Protocol identifier that {@link #supportsProtocol(String)} returned true. * @param channel * Communication channel to the client. - * @param con */ public abstract void authenticate(String protocol, Channel channel, Connection con); diff --git a/core/src/main/java/hudson/cli/CloneableCLICommand.java b/core/src/main/java/hudson/cli/CloneableCLICommand.java index f6a4c60b02c1..74d789179f5f 100644 --- a/core/src/main/java/hudson/cli/CloneableCLICommand.java +++ b/core/src/main/java/hudson/cli/CloneableCLICommand.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.cli; /** @@ -34,7 +35,7 @@ public abstract class CloneableCLICommand extends CLICommand implements Cloneabl @Override protected CLICommand createClone() { try { - return (CLICommand)clone(); + return (CLICommand) clone(); } catch (CloneNotSupportedException e) { throw new AssertionError(e); } diff --git a/core/src/main/java/hudson/cli/ConnectNodeCommand.java b/core/src/main/java/hudson/cli/ConnectNodeCommand.java index 0a9a152e2265..0d3e9049205a 100644 --- a/core/src/main/java/hudson/cli/ConnectNodeCommand.java +++ b/core/src/main/java/hudson/cli/ConnectNodeCommand.java @@ -21,17 +21,17 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.cli; import hudson.AbortException; import hudson.Extension; import hudson.model.Computer; -import org.kohsuke.args4j.Argument; -import org.kohsuke.args4j.Option; - import java.util.HashSet; import java.util.List; import java.util.logging.Logger; +import org.kohsuke.args4j.Argument; +import org.kohsuke.args4j.Option; /** * Reconnect to a node or nodes. @@ -42,10 +42,10 @@ public class ConnectNodeCommand extends CLICommand { @SuppressWarnings("MismatchedQueryAndUpdateOfCollection") - @Argument(metaVar="NAME", usage="Slave name, or empty string for master; comma-separated list is supported", required=true, multiValued=true) + @Argument(metaVar = "NAME", usage = "Agent name, or empty string for built-in node; comma-separated list is supported", required = true, multiValued = true) private List nodes; - @Option(name="-f", usage="Cancel any currently pending connect operation and retry from scratch") + @Option(name = "-f", usage = "Cancel any currently pending connect operation and retry from scratch") public boolean force = false; private static final Logger LOGGER = Logger.getLogger(ConnectNodeCommand.class.getName()); diff --git a/core/src/main/java/hudson/cli/Connection.java b/core/src/main/java/hudson/cli/Connection.java index 13cec3f6159f..eb97d996ff01 100644 --- a/core/src/main/java/hudson/cli/Connection.java +++ b/core/src/main/java/hudson/cli/Connection.java @@ -21,21 +21,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.cli; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.remoting.ClassFilter; import hudson.remoting.ObjectInputStreamEx; import hudson.remoting.SocketChannelStream; - -import javax.crypto.Cipher; -import javax.crypto.CipherInputStream; -import javax.crypto.CipherOutputStream; -import javax.crypto.KeyAgreement; -import javax.crypto.SecretKey; -import javax.crypto.interfaces.DHPublicKey; -import javax.crypto.spec.DHParameterSpec; -import javax.crypto.spec.IvParameterSpec; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; @@ -56,6 +48,14 @@ import java.security.interfaces.RSAPublicKey; import java.security.spec.X509EncodedKeySpec; import java.util.Base64; +import javax.crypto.Cipher; +import javax.crypto.CipherInputStream; +import javax.crypto.CipherOutputStream; +import javax.crypto.KeyAgreement; +import javax.crypto.SecretKey; +import javax.crypto.interfaces.DHPublicKey; +import javax.crypto.spec.DHParameterSpec; +import javax.crypto.spec.IvParameterSpec; import org.jenkinsci.remoting.util.AnonymousClassWarnings; /** @@ -70,7 +70,7 @@ public class Connection { public final DataOutputStream dout; public Connection(Socket socket) throws IOException { - this(SocketChannelStream.in(socket),SocketChannelStream.out(socket)); + this(SocketChannelStream.in(socket), SocketChannelStream.out(socket)); } public Connection(InputStream in, OutputStream out) { @@ -119,7 +119,7 @@ public void writeObject(Object o) throws IOException { public T readObject() throws IOException, ClassNotFoundException { ObjectInputStream ois = new ObjectInputStreamEx(in, getClass().getClassLoader(), ClassFilter.DEFAULT); - return (T)ois.readObject(); + return (T) ois.readObject(); } public void writeKey(Key key) throws IOException { @@ -154,8 +154,9 @@ public byte[] readByteArray() throws IOException { * each other. */ public KeyAgreement diffieHellman(boolean side) throws IOException, GeneralSecurityException { - return diffieHellman(side,512); + return diffieHellman(side, 512); } + public KeyAgreement diffieHellman(boolean side, int keySize) throws IOException, GeneralSecurityException { KeyPair keyPair; PublicKey otherHalf; @@ -204,7 +205,7 @@ public Connection encryptConnection(SecretKey sessionKey, String algorithm) thro cin.init(Cipher.DECRYPT_MODE, sessionKey, createIv(sessionKey)); CipherInputStream i = new CipherInputStream(in, cin); - return new Connection(i,o); + return new Connection(i, o); } private IvParameterSpec createIv(SecretKey sessionKey) { @@ -219,8 +220,8 @@ private IvParameterSpec createIv(SecretKey sessionKey) { */ public static byte[] fold(byte[] bytes, int size) { byte[] r = new byte[size]; - for (int i=Math.max(bytes.length,size)-1; i>=0; i-- ) { - r[i%r.length] ^= bytes[i%bytes.length]; + for (int i = Math.max(bytes.length, size) - 1; i >= 0; i--) { + r[i % r.length] ^= bytes[i % bytes.length]; } return r; } @@ -232,7 +233,7 @@ private String detectKeyAlgorithm(KeyPair kp) { private String detectKeyAlgorithm(PublicKey kp) { if (kp instanceof RSAPublicKey) return "RSA"; if (kp instanceof DSAPublicKey) return "DSA"; - throw new IllegalArgumentException("Unknown public key type: "+kp); + throw new IllegalArgumentException("Unknown public key type: " + kp); } /** @@ -244,7 +245,7 @@ public void proveIdentity(byte[] sharedSecret, KeyPair key) throws IOException, writeUTF(algorithm); writeKey(key.getPublic()); - Signature sig = Signature.getInstance("SHA1with"+algorithm); + Signature sig = Signature.getInstance("SHA1with" + algorithm); sig.initSign(key.getPrivate()); sig.update(key.getPublic().getEncoded()); sig.update(sharedSecret); @@ -260,7 +261,7 @@ public PublicKey verifyIdentity(byte[] sharedSecret) throws IOException, General PublicKey spk = KeyFactory.getInstance(serverKeyAlgorithm).generatePublic(readKey()); // verify the identity of the server - Signature sig = Signature.getInstance("SHA1with"+serverKeyAlgorithm); + Signature sig = Signature.getInstance("SHA1with" + serverKeyAlgorithm); sig.initVerify(spk); sig.update(spk.getEncoded()); sig.update(sharedSecret); @@ -268,7 +269,7 @@ public PublicKey verifyIdentity(byte[] sharedSecret) throws IOException, General return spk; } catch (ClassNotFoundException e) { - throw new Error(e); // impossible + throw new AssertionError(e); // impossible } } diff --git a/core/src/main/java/hudson/cli/ConsoleCommand.java b/core/src/main/java/hudson/cli/ConsoleCommand.java index 8965af0fe695..12d9ef1dff2d 100644 --- a/core/src/main/java/hudson/cli/ConsoleCommand.java +++ b/core/src/main/java/hudson/cli/ConsoleCommand.java @@ -6,15 +6,14 @@ import hudson.model.Job; import hudson.model.PermalinkProjectAction.Permalink; import hudson.model.Run; -import org.kohsuke.args4j.Argument; -import org.kohsuke.args4j.Option; - import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintStream; import org.apache.commons.io.IOUtils; +import org.kohsuke.args4j.Argument; +import org.kohsuke.args4j.Option; /** * cat/tail/head of the console output. @@ -28,47 +27,48 @@ public String getShortDescription() { return Messages.ConsoleCommand_ShortDescription(); } - @Argument(metaVar="JOB",usage="Name of the job",required=true) - public Job job; + @Argument(metaVar = "JOB", usage = "Name of the job", required = true) + public Job job; - @Argument(metaVar="BUILD",usage="Build number or permalink to point to the build. Defaults to the last build",required=false,index=1) - public String build="lastBuild"; + @Argument(metaVar = "BUILD", usage = "Build number or permalink to point to the build. Defaults to the last build", required = false, index = 1) + public String build = "lastBuild"; - @Option(name="-f",usage="If the build is in progress, stay around and append console output as it comes, like 'tail -f'") + @Option(name = "-f", usage = "If the build is in progress, stay around and append console output as it comes, like 'tail -f'") public boolean follow = false; - @Option(name="-n",metaVar="N",usage="Display the last N lines") + @Option(name = "-n", metaVar = "N", usage = "Display the last N lines") public int n = -1; + @Override protected int run() throws Exception { job.checkPermission(Item.READ); - Run run; + Run run; try { int n = Integer.parseInt(build); run = job.getBuildByNumber(n); - if (run==null) - throw new IllegalArgumentException("No such build #"+n); + if (run == null) + throw new IllegalArgumentException("No such build #" + n); } catch (NumberFormatException e) { // maybe a permalink? Permalink p = job.getPermalinks().get(build); - if (p!=null) { + if (p != null) { run = p.resolve(job); - if (run==null) - throw new IllegalStateException("Permalink "+build+" produced no build"); + if (run == null) + throw new IllegalStateException("Permalink " + build + " produced no build", e); } else { Permalink nearest = job.getPermalinks().findNearest(build); throw new IllegalArgumentException(nearest == null ? String.format("Not sure what you meant by \"%s\".", build) : String.format("Not sure what you meant by \"%s\". Did you mean \"%s\"?", - build, nearest.getId())); + build, nearest.getId()), e); } } OutputStreamWriter w = new OutputStreamWriter(stdout, getClientCharset()); try { - long pos = n>=0 ? seek(run) : 0; + long pos = n >= 0 ? seek(run) : 0; if (follow) { AnnotatedLargeText logText; @@ -97,38 +97,39 @@ protected int run() throws Exception { private long seek(Run run) throws IOException { class RingBuffer { long[] lastNlines = new long[n]; - int ptr=0; + int ptr = 0; RingBuffer() { - for (int i=0; i=0) { - for (int i=0; i= 0) { + for (int i = 0; i < len; i++) { byte ch = buf[i]; - boolean isNL = ch=='\r' || ch=='\n'; + boolean isNL = ch == '\r' || ch == '\n'; if (!isNL && prevIsNL) rb.add(pos); - if (isNL && prevIsNL && !(prev=='\r' && ch=='\n')) rb.add(pos); + if (isNL && prevIsNL && !(prev == '\r' && ch == '\n')) rb.add(pos); pos++; prev = ch; prevIsNL = isNL; diff --git a/core/src/main/java/hudson/cli/CopyJobCommand.java b/core/src/main/java/hudson/cli/CopyJobCommand.java index fd6b658f8f50..021d34d76167 100644 --- a/core/src/main/java/hudson/cli/CopyJobCommand.java +++ b/core/src/main/java/hudson/cli/CopyJobCommand.java @@ -21,19 +21,19 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.cli; -import jenkins.model.Jenkins; -import hudson.model.TopLevelItem; import hudson.Extension; import hudson.model.Item; +import hudson.model.TopLevelItem; +import jenkins.model.Jenkins; import jenkins.model.ModifiableTopLevelItemGroup; import org.kohsuke.args4j.Argument; - /** * Copies a job from CLI. - * + * * @author Kohsuke Kawaguchi */ @Extension @@ -43,17 +43,18 @@ public String getShortDescription() { return Messages.CopyJobCommand_ShortDescription(); } - @Argument(metaVar="SRC",usage="Name of the job to copy",required=true) + @Argument(metaVar = "SRC", usage = "Name of the job to copy", required = true) public TopLevelItem src; - @Argument(metaVar="DST",usage="Name of the new job to be created.",index=1,required=true) + @Argument(metaVar = "DST", usage = "Name of the new job to be created.", index = 1, required = true) public String dst; + @Override protected int run() throws Exception { Jenkins jenkins = Jenkins.get(); - if (jenkins.getItemByFullName(dst)!=null) { - throw new IllegalStateException("Job '"+dst+"' already exists"); + if (jenkins.getItemByFullName(dst) != null) { + throw new IllegalStateException("Job '" + dst + "' already exists"); } ModifiableTopLevelItemGroup ig = jenkins; @@ -73,8 +74,7 @@ protected int run() throws Exception { dst = dst.substring(i + 1); } - ig.copy(src,dst).save(); + ig.copy(src, dst).save(); return 0; } } - diff --git a/core/src/main/java/hudson/cli/CreateJobCommand.java b/core/src/main/java/hudson/cli/CreateJobCommand.java index 10ea5798fdbe..4b3dc23d9857 100644 --- a/core/src/main/java/hudson/cli/CreateJobCommand.java +++ b/core/src/main/java/hudson/cli/CreateJobCommand.java @@ -21,17 +21,18 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.cli; -import jenkins.model.Jenkins; import hudson.Extension; import hudson.model.Item; +import jenkins.model.Jenkins; import jenkins.model.ModifiableTopLevelItemGroup; import org.kohsuke.args4j.Argument; /** * Creates a new job by reading stdin as a configuration XML file. - * + * * @author Kohsuke Kawaguchi */ @Extension @@ -41,14 +42,15 @@ public String getShortDescription() { return Messages.CreateJobCommand_ShortDescription(); } - @Argument(metaVar="NAME",usage="Name of the job to create",required=true) + @Argument(metaVar = "NAME", usage = "Name of the job to create", required = true) public String name; + @Override protected int run() throws Exception { Jenkins h = Jenkins.get(); - if (h.getItemByFullName(name)!=null) { - throw new IllegalStateException("Job '"+name+"' already exists"); + if (h.getItemByFullName(name) != null) { + throw new IllegalStateException("Job '" + name + "' already exists"); } ModifiableTopLevelItemGroup ig = h; @@ -73,5 +75,3 @@ protected int run() throws Exception { return 0; } } - - diff --git a/core/src/main/java/hudson/cli/CreateNodeCommand.java b/core/src/main/java/hudson/cli/CreateNodeCommand.java index 791982daecf1..24aa9256e006 100644 --- a/core/src/main/java/hudson/cli/CreateNodeCommand.java +++ b/core/src/main/java/hudson/cli/CreateNodeCommand.java @@ -28,7 +28,6 @@ import hudson.model.Computer; import hudson.model.Node; import jenkins.model.Jenkins; - import org.kohsuke.args4j.Argument; /** @@ -38,7 +37,7 @@ @Extension public class CreateNodeCommand extends CLICommand { - @Argument(metaVar="NODE", usage="Name of the node") + @Argument(metaVar = "NODE", usage = "Name of the node") public String nodeName; @Override diff --git a/core/src/main/java/hudson/cli/CreateViewCommand.java b/core/src/main/java/hudson/cli/CreateViewCommand.java index dea72441fa0c..db61aa591276 100644 --- a/core/src/main/java/hudson/cli/CreateViewCommand.java +++ b/core/src/main/java/hudson/cli/CreateViewCommand.java @@ -21,14 +21,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package hudson.cli; -import org.kohsuke.args4j.Argument; +package hudson.cli; -import jenkins.model.Jenkins; import hudson.Extension; import hudson.model.Failure; import hudson.model.View; +import jenkins.model.Jenkins; +import org.kohsuke.args4j.Argument; /** * @author ogondza @@ -37,7 +37,7 @@ @Extension public class CreateViewCommand extends CLICommand { - @Argument(usage="Name of the view to use instead of the one in XML") + @Argument(usage = "Name of the view to use instead of the one in XML") public String viewName = null; @Override diff --git a/core/src/main/java/hudson/cli/DeleteBuildsCommand.java b/core/src/main/java/hudson/cli/DeleteBuildsCommand.java index b7c2531446b0..6d62eb9db937 100644 --- a/core/src/main/java/hudson/cli/DeleteBuildsCommand.java +++ b/core/src/main/java/hudson/cli/DeleteBuildsCommand.java @@ -21,11 +21,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.cli; import hudson.Extension; import hudson.model.Run; - import java.io.IOException; import java.io.PrintStream; import java.util.HashSet; @@ -66,7 +66,7 @@ protected int act(List> builds) throws IOException { } } - stdout.println("Deleted "+hsBuilds.size()+" builds"); + stdout.println("Deleted " + hsBuilds.size() + " builds"); return 0; } diff --git a/core/src/main/java/hudson/cli/DeleteJobCommand.java b/core/src/main/java/hudson/cli/DeleteJobCommand.java index d829340892e1..b203fc59c1c2 100644 --- a/core/src/main/java/hudson/cli/DeleteJobCommand.java +++ b/core/src/main/java/hudson/cli/DeleteJobCommand.java @@ -21,17 +21,18 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.cli; import hudson.AbortException; import hudson.Extension; import hudson.model.AbstractItem; +import hudson.model.Item; +import java.util.HashSet; +import java.util.List; import jenkins.model.Jenkins; import org.kohsuke.args4j.Argument; -import java.util.List; -import java.util.HashSet; - /** * CLI command, which deletes a job or multiple jobs. * @author pjanouse @@ -41,7 +42,7 @@ public class DeleteJobCommand extends CLICommand { @SuppressWarnings("MismatchedQueryAndUpdateOfCollection") - @Argument(usage="Name of the job(s) to delete", required=true, multiValued=true) + @Argument(usage = "Name of the job(s) to delete", required = true, multiValued = true) private List jobs; @Override @@ -58,20 +59,20 @@ protected int run() throws Exception { final HashSet hs = new HashSet<>(jobs); - for (String job_s: hs) { + for (String job_s : hs) { AbstractItem job; try { job = (AbstractItem) jenkins.getItemByFullName(job_s); - if(job == null) { + if (job == null) { throw new IllegalArgumentException("No such job '" + job_s + "'"); } - job.checkPermission(AbstractItem.DELETE); + job.checkPermission(Item.DELETE); job.delete(); } catch (Exception e) { - if(hs.size() == 1) { + if (hs.size() == 1) { throw e; } diff --git a/core/src/main/java/hudson/cli/DeleteNodeCommand.java b/core/src/main/java/hudson/cli/DeleteNodeCommand.java index 57aad4350758..5989aa247b67 100644 --- a/core/src/main/java/hudson/cli/DeleteNodeCommand.java +++ b/core/src/main/java/hudson/cli/DeleteNodeCommand.java @@ -21,16 +21,16 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.cli; import hudson.AbortException; import hudson.Extension; import hudson.model.Node; -import jenkins.model.Jenkins; -import org.kohsuke.args4j.Argument; - import java.util.HashSet; import java.util.List; +import jenkins.model.Jenkins; +import org.kohsuke.args4j.Argument; /** * CLI command, which deletes Jenkins nodes. @@ -41,7 +41,7 @@ public class DeleteNodeCommand extends CLICommand { @SuppressWarnings("MismatchedQueryAndUpdateOfCollection") - @Argument(usage="Names of nodes to delete", required=true, multiValued=true) + @Argument(usage = "Names of nodes to delete", required = true, multiValued = true) private List nodes; @Override @@ -70,7 +70,7 @@ protected int run() throws Exception { node.toComputer().doDoDelete(); } catch (Exception e) { - if(hs.size() == 1) { + if (hs.size() == 1) { throw e; } diff --git a/core/src/main/java/hudson/cli/DeleteViewCommand.java b/core/src/main/java/hudson/cli/DeleteViewCommand.java index 9950ff3a26d8..33a1743464b4 100644 --- a/core/src/main/java/hudson/cli/DeleteViewCommand.java +++ b/core/src/main/java/hudson/cli/DeleteViewCommand.java @@ -21,18 +21,17 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.cli; import hudson.AbortException; import hudson.Extension; import hudson.cli.handlers.ViewOptionHandler; -import hudson.model.ViewGroup; import hudson.model.View; - -import org.kohsuke.args4j.Argument; - +import hudson.model.ViewGroup; import java.util.HashSet; import java.util.List; +import org.kohsuke.args4j.Argument; /** * @author ogondza, pjanouse @@ -42,7 +41,7 @@ public class DeleteViewCommand extends CLICommand { @SuppressWarnings("MismatchedQueryAndUpdateOfCollection") - @Argument(usage="View names to delete", required=true, multiValued=true) + @Argument(usage = "View names to delete", required = true, multiValued = true) private List views; @Override @@ -61,7 +60,7 @@ protected int run() throws Exception { ViewOptionHandler voh = new ViewOptionHandler(null, null, null); - for(String view_s : hs) { + for (String view_s : hs) { View view; try { @@ -82,7 +81,7 @@ protected int run() throws Exception { group.deleteView(view); } catch (Exception e) { - if(hs.size() == 1) { + if (hs.size() == 1) { throw e; } diff --git a/core/src/main/java/hudson/cli/DisablePluginCommand.java b/core/src/main/java/hudson/cli/DisablePluginCommand.java index 58dbbb329156..53af28828ddb 100644 --- a/core/src/main/java/hudson/cli/DisablePluginCommand.java +++ b/core/src/main/java/hudson/cli/DisablePluginCommand.java @@ -27,13 +27,12 @@ import hudson.Extension; import hudson.PluginWrapper; import hudson.lifecycle.RestartNotSupportedException; +import java.io.PrintStream; +import java.util.List; import jenkins.model.Jenkins; import org.kohsuke.args4j.Argument; import org.kohsuke.args4j.Option; -import java.io.PrintStream; -import java.util.List; - /** * Disable one or more installed plugins. * @since 2.151 @@ -83,7 +82,15 @@ protected int run() throws Exception { try { strategyToUse = PluginWrapper.PluginDisableStrategy.valueOf(strategy.toUpperCase()); } catch (IllegalArgumentException iae) { - throw new IllegalArgumentException(hudson.cli.Messages.DisablePluginCommand_NoSuchStrategy(strategy, String.format("%s, %s, %s", PluginWrapper.PluginDisableStrategy.NONE, PluginWrapper.PluginDisableStrategy.MANDATORY, PluginWrapper.PluginDisableStrategy.ALL))); + throw new IllegalArgumentException( + hudson.cli.Messages.DisablePluginCommand_NoSuchStrategy( + strategy, + String.format( + "%s, %s, %s", + PluginWrapper.PluginDisableStrategy.NONE, + PluginWrapper.PluginDisableStrategy.MANDATORY, + PluginWrapper.PluginDisableStrategy.ALL)), + iae); } // disable... @@ -214,13 +221,13 @@ private int getResultCode(List results) { */ private int getResultCode(PluginWrapper.PluginDisableResult result) { int returnCode = 0; - switch (result.getStatus()){ + switch (result.getStatus()) { case NOT_DISABLED_DEPENDANTS: returnCode = RETURN_CODE_NOT_DISABLED_DEPENDANTS; break; case NO_SUCH_PLUGIN: returnCode = RETURN_CODE_NO_SUCH_PLUGIN; - break; + break; default: for (PluginWrapper.PluginDisableResult oneDependentResult : result.getDependentsDisableStatus()) { returnCode = getResultCode(oneDependentResult); diff --git a/core/src/main/java/hudson/cli/DisconnectNodeCommand.java b/core/src/main/java/hudson/cli/DisconnectNodeCommand.java index 5a0a25c954e2..eb080cf1eb98 100644 --- a/core/src/main/java/hudson/cli/DisconnectNodeCommand.java +++ b/core/src/main/java/hudson/cli/DisconnectNodeCommand.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.cli; import hudson.AbortException; @@ -28,13 +29,12 @@ import hudson.model.Computer; import hudson.model.ComputerSet; import hudson.util.EditDistance; -import jenkins.model.Jenkins; -import org.kohsuke.args4j.Argument; -import org.kohsuke.args4j.Option; - import java.util.HashSet; import java.util.List; import java.util.logging.Logger; +import jenkins.model.Jenkins; +import org.kohsuke.args4j.Argument; +import org.kohsuke.args4j.Option; /** * CLI Command, which disconnects nodes. @@ -43,7 +43,7 @@ */ @Extension public class DisconnectNodeCommand extends CLICommand { - @Argument(metaVar = "NAME", usage = "Slave name, or empty string for master; comma-separated list is supported", required = true, multiValued = true) + @Argument(metaVar = "NAME", usage = "Agent name, or empty string for built-in node; comma-separated list is supported", required = true, multiValued = true) private List nodes; @Option(name = "-m", usage = "Record the reason about why you are disconnecting this node") diff --git a/core/src/main/java/hudson/cli/EnablePluginCommand.java b/core/src/main/java/hudson/cli/EnablePluginCommand.java index a25c3b9871e7..c44bad65ebe8 100644 --- a/core/src/main/java/hudson/cli/EnablePluginCommand.java +++ b/core/src/main/java/hudson/cli/EnablePluginCommand.java @@ -27,13 +27,12 @@ import hudson.Extension; import hudson.PluginManager; import hudson.PluginWrapper; +import java.io.IOException; +import java.util.List; import jenkins.model.Jenkins; import org.kohsuke.args4j.Argument; import org.kohsuke.args4j.Option; -import java.io.IOException; -import java.util.List; - /** * Enables one or more installed plugins. The listed plugins must already be installed along with its dependencies. * Any listed plugin with disabled dependencies will have its dependencies enabled transitively. Note that enabling an diff --git a/core/src/main/java/hudson/cli/GetJobCommand.java b/core/src/main/java/hudson/cli/GetJobCommand.java index 051e75f6c083..d94044ef461c 100644 --- a/core/src/main/java/hudson/cli/GetJobCommand.java +++ b/core/src/main/java/hudson/cli/GetJobCommand.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.cli; import hudson.Extension; @@ -32,7 +33,7 @@ */ @Extension public class GetJobCommand extends CLICommand { - @Argument(metaVar="JOB",usage="Name of the job",required=true) + @Argument(metaVar = "JOB", usage = "Name of the job", required = true) public AbstractItem job; @Override @@ -40,6 +41,7 @@ public String getShortDescription() { return Messages.GetJobCommand_ShortDescription(); } + @Override protected int run() throws Exception { job.writeConfigDotXml(stdout); return 0; diff --git a/core/src/main/java/hudson/cli/GetNodeCommand.java b/core/src/main/java/hudson/cli/GetNodeCommand.java index 15df13bcd99c..62dd21826029 100644 --- a/core/src/main/java/hudson/cli/GetNodeCommand.java +++ b/core/src/main/java/hudson/cli/GetNodeCommand.java @@ -21,16 +21,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.cli; import hudson.Extension; import hudson.model.Computer; import hudson.model.Node; - import java.io.IOException; - import jenkins.model.Jenkins; - import org.kohsuke.args4j.Argument; /** @@ -40,7 +38,7 @@ @Extension public class GetNodeCommand extends CLICommand { - @Argument(metaVar="NODE", usage="Name of the node", required=true) + @Argument(metaVar = "NODE", usage = "Name of the node", required = true) public Node node; @Override diff --git a/core/src/main/java/hudson/cli/GetViewCommand.java b/core/src/main/java/hudson/cli/GetViewCommand.java index 0ae0ffa552af..e94bb7947a81 100644 --- a/core/src/main/java/hudson/cli/GetViewCommand.java +++ b/core/src/main/java/hudson/cli/GetViewCommand.java @@ -21,11 +21,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.cli; import hudson.Extension; import hudson.model.View; - import org.kohsuke.args4j.Argument; /** @@ -35,7 +35,7 @@ @Extension public class GetViewCommand extends CLICommand { - @Argument(usage="Name of the view to obtain", required=true) + @Argument(usage = "Name of the view to obtain", required = true) private View view; @Override diff --git a/core/src/main/java/hudson/cli/GroovyCommand.java b/core/src/main/java/hudson/cli/GroovyCommand.java index 8279f7ba4e7c..0d7e45e6ca18 100644 --- a/core/src/main/java/hudson/cli/GroovyCommand.java +++ b/core/src/main/java/hudson/cli/GroovyCommand.java @@ -21,20 +21,21 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.cli; -import groovy.lang.GroovyShell; import groovy.lang.Binding; -import jenkins.model.Jenkins; +import groovy.lang.GroovyShell; import hudson.Extension; -import org.kohsuke.args4j.Argument; -import org.kohsuke.args4j.CmdLineException; -import org.apache.commons.io.IOUtils; - import java.io.IOException; +import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; +import jenkins.model.Jenkins; +import org.apache.commons.io.IOUtils; +import org.kohsuke.args4j.Argument; +import org.kohsuke.args4j.CmdLineException; /** * Executes the specified groovy script. @@ -48,27 +49,28 @@ public String getShortDescription() { return Messages.GroovyCommand_ShortDescription(); } - @Argument(metaVar="SCRIPT",usage="Script to be executed. Only '=' (to represent stdin) is supported.") + @Argument(metaVar = "SCRIPT", usage = "Script to be executed. Only '=' (to represent stdin) is supported.") public String script; /** * Remaining arguments. */ - @Argument(metaVar="ARGUMENTS", index=1, usage="Command line arguments to pass into script.") + @Argument(metaVar = "ARGUMENTS", index = 1, usage = "Command line arguments to pass into script.") public List remaining = new ArrayList<>(); + @Override protected int run() throws Exception { // this allows the caller to manipulate the JVM state, so require the execute script privilege. Jenkins.get().checkPermission(Jenkins.ADMINISTER); Binding binding = new Binding(); - binding.setProperty("out",new PrintWriter(stdout,true)); - binding.setProperty("stdin",stdin); - binding.setProperty("stdout",stdout); - binding.setProperty("stderr",stderr); + binding.setProperty("out", new PrintWriter(new OutputStreamWriter(stdout, getClientCharset()), true)); + binding.setProperty("stdin", stdin); + binding.setProperty("stdout", stdout); + binding.setProperty("stderr", stderr); GroovyShell groovy = new GroovyShell(Jenkins.get().getPluginManager().uberClassLoader, binding); - groovy.run(loadScript(),"RemoteClass",remaining.toArray(new String[0])); + groovy.run(loadScript(), "RemoteClass", remaining.toArray(new String[0])); return 0; } @@ -76,7 +78,7 @@ protected int run() throws Exception { * Loads the script from the argument. */ private String loadScript() throws CmdLineException, IOException, InterruptedException { - if(script==null) + if (script == null) throw new CmdLineException(null, "No script is specified"); if (script.equals("=")) return IOUtils.toString(stdin); @@ -85,4 +87,3 @@ private String loadScript() throws CmdLineException, IOException, InterruptedExc return null; // never called } } - diff --git a/core/src/main/java/hudson/cli/GroovyshCommand.java b/core/src/main/java/hudson/cli/GroovyshCommand.java index 8a874348a94a..4f6c741c8a47 100644 --- a/core/src/main/java/hudson/cli/GroovyshCommand.java +++ b/core/src/main/java/hudson/cli/GroovyshCommand.java @@ -21,26 +21,30 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.cli; -import hudson.Extension; -import jenkins.model.Jenkins; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import groovy.lang.Binding; import groovy.lang.Closure; -import org.codehaus.groovy.tools.shell.Groovysh; -import org.codehaus.groovy.tools.shell.IO; -import org.codehaus.groovy.tools.shell.Shell; -import org.codehaus.groovy.tools.shell.util.XmlCommandRegistrar; - -import java.util.List; -import java.io.PrintStream; -import java.io.InputStream; +import hudson.Extension; import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStreamWriter; +import java.io.PrintStream; import java.io.PrintWriter; +import java.io.UncheckedIOException; +import java.nio.charset.Charset; import java.util.ArrayList; - -import jline.UnsupportedTerminal; +import java.util.List; +import jenkins.model.Jenkins; import jline.TerminalFactory; +import jline.UnsupportedTerminal; +import org.codehaus.groovy.tools.shell.Groovysh; +import org.codehaus.groovy.tools.shell.IO; +import org.codehaus.groovy.tools.shell.Shell; +import org.codehaus.groovy.tools.shell.util.XmlCommandRegistrar; import org.kohsuke.args4j.Argument; /** @@ -55,7 +59,7 @@ public String getShortDescription() { return Messages.GroovyshCommand_ShortDescription(); } - @Argument(metaVar="ARGS") public List args = new ArrayList<>(); + @Argument(metaVar = "ARGS") public List args = new ArrayList<>(); @Override protected int run() { @@ -78,29 +82,37 @@ protected int run() { return shell.run(commandLine.toString()); } - @SuppressWarnings({"rawtypes"}) + @SuppressWarnings("rawtypes") protected Groovysh createShell(InputStream stdin, PrintStream stdout, PrintStream stderr) { Binding binding = new Binding(); // redirect "println" to the CLI - binding.setProperty("out", new PrintWriter(stdout,true)); + Charset charset; + try { + charset = getClientCharset(); + } catch (IOException e) { + throw new UncheckedIOException(e); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + binding.setProperty("out", new PrintWriter(new OutputStreamWriter(stdout, charset), true)); binding.setProperty("hudson", Jenkins.get()); // backward compatibility binding.setProperty("jenkins", Jenkins.get()); - IO io = new IO(new BufferedInputStream(stdin),stdout,stderr); + IO io = new IO(new BufferedInputStream(stdin), stdout, stderr); final ClassLoader cl = Jenkins.get().pluginManager.uberClassLoader; Closure registrar = new Closure(null, null) { private static final long serialVersionUID = 1L; @SuppressWarnings("unused") - @edu.umd.cs.findbugs.annotations.SuppressFBWarnings(value="UMAC_UNCALLABLE_METHOD_OF_ANONYMOUS_CLASS",justification="Closure invokes this via reflection") + @SuppressFBWarnings(value = "UMAC_UNCALLABLE_METHOD_OF_ANONYMOUS_CLASS", justification = "Closure invokes this via reflection") public Object doCall(Object[] args) { - assert(args.length == 1); - assert(args[0] instanceof Shell); + assert args.length == 1; + assert args[0] instanceof Shell; - Shell shell = (Shell)args[0]; + Shell shell = (Shell) args[0]; XmlCommandRegistrar r = new XmlCommandRegistrar(shell, cl); r.register(GroovyshCommand.class.getResource("commands.xml")); diff --git a/core/src/main/java/hudson/cli/HelpCommand.java b/core/src/main/java/hudson/cli/HelpCommand.java index fa4c73756f6c..9e606102894b 100644 --- a/core/src/main/java/hudson/cli/HelpCommand.java +++ b/core/src/main/java/hudson/cli/HelpCommand.java @@ -21,15 +21,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.cli; import hudson.AbortException; import hudson.Extension; -import jenkins.model.Jenkins; - import java.util.Map; import java.util.TreeMap; - +import jenkins.model.Jenkins; import org.kohsuke.args4j.Argument; import org.springframework.security.access.AccessDeniedException; @@ -41,7 +40,7 @@ @Extension public class HelpCommand extends CLICommand { - @Argument(metaVar="COMMAND", usage="Name of the command") + @Argument(metaVar = "COMMAND", usage = "Name of the command") public String command; @Override @@ -65,13 +64,13 @@ protected int run() throws Exception { } private int showAllCommands() { - Map commands = new TreeMap<>(); + Map commands = new TreeMap<>(); for (CLICommand c : CLICommand.all()) - commands.put(c.getName(),c); + commands.put(c.getName(), c); for (CLICommand c : commands.values()) { - stderr.println(" "+c.getName()); - stderr.println(" "+c.getShortDescription()); + stderr.println(" " + c.getName()); + stderr.println(" " + c.getShortDescription()); } return 0; @@ -85,7 +84,7 @@ private int showCommandDetails() throws Exception { } command.printUsage(stderr, command.getCmdLineParser()); - + return 0; } } diff --git a/core/src/main/java/hudson/cli/InstallPluginCommand.java b/core/src/main/java/hudson/cli/InstallPluginCommand.java index 7b5985c75e5b..cc9d3b59f91d 100644 --- a/core/src/main/java/hudson/cli/InstallPluginCommand.java +++ b/core/src/main/java/hudson/cli/InstallPluginCommand.java @@ -21,35 +21,35 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.cli; import hudson.AbortException; import hudson.Extension; import hudson.PluginManager; -import hudson.util.VersionNumber; -import jenkins.model.Jenkins; import hudson.model.UpdateSite; import hudson.model.UpdateSite.Data; import hudson.util.EditDistance; -import org.kohsuke.args4j.Argument; -import org.kohsuke.args4j.Option; - +import hudson.util.VersionNumber; import java.io.File; -import java.net.URL; import java.net.MalformedURLException; +import java.net.URL; import java.nio.file.Files; import java.nio.file.StandardCopyOption; +import java.util.ArrayList; import java.util.HashSet; import java.util.List; -import java.util.ArrayList; import java.util.Set; import java.util.jar.JarFile; import java.util.jar.Manifest; +import jenkins.model.Jenkins; import org.apache.commons.io.FileUtils; +import org.kohsuke.args4j.Argument; +import org.kohsuke.args4j.Option; /** * Installs a plugin either from a file, an URL, or from update center. - * + * * @author Kohsuke Kawaguchi * @since 1.331 */ @@ -61,7 +61,7 @@ public String getShortDescription() { return Messages.InstallPluginCommand_ShortDescription(); } - @Argument(metaVar="SOURCE",required=true,usage= + @Argument(metaVar = "SOURCE", required = true, usage = "If this is an URL, Jenkins downloads the URL and installs that as a plugin. " + "If it is the string ‘=’, the file will be read from standard input of the command. " + "Otherwise the name is assumed to be the short name of the plugin in the existing update center (like ‘findbugs’), " + @@ -74,10 +74,10 @@ public String getShortDescription() { @Option(name = "-name", usage = "No longer used.") public String name; - @Option(name="-restart",usage="Restart Jenkins upon successful installation.") + @Option(name = "-restart", usage = "Restart Jenkins upon successful installation.") public boolean restart; - @Option(name="-deploy",usage="Deploy plugins right away without postponing them until the reboot.") + @Option(name = "-deploy", usage = "Deploy plugins right away without postponing them until the reboot.") public boolean dynamicLoad; @Override @@ -125,15 +125,15 @@ protected int run() throws Exception { } else { // try to find matching min version number VersionNumber version = new VersionNumber(source.substring(index + 1)); - p = h.getUpdateCenter().getPlugin(source.substring(0,index), version); + p = h.getUpdateCenter().getPlugin(source.substring(0, index), version); if (p == null) { p = h.getUpdateCenter().getPlugin(source); } } - if (p!=null) { + if (p != null) { stdout.println(Messages.InstallPluginCommand_InstallingFromUpdateCenter(source)); Throwable e = p.deploy(dynamicLoad).get().getError(); - if (e!=null) { + if (e != null) { AbortException myException = new AbortException("Failed to install plugin " + source); myException.initCause(e); throw myException; @@ -151,12 +151,12 @@ protected int run() throws Exception { Set candidates = new HashSet<>(); for (UpdateSite s : h.getUpdateCenter().getSites()) { Data dt = s.getData(); - if (dt==null) + if (dt == null) stdout.println(Messages.InstallPluginCommand_NoUpdateDataRetrieved(s.getUrl())); else candidates.addAll(dt.plugins.keySet()); } - stdout.println(Messages.InstallPluginCommand_DidYouMean(source,EditDistance.findNearest(source,candidates))); + stdout.println(Messages.InstallPluginCommand_DidYouMean(source, EditDistance.findNearest(source, candidates))); } } diff --git a/core/src/main/java/hudson/cli/ListChangesCommand.java b/core/src/main/java/hudson/cli/ListChangesCommand.java index 1b398bddad95..6c65f3ef8b2d 100644 --- a/core/src/main/java/hudson/cli/ListChangesCommand.java +++ b/core/src/main/java/hudson/cli/ListChangesCommand.java @@ -3,19 +3,20 @@ import hudson.Extension; import hudson.model.Run; import hudson.scm.ChangeLogSet; -import hudson.scm.ChangeLogSet.Entry; import hudson.util.QuotedStringTokenizer; -import jenkins.scm.RunWithSCM; -import org.kohsuke.args4j.Option; -import org.kohsuke.stapler.export.Flavor; -import org.kohsuke.stapler.export.Model; -import org.kohsuke.stapler.export.ModelBuilder; - import java.io.IOException; +import java.io.OutputStreamWriter; import java.io.PrintWriter; +import java.io.UncheckedIOException; +import java.nio.charset.Charset; import java.util.List; +import jenkins.scm.RunWithSCM; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.args4j.Option; +import org.kohsuke.stapler.export.Flavor; +import org.kohsuke.stapler.export.Model; +import org.kohsuke.stapler.export.ModelBuilder; /** * Retrieves a change list for the specified builds. @@ -39,7 +40,7 @@ enum Format { XML, CSV, PLAIN } - @Option(name="-format",usage="Controls how the output from this command is printed.") + @Option(name = "-format", usage = "Controls how the output from this command is printed.") public Format format = Format.PLAIN; @Override @@ -48,7 +49,15 @@ protected int act(List> builds) throws IOException { // No other permission check needed. switch (format) { case XML: - PrintWriter w = new PrintWriter(stdout); + Charset charset; + try { + charset = getClientCharset(); + } catch (IOException e) { + throw new UncheckedIOException(e); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + PrintWriter w = new PrintWriter(new OutputStreamWriter(stdout, charset)); w.println(""); for (Run build : builds) { if (build instanceof RunWithSCM) { @@ -67,7 +76,7 @@ protected int act(List> builds) throws IOException { for (Run build : builds) { if (build instanceof RunWithSCM) { for (ChangeLogSet cs : ((RunWithSCM) build).getChangeSets()) { - for (Entry e : cs) { + for (ChangeLogSet.Entry e : cs) { stdout.printf("%s,%s%n", QuotedStringTokenizer.quote(e.getAuthor().getId()), QuotedStringTokenizer.quote(e.getMsg())); @@ -80,7 +89,7 @@ protected int act(List> builds) throws IOException { for (Run build : builds) { if (build instanceof RunWithSCM) { for (ChangeLogSet cs : ((RunWithSCM) build).getChangeSets()) { - for (Entry e : cs) { + for (ChangeLogSet.Entry e : cs) { stdout.printf("%s\t%s%n", e.getAuthor(), e.getMsg()); for (String p : e.getAffectedPaths()) { stdout.println(" " + p); @@ -90,6 +99,8 @@ protected int act(List> builds) throws IOException { } } break; + default: + throw new AssertionError("Unknown format: " + format); } return 0; diff --git a/core/src/main/java/hudson/cli/ListJobsCommand.java b/core/src/main/java/hudson/cli/ListJobsCommand.java index dd7a1daf8f5f..1a366227ddbc 100644 --- a/core/src/main/java/hudson/cli/ListJobsCommand.java +++ b/core/src/main/java/hudson/cli/ListJobsCommand.java @@ -21,21 +21,21 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package hudson.cli; -import java.util.Collection; +package hudson.cli; +import hudson.Extension; import hudson.model.Item; import hudson.model.TopLevelItem; import hudson.model.View; -import hudson.Extension; -import jenkins.model.ModifiableTopLevelItemGroup; +import java.util.Collection; import jenkins.model.Jenkins; +import jenkins.model.ModifiableTopLevelItemGroup; import org.kohsuke.args4j.Argument; /** * Lists all jobs (in a specific view). - * + * * @author Michael Koch */ @Extension @@ -45,9 +45,10 @@ public String getShortDescription() { return Messages.ListJobsCommand_ShortDescription(); } - @Argument(metaVar="NAME",usage="Name of the view",required=false) + @Argument(metaVar = "NAME", usage = "Name of the view", required = false) public String name; + @Override protected int run() throws Exception { Jenkins h = Jenkins.get(); final Collection jobs; diff --git a/core/src/main/java/hudson/cli/ListPluginsCommand.java b/core/src/main/java/hudson/cli/ListPluginsCommand.java index ef4265b1b5a6..9312bedb10ff 100644 --- a/core/src/main/java/hudson/cli/ListPluginsCommand.java +++ b/core/src/main/java/hudson/cli/ListPluginsCommand.java @@ -21,13 +21,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.cli; -import java.util.List; import hudson.Extension; import hudson.PluginManager; import hudson.PluginWrapper; import hudson.model.UpdateSite; +import java.util.List; import jenkins.model.Jenkins; import org.kohsuke.args4j.Argument; @@ -46,10 +47,11 @@ public String getShortDescription() { @Argument(metaVar = "NAME", usage = "Name of a specific plugin", required = false) public String name; + @Override protected int run() { Jenkins h = Jenkins.get(); h.checkPermission(Jenkins.ADMINISTER); - + PluginManager pluginManager = h.getPluginManager(); if (this.name != null) { diff --git a/core/src/main/java/hudson/cli/OfflineNodeCommand.java b/core/src/main/java/hudson/cli/OfflineNodeCommand.java index 39270918dcb8..25c4ddc6de3b 100644 --- a/core/src/main/java/hudson/cli/OfflineNodeCommand.java +++ b/core/src/main/java/hudson/cli/OfflineNodeCommand.java @@ -29,14 +29,12 @@ import hudson.model.Computer; import hudson.model.ComputerSet; import hudson.util.EditDistance; +import java.util.HashSet; +import java.util.List; import jenkins.model.Jenkins; - import org.kohsuke.args4j.Argument; import org.kohsuke.args4j.Option; -import java.util.HashSet; -import java.util.List; - /** * CLI Command, which puts the Jenkins node offline. * @author pjanouse @@ -45,7 +43,7 @@ @Extension public class OfflineNodeCommand extends CLICommand { - @Argument(metaVar = "NAME", usage = "Agent name, or empty string for master", required = true, multiValued = true) + @Argument(metaVar = "NAME", usage = "Agent name, or empty string for built-in node", required = true, multiValued = true) private List nodes; @Option(name = "-m", usage = "Record the reason about why you are disconnecting this node") diff --git a/core/src/main/java/hudson/cli/OnlineNodeCommand.java b/core/src/main/java/hudson/cli/OnlineNodeCommand.java index e4a56ef8ed72..e4a37fa74c6e 100644 --- a/core/src/main/java/hudson/cli/OnlineNodeCommand.java +++ b/core/src/main/java/hudson/cli/OnlineNodeCommand.java @@ -27,11 +27,9 @@ import hudson.AbortException; import hudson.Extension; import hudson.model.Computer; - -import org.kohsuke.args4j.Argument; - import java.util.HashSet; import java.util.List; +import org.kohsuke.args4j.Argument; /** * CLI Command, which moves the node to the online state. @@ -41,7 +39,7 @@ @Extension public class OnlineNodeCommand extends CLICommand { - @Argument(metaVar = "NAME", usage = "Agent name, or empty string for master", required = true, multiValued = true) + @Argument(metaVar = "NAME", usage = "Agent name, or empty string for built-in node", required = true, multiValued = true) private List nodes; @Override @@ -70,7 +68,7 @@ protected int run() throws Exception { } } - if (errorOccurred){ + if (errorOccurred) { throw new AbortException(CLI_LISTPARAM_SUMMARY_ERROR_TEXT); } return 0; diff --git a/core/src/main/java/hudson/cli/QuietDownCommand.java b/core/src/main/java/hudson/cli/QuietDownCommand.java index 4541be077d72..c4cd7e02a97f 100644 --- a/core/src/main/java/hudson/cli/QuietDownCommand.java +++ b/core/src/main/java/hudson/cli/QuietDownCommand.java @@ -25,11 +25,10 @@ package hudson.cli; import hudson.Extension; +import java.util.logging.Logger; import jenkins.model.Jenkins; import org.kohsuke.args4j.Option; -import java.util.logging.Logger; - /** * Quiet down Jenkins - preparation for a restart * @@ -41,13 +40,13 @@ public class QuietDownCommand extends CLICommand { private static final Logger LOGGER = Logger.getLogger(QuietDownCommand.class.getName()); - @Option(name="-block",usage="Block until the system really quiets down and no builds are running") + @Option(name = "-block", usage = "Block until the system really quiets down and no builds are running") public boolean block = false; - @Option(name="-timeout",usage="If non-zero, only block up to the specified number of milliseconds") + @Option(name = "-timeout", usage = "If non-zero, only block up to the specified number of milliseconds") public int timeout = 0; - @Option(name="-reason",usage="Reason for quiet down that will be visible to users") + @Option(name = "-reason", usage = "Reason for quiet down that will be visible to users") public String reason = null; @Override diff --git a/core/src/main/java/hudson/cli/ReloadJobCommand.java b/core/src/main/java/hudson/cli/ReloadJobCommand.java index e8c51f95833a..cea8823144bc 100644 --- a/core/src/main/java/hudson/cli/ReloadJobCommand.java +++ b/core/src/main/java/hudson/cli/ReloadJobCommand.java @@ -21,21 +21,20 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.cli; import hudson.AbortException; import hudson.Extension; import hudson.model.AbstractItem; import hudson.model.Item; - import hudson.model.Items; -import jenkins.model.Jenkins; -import org.kohsuke.args4j.Argument; - import java.util.HashSet; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; +import jenkins.model.Jenkins; +import org.kohsuke.args4j.Argument; /** * Reloads job from the disk. @@ -45,7 +44,7 @@ @Extension public class ReloadJobCommand extends CLICommand { - @Argument(usage="Name of the job(s) to reload", required=true, multiValued=true) + @Argument(usage = "Name of the job(s) to reload", required = true, multiValued = true) private List jobs; private static final Logger LOGGER = Logger.getLogger(ReloadJobCommand.class.getName()); @@ -64,7 +63,7 @@ protected int run() throws Exception { final HashSet hs = new HashSet<>(jobs); - for (String job_s: hs) { + for (String job_s : hs) { AbstractItem job = null; try { @@ -75,7 +74,7 @@ protected int run() throws Exception { LOGGER.log(Level.WARNING, "Unsupported item type: {0}", item.getClass().getName()); } - if(job == null) { + if (job == null) { AbstractItem project = Items.findNearest(AbstractItem.class, job_s, jenkins); throw new IllegalArgumentException(project == null ? "No such item \u2018" + job_s + "\u2019 exists." : @@ -83,10 +82,10 @@ protected int run() throws Exception { job_s, project.getFullName())); } - job.checkPermission(AbstractItem.CONFIGURE); + job.checkPermission(Item.CONFIGURE); job.doReload(); } catch (Exception e) { - if(hs.size() == 1) { + if (hs.size() == 1) { throw e; } diff --git a/core/src/main/java/hudson/cli/RemoveJobFromViewCommand.java b/core/src/main/java/hudson/cli/RemoveJobFromViewCommand.java index 5a543c91c53a..416796b82e46 100644 --- a/core/src/main/java/hudson/cli/RemoveJobFromViewCommand.java +++ b/core/src/main/java/hudson/cli/RemoveJobFromViewCommand.java @@ -21,15 +21,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package hudson.cli; -import java.util.List; +package hudson.cli; import hudson.Extension; -import hudson.model.TopLevelItem; import hudson.model.DirectlyModifiableView; +import hudson.model.TopLevelItem; import hudson.model.View; - +import java.util.List; import org.kohsuke.args4j.Argument; /** @@ -39,10 +38,10 @@ @Extension public class RemoveJobFromViewCommand extends CLICommand { - @Argument(usage="Name of the view", required=true, index=0) + @Argument(usage = "Name of the view", required = true, index = 0) private View view; - @Argument(usage="Job names", required=true, index=1) + @Argument(usage = "Job names", required = true, index = 1) private List jobs; @Override @@ -57,7 +56,7 @@ protected int run() throws Exception { if (!(view instanceof DirectlyModifiableView)) throw new IllegalStateException("'" + view.getDisplayName() + "' view can not be modified directly"); - for (TopLevelItem job: jobs) { + for (TopLevelItem job : jobs) { ((DirectlyModifiableView) view).remove(job); } diff --git a/core/src/main/java/hudson/cli/RunRangeCommand.java b/core/src/main/java/hudson/cli/RunRangeCommand.java index ceb3ffc33f49..6d6afe11caa1 100644 --- a/core/src/main/java/hudson/cli/RunRangeCommand.java +++ b/core/src/main/java/hudson/cli/RunRangeCommand.java @@ -3,27 +3,27 @@ import hudson.model.Fingerprint.RangeSet; import hudson.model.Job; import hudson.model.Run; -import org.kohsuke.args4j.Argument; - import java.io.IOException; import java.util.List; +import org.kohsuke.args4j.Argument; /** * {@link CLICommand} that acts on a series of {@link Run}s. * @since 2.62 */ public abstract class RunRangeCommand extends CLICommand { - @Argument(metaVar="JOB",usage="Name of the job to build",required=true,index=0) - public Job job; + @Argument(metaVar = "JOB", usage = "Name of the job to build", required = true, index = 0) + public Job job; - @Argument(metaVar="RANGE",usage="Range of the build records to delete. 'N-M', 'N,M', or 'N'",required=true,index=1) + @Argument(metaVar = "RANGE", usage = "Range of the build records to delete. 'N-M', 'N,M', or 'N'", required = true, index = 1) public String range; + @Override protected int run() throws Exception { - RangeSet rs = RangeSet.fromString(range,false); + RangeSet rs = RangeSet.fromString(range, false); - return act((List)job.getBuilds(rs)); + return act((List) job.getBuilds(rs)); } - protected abstract int act(List> builds) throws IOException; + protected abstract int act(List> builds) throws IOException; } diff --git a/core/src/main/java/hudson/cli/SessionIdCommand.java b/core/src/main/java/hudson/cli/SessionIdCommand.java index 5e45dab55d57..64282318d498 100644 --- a/core/src/main/java/hudson/cli/SessionIdCommand.java +++ b/core/src/main/java/hudson/cli/SessionIdCommand.java @@ -16,9 +16,9 @@ public String getShortDescription() { return Messages.SessionIdCommand_ShortDescription(); } + @Override protected int run() { stdout.println(Jenkins.SESSION_HASH); return 0; } } - diff --git a/core/src/main/java/hudson/cli/SetBuildDescriptionCommand.java b/core/src/main/java/hudson/cli/SetBuildDescriptionCommand.java index a689a6e2e5f4..458e22419369 100644 --- a/core/src/main/java/hudson/cli/SetBuildDescriptionCommand.java +++ b/core/src/main/java/hudson/cli/SetBuildDescriptionCommand.java @@ -4,13 +4,10 @@ import hudson.Extension; import hudson.model.Job; import hudson.model.Run; - import java.io.Serializable; - import org.apache.commons.io.IOUtils; import org.kohsuke.args4j.Argument; - // TODO: Remove Serializable @SuppressFBWarnings(value = "SE_NO_SERIALVERSIONID", justification = "The Serializable should be removed.") @Extension @@ -21,29 +18,30 @@ public String getShortDescription() { return Messages.SetBuildDescriptionCommand_ShortDescription(); } - @Argument(metaVar="JOB",usage="Name of the job to build",required=true,index=0) - public transient Job job; + @Argument(metaVar = "JOB", usage = "Name of the job to build", required = true, index = 0) + public transient Job job; - @Argument(metaVar="BUILD#",usage="Number of the build",required=true,index=1) + @Argument(metaVar = "BUILD#", usage = "Number of the build", required = true, index = 1) public int number; - - @Argument(metaVar="DESCRIPTION",required=true,usage="Description to be set. '=' to read from stdin.", index=2) + + @Argument(metaVar = "DESCRIPTION", required = true, usage = "Description to be set. '=' to read from stdin.", index = 2) public String description; + @Override protected int run() throws Exception { - Run run = job.getBuildByNumber(number); + Run run = job.getBuildByNumber(number); if (run == null) - throw new IllegalArgumentException("No such build #"+number); + throw new IllegalArgumentException("No such build #" + number); run.checkPermission(Run.UPDATE); if ("=".equals(description)) { - description = IOUtils.toString(stdin); + description = IOUtils.toString(stdin); } - + run.setDescription(description); - + return 0; } - + } diff --git a/core/src/main/java/hudson/cli/SetBuildDisplayNameCommand.java b/core/src/main/java/hudson/cli/SetBuildDisplayNameCommand.java index 50717a7469d8..08befa394684 100644 --- a/core/src/main/java/hudson/cli/SetBuildDisplayNameCommand.java +++ b/core/src/main/java/hudson/cli/SetBuildDisplayNameCommand.java @@ -3,11 +3,10 @@ import hudson.Extension; import hudson.model.Job; import hudson.model.Run; +import java.io.Serializable; import org.apache.commons.io.IOUtils; import org.kohsuke.args4j.Argument; -import java.io.Serializable; - @Extension public class SetBuildDisplayNameCommand extends CLICommand implements Serializable { private static final long serialVersionUID = 6665171784136358536L; @@ -17,13 +16,13 @@ public String getShortDescription() { return Messages.SetBuildDisplayNameCommand_ShortDescription(); } - @Argument(metaVar="JOB", usage="Name of the job to build", required=true, index=0) + @Argument(metaVar = "JOB", usage = "Name of the job to build", required = true, index = 0) public transient Job job; - @Argument(metaVar="BUILD#", usage="Number of the build", required=true, index=1) + @Argument(metaVar = "BUILD#", usage = "Number of the build", required = true, index = 1) public int number; - @Argument(metaVar="DISPLAYNAME", required=true, usage="DisplayName to be set. '-' to read from stdin.", index=2) + @Argument(metaVar = "DISPLAYNAME", required = true, usage = "DisplayName to be set. '-' to read from stdin.", index = 2) public String displayName; @Override diff --git a/core/src/main/java/hudson/cli/UpdateJobCommand.java b/core/src/main/java/hudson/cli/UpdateJobCommand.java index a9a34403ec03..396d2d229cc2 100644 --- a/core/src/main/java/hudson/cli/UpdateJobCommand.java +++ b/core/src/main/java/hudson/cli/UpdateJobCommand.java @@ -21,21 +21,21 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.cli; import hudson.Extension; import hudson.model.AbstractItem; -import org.kohsuke.args4j.Argument; - import javax.xml.transform.Source; import javax.xml.transform.stream.StreamSource; +import org.kohsuke.args4j.Argument; /** * @author Kohsuke Kawaguchi */ @Extension public class UpdateJobCommand extends CLICommand { - @Argument(metaVar="JOB",usage="Name of the job",required=true) + @Argument(metaVar = "JOB", usage = "Name of the job", required = true) public AbstractItem job; @Override @@ -43,9 +43,9 @@ public String getShortDescription() { return Messages.UpdateJobCommand_ShortDescription(); } + @Override protected int run() throws Exception { - job.updateByXml((Source)new StreamSource(stdin)); + job.updateByXml((Source) new StreamSource(stdin)); return 0; } } - diff --git a/core/src/main/java/hudson/cli/UpdateNodeCommand.java b/core/src/main/java/hudson/cli/UpdateNodeCommand.java index ee56fdfd8eb1..c9210f89cc68 100644 --- a/core/src/main/java/hudson/cli/UpdateNodeCommand.java +++ b/core/src/main/java/hudson/cli/UpdateNodeCommand.java @@ -24,13 +24,10 @@ package hudson.cli; -import java.io.IOException; - -import javax.servlet.ServletException; - import hudson.Extension; import hudson.model.Node; - +import java.io.IOException; +import javax.servlet.ServletException; import org.kohsuke.args4j.Argument; /** @@ -40,7 +37,7 @@ @Extension public class UpdateNodeCommand extends CLICommand { - @Argument(metaVar="NODE", usage="Name of the node", required=true) + @Argument(metaVar = "NODE", usage = "Name of the node", required = true) public Node node; @Override diff --git a/core/src/main/java/hudson/cli/UpdateViewCommand.java b/core/src/main/java/hudson/cli/UpdateViewCommand.java index 4f861fcb04d9..36561f34f3f0 100644 --- a/core/src/main/java/hudson/cli/UpdateViewCommand.java +++ b/core/src/main/java/hudson/cli/UpdateViewCommand.java @@ -21,13 +21,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package hudson.cli; -import javax.xml.transform.stream.StreamSource; +package hudson.cli; import hudson.Extension; import hudson.model.View; - +import javax.xml.transform.stream.StreamSource; import org.kohsuke.args4j.Argument; /** @@ -37,7 +36,7 @@ @Extension public class UpdateViewCommand extends CLICommand { - @Argument(usage="Name of the view to update", required=true) + @Argument(usage = "Name of the view to update", required = true) private View view; @Override diff --git a/core/src/main/java/hudson/cli/VersionCommand.java b/core/src/main/java/hudson/cli/VersionCommand.java index 213581799af9..8b77c417d187 100644 --- a/core/src/main/java/hudson/cli/VersionCommand.java +++ b/core/src/main/java/hudson/cli/VersionCommand.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.cli; import hudson.Extension; @@ -38,6 +39,7 @@ public String getShortDescription() { return Messages.VersionCommand_ShortDescription(); } + @Override protected int run() { // CLICommand.main checks Hudson.READ permission.. no other check needed. stdout.println(Jenkins.VERSION); diff --git a/core/src/main/java/hudson/cli/WaitNodeOfflineCommand.java b/core/src/main/java/hudson/cli/WaitNodeOfflineCommand.java index 319e4424a9e4..fee99ef6bf1a 100644 --- a/core/src/main/java/hudson/cli/WaitNodeOfflineCommand.java +++ b/core/src/main/java/hudson/cli/WaitNodeOfflineCommand.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.cli; import hudson.Extension; @@ -35,7 +36,7 @@ @Extension public class WaitNodeOfflineCommand extends CLICommand { - @Argument(metaVar="NODE", usage="Name of the node", required=true) + @Argument(metaVar = "NODE", usage = "Name of the node", required = true) public Node node; @Override diff --git a/core/src/main/java/hudson/cli/WaitNodeOnlineCommand.java b/core/src/main/java/hudson/cli/WaitNodeOnlineCommand.java index 2e9713ad6f4c..95a621b087b0 100644 --- a/core/src/main/java/hudson/cli/WaitNodeOnlineCommand.java +++ b/core/src/main/java/hudson/cli/WaitNodeOnlineCommand.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.cli; import hudson.Extension; @@ -35,7 +36,7 @@ @Extension public class WaitNodeOnlineCommand extends CLICommand { - @Argument(metaVar="NODE", usage="Name of the node", required=true) + @Argument(metaVar = "NODE", usage = "Name of the node", required = true) public Node node; @Override diff --git a/core/src/main/java/hudson/cli/WhoAmICommand.java b/core/src/main/java/hudson/cli/WhoAmICommand.java index 9ffc35861ace..a4ecc4af79d0 100644 --- a/core/src/main/java/hudson/cli/WhoAmICommand.java +++ b/core/src/main/java/hudson/cli/WhoAmICommand.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.cli; import hudson.Extension; @@ -40,14 +41,14 @@ public String getShortDescription() { return Messages.WhoAmICommand_ShortDescription(); } + @Override protected int run() { Authentication a = Jenkins.getAuthentication2(); - stdout.println("Authenticated as: "+a.getName()); + stdout.println("Authenticated as: " + a.getName()); stdout.println("Authorities:"); for (GrantedAuthority ga : a.getAuthorities()) { - stdout.println(" "+ga.getAuthority()); + stdout.println(" " + ga.getAuthority()); } return 0; } } - diff --git a/core/src/main/java/hudson/cli/declarative/CLIMethod.java b/core/src/main/java/hudson/cli/declarative/CLIMethod.java index 6366e4409ed6..7b9c35202bb9 100644 --- a/core/src/main/java/hudson/cli/declarative/CLIMethod.java +++ b/core/src/main/java/hudson/cli/declarative/CLIMethod.java @@ -21,18 +21,19 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.cli.declarative; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + import hudson.cli.CLICommand; import hudson.util.ListBoxModel.Option; -import org.jvnet.hudson.annotation_indexer.Indexed; -import org.kohsuke.args4j.Argument; - import java.lang.annotation.Documented; -import static java.lang.annotation.ElementType.METHOD; import java.lang.annotation.Retention; -import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Target; +import org.jvnet.hudson.annotation_indexer.Indexed; +import org.kohsuke.args4j.Argument; /** * Annotates methods on model objects to expose them as CLI commands. @@ -59,11 +60,11 @@ */ @Indexed @Retention(RUNTIME) -@Target({METHOD}) +@Target(METHOD) @Documented public @interface CLIMethod { /** - * CLI command name. Used as {@link CLICommand#getName()} + * CLI command name. Used as {@link CLICommand#getName()} */ String name(); diff --git a/core/src/main/java/hudson/cli/declarative/CLIRegisterer.java b/core/src/main/java/hudson/cli/declarative/CLIRegisterer.java index 168aa49f7bb5..8b2f2348c577 100644 --- a/core/src/main/java/hudson/cli/declarative/CLIRegisterer.java +++ b/core/src/main/java/hudson/cli/declarative/CLIRegisterer.java @@ -21,8 +21,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.cli.declarative; +import static java.util.logging.Level.SEVERE; + import edu.umd.cs.findbugs.annotations.NonNull; import hudson.AbortException; import hudson.Extension; @@ -48,7 +51,6 @@ import java.util.Stack; import java.util.UUID; import java.util.logging.Level; -import static java.util.logging.Level.SEVERE; import java.util.logging.Logger; import jenkins.ExtensionComponentSet; import jenkins.ExtensionRefreshException; @@ -76,9 +78,10 @@ public ExtensionComponentSet refresh() throws ExtensionRefreshException { return ExtensionComponentSet.EMPTY; } + @Override public Collection> find(Class type, Hudson jenkins) { - if (type==CLICommand.class) - return (List)discover(jenkins); + if (type == CLICommand.class) + return (List) discover(jenkins); else return Collections.emptyList(); } @@ -88,9 +91,9 @@ public Collection> find(Class type, Hudson jenkins) */ private Method findResolver(Class type) throws IOException { List resolvers = Util.filter(Index.list(CLIResolver.class, Jenkins.get().getPluginManager().uberClassLoader), Method.class); - for ( ; type!=null; type=type.getSuperclass()) + for ( ; type != null; type = type.getSuperclass()) for (Method m : resolvers) - if (m.getReturnType()==type) + if (m.getReturnType() == type) return m; return null; } @@ -100,13 +103,13 @@ private List> discover(@NonNull final Jenkins jen List> r = new ArrayList<>(); try { - for ( final Method m : Util.filter(Index.list(CLIMethod.class, jenkins.getPluginManager().uberClassLoader),Method.class)) { + for (final Method m : Util.filter(Index.list(CLIMethod.class, jenkins.getPluginManager().uberClassLoader), Method.class)) { try { // command name final String name = m.getAnnotation(CLIMethod.class).name(); final ResourceBundleHolder res = loadMessageBundle(m); - res.format("CLI."+name+".shortDescription"); // make sure we have the resource, to fail early + res.format("CLI." + name + ".shortDescription"); // make sure we have the resource, to fail early r.add(new ExtensionComponent<>(new CloneableCLICommand() { @Override @@ -269,16 +272,17 @@ private void logAndPrintError(Throwable e, String errorMessage, String logMessag printError(errorMessage); } + @Override protected int run() throws Exception { throw new UnsupportedOperationException(); } })); } catch (ClassNotFoundException | MissingResourceException e) { - LOGGER.log(SEVERE,"Failed to process @CLIMethod: "+m,e); + LOGGER.log(SEVERE, "Failed to process @CLIMethod: " + m, e); } } } catch (IOException e) { - LOGGER.log(SEVERE, "Failed to discover @CLIMethod",e); + LOGGER.log(SEVERE, "Failed to discover @CLIMethod", e); } return r; diff --git a/core/src/main/java/hudson/cli/declarative/CLIResolver.java b/core/src/main/java/hudson/cli/declarative/CLIResolver.java index 5c4b93444e8e..80f1d19edff4 100644 --- a/core/src/main/java/hudson/cli/declarative/CLIResolver.java +++ b/core/src/main/java/hudson/cli/declarative/CLIResolver.java @@ -21,17 +21,18 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.cli.declarative; -import hudson.cli.CLICommand; -import org.jvnet.hudson.annotation_indexer.Indexed; -import org.kohsuke.args4j.CmdLineException; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import hudson.cli.CLICommand; import java.lang.annotation.Documented; -import static java.lang.annotation.ElementType.METHOD; import java.lang.annotation.Retention; -import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Target; +import org.jvnet.hudson.annotation_indexer.Indexed; +import org.kohsuke.args4j.CmdLineException; /** * Annotates a resolver method that binds a portion of the command line arguments and parameters @@ -64,7 +65,7 @@ */ @Indexed @Retention(RUNTIME) -@Target({METHOD}) +@Target(METHOD) @Documented public @interface CLIResolver { } diff --git a/core/src/main/java/hudson/cli/declarative/MethodBinder.java b/core/src/main/java/hudson/cli/declarative/MethodBinder.java index a75e14f8a689..91dfd11da7f0 100644 --- a/core/src/main/java/hudson/cli/declarative/MethodBinder.java +++ b/core/src/main/java/hudson/cli/declarative/MethodBinder.java @@ -21,24 +21,25 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.cli.declarative; import hudson.cli.CLICommand; import hudson.util.ReflectionUtils; import hudson.util.ReflectionUtils.Parameter; +import java.lang.annotation.Annotation; +import java.lang.reflect.AnnotatedElement; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.List; +import java.util.Objects; import org.kohsuke.args4j.Argument; import org.kohsuke.args4j.CmdLineException; import org.kohsuke.args4j.CmdLineParser; import org.kohsuke.args4j.Option; import org.kohsuke.args4j.spi.FieldSetter; -import org.kohsuke.args4j.spi.Setter; import org.kohsuke.args4j.spi.OptionHandler; - -import java.lang.annotation.Annotation; -import java.lang.reflect.AnnotatedElement; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.List; +import org.kohsuke.args4j.spi.Setter; /** * Binds method parameters to CLI arguments and parameters via args4j. @@ -52,9 +53,6 @@ class MethodBinder { private final Method method; private final Object[] arguments; - /** - * @param method - */ MethodBinder(Method method, CLICommand command, CmdLineParser parser) { this.method = method; this.command = command; @@ -70,14 +68,17 @@ class MethodBinder { // TODO: collection and map support Setter setter = new Setter() { + @Override public void addValue(Object value) throws CmdLineException { arguments[index] = value; } + @Override public Class getType() { return p.type(); } + @Override public boolean isMultiValued() { return false; } @@ -93,15 +94,15 @@ public AnnotatedElement asAnnotatedElement() { } }; Option option = p.annotation(Option.class); - if (option!=null) { - parser.addOption(setter,option); + if (option != null) { + parser.addOption(setter, option); } Argument arg = p.annotation(Argument.class); - if (arg!=null) { - if (bias>0) arg = new ArgumentImpl(arg,bias); - parser.addArgument(setter,arg); + if (arg != null) { + if (bias > 0) arg = new ArgumentImpl(arg, bias); + parser.addArgument(setter, arg); } - if (p.type()==CLICommand.class) + if (p.type() == CLICommand.class) arguments[index] = command; if (p.type().isPrimitive()) @@ -111,7 +112,7 @@ public AnnotatedElement asAnnotatedElement() { public Object call(Object instance) throws Exception { try { - return method.invoke(instance,arguments); + return method.invoke(instance, arguments); } catch (InvocationTargetException e) { Throwable t = e.getTargetException(); if (t instanceof Exception) @@ -123,7 +124,7 @@ public Object call(Object instance) throws Exception { /** * {@link Argument} implementation that adds a bias to {@link #index()}. */ - @SuppressWarnings({"ClassExplicitlyAnnotation"}) + @SuppressWarnings("ClassExplicitlyAnnotation") private static final class ArgumentImpl implements Argument { private final Argument base; private final int bias; @@ -133,30 +134,37 @@ private ArgumentImpl(Argument base, int bias) { this.bias = bias; } + @Override public String usage() { return base.usage(); } + @Override public String metaVar() { return base.metaVar(); } + @Override public boolean required() { return base.required(); } + @Override public Class handler() { return base.handler(); } + @Override public int index() { - return base.index()+bias; + return base.index() + bias; } + @Override public boolean multiValued() { return base.multiValued(); } + @Override public Class annotationType() { return base.annotationType(); } @@ -165,5 +173,22 @@ public Class annotationType() { public boolean hidden() { return base.hidden(); } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof ArgumentImpl)) { + return false; + } + ArgumentImpl argument = (ArgumentImpl) o; + return Objects.equals(base, argument.base) && bias == argument.bias; + } + + @Override + public int hashCode() { + return Objects.hash(base, bias); + } } } diff --git a/core/src/main/java/hudson/cli/declarative/OptionHandlerExtension.java b/core/src/main/java/hudson/cli/declarative/OptionHandlerExtension.java index 7e76e117d2b6..f009038ed2ac 100644 --- a/core/src/main/java/hudson/cli/declarative/OptionHandlerExtension.java +++ b/core/src/main/java/hudson/cli/declarative/OptionHandlerExtension.java @@ -24,15 +24,14 @@ package hudson.cli.declarative; -import org.jvnet.hudson.annotation_indexer.Indexed; -import org.kohsuke.args4j.spi.OptionHandler; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; - -import static java.lang.annotation.ElementType.TYPE; -import static java.lang.annotation.RetentionPolicy.RUNTIME; +import org.jvnet.hudson.annotation_indexer.Indexed; +import org.kohsuke.args4j.spi.OptionHandler; /** * {@link OptionHandler}s that should be auto-discovered. @@ -41,7 +40,7 @@ */ @Indexed @Retention(RUNTIME) -@Target({TYPE}) +@Target(TYPE) @Documented public @interface OptionHandlerExtension { } diff --git a/core/src/main/java/hudson/cli/handlers/AbstractProjectOptionHandler.java b/core/src/main/java/hudson/cli/handlers/AbstractProjectOptionHandler.java index b630e48b56ab..ab7402de65ae 100644 --- a/core/src/main/java/hudson/cli/handlers/AbstractProjectOptionHandler.java +++ b/core/src/main/java/hudson/cli/handlers/AbstractProjectOptionHandler.java @@ -21,14 +21,15 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.cli.handlers; import hudson.model.AbstractProject; +import org.kohsuke.MetaInfServices; import org.kohsuke.args4j.CmdLineParser; import org.kohsuke.args4j.OptionDef; -import org.kohsuke.args4j.spi.Setter; -import org.kohsuke.MetaInfServices; import org.kohsuke.args4j.spi.OptionHandler; +import org.kohsuke.args4j.spi.Setter; /** * Refer to {@link AbstractProject} by its name. diff --git a/core/src/main/java/hudson/cli/handlers/JobOptionHandler.java b/core/src/main/java/hudson/cli/handlers/JobOptionHandler.java index c0326fbacc9a..519293150341 100644 --- a/core/src/main/java/hudson/cli/handlers/JobOptionHandler.java +++ b/core/src/main/java/hudson/cli/handlers/JobOptionHandler.java @@ -21,14 +21,15 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.cli.handlers; import hudson.model.Job; +import org.kohsuke.MetaInfServices; import org.kohsuke.args4j.CmdLineParser; import org.kohsuke.args4j.OptionDef; -import org.kohsuke.args4j.spi.Setter; -import org.kohsuke.MetaInfServices; import org.kohsuke.args4j.spi.OptionHandler; +import org.kohsuke.args4j.spi.Setter; /** * Refer to {@link Job} by its name. diff --git a/core/src/main/java/hudson/cli/handlers/NodeOptionHandler.java b/core/src/main/java/hudson/cli/handlers/NodeOptionHandler.java index a90199e8c118..45bd0f4e679b 100644 --- a/core/src/main/java/hudson/cli/handlers/NodeOptionHandler.java +++ b/core/src/main/java/hudson/cli/handlers/NodeOptionHandler.java @@ -21,11 +21,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.cli.handlers; import hudson.model.Node; import jenkins.model.Jenkins; - import org.kohsuke.MetaInfServices; import org.kohsuke.args4j.CmdLineException; import org.kohsuke.args4j.CmdLineParser; diff --git a/core/src/main/java/hudson/cli/handlers/ParameterizedJobOptionHandler.java b/core/src/main/java/hudson/cli/handlers/ParameterizedJobOptionHandler.java index 5776c221433e..a37dbf1790f1 100644 --- a/core/src/main/java/hudson/cli/handlers/ParameterizedJobOptionHandler.java +++ b/core/src/main/java/hudson/cli/handlers/ParameterizedJobOptionHandler.java @@ -40,7 +40,7 @@ @MetaInfServices(OptionHandler.class) @SuppressWarnings("rawtypes") public class ParameterizedJobOptionHandler extends GenericItemOptionHandler { - + public ParameterizedJobOptionHandler(CmdLineParser parser, OptionDef option, Setter setter) { super(parser, option, setter); } diff --git a/core/src/main/java/hudson/cli/handlers/ViewOptionHandler.java b/core/src/main/java/hudson/cli/handlers/ViewOptionHandler.java index 33f787e998b1..65656c15e33c 100644 --- a/core/src/main/java/hudson/cli/handlers/ViewOptionHandler.java +++ b/core/src/main/java/hudson/cli/handlers/ViewOptionHandler.java @@ -21,15 +21,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.cli.handlers; -import hudson.model.ViewGroup; +import edu.umd.cs.findbugs.annotations.CheckForNull; import hudson.model.View; - +import hudson.model.ViewGroup; import java.util.StringTokenizer; - import jenkins.model.Jenkins; - import org.kohsuke.MetaInfServices; import org.kohsuke.args4j.CmdLineException; import org.kohsuke.args4j.CmdLineParser; @@ -37,8 +36,6 @@ import org.kohsuke.args4j.spi.OptionHandler; import org.kohsuke.args4j.spi.Parameters; import org.kohsuke.args4j.spi.Setter; - -import edu.umd.cs.findbugs.annotations.CheckForNull; import org.springframework.security.access.AccessDeniedException; /** @@ -98,7 +95,7 @@ public View getView(final String name) { View view = null; final StringTokenizer tok = new StringTokenizer(name, "/"); - while(tok.hasMoreTokens()) { + while (tok.hasMoreTokens()) { String viewName = tok.nextToken(); diff --git a/core/src/main/java/hudson/cli/handlers/package-info.java b/core/src/main/java/hudson/cli/handlers/package-info.java index 65a4bb7adf56..d73ca4f88703 100644 --- a/core/src/main/java/hudson/cli/handlers/package-info.java +++ b/core/src/main/java/hudson/cli/handlers/package-info.java @@ -2,4 +2,3 @@ * {@link org.kohsuke.args4j.spi.OptionHandler} implementations for Hudson. */ package hudson.cli.handlers; - diff --git a/core/src/main/java/hudson/console/AnnotatedLargeText.java b/core/src/main/java/hudson/console/AnnotatedLargeText.java index 9790bf82071a..e074044e806d 100644 --- a/core/src/main/java/hudson/console/AnnotatedLargeText.java +++ b/core/src/main/java/hudson/console/AnnotatedLargeText.java @@ -23,23 +23,16 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.console; +import static java.lang.Math.abs; + +import com.jcraft.jzlib.GZIPInputStream; +import com.jcraft.jzlib.GZIPOutputStream; +import edu.umd.cs.findbugs.annotations.CheckReturnValue; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import jenkins.model.Jenkins; import hudson.remoting.ObjectInputStreamEx; -import java.util.concurrent.TimeUnit; -import jenkins.security.CryptoConfidentialKey; -import org.apache.commons.io.output.ByteArrayOutputStream; -import org.kohsuke.stapler.Stapler; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; -import org.kohsuke.stapler.framework.io.ByteBuffer; -import org.kohsuke.stapler.framework.io.LargeText; - -import javax.crypto.Cipher; -import javax.crypto.CipherInputStream; -import javax.crypto.CipherOutputStream; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; @@ -50,13 +43,19 @@ import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.Base64; - -import com.jcraft.jzlib.GZIPInputStream; -import com.jcraft.jzlib.GZIPOutputStream; - -import static java.lang.Math.abs; -import edu.umd.cs.findbugs.annotations.CheckReturnValue; +import java.util.concurrent.TimeUnit; +import javax.crypto.Cipher; +import javax.crypto.CipherInputStream; +import javax.crypto.CipherOutputStream; +import jenkins.model.Jenkins; +import jenkins.security.CryptoConfidentialKey; +import org.apache.commons.io.output.ByteArrayOutputStream; import org.jenkinsci.remoting.util.AnonymousClassWarnings; +import org.kohsuke.stapler.Stapler; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.framework.io.ByteBuffer; +import org.kohsuke.stapler.framework.io.LargeText; /** * Extension to {@link LargeText} that handles annotations by {@link ConsoleAnnotator}. @@ -92,24 +91,24 @@ public AnnotatedLargeText(ByteBuffer memory, Charset charset, boolean completed, } public void doProgressiveHtml(StaplerRequest req, StaplerResponse rsp) throws IOException { - req.setAttribute("html",true); - doProgressText(req,rsp); + req.setAttribute("html", true); + doProgressText(req, rsp); } /** * Aliasing what I think was a wrong name in {@link LargeText} */ public void doProgressiveText(StaplerRequest req, StaplerResponse rsp) throws IOException { - doProgressText(req,rsp); + doProgressText(req, rsp); } /** * For reusing code between text/html and text/plain, we run them both through the same code path - * and use this request attribute to differentiate. + * and use this request attribute to differentiate. */ private boolean isHtml() { StaplerRequest req = Stapler.getCurrentRequest(); - return req!=null && req.getAttribute("html")!=null; + return req != null && req.getAttribute("html") != null; } @Override @@ -119,15 +118,15 @@ protected void setContentType(StaplerResponse rsp) { private ConsoleAnnotator createAnnotator(StaplerRequest req) throws IOException { try { - String base64 = req!=null ? req.getHeader("X-ConsoleAnnotator") : null; - if (base64!=null) { + String base64 = req != null ? req.getHeader("X-ConsoleAnnotator") : null; + if (base64 != null) { Cipher sym = PASSING_ANNOTATOR.decrypt(); try (ObjectInputStream ois = new ObjectInputStreamEx(new GZIPInputStream( new CipherInputStream(new ByteArrayInputStream(Base64.getDecoder().decode(base64.getBytes(StandardCharsets.UTF_8))), sym)), Jenkins.get().pluginManager.uberClassLoader)) { long timestamp = ois.readLong(); - if (TimeUnit.HOURS.toMillis(1) > abs(System.currentTimeMillis()-timestamp)) + if (TimeUnit.HOURS.toMillis(1) > abs(System.currentTimeMillis() - timestamp)) // don't deserialize something too old to prevent a replay attack return getConsoleAnnotator(ois); } catch (RuntimeException ex) { @@ -152,7 +151,7 @@ public long writeLogTo(long start, Writer w) throws IOException { if (isHtml()) return writeHtmlTo(start, w); else - return super.writeLogTo(start,w); + return super.writeLogTo(start, w); } /** @@ -178,22 +177,22 @@ public long writeRawLogTo(long start, OutputStream out) throws IOException { public long writeHtmlTo(long start, Writer w) throws IOException { ConsoleAnnotationOutputStream caw = new ConsoleAnnotationOutputStream<>( w, createAnnotator(Stapler.getCurrentRequest()), context, charset); - long r = super.writeLogTo(start,caw); + long r = super.writeLogTo(start, caw); ByteArrayOutputStream baos = new ByteArrayOutputStream(); Cipher sym = PASSING_ANNOTATOR.encrypt(); - ObjectOutputStream oos = AnonymousClassWarnings.checkingObjectOutputStream(new GZIPOutputStream(new CipherOutputStream(baos,sym))); + ObjectOutputStream oos = AnonymousClassWarnings.checkingObjectOutputStream(new GZIPOutputStream(new CipherOutputStream(baos, sym))); oos.writeLong(System.currentTimeMillis()); // send timestamp to prevent a replay attack oos.writeObject(caw.getConsoleAnnotator()); oos.close(); StaplerResponse rsp = Stapler.getCurrentResponse(); - if (rsp!=null) - rsp.setHeader("X-ConsoleAnnotator", new String(Base64.getEncoder().encode(baos.toByteArray()))); + if (rsp != null) + rsp.setHeader("X-ConsoleAnnotator", Base64.getEncoder().encodeToString(baos.toByteArray())); return r; } /** * Used for sending the state of ConsoleAnnotator to the client, because we are deserializing this object later. */ - private static final CryptoConfidentialKey PASSING_ANNOTATOR = new CryptoConfidentialKey(AnnotatedLargeText.class,"consoleAnnotator"); + private static final CryptoConfidentialKey PASSING_ANNOTATOR = new CryptoConfidentialKey(AnnotatedLargeText.class, "consoleAnnotator"); } diff --git a/core/src/main/java/hudson/console/ConsoleAnnotationDescriptor.java b/core/src/main/java/hudson/console/ConsoleAnnotationDescriptor.java index 2126cdc28391..e13d65ea4627 100644 --- a/core/src/main/java/hudson/console/ConsoleAnnotationDescriptor.java +++ b/core/src/main/java/hudson/console/ConsoleAnnotationDescriptor.java @@ -21,21 +21,21 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.console; import hudson.DescriptorExtensionList; import hudson.ExtensionPoint; import hudson.model.Descriptor; -import jenkins.model.Jenkins; +import java.io.IOException; +import java.net.URL; import java.util.concurrent.TimeUnit; +import javax.servlet.ServletException; +import jenkins.model.Jenkins; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; import org.kohsuke.stapler.WebMethod; -import javax.servlet.ServletException; -import java.io.IOException; -import java.net.URL; - /** * Descriptor for {@link ConsoleNote}. * @@ -43,11 +43,11 @@ * @since 1.349 */ public abstract class ConsoleAnnotationDescriptor extends Descriptor> implements ExtensionPoint { - public ConsoleAnnotationDescriptor(Class> clazz) { + protected ConsoleAnnotationDescriptor(Class> clazz) { super(clazz); } - public ConsoleAnnotationDescriptor() { + protected ConsoleAnnotationDescriptor() { } /** @@ -64,26 +64,26 @@ public String getDisplayName() { * Returns true if this descriptor has a JavaScript to be inserted on applicable console page. */ public boolean hasScript() { - return hasResource("/script.js") !=null; + return hasResource("/script.js") != null; } /** * Returns true if this descriptor has a stylesheet to be inserted on applicable console page. */ public boolean hasStylesheet() { - return hasResource("/style.css") !=null; + return hasResource("/style.css") != null; } private URL hasResource(String name) { - return clazz.getClassLoader().getResource(clazz.getName().replace('.','/').replace('$','/')+ name); + return clazz.getClassLoader().getResource(clazz.getName().replace('.', '/').replace('$', '/') + name); } - @WebMethod(name="script.js") + @WebMethod(name = "script.js") public void doScriptJs(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { rsp.serveFile(req, hasResource("/script.js"), TimeUnit.DAYS.toMillis(1)); } - @WebMethod(name="style.css") + @WebMethod(name = "style.css") public void doStyleCss(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { rsp.serveFile(req, hasResource("/style.css"), TimeUnit.DAYS.toMillis(1)); } @@ -91,7 +91,7 @@ public void doStyleCss(StaplerRequest req, StaplerResponse rsp) throws IOExcepti /** * Returns all the registered {@link ConsoleAnnotationDescriptor} descriptors. */ - public static DescriptorExtensionList,ConsoleAnnotationDescriptor> all() { + public static DescriptorExtensionList, ConsoleAnnotationDescriptor> all() { return (DescriptorExtensionList) Jenkins.get().getDescriptorList(ConsoleNote.class); } } diff --git a/core/src/main/java/hudson/console/ConsoleAnnotationOutputStream.java b/core/src/main/java/hudson/console/ConsoleAnnotationOutputStream.java index 00a84b6f4612..d2ac95da65bd 100644 --- a/core/src/main/java/hudson/console/ConsoleAnnotationOutputStream.java +++ b/core/src/main/java/hudson/console/ConsoleAnnotationOutputStream.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.console; import hudson.MarkupText; @@ -69,7 +70,7 @@ public ConsoleAnnotationOutputStream(Writer out, ConsoleAnnotator ann this.out = out; this.ann = ConsoleAnnotator.cast(ann); this.context = context; - this.lineOut = new WriterOutputStream(line,charset); + this.lineOut = new WriterOutputStream(line, charset); } public ConsoleAnnotator getConsoleAnnotator() { @@ -86,19 +87,19 @@ protected void eol(byte[] in, int sz) throws IOException { line.reset(); final StringBuffer strBuf = line.getStringBuffer(); - int next = ConsoleNote.findPreamble(in,0,sz); + int next = ConsoleNote.findPreamble(in, 0, sz); - List> annotators=null; + List> annotators = null; - {// perform byte[]->char[] while figuring out the char positions of the BLOBs + { // perform byte[]->char[] while figuring out the char positions of the BLOBs int written = 0; - while (next>=0) { - if (next>written) { - lineOut.write(in,written,next-written); + while (next >= 0) { + if (next > written) { + lineOut.write(in, written, next - written); lineOut.flush(); written = next; } else { - assert next==written; + assert next == written; } // character position of this annotation in this line @@ -109,41 +110,41 @@ protected void eol(byte[] in, int sz) throws IOException { try { final ConsoleNote a = ConsoleNote.readFrom(new DataInputStream(b)); - if (a!=null) { - if (annotators==null) + if (a != null) { + if (annotators == null) annotators = new ArrayList<>(); annotators.add(new ConsoleAnnotator() { @Override public ConsoleAnnotator annotate(T context, MarkupText text) { - return a.annotate(context,text,charPos); + return a.annotate(context, text, charPos); } }); } } catch (IOException | ClassNotFoundException e) { // if we failed to resurrect an annotation, ignore it. - LOGGER.log(Level.FINE, "Failed to resurrect annotation from \"" + StringEscapeUtils.escapeJava(new String(in, next, rest)) + "\"", e); + LOGGER.log(Level.FINE, "Failed to resurrect annotation from \"" + StringEscapeUtils.escapeJava(new String(in, next, rest, Charset.defaultCharset())) + "\"", e); } int bytesUsed = rest - b.available(); // bytes consumed by annotations written += bytesUsed; - next = ConsoleNote.findPreamble(in,written,sz-written); + next = ConsoleNote.findPreamble(in, written, sz - written); } // finish the remaining bytes->chars conversion - lineOut.write(in,written,sz-written); + lineOut.write(in, written, sz - written); - if (annotators!=null) { + if (annotators != null) { // aggregate newly retrieved ConsoleAnnotators into the current one. - if (ann!=null) annotators.add(ann); + if (ann != null) annotators.add(ann); ann = ConsoleAnnotator.combine(annotators); } } lineOut.flush(); MarkupText mt = new MarkupText(strBuf.toString()); - if (ann!=null) - ann = ann.annotate(context,mt); + if (ann != null) + ann = ann.annotate(context, mt); out.write(mt.toString(true)); // this perform escapes } @@ -172,14 +173,14 @@ private LineBuffer(int initialSize) { private void reset() { StringBuffer buf = getStringBuffer(); - if (buf.length()>4096) + if (buf.length() > 4096) out = new StringWriter(256); else buf.setLength(0); } private StringBuffer getStringBuffer() { - StringWriter w = (StringWriter)out; + StringWriter w = (StringWriter) out; return w.getBuffer(); } } diff --git a/core/src/main/java/hudson/console/ConsoleAnnotator.java b/core/src/main/java/hudson/console/ConsoleAnnotator.java index cc28c35452fa..8f289fd70cb9 100644 --- a/core/src/main/java/hudson/console/ConsoleAnnotator.java +++ b/core/src/main/java/hudson/console/ConsoleAnnotator.java @@ -21,17 +21,17 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.console; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.MarkupText; - import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.ListIterator; -import edu.umd.cs.findbugs.annotations.CheckForNull; -import edu.umd.cs.findbugs.annotations.NonNull; /** * Annotates one line of console output. @@ -82,14 +82,14 @@ public abstract class ConsoleAnnotator implements Serializable { * To indicate that you are not interested in the following lines, return {@code null}. */ @CheckForNull - public abstract ConsoleAnnotator annotate(@NonNull T context, @NonNull MarkupText text ); + public abstract ConsoleAnnotator annotate(@NonNull T context, @NonNull MarkupText text); /** * Cast operation that restricts T. */ @SuppressWarnings("unchecked") public static ConsoleAnnotator cast(ConsoleAnnotator a) { - return (ConsoleAnnotator)a; + return (ConsoleAnnotator) a; } @SuppressWarnings({"unchecked", "rawtypes"}) // unclear to jglick what is going on here @@ -105,9 +105,9 @@ public ConsoleAnnotator annotate(T context, MarkupText text) { ListIterator> itr = list.listIterator(); while (itr.hasNext()) { ConsoleAnnotator a = itr.next(); - ConsoleAnnotator b = a.annotate(context,text); - if (a!=b) { - if (b==null) itr.remove(); + ConsoleAnnotator b = a.annotate(context, text); + if (a != b) { + if (b == null) itr.remove(); else itr.set(b); } } @@ -127,9 +127,8 @@ public static ConsoleAnnotator combine(Collection(all); } - - return new ConsoleAnnotatorAggregator<>(all); } /** @@ -149,7 +148,7 @@ public static List> _for(T context) { for (ConsoleAnnotatorFactory f : ConsoleAnnotatorFactory.all()) { if (f.type().isInstance(context)) { ConsoleAnnotator ca = f.newInstance(context); - if (ca!=null) + if (ca != null) r.add(ca); } } diff --git a/core/src/main/java/hudson/console/ConsoleAnnotatorFactory.java b/core/src/main/java/hudson/console/ConsoleAnnotatorFactory.java index 409ee59c67f4..b2f6948fd155 100644 --- a/core/src/main/java/hudson/console/ConsoleAnnotatorFactory.java +++ b/core/src/main/java/hudson/console/ConsoleAnnotatorFactory.java @@ -21,24 +21,24 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.console; import hudson.Extension; import hudson.ExtensionList; import hudson.ExtensionPoint; import hudson.model.Run; +import java.io.IOException; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.net.URL; import java.util.concurrent.TimeUnit; +import javax.servlet.ServletException; import org.jvnet.tiger_types.Types; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; import org.kohsuke.stapler.WebMethod; -import javax.servlet.ServletException; -import java.io.IOException; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.net.URL; - /** * Entry point to the {@link ConsoleAnnotator} extension point. This class creates a new instance * of {@link ConsoleAnnotator} that starts a new console annotation session. @@ -62,7 +62,7 @@ * in the same resource directory that you normally put Jelly scripts), which will be loaded into * the HTML page whenever the console notes are used. This allows you to use minimal markup in * code generation, and do the styling in CSS and perform the rest of the interesting work as a CSS behaviour/JavaScript. - * + * * @author Kohsuke Kawaguchi * @since 1.349 */ @@ -88,7 +88,7 @@ public abstract class ConsoleAnnotatorFactory implements ExtensionPoint { public Class type() { Type type = Types.getBaseClass(getClass(), ConsoleAnnotatorFactory.class); if (type instanceof ParameterizedType) - return Types.erasure(Types.getTypeArgument(type,0)); + return Types.erasure(Types.getTypeArgument(type, 0)); else return Object.class; } @@ -97,27 +97,27 @@ public Class type() { * Returns true if this descriptor has a JavaScript to be inserted on applicable console page. */ public boolean hasScript() { - return getResource("/script.js") !=null; + return getResource("/script.js") != null; } public boolean hasStylesheet() { - return getResource("/style.css") !=null; + return getResource("/style.css") != null; } private URL getResource(String fileName) { Class c = getClass(); - return c.getClassLoader().getResource(c.getName().replace('.','/').replace('$','/')+ fileName); + return c.getClassLoader().getResource(c.getName().replace('.', '/').replace('$', '/') + fileName); } /** * Serves the JavaScript file associated with this console annotator factory. */ - @WebMethod(name="script.js") + @WebMethod(name = "script.js") public void doScriptJs(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { rsp.serveFile(req, getResource("/script.js"), TimeUnit.DAYS.toMillis(1)); } - @WebMethod(name="style.css") + @WebMethod(name = "style.css") public void doStyleCss(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { rsp.serveFile(req, getResource("/style.css"), TimeUnit.DAYS.toMillis(1)); } diff --git a/core/src/main/java/hudson/console/ConsoleLogFilter.java b/core/src/main/java/hudson/console/ConsoleLogFilter.java index 2b13ed88b7f5..3523fce8e9d2 100644 --- a/core/src/main/java/hudson/console/ConsoleLogFilter.java +++ b/core/src/main/java/hudson/console/ConsoleLogFilter.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright 2010 Yahoo! Inc. - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -24,6 +24,7 @@ package hudson.console; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.ExtensionList; import hudson.ExtensionPoint; import hudson.Util; @@ -32,8 +33,6 @@ import hudson.model.Run; import hudson.tasks.BuildWrapper; import hudson.util.ArgumentListBuilder; - -import edu.umd.cs.findbugs.annotations.NonNull; import java.io.IOException; import java.io.OutputStream; import java.io.Serializable; @@ -46,7 +45,7 @@ * data, which isn't possible from the other interfaces. * ({@link ArgumentListBuilder#add(String, boolean)} is a simpler way to suppress a single password.) *

    Implementations which are {@link Serializable} may be sent to an agent JVM for processing. - * In particular, this happens under JEP-210. + * In particular, this happens under JEP-210. * In this case, the implementation should not assume that {@link JenkinsJVM#isJenkinsJVM}, * and if generating {@link ConsoleNote}s will need to encode them on the master side first. * @author dty diff --git a/core/src/main/java/hudson/console/ConsoleNote.java b/core/src/main/java/hudson/console/ConsoleNote.java index 79eabdf98f02..8183934aedce 100644 --- a/core/src/main/java/hudson/console/ConsoleNote.java +++ b/core/src/main/java/hudson/console/ConsoleNote.java @@ -21,20 +21,20 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.console; +import com.jcraft.jzlib.GZIPInputStream; +import com.jcraft.jzlib.GZIPOutputStream; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.ExtensionPoint; import hudson.Functions; import hudson.MarkupText; import hudson.model.Describable; -import jenkins.model.Jenkins; import hudson.model.Run; +import hudson.remoting.ClassFilter; import hudson.remoting.ObjectInputStreamEx; import hudson.util.IOUtils; -import org.apache.commons.io.output.ByteArrayOutputStream; -import org.apache.tools.ant.BuildListener; - import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.DataOutputStream; @@ -44,17 +44,18 @@ import java.io.OutputStream; import java.io.Serializable; import java.io.Writer; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; import java.util.Base64; import java.util.Collection; import java.util.List; -import com.jcraft.jzlib.GZIPInputStream; -import com.jcraft.jzlib.GZIPOutputStream; -import hudson.remoting.ClassFilter; +import jenkins.model.Jenkins; import jenkins.security.HMACConfidentialKey; import jenkins.util.JenkinsJVM; import jenkins.util.SystemProperties; +import org.apache.commons.io.output.ByteArrayOutputStream; +import org.apache.tools.ant.BuildListener; import org.jenkinsci.remoting.util.AnonymousClassWarnings; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; @@ -114,7 +115,7 @@ * Note that {@link #encode}, {@link #encodeTo(OutputStream)}, and {@link #encodeTo(Writer)} * should be called on the Jenkins master. * If called from an agent JVM, a signature will be missing and so as per - * SECURITY-382 + * SECURITY-382 * the console note will be ignored. * This may happen, in particular, if the note was generated by a {@link ConsoleLogFilter} sent to the agent. * Alternative solutions include using a {@link ConsoleAnnotatorFactory} where practical; @@ -145,7 +146,7 @@ public abstract class ConsoleNote implements Serializable, Describable implements Serializable, Describable 0) { // new format - mac = new byte[macSz]; - decoded.readFully(mac); - sz = decoded.readInt(); - if (sz < 0) { - throw new IOException("Corrupt stream"); + byte[] buf; + try (DataInputStream decoded = new DataInputStream(Base64.getDecoder().wrap(in))) { + int macSz = -decoded.readInt(); + int sz; + if (macSz > 0) { // new format + mac = new byte[macSz]; + decoded.readFully(mac); + sz = decoded.readInt(); + if (sz < 0) { + throw new IOException("Corrupt stream"); + } + } else { + mac = null; + sz = -macSz; } - } else { - mac = null; - sz = - macSz; + buf = new byte[sz]; + decoded.readFully(buf); } - byte[] buf = new byte[sz]; - decoded.readFully(buf); byte[] postamble = new byte[POSTAMBLE.length]; in.readFully(postamble); - if (!Arrays.equals(postamble,POSTAMBLE)) + if (!Arrays.equals(postamble, POSTAMBLE)) return null; // not a valid postamble if (!INSECURE) { @@ -296,7 +300,7 @@ private static ConsoleNote getConsoleNote(ObjectInputStream ois) throws IOExcept public static void skip(DataInputStream in) throws IOException { byte[] preamble = new byte[PREAMBLE.length]; in.readFully(preamble); - if (!Arrays.equals(preamble,PREAMBLE)) + if (!Arrays.equals(preamble, PREAMBLE)) return; // not a valid preamble DataInputStream decoded = new DataInputStream(Base64.getDecoder().wrap(in)); @@ -323,11 +327,13 @@ public static void skip(DataInputStream in) throws IOException { * Preamble of the encoded form. ANSI escape sequence to stop echo back * plus a few magic characters. */ - public static final byte[] PREAMBLE = PREAMBLE_STR.getBytes(); + @SuppressFBWarnings(value = "MS_PKGPROTECT", justification = "used in several plugins") + public static final byte[] PREAMBLE = PREAMBLE_STR.getBytes(StandardCharsets.UTF_8); /** * Post amble is the ANSI escape sequence that brings back the echo. */ - public static final byte[] POSTAMBLE = POSTAMBLE_STR.getBytes(); + @SuppressFBWarnings(value = "MS_PKGPROTECT", justification = "used in several plugins") + public static final byte[] POSTAMBLE = POSTAMBLE_STR.getBytes(StandardCharsets.UTF_8); /** * Locates the preamble in the given buffer. @@ -336,11 +342,11 @@ public static int findPreamble(byte[] buf, int start, int len) { int e = start + len - PREAMBLE.length + 1; OUTER: - for (int i=start; i removeNotes(Collection logLines) { public static String removeNotes(String line) { while (true) { int idx = line.indexOf(PREAMBLE_STR); - if (idx<0) return line; - int e = line.indexOf(POSTAMBLE_STR,idx); - if (e<0) return line; - line = line.substring(0,idx)+line.substring(e+POSTAMBLE_STR.length()); + if (idx < 0) return line; + int e = line.indexOf(POSTAMBLE_STR, idx); + if (e < 0) return line; + line = line.substring(0, idx) + line.substring(e + POSTAMBLE_STR.length()); } } } diff --git a/core/src/main/java/hudson/console/ExpandableDetailsNote.java b/core/src/main/java/hudson/console/ExpandableDetailsNote.java index 83a4661c8d93..57ed88e06e22 100644 --- a/core/src/main/java/hudson/console/ExpandableDetailsNote.java +++ b/core/src/main/java/hudson/console/ExpandableDetailsNote.java @@ -21,11 +21,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.console; import hudson.Extension; import hudson.MarkupText; - import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; @@ -51,7 +51,7 @@ public ExpandableDetailsNote(String caption, String html) { @Override public ConsoleAnnotator annotate(Object context, MarkupText text, int charPos) { text.addMarkup(charPos, - "

    "+html+"
    "); + "
    " + html + "
    "); return null; } @@ -60,7 +60,7 @@ public static String encodeTo(String buttonCaption, String html) { return new ExpandableDetailsNote(buttonCaption, html).encode(); } catch (IOException e) { // impossible, but don't make this a fatal problem - LOGGER.log(Level.WARNING, "Failed to serialize "+HyperlinkNote.class,e); + LOGGER.log(Level.WARNING, "Failed to serialize " + HyperlinkNote.class, e); return ""; } } diff --git a/core/src/main/java/hudson/console/HyperlinkNote.java b/core/src/main/java/hudson/console/HyperlinkNote.java index 395ebd38e4fb..f8e7e6520838 100644 --- a/core/src/main/java/hudson/console/HyperlinkNote.java +++ b/core/src/main/java/hudson/console/HyperlinkNote.java @@ -21,11 +21,16 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.console; import hudson.Extension; import hudson.MarkupText; import hudson.Util; +import java.io.IOException; +import java.util.function.BiFunction; +import java.util.logging.Level; +import java.util.logging.Logger; import jenkins.model.Jenkins; import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; @@ -33,11 +38,6 @@ import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.StaplerRequest; -import java.io.IOException; -import java.util.function.BiFunction; -import java.util.logging.Level; -import java.util.logging.Logger; - /** * Turns a text into a hyperlink by specifying the URL separately. * @@ -62,15 +62,15 @@ public ConsoleAnnotator annotate(Object context, MarkupText text, int charPos) { String url = this.url; if (url.startsWith("/")) { StaplerRequest req = Stapler.getCurrentRequest(); - if (req!=null) { + if (req != null) { // if we are serving HTTP request, we want to use app relative URL - url = req.getContextPath()+url; + url = req.getContextPath() + url; } else { // otherwise presumably this is rendered for e-mails and other non-HTTP stuff - url = Jenkins.get().getRootUrl()+url.substring(1); + url = Jenkins.get().getRootUrl() + url.substring(1); } } - text.addMarkup(charPos, charPos + length, "", ""); + text.addMarkup(charPos, charPos + length, "", ""); return null; } @@ -92,10 +92,10 @@ static String encodeTo(String url, String text, BiFunction4096) + if (buf.size() > 4096) buf = new ByteArrayOutputStream2(); else buf.reset(); @@ -68,9 +69,9 @@ private void eol() throws IOException { @Override public void write(byte[] b, int off, int len) throws IOException { - int end = off+len; + int end = off + len; - for( int i=off; i0) { + if (buf.size() > 0) { /* because LargeText cuts output at the line end boundary, this is possible only for the very end of the console output, if the output ends without NL. @@ -97,15 +98,15 @@ public void forceEol() throws IOException { protected String trimEOL(String line) { int slen = line.length(); - while (slen>0) { - char ch = line.charAt(slen-1); - if (ch=='\r' || ch=='\n') { + while (slen > 0) { + char ch = line.charAt(slen - 1); + if (ch == '\r' || ch == '\n') { slen--; continue; } break; } - line = line.substring(0,slen); + line = line.substring(0, slen); return line; } diff --git a/core/src/main/java/hudson/console/ModelHyperlinkNote.java b/core/src/main/java/hudson/console/ModelHyperlinkNote.java index 161aae3b65c0..fa5d57eedd4e 100644 --- a/core/src/main/java/hudson/console/ModelHyperlinkNote.java +++ b/core/src/main/java/hudson/console/ModelHyperlinkNote.java @@ -1,13 +1,18 @@ package hudson.console; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.Extension; -import hudson.model.*; +import hudson.model.Computer; +import hudson.model.Item; +import hudson.model.Label; +import hudson.model.ModelObject; +import hudson.model.Node; +import hudson.model.Run; +import hudson.model.User; +import java.util.logging.Logger; import jenkins.model.Jenkins; import org.jenkinsci.Symbol; -import java.util.logging.Logger; -import edu.umd.cs.findbugs.annotations.NonNull; - /** * {@link HyperlinkNote} that links to a {@linkplain ModelObject model object}, * which in the UI gets rendered with context menu and etc. @@ -22,27 +27,27 @@ public ModelHyperlinkNote(String url, int length) { @Override protected String extraAttributes() { - return " class='model-link'"; + return " class='model-link model-link--float'"; } public static String encodeTo(@NonNull User u) { - return encodeTo(u,u.getDisplayName()); + return encodeTo(u, u.getDisplayName()); } public static String encodeTo(User u, String text) { - return encodeTo('/'+u.getUrl(),text); + return encodeTo('/' + u.getUrl(), text); } public static String encodeTo(Item item) { - return encodeTo(item,item.getFullDisplayName()); + return encodeTo(item, item.getFullDisplayName()); } public static String encodeTo(Item item, String text) { - return encodeTo('/'+item.getUrl(),text); + return encodeTo('/' + item.getUrl(), text); } public static String encodeTo(Run r) { - return encodeTo('/'+r.getUrl(),r.getDisplayName()); + return encodeTo('/' + r.getUrl(), r.getDisplayName()); } public static String encodeTo(Node node) { @@ -50,7 +55,7 @@ public static String encodeTo(Node node) { if (c != null) { return encodeTo("/" + c.getUrl(), node.getDisplayName()); } - String nodePath = node == Jenkins.get() ? "(master)" : node.getNodeName(); + String nodePath = node == Jenkins.get() ? "(built-in)" : node.getNodeName(); return encodeTo("/computer/" + nodePath, node.getDisplayName()); } @@ -72,7 +77,7 @@ public String getDisplayName() { return "Hyperlinks to models"; } } - + private static final long serialVersionUID = 1L; private static final Logger LOGGER = Logger.getLogger(ModelHyperlinkNote.class.getName()); diff --git a/core/src/main/java/hudson/console/PlainTextConsoleOutputStream.java b/core/src/main/java/hudson/console/PlainTextConsoleOutputStream.java index 6eb4c9f4eab6..f3b5bd8adf7e 100644 --- a/core/src/main/java/hudson/console/PlainTextConsoleOutputStream.java +++ b/core/src/main/java/hudson/console/PlainTextConsoleOutputStream.java @@ -46,18 +46,19 @@ public PlainTextConsoleOutputStream(OutputStream out) { /** * Called after we read the whole line of plain text. */ + @Override protected void eol(byte[] in, int sz) throws IOException { - int next = ConsoleNote.findPreamble(in,0,sz); + int next = ConsoleNote.findPreamble(in, 0, sz); // perform byte[]->char[] while figuring out the char positions of the BLOBs int written = 0; - while (next>=0) { - if (next>written) { - out.write(in,written,next-written); + while (next >= 0) { + if (next > written) { + out.write(in, written, next - written); written = next; } else { - assert next==written; + assert next == written; } int rest = sz - next; @@ -69,10 +70,10 @@ protected void eol(byte[] in, int sz) throws IOException { written += bytesUsed; - next = ConsoleNote.findPreamble(in,written,sz-written); + next = ConsoleNote.findPreamble(in, written, sz - written); } // finish the remaining bytes->chars conversion - out.write(in,written,sz-written); + out.write(in, written, sz - written); } } diff --git a/core/src/main/java/hudson/console/UrlAnnotator.java b/core/src/main/java/hudson/console/UrlAnnotator.java index 95b7b8f4f0d9..7422faee4b2c 100644 --- a/core/src/main/java/hudson/console/UrlAnnotator.java +++ b/core/src/main/java/hudson/console/UrlAnnotator.java @@ -3,9 +3,8 @@ import hudson.Extension; import hudson.MarkupText; import hudson.MarkupText.SubText; -import org.jenkinsci.Symbol; - import java.util.regex.Pattern; +import org.jenkinsci.Symbol; /** * Annotates URLs in the console output to hyperlink. @@ -20,13 +19,14 @@ public ConsoleAnnotator newInstance(Object context) { } private static class UrlConsoleAnnotator extends ConsoleAnnotator { + @Override public ConsoleAnnotator annotate(Object context, MarkupText text) { for (SubText t : text.findTokens(URL)) { int prev = t.start() - 1; - char ch = prev>=0 ? text.charAt(prev) : ' '; + char ch = prev >= 0 ? text.charAt(prev) : ' '; int idx = OPEN.indexOf(ch); - if (idx>=0) {// if inside a bracket, exclude the end bracket. - t=t.subText(0,t.getText().indexOf(CLOSE.charAt(idx))); + if (idx >= 0) { // if inside a bracket, exclude the end bracket. + t = t.subText(0, t.getText().indexOf(CLOSE.charAt(idx))); } t.href(t.getText()); } @@ -44,6 +44,6 @@ public ConsoleAnnotator annotate(Object context, MarkupText text) { private static final Pattern URL = Pattern.compile("\\b(http|https|file|ftp)://[^\\s<>]+[^\\s<>,\\.:\"'()\\[\\]=]"); private static final String OPEN = "'\"()[]<>"; - private static final String CLOSE= "'\")(][><"; + private static final String CLOSE = "'\")(][><"; } } diff --git a/core/src/main/java/hudson/diagnosis/HudsonHomeDiskUsageChecker.java b/core/src/main/java/hudson/diagnosis/HudsonHomeDiskUsageChecker.java index a2b1e53321a5..8b38c3e5a776 100644 --- a/core/src/main/java/hudson/diagnosis/HudsonHomeDiskUsageChecker.java +++ b/core/src/main/java/hudson/diagnosis/HudsonHomeDiskUsageChecker.java @@ -21,15 +21,16 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.diagnosis; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.Extension; -import jenkins.model.Jenkins; import hudson.model.PeriodicWork; -import org.jenkinsci.Symbol; - import java.util.logging.Logger; +import jenkins.model.Jenkins; +import jenkins.util.SystemProperties; +import org.jenkinsci.Symbol; /** * Periodically checks the disk usage of {@code JENKINS_HOME}, @@ -39,27 +40,29 @@ */ @Extension @Symbol("diskUsageCheck") public class HudsonHomeDiskUsageChecker extends PeriodicWork { + @Override public long getRecurrencePeriod() { return HOUR; } + @Override protected void doRun() { long free = Jenkins.get().getRootDir().getUsableSpace(); long total = Jenkins.get().getRootDir().getTotalSpace(); - if(free<=0 || total<=0) { + if (free <= 0 || total <= 0) { // information unavailable. pointless to try. LOGGER.info("JENKINS_HOME disk usage information isn't available. aborting to monitor"); cancel(); return; } - LOGGER.fine("Monitoring disk usage of JENKINS_HOME. total="+total+" free="+free); + LOGGER.fine("Monitoring disk usage of JENKINS_HOME. total=" + total + " free=" + free); // if it's more than 90% full and less than the minimum, activate // it's AND and not OR so that small Hudson home won't get a warning, // and similarly, if you have a 1TB disk, you don't get a warning when you still have 100GB to go. - HudsonHomeDiskUsageMonitor.get().activated = (total/free>10 && free< FREE_SPACE_THRESHOLD); + HudsonHomeDiskUsageMonitor.get().activated = total / free > 10 && free < FREE_SPACE_THRESHOLD; } private static final Logger LOGGER = Logger.getLogger(HudsonHomeDiskUsageChecker.class.getName()); @@ -67,9 +70,7 @@ protected void doRun() { /** * Gets the minimum amount of space to check for, with a default of 10GB */ - @SuppressFBWarnings("MS_SHOULD_BE_FINAL") - public static long FREE_SPACE_THRESHOLD = Long.getLong( - HudsonHomeDiskUsageChecker.class.getName() + ".freeSpaceThreshold", - 1024L*1024*1024*10); - + @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "for script console") + public static long FREE_SPACE_THRESHOLD = SystemProperties.getLong(HudsonHomeDiskUsageChecker.class.getName() + + ".freeSpaceThreshold", 1024L * 1024 * 1024 * 10); } diff --git a/core/src/main/java/hudson/diagnosis/HudsonHomeDiskUsageMonitor.java b/core/src/main/java/hudson/diagnosis/HudsonHomeDiskUsageMonitor.java index 2c29f4488754..20e112f5ba84 100644 --- a/core/src/main/java/hudson/diagnosis/HudsonHomeDiskUsageMonitor.java +++ b/core/src/main/java/hudson/diagnosis/HudsonHomeDiskUsageMonitor.java @@ -21,22 +21,22 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.diagnosis; -import hudson.model.AdministrativeMonitor; -import hudson.model.AbstractModelObject; import hudson.Extension; -import hudson.ExtensionPoint; import hudson.ExtensionList; +import hudson.ExtensionPoint; +import hudson.model.AbstractModelObject; +import hudson.model.AdministrativeMonitor; +import java.io.IOException; +import java.util.List; import org.jenkinsci.Symbol; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.HttpResponses; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.interceptor.RequirePOST; -import java.io.IOException; -import java.util.List; - /** * Monitors the disk usage of {@code JENKINS_HOME}, and if it's almost filled up, warn the user. * @@ -53,13 +53,14 @@ public HudsonHomeDiskUsageMonitor() { super("hudsonHomeIsFull"); } + @Override public boolean isActivated() { return activated; } - + @Override public String getDisplayName() { - return Messages.HudsonHomeDiskUsageMonitor_DisplayName(); + return Messages.HudsonHomeDiskUsageMonitor_DisplayName(); } /** @@ -67,7 +68,7 @@ public String getDisplayName() { */ @RequirePOST public HttpResponse doAct(@QueryParameter String no) throws IOException { - if(no!=null) { + if (no != null) { disable(true); return HttpResponses.redirectViaContextPath("/manage"); } else { @@ -83,8 +84,8 @@ public List getSolutions() { * Binds a solution to the URL. */ public Solution getSolution(String id) { - for( Solution s : Solution.all() ) - if(s.id.equals(id)) + for (Solution s : Solution.all()) + if (s.id.equals(id)) return s; return null; } @@ -98,8 +99,8 @@ public static HudsonHomeDiskUsageMonitor get() { /** * Extension point for suggesting solutions for full JENKINS_HOME. + * Views are as follows: * - *

    Views

    *
    *
    message.jelly
    *
    @@ -129,7 +130,7 @@ protected Solution() { * Returns the URL of this monitor, relative to the context path. */ public String getUrl() { - return HudsonHomeDiskUsageMonitor.get().getUrl()+"/solution/"+id; + return HudsonHomeDiskUsageMonitor.get().getUrl() + "/solution/" + id; } /** diff --git a/core/src/main/java/hudson/diagnosis/MemoryUsageMonitor.java b/core/src/main/java/hudson/diagnosis/MemoryUsageMonitor.java index 3f3cf3efb114..797ee03d6b21 100644 --- a/core/src/main/java/hudson/diagnosis/MemoryUsageMonitor.java +++ b/core/src/main/java/hudson/diagnosis/MemoryUsageMonitor.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,24 +21,23 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.diagnosis; -import java.util.concurrent.TimeUnit; -import hudson.util.ColorPalette; import hudson.Extension; -import hudson.model.PeriodicWork; import hudson.model.MultiStageTimeSeries; -import hudson.model.MultiStageTimeSeries.TrendChart; import hudson.model.MultiStageTimeSeries.TimeScale; - +import hudson.model.MultiStageTimeSeries.TrendChart; +import hudson.model.PeriodicWork; +import hudson.util.ColorPalette; +import java.io.IOException; +import java.lang.management.ManagementFactory; import java.lang.management.MemoryPoolMXBean; import java.lang.management.MemoryType; import java.lang.management.MemoryUsage; -import java.lang.management.ManagementFactory; -import java.util.List; import java.util.ArrayList; -import java.io.IOException; - +import java.util.List; +import java.util.concurrent.TimeUnit; import jenkins.model.Jenkins; import org.jenkinsci.Symbol; import org.kohsuke.stapler.QueryParameter; @@ -51,20 +50,20 @@ @Extension @Symbol("memoryUsage") public final class MemoryUsageMonitor extends PeriodicWork { /** - * A memory group is conceptually a set of memory pools. + * A memory group is conceptually a set of memory pools. */ - public final class MemoryGroup { + public static final class MemoryGroup { private final List pools = new ArrayList<>(); /** * Trend of the memory usage, after GCs. * So this shows the accurate snapshot of the footprint of live objects. */ - public final MultiStageTimeSeries used = new MultiStageTimeSeries(Messages._MemoryUsageMonitor_USED(), ColorPalette.RED, 0,0); + public final MultiStageTimeSeries used = new MultiStageTimeSeries(Messages._MemoryUsageMonitor_USED(), ColorPalette.RED, 0, 0); /** * Trend of the maximum memory size, after GCs. */ - public final MultiStageTimeSeries max = new MultiStageTimeSeries(Messages._MemoryUsageMonitor_TOTAL(), ColorPalette.BLUE, 0,0); + public final MultiStageTimeSeries max = new MultiStageTimeSeries(Messages._MemoryUsageMonitor_TOTAL(), ColorPalette.BLUE, 0, 0); private MemoryGroup(List pools, MemoryType type) { for (MemoryPoolMXBean pool : pools) { @@ -76,27 +75,19 @@ private MemoryGroup(List pools, MemoryType type) { private void update() { long used = 0; long max = 0; -// long cur = 0; for (MemoryPoolMXBean pool : pools) { MemoryUsage usage = pool.getCollectionUsage(); - if(usage==null) continue; // not available + if (usage == null) continue; // not available used += usage.getUsed(); max += usage.getMax(); - -// usage = pool.getUsage(); -// if(usage==null) continue; // not available -// cur += usage.getUsed(); } // B -> KB used /= 1024; max /= 1024; -// cur /= 1024; this.used.update(used); this.max.update(max); -// -// return String.format("%d/%d/%d (%d%%)",used,cur,max,used*100/max); } /** @@ -104,7 +95,7 @@ private void update() { */ public TrendChart doGraph(@QueryParameter String type) throws IOException { Jenkins.get().checkAnyPermission(Jenkins.SYSTEM_READ, Jenkins.MANAGE); - return MultiStageTimeSeries.createTrendChart(TimeScale.parse(type),used,max); + return MultiStageTimeSeries.createTrendChart(TimeScale.parse(type), used, max); } } @@ -117,10 +108,12 @@ public MemoryUsageMonitor() { nonHeap = new MemoryGroup(pools, MemoryType.NON_HEAP); } + @Override public long getRecurrencePeriod() { return TimeUnit.SECONDS.toMillis(10); } + @Override protected void doRun() { heap.update(); nonHeap.update(); diff --git a/core/src/main/java/hudson/diagnosis/NullIdDescriptorMonitor.java b/core/src/main/java/hudson/diagnosis/NullIdDescriptorMonitor.java index 5663a32d967a..43a1505aa606 100644 --- a/core/src/main/java/hudson/diagnosis/NullIdDescriptorMonitor.java +++ b/core/src/main/java/hudson/diagnosis/NullIdDescriptorMonitor.java @@ -21,24 +21,24 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.diagnosis; +import static hudson.init.InitMilestone.EXTENSIONS_AUGMENTED; + import hudson.Extension; import hudson.PluginWrapper; import hudson.init.Initializer; import hudson.model.AdministrativeMonitor; import hudson.model.Descriptor; -import jenkins.model.Jenkins; -import org.jenkinsci.Symbol; - import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; - -import static hudson.init.InitMilestone.EXTENSIONS_AUGMENTED; +import jenkins.model.Jenkins; +import org.jenkinsci.Symbol; /** * Some old descriptors apparently has the getId() method that's used in different ways @@ -66,7 +66,7 @@ public List getProblems() { return Collections.unmodifiableList(problems); } - @Initializer(after=EXTENSIONS_AUGMENTED) + @Initializer(after = EXTENSIONS_AUGMENTED) public void verify() { Jenkins h = Jenkins.get(); for (Descriptor d : h.getExtensionList(Descriptor.class)) { @@ -75,14 +75,14 @@ public void verify() { try { id = d.getId(); } catch (Throwable t) { - LOGGER.log(Level.SEVERE,MessageFormat.format("Descriptor {0} from plugin {1} with display name {2} reported an exception for ID", - d, p == null ? "???" : p.getLongName(), d.getDisplayName()),t); + LOGGER.log(Level.SEVERE, MessageFormat.format("Descriptor {0} from plugin {1} with display name {2} reported an exception for ID", + d, p == null ? "???" : p.getLongName(), d.getDisplayName()), t); problems.add(d); continue; } - if (id==null) { + if (id == null) { LOGGER.severe(MessageFormat.format("Descriptor {0} from plugin {1} with display name {2} has null ID", - d, p==null?"???":p.getLongName(), d.getDisplayName())); + d, p == null ? "???" : p.getLongName(), d.getDisplayName())); problems.add(d); } } diff --git a/core/src/main/java/hudson/diagnosis/OldDataMonitor.java b/core/src/main/java/hudson/diagnosis/OldDataMonitor.java index 56f48d6be367..b29ec1a80fb2 100644 --- a/core/src/main/java/hudson/diagnosis/OldDataMonitor.java +++ b/core/src/main/java/hudson/diagnosis/OldDataMonitor.java @@ -21,10 +21,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.diagnosis; -import com.google.common.base.Predicate; import com.thoughtworks.xstream.converters.UnmarshallingContext; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.Extension; import hudson.ExtensionList; import hudson.Main; @@ -52,11 +54,9 @@ import java.util.TreeSet; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import java.util.function.Predicate; import java.util.logging.Level; import java.util.logging.Logger; -import edu.umd.cs.findbugs.annotations.CheckForNull; -import edu.umd.cs.findbugs.annotations.NonNull; - import jenkins.model.Jenkins; import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; @@ -78,7 +78,7 @@ public class OldDataMonitor extends AdministrativeMonitor { private static final Logger LOGGER = Logger.getLogger(OldDataMonitor.class.getName()); - private ConcurrentMap data = new ConcurrentHashMap<>(); + private ConcurrentMap data = new ConcurrentHashMap<>(); /** * Gets instance of the monitor. @@ -101,13 +101,14 @@ public String getDisplayName() { return Messages.OldDataMonitor_DisplayName(); } + @Override public boolean isActivated() { return !data.isEmpty(); } - public Map getData() { - Map r = new HashMap<>(); - for (Map.Entry entry : this.data.entrySet()) { + public Map getData() { + Map r = new HashMap<>(); + for (Map.Entry entry : this.data.entrySet()) { Saveable s = entry.getKey().get(); if (s != null) { r.put(s, entry.getValue()); @@ -191,6 +192,7 @@ public static void report(UnmarshallingContext context, String version) { private static class ReportException extends Exception { private String version; + private ReportException(String version) { this.version = version; } @@ -206,7 +208,7 @@ public static void report(Saveable obj, Collection errors) { int i = 0; for (Throwable e : errors) { if (e instanceof ReportException) { - report(obj, ((ReportException)e).version); + report(obj, ((ReportException) e).version); } else { if (Main.isUnitTest) { LOGGER.log(Level.INFO, "Trouble loading " + obj, e); @@ -273,7 +275,7 @@ public VersionRange(VersionRange previous, String version, String extra) { @Override public String toString() { - return min==null ? "" : min.toString() + (single ? "" : " - " + max.toString()); + return min == null ? "" : min + (single ? "" : " - " + max.toString()); } /** @@ -325,12 +327,9 @@ public HttpResponse doUpgrade(StaplerRequest req, StaplerResponse rsp) { final String thruVerParam = req.getParameter("thruVer"); final VersionNumber thruVer = thruVerParam.equals("all") ? null : new VersionNumber(thruVerParam); - saveAndRemoveEntries(new Predicate>() { - @Override - public boolean apply(Map.Entry entry) { - VersionNumber version = entry.getValue().max; - return version != null && (thruVer == null || !version.isNewerThan(thruVer)); - } + saveAndRemoveEntries(entry -> { + VersionNumber version = entry.getValue().max; + return version != null && (thruVer == null || !version.isNewerThan(thruVer)); }); return HttpResponses.forwardToPreviousPage(); @@ -342,12 +341,7 @@ public boolean apply(Map.Entry entry) { */ @RequirePOST public HttpResponse doDiscard(StaplerRequest req, StaplerResponse rsp) { - saveAndRemoveEntries( new Predicate>() { - @Override - public boolean apply(Map.Entry entry) { - return entry.getValue().max == null; - } - }); + saveAndRemoveEntries(entry -> entry.getValue().max == null); return HttpResponses.forwardToPreviousPage(); } @@ -365,8 +359,8 @@ private void saveAndRemoveEntries(Predicate removed = new ArrayList<>(); - for (Map.Entry entry : data.entrySet()) { - if (matchingPredicate.apply(entry)) { + for (Map.Entry entry : data.entrySet()) { + if (matchingPredicate.test(entry)) { Saveable s = entry.getKey().get(); if (s != null) { try { @@ -404,15 +398,19 @@ private static SaveableReference referTo(Saveable s) { private static final class SimpleSaveableReference implements SaveableReference { private final Saveable instance; + SimpleSaveableReference(Saveable instance) { this.instance = instance; } + @Override public Saveable get() { return instance; } + @Override public int hashCode() { return instance.hashCode(); } + @Override public boolean equals(Object obj) { return obj instanceof SimpleSaveableReference && instance.equals(((SimpleSaveableReference) obj).instance); } @@ -422,9 +420,11 @@ private static final class SimpleSaveableReference implements SaveableReference private static final class RunSaveableReference implements SaveableReference { private final String id; - RunSaveableReference(Run r) { + + RunSaveableReference(Run r) { id = r.getExternalizableId(); } + @Override public Saveable get() { try { return Run.fromExternalizableId(id); @@ -434,9 +434,11 @@ private static final class RunSaveableReference implements SaveableReference { return null; } } + @Override public int hashCode() { return id.hashCode(); } + @Override public boolean equals(Object obj) { return obj instanceof RunSaveableReference && id.equals(((RunSaveableReference) obj).id); } @@ -452,7 +454,7 @@ public Category getCategory() { @Override public String getIconFileName() { - return "document.png"; + return "symbol-cube"; } @Override @@ -465,6 +467,7 @@ public String getDescription() { return Messages.OldDataMonitor_Description(); } + @Override public String getDisplayName() { return Messages.OldDataMonitor_DisplayName(); } diff --git a/core/src/main/java/hudson/diagnosis/ReverseProxySetupMonitor.java b/core/src/main/java/hudson/diagnosis/ReverseProxySetupMonitor.java index 8d64deddd82c..af7b2579db74 100644 --- a/core/src/main/java/hudson/diagnosis/ReverseProxySetupMonitor.java +++ b/core/src/main/java/hudson/diagnosis/ReverseProxySetupMonitor.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.diagnosis; import hudson.Extension; @@ -28,6 +29,10 @@ import hudson.Util; import hudson.model.AdministrativeMonitor; import hudson.security.Permission; +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; +import jenkins.model.Jenkins; import jenkins.security.stapler.StaplerDispatchable; import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; @@ -36,11 +41,6 @@ import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.HttpResponses; import org.kohsuke.stapler.QueryParameter; - -import java.io.IOException; -import java.util.logging.Level; -import java.util.logging.Logger; -import jenkins.model.Jenkins; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.interceptor.RequirePOST; @@ -116,13 +116,13 @@ public Permission getRequiredPermission() { @RestrictedSince("2.235") @RequirePOST public HttpResponse doAct(@QueryParameter String no) throws IOException { - if(no!=null) { // dismiss + if (no != null) { // dismiss Jenkins.get().checkPermission(Jenkins.ADMINISTER); disable(true); // of course the irony is that this redirect won't work return HttpResponses.redirectViaContextPath("/manage"); } else { - return new HttpRedirect("https://jenkins.io/redirect/troubleshooting/broken-reverse-proxy"); + return new HttpRedirect("https://www.jenkins.io/redirect/troubleshooting/broken-reverse-proxy"); } } @@ -131,4 +131,3 @@ public String getDisplayName() { return Messages.ReverseProxySetupMonitor_DisplayName(); } } - diff --git a/core/src/main/java/hudson/diagnosis/TooManyJobsButNoView.java b/core/src/main/java/hudson/diagnosis/TooManyJobsButNoView.java index 93918ebfd547..6412ac63bcb2 100644 --- a/core/src/main/java/hudson/diagnosis/TooManyJobsButNoView.java +++ b/core/src/main/java/hudson/diagnosis/TooManyJobsButNoView.java @@ -21,24 +21,24 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.diagnosis; +import hudson.Extension; import hudson.model.AdministrativeMonitor; import hudson.security.Permission; +import java.io.IOException; import jenkins.model.Jenkins; -import hudson.Extension; import org.jenkinsci.Symbol; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; import org.kohsuke.stapler.interceptor.RequirePOST; -import java.io.IOException; - /** * If Hudson is run with a lot of jobs but no views, suggest the user that they can create views. * *

    - * I noticed at an user visit that some users didn't notice the '+' icon in the tab bar. + * I noticed at an user visit that some users didn't notice the '+' icon in the tab bar. * * @author Kohsuke Kawaguchi */ @@ -50,6 +50,7 @@ public String getDisplayName() { return Messages.TooManyJobsButNoView_DisplayName(); } + @Override public boolean isActivated() { Jenkins j = Jenkins.get(); if (j.hasPermission(Jenkins.ADMINISTER)) { @@ -65,11 +66,11 @@ public boolean isActivated() { @RequirePOST public void doAct(StaplerRequest req, StaplerResponse rsp) throws IOException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); - if(req.hasParameter("no")) { + if (req.hasParameter("no")) { disable(true); - rsp.sendRedirect(req.getContextPath()+"/manage"); + rsp.sendRedirect(req.getContextPath() + "/manage"); } else { - rsp.sendRedirect(req.getContextPath()+"/newView"); + rsp.sendRedirect(req.getContextPath() + "/newView"); } } diff --git a/core/src/main/java/hudson/init/InitMilestone.java b/core/src/main/java/hudson/init/InitMilestone.java index 4ee9fa26f418..5e8c03c3e055 100644 --- a/core/src/main/java/hudson/init/InitMilestone.java +++ b/core/src/main/java/hudson/init/InitMilestone.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.init; import org.jvnet.hudson.reactor.Executable; @@ -49,7 +50,7 @@ *

  • JOB_CONFIG_ADAPTED
  • *
  • COMPLETED * - * + * * @author Kohsuke Kawaguchi */ public enum InitMilestone implements Milestone { @@ -131,8 +132,8 @@ public enum InitMilestone implements Milestone { public static TaskBuilder ordering() { TaskGraphBuilder b = new TaskGraphBuilder(); InitMilestone[] v = values(); - for (int i=0; i * To register, put {@link MetaInfServices} on your implementation. - * + * * @author Kohsuke Kawaguchi */ public class InitStrategy { @@ -60,10 +58,10 @@ public List listPluginArchives(PluginManager pm) throws IOException { return r; } - + private void listPluginFiles(PluginManager pm, String extension, Collection all) throws IOException { File[] files = pm.rootDir.listFiles(new FilterByExtension(extension)); - if (files==null) + if (files == null) throw new IOException("Jenkins is unable to create " + pm.rootDir + "\nPerhaps its security privilege is insufficient"); all.addAll(Arrays.asList(files)); @@ -101,7 +99,7 @@ protected void getBundledPluginsFromProperty(final List r) { /** * Selectively skip some of the initialization tasks. - * + * * @return * true to skip the execution. */ @@ -132,6 +130,7 @@ private static class FilterByExtension implements FilenameFilter { this.extensions = Arrays.asList(extensions); } + @Override public boolean accept(File dir, String name) { for (String extension : extensions) { if (name.endsWith(extension)) diff --git a/core/src/main/java/hudson/init/Initializer.java b/core/src/main/java/hudson/init/Initializer.java index 402a2c3dfbd8..78f4b2b444fd 100644 --- a/core/src/main/java/hudson/init/Initializer.java +++ b/core/src/main/java/hudson/init/Initializer.java @@ -21,26 +21,25 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.init; -import hudson.Extension; -import org.jvnet.hudson.annotation_indexer.Indexed; -import org.jvnet.hudson.reactor.Task; +import static hudson.init.InitMilestone.COMPLETED; +import static hudson.init.InitMilestone.STARTED; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import hudson.Extension; import java.lang.annotation.Documented; -import static java.lang.annotation.ElementType.METHOD; import java.lang.annotation.Retention; -import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Target; - -import static hudson.init.InitMilestone.STARTED; -import static hudson.init.InitMilestone.COMPLETED; +import org.jvnet.hudson.annotation_indexer.Indexed; +import org.jvnet.hudson.reactor.Task; /** * Placed on methods to indicate that this method is to be run during the Jenkins start up to perform - * some sort of initialization tasks. + * some sort of initialization tasks, for example: * - *

    Example

    *
        @Initializer(after=JOB_LOADED)
        public static void init() throws IOException {
    @@ -52,7 +51,7 @@ public static void init() throws IOException {
      * The method in question can be either {@code static} or an instance method. When used with instance
      * methods, those methods have to be on a class annotated with {@link Extension} and marked as
      * {@link #after()} {@link InitMilestone#PLUGINS_PREPARED}.
    - * 
    + *
      * @author Kohsuke Kawaguchi
      */
     @Indexed
    @@ -100,7 +99,7 @@ public static void init() throws IOException {
         /**
          * Should the failure in this task prevent Hudson from starting up?
          *
    -     * @see Task#failureIsFatal() 
    +     * @see Task#failureIsFatal()
          */
         boolean fatal() default true;
     }
    diff --git a/core/src/main/java/hudson/init/InitializerFinder.java b/core/src/main/java/hudson/init/InitializerFinder.java
    index 8b11b5740c50..938cbd5d78e3 100644
    --- a/core/src/main/java/hudson/init/InitializerFinder.java
    +++ b/core/src/main/java/hudson/init/InitializerFinder.java
    @@ -21,6 +21,7 @@
      * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
      * THE SOFTWARE.
      */
    +
     package hudson.init;
     
     import org.jvnet.hudson.reactor.Milestone;
    @@ -33,7 +34,7 @@
     public class InitializerFinder extends TaskMethodFinder {
     
         public InitializerFinder(ClassLoader cl) {
    -        super(Initializer.class,InitMilestone.class,cl);
    +        super(Initializer.class, InitMilestone.class, cl);
         }
     
         public InitializerFinder() {
    diff --git a/core/src/main/java/hudson/init/TaskMethodFinder.java b/core/src/main/java/hudson/init/TaskMethodFinder.java
    index c5c3cffdef9d..b15869ba8831 100644
    --- a/core/src/main/java/hudson/init/TaskMethodFinder.java
    +++ b/core/src/main/java/hudson/init/TaskMethodFinder.java
    @@ -1,16 +1,9 @@
     package hudson.init;
     
    +import static java.util.logging.Level.WARNING;
    +
     import com.google.inject.Injector;
     import hudson.model.Hudson;
    -import jenkins.model.Jenkins;
    -import org.jvnet.hudson.annotation_indexer.Index;
    -import org.jvnet.hudson.reactor.Milestone;
    -import org.jvnet.hudson.reactor.MilestoneImpl;
    -import org.jvnet.hudson.reactor.Reactor;
    -import org.jvnet.hudson.reactor.Task;
    -import org.jvnet.hudson.reactor.TaskBuilder;
    -import org.jvnet.localizer.ResourceBundleHolder;
    -
     import java.io.IOException;
     import java.lang.annotation.Annotation;
     import java.lang.reflect.InvocationTargetException;
    @@ -23,8 +16,14 @@
     import java.util.MissingResourceException;
     import java.util.Set;
     import java.util.logging.Logger;
    -
    -import static java.util.logging.Level.WARNING;
    +import jenkins.model.Jenkins;
    +import org.jvnet.hudson.annotation_indexer.Index;
    +import org.jvnet.hudson.reactor.Milestone;
    +import org.jvnet.hudson.reactor.MilestoneImpl;
    +import org.jvnet.hudson.reactor.Reactor;
    +import org.jvnet.hudson.reactor.Task;
    +import org.jvnet.hudson.reactor.TaskBuilder;
    +import org.jvnet.localizer.ResourceBundleHolder;
     
     /**
      * @author Kohsuke Kawaguchi
    @@ -45,19 +44,25 @@ abstract class TaskMethodFinder extends TaskBuilder {
     
         // working around the restriction that Java doesn't allow annotation types to extend interfaces
         protected abstract String displayNameOf(T i);
    +
         protected abstract String[] requiresOf(T i);
    +
         protected abstract String[] attainsOf(T i);
    +
         protected abstract Milestone afterOf(T i);
    +
         protected abstract Milestone beforeOf(T i);
    +
         protected abstract boolean fatalOf(T i);
     
    +    @Override
         public Collection discoverTasks(Reactor session) throws IOException {
             List result = new ArrayList<>();
             for (Method e : Index.list(type, cl, Method.class)) {
                 if (filter(e)) continue;   // already reported once
     
                 T i = e.getAnnotation(type);
    -            if (i==null)        continue; // stale index
    +            if (i == null)        continue; // stale index
     
                 result.add(new TaskImpl(i, e));
             }
    @@ -77,13 +82,13 @@ protected boolean filter(Method e) {
         protected String getDisplayNameOf(Method e, T i) {
             Class c = e.getDeclaringClass();
             String key = displayNameOf(i);
    -        if (key.length()==0)  return c.getSimpleName()+"."+e.getName();
    +        if (key.length() == 0)  return c.getSimpleName() + "." + e.getName();
             try {
                 ResourceBundleHolder rb = ResourceBundleHolder.get(
                         c.getClassLoader().loadClass(c.getPackage().getName() + ".Messages"));
                 return rb.format(key);
             } catch (ClassNotFoundException x) {
    -            LOGGER.log(WARNING, "Failed to load "+x.getMessage()+" for "+e.toString(),x);
    +            LOGGER.log(WARNING, "Failed to load " + x.getMessage() + " for " + e, x);
                 return key;
             } catch (MissingResourceException x) {
                 LOGGER.log(WARNING, "Could not find key '" + key + "' in " + c.getPackage().getName() + ".Messages", x);
    @@ -98,14 +103,14 @@ protected void invoke(Method e) {
             try {
                 Class[] pt = e.getParameterTypes();
                 Object[] args = new Object[pt.length];
    -            for (int i=0; i type) {
             Jenkins j = Jenkins.get();
             assert j != null : "This method is only invoked after the Jenkins singleton instance has been set";
    -        if (type==Jenkins.class || type==Hudson.class)
    +        if (type == Jenkins.class || type == Hudson.class)
                 return j;
             Injector i = j.getInjector();
    -        if (i!=null)
    +        if (i != null)
                 return i.getInstance(type);
    -        throw new IllegalArgumentException("Unable to inject "+type);
    +        throw new IllegalArgumentException("Unable to inject " + type);
         }
     
         /**
    @@ -155,26 +160,32 @@ public Method getMethod() {
                 return e;
             }
     
    +        @Override
             public Collection requires() {
                 return requires;
             }
     
    +        @Override
             public Collection attains() {
                 return attains;
             }
     
    +        @Override
             public String getDisplayName() {
                 return getDisplayNameOf(e, i);
             }
     
    +        @Override
             public boolean failureIsFatal() {
                 return fatalOf(i);
             }
     
    +        @Override
             public void run(Reactor session) {
                 invoke(e);
             }
     
    +        @Override
             public String toString() {
                 return e.toString();
             }
    @@ -183,7 +194,7 @@ private Collection toMilestones(String[] tokens, Milestone m) {
                 List r = new ArrayList<>();
                 for (String s : tokens) {
                     try {
    -                    r.add((Milestone)Enum.valueOf(milestoneType,s));
    +                    r.add((Milestone) Enum.valueOf(milestoneType, s));
                     } catch (IllegalArgumentException x) {
                         r.add(new MilestoneImpl(s));
                     }
    diff --git a/core/src/main/java/hudson/init/TermMilestone.java b/core/src/main/java/hudson/init/TermMilestone.java
    index 85efd8d5eab7..5146e2dbb4eb 100644
    --- a/core/src/main/java/hudson/init/TermMilestone.java
    +++ b/core/src/main/java/hudson/init/TermMilestone.java
    @@ -44,8 +44,8 @@ public enum TermMilestone implements Milestone {
         public static TaskBuilder ordering() {
             TaskGraphBuilder b = new TaskGraphBuilder();
             TermMilestone[] v = values();
    -        for (int i=0; i {
         public TerminatorFinder(ClassLoader cl) {
             super(Terminator.class, TermMilestone.class, cl);
         }
    -    
    +
         @Override
         protected String displayNameOf(Terminator i) {
             return i.displayName();
    diff --git a/core/src/main/java/hudson/init/impl/GroovyInitScript.java b/core/src/main/java/hudson/init/impl/GroovyInitScript.java
    index b0ec56ddf3f8..17f6a4702c94 100644
    --- a/core/src/main/java/hudson/init/impl/GroovyInitScript.java
    +++ b/core/src/main/java/hudson/init/impl/GroovyInitScript.java
    @@ -21,23 +21,23 @@
      * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
      * THE SOFTWARE.
      */
    +
     package hudson.init.impl;
     
    +import static hudson.init.InitMilestone.JOB_CONFIG_ADAPTED;
    +
     import hudson.init.Initializer;
     import jenkins.model.Jenkins;
     import jenkins.util.groovy.GroovyHookScript;
     
    -
    -import static hudson.init.InitMilestone.*;
    -
     /**
      * Run the initialization script, if it exists.
      * It runs strictly after the initialization of other tasks during the last initialization milestone.
    - * 
    + *
      * @author Kohsuke Kawaguchi
      */
     public class GroovyInitScript {
    -    @Initializer(after=JOB_CONFIG_ADAPTED)
    +    @Initializer(after = JOB_CONFIG_ADAPTED)
         public static void init(Jenkins j) {
             new GroovyHookScript("init", j.servletContext, j.getRootDir(), j.getPluginManager().uberClassLoader).run();
         }
    diff --git a/core/src/main/java/hudson/init/impl/InitialUserContent.java b/core/src/main/java/hudson/init/impl/InitialUserContent.java
    index 8124c3b2f1dd..81cc279eb909 100644
    --- a/core/src/main/java/hudson/init/impl/InitialUserContent.java
    +++ b/core/src/main/java/hudson/init/impl/InitialUserContent.java
    @@ -21,28 +21,31 @@
      * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
      * THE SOFTWARE.
      */
    +
     package hudson.init.impl;
     
     import static hudson.init.InitMilestone.JOB_CONFIG_ADAPTED;
    +
    +import hudson.Util;
     import hudson.init.Initializer;
    -import jenkins.model.Jenkins;
     import hudson.model.Messages;
    -import org.apache.commons.io.FileUtils;
    -
     import java.io.File;
     import java.io.IOException;
    +import java.nio.file.Files;
    +import jenkins.model.Jenkins;
    +import org.apache.commons.io.FileUtils;
     
     /**
      * Prepares userContent folder and put a readme if it doesn't exist.
      * @author Kohsuke Kawaguchi
      */
     public class InitialUserContent {
    -    @Initializer(after=JOB_CONFIG_ADAPTED)
    +    @Initializer(after = JOB_CONFIG_ADAPTED)
         public static void init(Jenkins h) throws IOException {
             File userContentDir = new File(h.getRootDir(), "userContent");
    -        if(!userContentDir.exists()) {
    -            userContentDir.mkdirs();
    -            FileUtils.writeStringToFile(new File(userContentDir,"readme.txt"), Messages.Hudson_USER_CONTENT_README() + "\n");
    +        if (!Files.isDirectory(Util.fileToPath(userContentDir))) {
    +            Util.createDirectories(Util.fileToPath(userContentDir));
    +            FileUtils.writeStringToFile(new File(userContentDir, "readme.txt"), Messages.Hudson_USER_CONTENT_README() + "\n");
             }
         }
     }
    diff --git a/core/src/main/java/hudson/init/impl/InstallUncaughtExceptionHandler.java b/core/src/main/java/hudson/init/impl/InstallUncaughtExceptionHandler.java
    index ccce1d159c2f..e09237bef918 100644
    --- a/core/src/main/java/hudson/init/impl/InstallUncaughtExceptionHandler.java
    +++ b/core/src/main/java/hudson/init/impl/InstallUncaughtExceptionHandler.java
    @@ -1,8 +1,16 @@
     package hudson.init.impl;
     
    +import edu.umd.cs.findbugs.annotations.CheckForNull;
     import hudson.init.Initializer;
    +import java.io.EOFException;
    +import java.io.IOException;
    +import java.util.UUID;
    +import java.util.logging.Level;
    +import java.util.logging.Logger;
    +import javax.servlet.ServletException;
    +import javax.servlet.http.HttpServletRequest;
    +import javax.servlet.http.HttpServletResponse;
     import jenkins.model.Jenkins;
    -import jenkins.telemetry.impl.java11.MissingClassTelemetry;
     import org.kohsuke.MetaInfServices;
     import org.kohsuke.accmod.Restricted;
     import org.kohsuke.accmod.restrictions.NoExternalUse;
    @@ -13,16 +21,6 @@
     import org.kohsuke.stapler.WebApp;
     import org.kohsuke.stapler.compression.CompressionFilter;
     
    -import edu.umd.cs.findbugs.annotations.CheckForNull;
    -import javax.servlet.ServletException;
    -import javax.servlet.http.HttpServletRequest;
    -import javax.servlet.http.HttpServletResponse;
    -import java.io.EOFException;
    -import java.io.IOException;
    -import java.util.UUID;
    -import java.util.logging.Level;
    -import java.util.logging.Logger;
    -
     /**
      * Deals with exceptions that get thrown all the way up to the Stapler rendering layer.
      */
    @@ -32,9 +30,7 @@ public class InstallUncaughtExceptionHandler {
     
         @Initializer
         public static void init(final Jenkins j) throws IOException {
    -        CompressionFilter.setUncaughtExceptionHandler(j.servletContext, (e, context, req, rsp) -> {
    -            handleException(j, e, req, rsp, 500);
    -        });
    +        CompressionFilter.setUncaughtExceptionHandler(j.servletContext, (e, context, req, rsp) -> handleException(j, e, req, rsp, 500));
             try {
                 Thread.setDefaultUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler());
                 LOGGER.log(Level.FINE, "Successfully installed a global UncaughtExceptionHandler.");
    @@ -57,13 +53,9 @@ private static void handleException(Jenkins j, Throwable e, HttpServletRequest r
             String id = UUID.randomUUID().toString();
             LOGGER.log(isEOFException(e) ? Level.FINE : Level.WARNING, "Caught unhandled exception with ID " + id, e);
             req.setAttribute("jenkins.exception.id", id);
    -        req.setAttribute("javax.servlet.error.exception",e);
    +        req.setAttribute("javax.servlet.error.exception", e);
             rsp.setStatus(code);
             try {
    -            // If we have an exception, let's see if it's related with missing classes on Java 11. We reach
    -            // here with a ClassNotFoundException in an action, for example. Setting the report here is the only
    -            // way to catch the missing classes when the plugin uses Thread.currentThread().getContextClassLoader().loadClass
    -            MissingClassTelemetry.reportExceptionInside(e);
                 WebApp.get(j.servletContext).getSomeStapler().invoke(req, rsp, j, "/oops");
             } catch (ServletException | IOException x) {
                 if (!Stapler.isSocketException(x)) {
    @@ -82,6 +74,7 @@ public HttpResponses.HttpResponseException handleError(int code, Throwable cause
                     return null;
                 }
                 return new HttpResponses.HttpResponseException(cause) {
    +                @Override
                     public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException {
                         handleException(Jenkins.get(), cause, req, rsp, code);
                     }
    @@ -109,11 +102,6 @@ public void uncaughtException(Thread t, Throwable ex) {
                            "A thread (" + t.getName() + '/' + t.getId()
                                          + ") died unexpectedly due to an uncaught exception, this may leave your Jenkins in a bad way and is usually indicative of a bug in the code.",
                            ex);
    -
    -            // If we have an exception, let's see if it's related with missing classes on Java 11. We reach
    -            // here with a ClassNotFoundException in an action, for example. Setting the report here is the only
    -            // way to catch the missing classes when the plugin uses Thread.currentThread().getContextClassLoader().loadClass
    -            MissingClassTelemetry.reportExceptionInside(ex);
             }
     
         }
    diff --git a/core/src/main/java/hudson/init/package-info.java b/core/src/main/java/hudson/init/package-info.java
    index 57dbab8fd5c8..15a169df8a1d 100644
    --- a/core/src/main/java/hudson/init/package-info.java
    +++ b/core/src/main/java/hudson/init/package-info.java
    @@ -43,4 +43,3 @@
      * 
      */
     package hudson.init;
    -
    diff --git a/core/src/main/java/hudson/lifecycle/ExitLifecycle.java b/core/src/main/java/hudson/lifecycle/ExitLifecycle.java
    index 75bdcf78f734..f8fcc3abefbf 100644
    --- a/core/src/main/java/hudson/lifecycle/ExitLifecycle.java
    +++ b/core/src/main/java/hudson/lifecycle/ExitLifecycle.java
    @@ -21,19 +21,17 @@
      * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
      * THE SOFTWARE.
      */
    +
     package hudson.lifecycle;
     
     import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
     import hudson.Extension;
    -
    -import jenkins.util.SystemProperties;
    -import org.kohsuke.accmod.Restricted;
    -import org.kohsuke.accmod.restrictions.NoExternalUse;
    -
     import java.util.logging.Level;
     import java.util.logging.Logger;
    -
     import jenkins.model.Jenkins;
    +import jenkins.util.SystemProperties;
    +import org.kohsuke.accmod.Restricted;
    +import org.kohsuke.accmod.restrictions.NoExternalUse;
     
     /**
      * {@link Lifecycle} that delegates the responsibility to restart Jenkins to an external
    @@ -68,7 +66,7 @@ public void restart() {
                 if (jenkins != null) {
                     jenkins.cleanUp();
                 }
    -        } catch (Exception e) {
    +        } catch (Throwable e) {
                 LOGGER.log(Level.SEVERE, "Failed to clean up. Restart will continue.", e);
             }
     
    diff --git a/core/src/main/java/hudson/lifecycle/Lifecycle.java b/core/src/main/java/hudson/lifecycle/Lifecycle.java
    index 152f4d457b5c..a44e4c39fb83 100644
    --- a/core/src/main/java/hudson/lifecycle/Lifecycle.java
    +++ b/core/src/main/java/hudson/lifecycle/Lifecycle.java
    @@ -1,18 +1,18 @@
     /*
      * The MIT License
    - * 
    + *
      * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi
    - * 
    + *
      * Permission is hereby granted, free of charge, to any person obtaining a copy
      * of this software and associated documentation files (the "Software"), to deal
      * in the Software without restriction, including without limitation the rights
      * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      * copies of the Software, and to permit persons to whom the Software is
      * furnished to do so, subject to the following conditions:
    - * 
    + *
      * The above copyright notice and this permission notice shall be included in
      * all copies or substantial portions of the Software.
    - * 
    + *
      * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    @@ -21,19 +21,24 @@
      * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
      * THE SOFTWARE.
      */
    +
     package hudson.lifecycle;
     
    +import edu.umd.cs.findbugs.annotations.CheckForNull;
    +import edu.umd.cs.findbugs.annotations.NonNull;
     import hudson.ExtensionPoint;
     import hudson.Functions;
    -import jenkins.util.SystemProperties;
     import hudson.Util;
    -import jenkins.model.Jenkins;
    -
     import java.io.File;
     import java.io.IOException;
    -import java.util.logging.Logger;
    +import java.io.UncheckedIOException;
    +import java.lang.reflect.InvocationTargetException;
    +import java.nio.file.Files;
    +import java.util.concurrent.TimeUnit;
     import java.util.logging.Level;
    -
    +import java.util.logging.Logger;
    +import jenkins.model.Jenkins;
    +import jenkins.util.SystemProperties;
     import org.apache.commons.io.FileUtils;
     
     /**
    @@ -50,19 +55,36 @@
     public abstract class Lifecycle implements ExtensionPoint {
         private static Lifecycle INSTANCE = null;
     
    +    public Lifecycle() {
    +        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
    +            Jenkins jenkins = Jenkins.getInstanceOrNull();
    +            if (jenkins != null) {
    +                try {
    +                    jenkins.cleanUp();
    +                } catch (Throwable t) {
    +                    LOGGER.log(Level.SEVERE, "Failed to clean up. Shutdown will continue.", t);
    +                }
    +            }
    +        }));
    +    }
    +
         /**
          * Gets the singleton instance.
          *
          * @return never null
          */
         public static synchronized Lifecycle get() {
    -        if(INSTANCE==null) {
    +        if (INSTANCE == null) {
                 Lifecycle instance;
                 String p = SystemProperties.getString("hudson.lifecycle");
    -            if(p!=null) {
    +            if (p != null) {
                     try {
                         ClassLoader cl = Jenkins.get().getPluginManager().uberClassLoader;
    -                    instance = (Lifecycle)cl.loadClass(p).newInstance();
    +                    instance = (Lifecycle) cl.loadClass(p).getDeclaredConstructor().newInstance();
    +                } catch (NoSuchMethodException e) {
    +                    NoSuchMethodError x = new NoSuchMethodError(e.getMessage());
    +                    x.initCause(e);
    +                    throw x;
                     } catch (InstantiationException e) {
                         InstantiationError x = new InstantiationError(e.getMessage());
                         x.initCause(e);
    @@ -75,9 +97,22 @@ public static synchronized Lifecycle get() {
                         NoClassDefFoundError x = new NoClassDefFoundError(e.getMessage());
                         x.initCause(e);
                         throw x;
    +                } catch (InvocationTargetException e) {
    +                    Throwable t = e.getCause();
    +                    if (t instanceof RuntimeException) {
    +                        throw (RuntimeException) t;
    +                    } else if (t instanceof IOException) {
    +                        throw new UncheckedIOException((IOException) t);
    +                    } else if (t instanceof Exception) {
    +                        throw new RuntimeException(t);
    +                    } else if (t instanceof Error) {
    +                        throw (Error) t;
    +                    } else {
    +                        throw new Error(e);
    +                    }
                     }
                 } else {
    -                if(Functions.isWindows()) {
    +                if (Functions.isWindows()) {
                         instance = new Lifecycle() {
                             @Override
                             public void verifyRestartable() throws RestartNotSupportedException {
    @@ -85,15 +120,18 @@ public void verifyRestartable() throws RestartNotSupportedException {
                                         "Default Windows lifecycle does not support restart.");
                             }
                         };
    -                } else if (System.getenv("SMF_FMRI")!=null && System.getenv("SMF_RESTARTER")!=null) {
    +                } else if (System.getenv("SMF_FMRI") != null && System.getenv("SMF_RESTARTER") != null) {
                         // when we are run by Solaris SMF, these environment variables are set.
                         instance = new SolarisSMFLifecycle();
    +                } else if (System.getenv("NOTIFY_SOCKET") != null) {
    +                    // When we are running under systemd with Type=notify, this environment variable is set.
    +                    instance = new SystemdLifecycle();
                     } else {
                         // if run on Unix, we can do restart
                         try {
                             instance = new UnixLifecycle();
                         } catch (final IOException e) {
    -                        LOGGER.log(Level.WARNING, "Failed to install embedded lifecycle implementation",e);
    +                        LOGGER.log(Level.WARNING, "Failed to install embedded lifecycle implementation", e);
                             instance = new Lifecycle() {
                                 @Override
                                 public void verifyRestartable() throws RestartNotSupportedException {
    @@ -121,7 +159,7 @@ public void verifyRestartable() throws RestartNotSupportedException {
          */
         public File getHudsonWar() {
             String war = SystemProperties.getString("executable-war");
    -        if(war!=null && new File(war).exists())
    +        if (war != null && new File(war).exists())
                 return new File(war);
             return null;
         }
    @@ -138,7 +176,7 @@ public void rewriteHudsonWar(File by) throws IOException {
             File dest = getHudsonWar();
             // this should be impossible given the canRewriteHudsonWar method,
             // but let's be defensive
    -        if(dest==null)  throw new IOException("jenkins.war location is not known.");
    +        if (dest == null)  throw new IOException("jenkins.war location is not known.");
     
             // backing up the old jenkins.war before it gets lost due to upgrading
             // (newly downloaded jenkins.war and 'backup' (jenkins.war.tmp) are the same files
    @@ -146,11 +184,12 @@ public void rewriteHudsonWar(File by) throws IOException {
             File bak = new File(dest.getPath() + ".bak");
             if (!by.equals(bak))
                 FileUtils.copyFile(dest, bak);
    -       
    +
             FileUtils.copyFile(by, dest);
             // we don't want to keep backup if we are downgrading
    -        if (by.equals(bak)&&bak.exists())
    -            bak.delete();
    +        if (by.equals(bak)) {
    +            Files.deleteIfExists(Util.fileToPath(bak));
    +        }
         }
     
         /**
    @@ -194,7 +233,7 @@ public void restart() throws IOException, InterruptedException {
          */
         public void verifyRestartable() throws RestartNotSupportedException {
             // the rewriteHudsonWar method isn't overridden.
    -        if (!Util.isOverridden(Lifecycle.class,getClass(), "restart"))
    +        if (!Util.isOverridden(Lifecycle.class, getClass(), "restart"))
                 throw new RestartNotSupportedException("Restart is not supported in this running mode (" +
                         getClass().getName() + ").");
         }
    @@ -212,5 +251,74 @@ public boolean canRestart() {
             }
         }
     
    +    /**
    +     * Called when Jenkins startup is finished or when Jenkins has finished reloading its
    +     * configuration.
    +     *
    +     * @since 2.333
    +     */
    +    public void onReady() {
    +        LOGGER.log(Level.INFO, "Jenkins is fully up and running");
    +    }
    +
    +    /**
    +     * Called when Jenkins is reloading its configuration.
    +     *
    +     * 

    Callers must also send an {@link #onReady()} notification when Jenkins has finished + * reloading its configuration. + * + * @since 2.333 + */ + public void onReload(@NonNull String user, @CheckForNull String remoteAddr) { + if (remoteAddr != null) { + LOGGER.log( + Level.INFO, + "Reloading Jenkins as requested by {0} from {1}", + new Object[] {user, remoteAddr}); + } else { + LOGGER.log(Level.INFO, "Reloading Jenkins as requested by {0}", user); + } + } + + /** + * Called when Jenkins is beginning its shutdown. + * + * @since 2.333 + */ + public void onStop(@NonNull String user, @CheckForNull String remoteAddr) { + if (remoteAddr != null) { + LOGGER.log( + Level.INFO, + "Stopping Jenkins as requested by {0} from {1}", + new Object[] {user, remoteAddr}); + } else { + LOGGER.log(Level.INFO, "Stopping Jenkins as requested by {0}", user); + } + } + + /** + * Tell the service manager to extend the startup or shutdown timeout. The value specified is a + * time during which either {@link #onExtendTimeout(long, TimeUnit)} must be called again or + * startup/shutdown must complete. + * + * @param timeout The amount by which to extend the timeout. + * @param unit The time unit of the timeout argument. + * + * @since 2.335 + */ + public void onExtendTimeout(long timeout, @NonNull TimeUnit unit) {} + + /** + * Called when Jenkins service state has changed. + * + * @param status The status string. This is free-form and can be used for various purposes: + * general state feedback, completion percentages, human-readable error message, etc. + * + * @since 2.333 + */ + public void onStatusUpdate(String status) { + LOGGER.log(Level.INFO, status); + } + private static final Logger LOGGER = Logger.getLogger(Lifecycle.class.getName()); } diff --git a/core/src/main/java/hudson/lifecycle/RestartNotSupportedException.java b/core/src/main/java/hudson/lifecycle/RestartNotSupportedException.java index 08bae8291c06..50f87f457044 100644 --- a/core/src/main/java/hudson/lifecycle/RestartNotSupportedException.java +++ b/core/src/main/java/hudson/lifecycle/RestartNotSupportedException.java @@ -2,7 +2,7 @@ /** * Indicates that the {@link Lifecycle} doesn't support restart. - * + * * @author Kohsuke Kawaguchi */ public class RestartNotSupportedException extends Exception { diff --git a/core/src/main/java/hudson/lifecycle/SolarisSMFLifecycle.java b/core/src/main/java/hudson/lifecycle/SolarisSMFLifecycle.java index 755600510778..2dd362936599 100644 --- a/core/src/main/java/hudson/lifecycle/SolarisSMFLifecycle.java +++ b/core/src/main/java/hudson/lifecycle/SolarisSMFLifecycle.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,14 +21,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.lifecycle; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import jenkins.model.Jenkins; - import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; +import jenkins.model.Jenkins; /** * {@link Lifecycle} for Hudson installed as SMF service. @@ -47,7 +47,7 @@ public void restart() throws IOException, InterruptedException { if (jenkins != null) { jenkins.cleanUp(); } - } catch (Exception e) { + } catch (Throwable e) { LOGGER.log(Level.SEVERE, "Failed to clean up. Restart will continue.", e); } System.exit(0); diff --git a/core/src/main/java/hudson/lifecycle/SystemdLifecycle.java b/core/src/main/java/hudson/lifecycle/SystemdLifecycle.java new file mode 100644 index 000000000000..8d6b684cfe41 --- /dev/null +++ b/core/src/main/java/hudson/lifecycle/SystemdLifecycle.java @@ -0,0 +1,67 @@ +package hudson.lifecycle; + +import com.sun.jna.Library; +import com.sun.jna.Native; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; +import hudson.Extension; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; + +/** + * {@link Lifecycle} that delegates its responsibility to {@code systemd(1)}. + * + * @author Basil Crow + */ +@Restricted(NoExternalUse.class) +@Extension(optional = true) +public class SystemdLifecycle extends ExitLifecycle { + + private static final Logger LOGGER = Logger.getLogger(SystemdLifecycle.class.getName()); + + interface Systemd extends Library { + Systemd INSTANCE = Native.load("systemd", Systemd.class); + + int sd_notify(int unset_environment, String state); + } + + @Override + public void onReady() { + super.onReady(); + notify("READY=1"); + } + + @Override + public void onReload(@NonNull String user, @CheckForNull String remoteAddr) { + super.onReload(user, remoteAddr); + notify("RELOADING=1"); + } + + @Override + public void onStop(@NonNull String user, @CheckForNull String remoteAddr) { + super.onStop(user, remoteAddr); + notify("STOPPING=1"); + } + + @Override + public void onExtendTimeout(long timeout, @NonNull TimeUnit unit) { + super.onExtendTimeout(timeout, unit); + notify(String.format("EXTEND_TIMEOUT_USEC=%d", unit.toMicros(timeout))); + } + + @Override + public void onStatusUpdate(String status) { + super.onStatusUpdate(status); + notify(String.format("STATUS=%s", status)); + } + + private static synchronized void notify(String message) { + int rv = Systemd.INSTANCE.sd_notify(0, message); + if (rv < 0) { + LOGGER.log(Level.WARNING, "sd_notify(3) returned {0}", rv); + } + } +} diff --git a/core/src/main/java/hudson/lifecycle/UnixLifecycle.java b/core/src/main/java/hudson/lifecycle/UnixLifecycle.java index a17c898ab365..ca8f50b9f589 100644 --- a/core/src/main/java/hudson/lifecycle/UnixLifecycle.java +++ b/core/src/main/java/hudson/lifecycle/UnixLifecycle.java @@ -21,20 +21,23 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.lifecycle; -import com.sun.akuma.JavaVMArguments; +import static hudson.util.jna.GNUCLibrary.FD_CLOEXEC; +import static hudson.util.jna.GNUCLibrary.F_GETFD; +import static hudson.util.jna.GNUCLibrary.F_SETFD; +import static hudson.util.jna.GNUCLibrary.LIBC; + import com.sun.jna.Native; import com.sun.jna.StringArray; - +import hudson.Platform; import java.io.IOException; +import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; - -import static hudson.util.jna.GNUCLibrary.*; - -import hudson.Platform; import jenkins.model.Jenkins; +import jenkins.util.JavaVMArguments; /** * {@link Lifecycle} implementation when Hudson runs on the embedded @@ -47,17 +50,14 @@ * @since 1.304 */ public class UnixLifecycle extends Lifecycle { - private JavaVMArguments args; + private List args; private Throwable failedToObtainArgs; public UnixLifecycle() throws IOException { try { args = JavaVMArguments.current(); - - // if we are running as daemon, don't fork into background one more time during restart - args.remove("--daemon"); } catch (UnsupportedOperationException | LinkageError e) { - // can't restart / see HUDSON-3875 + // can't restart / see JENKINS-3875 failedToObtainArgs = e; } } @@ -69,22 +69,22 @@ public void restart() throws IOException, InterruptedException { if (jenkins != null) { jenkins.cleanUp(); } - } catch (Exception e) { + } catch (Throwable e) { LOGGER.log(Level.SEVERE, "Failed to clean up. Restart will continue.", e); } // close all files upon exec, except stdin, stdout, and stderr int sz = LIBC.getdtablesize(); - for(int i=3; i' + getHudsonWar().getAbsolutePath() + '\n'); } } @@ -122,7 +125,7 @@ public void restart() throws IOException, InterruptedException { if (jenkins != null) { jenkins.cleanUp(); } - } catch (Exception e) { + } catch (Throwable e) { LOGGER.log(Level.SEVERE, "Failed to clean up. Restart will continue.", e); } @@ -134,20 +137,20 @@ public void restart() throws IOException, InterruptedException { task.getLogger().println("Restarting a service"); String exe = System.getenv("WINSW_EXECUTABLE"); File executable; - if (exe!=null) executable = new File(exe); + if (exe != null) executable = new File(exe); else executable = new File(home, "hudson.exe"); if (!executable.exists()) executable = new File(home, "jenkins.exe"); // use restart! to run hudson/jenkins.exe restart in a separate process, so it doesn't kill itself int r = new LocalLauncher(task).launch().cmds(executable, "restart!") .stdout(task).pwd(home).join(); - if(r!=0) + if (r != 0) throw new IOException(baos.toString()); } - + private static File getBaseDir() { File baseDir; - + String baseEnv = System.getenv("BASE"); if (baseEnv != null) { baseDir = new File(baseEnv); diff --git a/core/src/main/java/hudson/logging/LogRecorder.java b/core/src/main/java/hudson/logging/LogRecorder.java index fa6481745a0e..929274a2fd41 100644 --- a/core/src/main/java/hudson/logging/LogRecorder.java +++ b/core/src/main/java/hudson/logging/LogRecorder.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,44 +21,67 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.logging; import com.google.common.annotations.VisibleForTesting; import com.thoughtworks.xstream.XStream; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.BulkChange; import hudson.Extension; import hudson.FilePath; +import hudson.RestrictedSince; import hudson.Util; import hudson.XmlFile; -import hudson.model.*; -import hudson.util.HttpResponses; -import jenkins.util.MemoryReductionUtil; -import jenkins.model.Jenkins; +import hudson.model.AbstractModelObject; +import hudson.model.AutoCompletionCandidates; +import hudson.model.Computer; +import hudson.model.Saveable; +import hudson.model.TaskListener; import hudson.model.listeners.SaveableListener; import hudson.remoting.Channel; import hudson.remoting.VirtualChannel; import hudson.slaves.ComputerListener; import hudson.util.CopyOnWriteList; +import hudson.util.HttpResponses; import hudson.util.RingBufferLogHandler; import hudson.util.XStream2; -import jenkins.security.MasterToSlaveCallable; -import net.sf.json.JSONObject; -import org.apache.commons.lang.StringUtils; -import org.kohsuke.stapler.*; -import org.kohsuke.stapler.interceptor.RequirePOST; - -import javax.servlet.ServletException; import java.io.File; import java.io.IOException; import java.io.Serializable; import java.text.Collator; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeMap; +import java.util.TreeSet; import java.util.logging.Level; import java.util.logging.LogManager; import java.util.logging.LogRecord; import java.util.logging.Logger; +import javax.servlet.ServletException; +import jenkins.model.Jenkins; +import jenkins.security.MasterToSlaveCallable; +import jenkins.util.MemoryReductionUtil; +import net.sf.json.JSONObject; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.HttpResponse; +import org.kohsuke.stapler.QueryParameter; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.interceptor.RequirePOST; import org.kohsuke.stapler.verb.POST; /** @@ -67,7 +90,7 @@ * * TODO: still a work in progress. * - *

    Access Control

    + *

    Access Control: * {@link LogRecorder} is only visible for administrators and system readers, and this access control happens at * {@link jenkins.model.Jenkins#getLog()}, the sole entry point for binding {@link LogRecorder} to URL. * @@ -77,13 +100,54 @@ public class LogRecorder extends AbstractModelObject implements Saveable { private volatile String name; - public final CopyOnWriteList targets = new CopyOnWriteList<>(); + /** + * No longer used. + * + * @deprecated use {@link #getLoggers()} + */ + @Deprecated + @Restricted(NoExternalUse.class) + @RestrictedSince("2.324") + public final transient CopyOnWriteList targets = new CopyOnWriteList<>(); + private List loggers = new ArrayList<>(); private static final TargetComparator TARGET_COMPARATOR = new TargetComparator(); - + + @DataBoundConstructor + public LogRecorder(String name) { + this.name = name; + // register it only once when constructed, and when this object dies + // WeakLogHandler will remove it + new WeakLogHandler(handler, Logger.getLogger("")); + } + + private Object readResolve() { + if (loggers == null) { + loggers = new ArrayList<>(); + } + + List tempLoggers = new ArrayList<>(loggers); + + if (!targets.isEmpty()) { + loggers.addAll(targets.getView()); + } + if (!tempLoggers.isEmpty() && !targets.getView().equals(tempLoggers)) { + targets.addAll(tempLoggers); + } + return this; + } + + public List getLoggers() { + return loggers; + } + + public void setLoggers(List loggers) { + this.loggers = loggers; + } + @Restricted(NoExternalUse.class) Target[] orderedTargets() { // will contain targets ordered by reverse name length (place specific targets at the beginning) - Target[] ts = targets.toArray(new Target[]{}); + Target[] ts = loggers.toArray(new Target[]{}); Arrays.sort(ts, TARGET_COMPARATOR); @@ -106,7 +170,7 @@ public static Set getAutoCompletionCandidates(List loggerNamesLi String longerPrefix = null; for (int i = loggerNameParts.length; i > 0; i--) { - String loggerNamePrefix = StringUtils.join(Arrays.copyOf(loggerNameParts, i), "."); + String loggerNamePrefix = String.join(".", Arrays.copyOf(loggerNameParts, i)); seenPrefixes.put(loggerNamePrefix, seenPrefixes.getOrDefault(loggerNamePrefix, 0) + 1); if (longerPrefix == null) { relevantPrefixes.add(loggerNamePrefix); // actual logger name @@ -179,7 +243,7 @@ public static final class Target { private transient /* almost final*/ Logger logger; public Target(String name, Level level) { - this(name,level.intValue()); + this(name, level.intValue()); } public Target(String name, int level) { @@ -189,7 +253,7 @@ public Target(String name, int level) { @DataBoundConstructor public Target(String name, String level) { - this(name,Level.parse(level)); + this(name, Level.parse(level)); } public Level getLevel() { @@ -200,30 +264,48 @@ public String getName() { return name; } + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Target target = (Target) o; + return level == target.level && Objects.equals(name, target.name); + } + + @Override + public int hashCode() { + return Objects.hash(name, level); + } + @Deprecated public boolean includes(LogRecord r) { - if(r.getLevel().intValue() < level) + if (r.getLevel().intValue() < level) return false; // below the threshold if (name.length() == 0) { return true; // like root logger, includes everything } String logName = r.getLoggerName(); - if(logName==null || !logName.startsWith(name)) + if (logName == null || !logName.startsWith(name)) return false; // not within this logger String rest = logName.substring(name.length()); - return rest.startsWith(".") || rest.length()==0; + return rest.startsWith(".") || rest.length() == 0; } + @SuppressFBWarnings(value = "NP_BOOLEAN_RETURN_NULL", justification = "converting this to YesNoMaybe would break backward compatibility") public Boolean matches(LogRecord r) { boolean levelSufficient = r.getLevel().intValue() >= level; if (name.length() == 0) { return levelSufficient; // include if level matches } String logName = r.getLoggerName(); - if(logName==null || !logName.startsWith(name)) + if (logName == null || !logName.startsWith(name)) return null; // not in the domain of this logger String rest = logName.substring(name.length()); - if (rest.startsWith(".") || rest.length()==0) { + if (rest.startsWith(".") || rest.length() == 0) { return levelSufficient; // include if level matches } return null; @@ -241,7 +323,7 @@ public Logger getLogger() { */ public void enable() { Logger l = getLogger(); - if(!l.isLoggable(getLevel())) + if (!l.isLoggable(getLevel())) l.setLevel(getLevel()); new SetLevel(name, getLevel()).broadcast(); } @@ -252,7 +334,7 @@ public void disable() { } } - + private static class TargetComparator implements Comparator, Serializable { private static final long serialVersionUID = 9285340752515798L; @@ -263,21 +345,24 @@ public int compare(Target left, Target right) { } } - private static final class SetLevel extends MasterToSlaveCallable { + private static final class SetLevel extends MasterToSlaveCallable { /** known loggers (kept per agent), to avoid GC */ @SuppressWarnings("MismatchedQueryAndUpdateOfCollection") private static final Set loggers = new HashSet<>(); private final String name; private final Level level; + SetLevel(String name, Level level) { this.name = name; this.level = level; } + @Override public Void call() throws Error { Logger logger = Logger.getLogger(name); loggers.add(logger); logger.setLevel(level); return null; } + void broadcast() { for (Computer c : Jenkins.get().getComputers()) { if (c.getName().length() > 0) { // i.e. not master @@ -296,25 +381,20 @@ void broadcast() { @Extension @Restricted(NoExternalUse.class) public static final class ComputerLogInitializer extends ComputerListener { @Override public void preOnline(Computer c, Channel channel, FilePath root, TaskListener listener) throws IOException, InterruptedException { - for (LogRecorder recorder : Jenkins.get().getLog().logRecorders.values()) { - for (Target t : recorder.targets) { + for (LogRecorder recorder : Jenkins.get().getLog().getRecorders()) { + for (Target t : recorder.getLoggers()) { channel.call(new SetLevel(t.name, t.getLevel())); } } } } - public LogRecorder(String name) { - this.name = name; - // register it only once when constructed, and when this object dies - // WeakLogHandler will remove it - new WeakLogHandler(handler,Logger.getLogger("")); - } - + @Override public String getDisplayName() { return name; } + @Override public String getSearchUrl() { return Util.rawEncode(name); } @@ -331,30 +411,30 @@ public LogRecorderManager getParent() { * Accepts submission from the configuration page. */ @POST - public synchronized void doConfigSubmit( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException { + public synchronized void doConfigSubmit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); JSONObject src = req.getSubmittedForm(); String newName = src.getString("name"), redirect = "."; XmlFile oldFile = null; - if(!name.equals(newName)) { + if (!name.equals(newName)) { Jenkins.checkGoodName(newName); oldFile = getConfigFile(); // rename - getParent().logRecorders.remove(name); + List recorders = getParent().getRecorders(); + recorders.remove(new LogRecorder(name)); this.name = newName; - getParent().logRecorders.put(name,this); + recorders.add(this); + getParent().setRecorders(recorders); // ensure that legacy logRecorders field is synced on save redirect = "../" + Util.rawEncode(newName) + '/'; } - List newTargets = req.bindJSONToList(Target.class, src.get("targets")); - for (Target t : newTargets) - t.enable(); - targets.replaceBy(newTargets); + List newTargets = req.bindJSONToList(Target.class, src.get("loggers")); + setLoggers(newTargets); save(); - if (oldFile!=null) oldFile.delete(); + if (oldFile != null) oldFile.delete(); rsp.sendRedirect2(redirect); } @@ -371,19 +451,58 @@ public HttpResponse doClear() throws IOException { */ public synchronized void load() throws IOException { getConfigFile().unmarshal(this); - for (Target t : targets) - t.enable(); + loggers.forEach(Target::enable); } /** * Save the settings to a file. */ + @Override public synchronized void save() throws IOException { - if(BulkChange.contains(this)) return; + if (BulkChange.contains(this)) return; + + handlePluginUpdatingLegacyLogManagerMap(); getConfigFile().write(this); + loggers.forEach(Target::enable); + SaveableListener.fireOnChange(this, getConfigFile()); } + @SuppressWarnings("deprecation") // this is for compatibility + private void handlePluginUpdatingLegacyLogManagerMap() { + if (getParent().logRecorders.size() > getParent().getRecorders().size()) { + for (LogRecorder logRecorder : getParent().logRecorders.values()) { + if (!getParent().getRecorders().contains(logRecorder)) { + getParent().getRecorders().add(logRecorder); + } + } + } + if (getParent().getRecorders().size() > getParent().logRecorders.size()) { + for (LogRecorder logRecorder : getParent().getRecorders()) { + if (!getParent().logRecorders.containsKey(logRecorder.getName())) { + getParent().logRecorders.put(logRecorder.getName(), logRecorder); + } + } + } + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + LogRecorder that = (LogRecorder) o; + return name.equals(that.name); + } + + @Override + public int hashCode() { + return Objects.hash(name); + } + /** * Deletes this recorder, then go back to the parent. */ @@ -392,22 +511,20 @@ public synchronized void doDoDelete(StaplerResponse rsp) throws IOException, Ser Jenkins.get().checkPermission(Jenkins.ADMINISTER); getConfigFile().delete(); - getParent().logRecorders.remove(name); + getParent().getRecorders().remove(new LogRecorder(name)); // Disable logging for all our targets, // then reenable all other loggers in case any also log the same targets - for (Target t : targets) - t.disable(); - for (LogRecorder log : getParent().logRecorders.values()) - for (Target t : log.targets) - t.enable(); + loggers.forEach(Target::disable); + + getParent().getRecorders().forEach(logRecorder -> logRecorder.getLoggers().forEach(Target::enable)); rsp.sendRedirect2(".."); } /** * RSS feed for log entries. */ - public void doRss( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException { - LogRecorderManager.doRss(req,rsp,getLogRecords()); + public void doRss(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + LogRecorderManager.doRss(req, rsp, getLogRecords()); } /** @@ -429,10 +546,11 @@ public List getLogRecords() { * @return a map (sorted by display name) from computer to (nonempty) list of log records * @since 1.519 */ - public Map> getSlaveLogRecords() { - Map> result = new TreeMap<>(new Comparator() { + public Map> getSlaveLogRecords() { + Map> result = new TreeMap<>(new Comparator() { final Collator COLL = Collator.getInstance(); + @Override public int compare(Computer c1, Computer c2) { return COLL.compare(c1.getDisplayName(), c2.getDisplayName()); } @@ -444,7 +562,7 @@ public int compare(Computer c1, Computer c2) { List recs = new ArrayList<>(); try { for (LogRecord rec : c.getLogRecords()) { - for (Target t : targets) { + for (Target t : loggers) { if (t.includes(rec)) { recs.add(rec); break; @@ -467,8 +585,8 @@ public int compare(Computer c1, Computer c2) { public static final XStream XSTREAM = new XStream2(); static { - XSTREAM.alias("log",LogRecorder.class); - XSTREAM.alias("target",Target.class); + XSTREAM.alias("log", LogRecorder.class); + XSTREAM.alias("target", Target.class); } /** diff --git a/core/src/main/java/hudson/logging/LogRecorderManager.java b/core/src/main/java/hudson/logging/LogRecorderManager.java index c34d0d0a9367..045ae3b07cc7 100644 --- a/core/src/main/java/hudson/logging/LogRecorderManager.java +++ b/core/src/main/java/hudson/logging/LogRecorderManager.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,44 +21,54 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.logging; +import static hudson.init.InitMilestone.PLUGINS_PREPARED; +import static java.util.stream.Collectors.toMap; + import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.FeedAdapter; import hudson.Functions; +import hudson.RestrictedSince; import hudson.init.Initializer; -import static hudson.init.InitMilestone.PLUGINS_PREPARED; import hudson.model.AbstractModelObject; -import jenkins.model.Jenkins; +import hudson.model.Failure; import hudson.model.RSS; import hudson.util.CopyOnWriteMap; -import jenkins.model.JenkinsLocationConfiguration; -import jenkins.model.ModelObjectWithChildren; -import jenkins.model.ModelObjectWithContextMenu.ContextMenu; -import org.apache.commons.io.filefilter.WildcardFileFilter; -import org.kohsuke.accmod.Restricted; -import org.kohsuke.accmod.restrictions.NoExternalUse; -import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerProxy; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; -import org.kohsuke.stapler.HttpResponse; -import org.kohsuke.stapler.HttpRedirect; -import org.kohsuke.stapler.interceptor.RequirePOST; - -import javax.servlet.ServletException; import java.io.File; import java.io.FileFilter; import java.io.IOException; import java.util.ArrayList; import java.util.Calendar; +import java.util.Collections; import java.util.GregorianCalendar; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.function.Function; import java.util.logging.Level; +import java.util.logging.LogManager; import java.util.logging.LogRecord; import java.util.logging.Logger; +import javax.servlet.ServletException; +import jenkins.model.Jenkins; +import jenkins.model.JenkinsLocationConfiguration; +import jenkins.model.ModelObjectWithChildren; +import jenkins.model.ModelObjectWithContextMenu.ContextMenu; +import jenkins.util.SystemProperties; +import org.apache.commons.io.filefilter.WildcardFileFilter; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.DataBoundSetter; +import org.kohsuke.stapler.HttpRedirect; +import org.kohsuke.stapler.HttpResponse; +import org.kohsuke.stapler.QueryParameter; +import org.kohsuke.stapler.StaplerProxy; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.interceptor.RequirePOST; /** * Owner of {@link LogRecorder}s, bound to "/log". @@ -67,14 +77,41 @@ */ public class LogRecorderManager extends AbstractModelObject implements ModelObjectWithChildren, StaplerProxy { /** - * {@link LogRecorder}s keyed by their {@linkplain LogRecorder#name name}. + * {@link LogRecorder}s keyed by their {@linkplain LogRecorder#getName()} name}. + * + * @deprecated use {@link #getRecorders()} instead */ - public final transient Map logRecorders = new CopyOnWriteMap.Tree<>(); + @Deprecated + @Restricted(NoExternalUse.class) + @RestrictedSince("2.323") + public final transient Map logRecorders = new CopyOnWriteMap.Tree<>(); + private List recorders; + + @DataBoundConstructor + public LogRecorderManager() { + this.recorders = new ArrayList<>(); + } + + public List getRecorders() { + return recorders; + } + + @DataBoundSetter + public void setRecorders(List recorders) { + this.recorders = recorders; + + Map values = recorders.stream() + .collect(toMap(LogRecorder::getName, Function.identity())); + ((CopyOnWriteMap) logRecorders).replaceBy(values); + } + + @Override public String getDisplayName() { return Messages.LogRecorderManager_DisplayName(); } + @Override public String getSearchUrl() { return "/log"; } @@ -84,7 +121,7 @@ public LogRecorder getDynamic(String token) { } public LogRecorder getLogRecorder(String token) { - return logRecorders.get(token); + return recorders.stream().filter(logRecorder -> logRecorder.getName().equals(token)).findAny().orElse(null); } static File configDir() { @@ -95,17 +132,18 @@ static File configDir() { * Loads the configuration from disk. */ public void load() throws IOException { - logRecorders.clear(); + recorders.clear(); File dir = configDir(); - File[] files = dir.listFiles((FileFilter)new WildcardFileFilter("*.xml")); - if(files==null) return; + File[] files = dir.listFiles((FileFilter) new WildcardFileFilter("*.xml")); + if (files == null) return; for (File child : files) { String name = child.getName(); - name = name.substring(0,name.length()-4); // cut off ".xml" + name = name.substring(0, name.length() - 4); // cut off ".xml" LogRecorder lr = new LogRecorder(name); lr.load(); - logRecorders.put(name,lr); + recorders.add(lr); } + setRecorders(recorders); // ensure that legacy logRecorders field is synced on load } /** @@ -116,17 +154,18 @@ public HttpResponse doNewLogRecorder(@QueryParameter String name) { Jenkins.get().checkPermission(Jenkins.ADMINISTER); Jenkins.checkGoodName(name); - - logRecorders.put(name,new LogRecorder(name)); + + recorders.add(new LogRecorder(name)); // redirect to the config screen - return new HttpRedirect(name+"/configure"); + return new HttpRedirect(name + "/configure"); } + @Override public ContextMenu doChildrenContextMenu(StaplerRequest request, StaplerResponse response) throws Exception { ContextMenu menu = new ContextMenu(); - menu.add("all","All Jenkins Logs"); - for (LogRecorder lr : logRecorders.values()) { + menu.add("all", "All Jenkins Logs"); + for (LogRecorder lr : recorders) { menu.add(lr.getSearchUrl(), lr.getDisplayName()); } return menu; @@ -135,23 +174,32 @@ public ContextMenu doChildrenContextMenu(StaplerRequest request, StaplerResponse /** * Configure the logging level. */ - @edu.umd.cs.findbugs.annotations.SuppressFBWarnings("LG_LOST_LOGGER_DUE_TO_WEAK_REFERENCE") @RequirePOST + @SuppressFBWarnings( + value = "LG_LOST_LOGGER_DUE_TO_WEAK_REFERENCE", + justification = + "if the logger is known, then we have a reference to it in LogRecorder#loggers") public HttpResponse doConfigLogger(@QueryParameter String name, @QueryParameter String level) { Jenkins.get().checkPermission(Jenkins.ADMINISTER); Level lv; - if(level.equals("inherit")) + if (level.equals("inherit")) lv = null; else lv = Level.parse(level.toUpperCase(Locale.ENGLISH)); - Logger.getLogger(name).setLevel(lv); - return new HttpRedirect("levels"); + Logger target; + if (Collections.list(LogManager.getLogManager().getLoggerNames()).contains(name) + && (target = Logger.getLogger(name)) != null) { + target.setLevel(lv); + return new HttpRedirect("levels"); + } else { + throw new Failure(Messages.LogRecorderManager_LoggerNotFound(name)); + } } /** * RSS feed for log entries. */ - public void doRss( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException { + public void doRss(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { doRss(req, rsp, Jenkins.logRecords); } @@ -162,47 +210,53 @@ public void doRss( StaplerRequest req, StaplerResponse rsp ) throws IOException, // filter log records based on the log level String entryType = "all"; String level = req.getParameter("level"); - if(level!=null) { + if (level != null) { Level threshold = Level.parse(level); List filtered = new ArrayList<>(); for (LogRecord r : logs) { - if(r.getLevel().intValue() >= threshold.intValue()) + if (r.getLevel().intValue() >= threshold.intValue()) filtered.add(r); } logs = filtered; entryType = level; } - RSS.forwardToRss("Jenkins:log (" + entryType + " entries)","", logs, new FeedAdapter() { + RSS.forwardToRss("Jenkins:log (" + entryType + " entries)", "", logs, new FeedAdapter() { + @Override public String getEntryTitle(LogRecord entry) { return entry.getMessage(); } + @Override public String getEntryUrl(LogRecord entry) { return "log"; // TODO: one URL for one log entry? } + @Override public String getEntryID(LogRecord entry) { return String.valueOf(entry.getSequenceNumber()); } + @Override public String getEntryDescription(LogRecord entry) { return Functions.printLogRecord(entry); } + @Override public Calendar getEntryTimestamp(LogRecord entry) { GregorianCalendar cal = new GregorianCalendar(); cal.setTimeInMillis(entry.getMillis()); return cal; } + @Override public String getEntryAuthor(LogRecord entry) { return JenkinsLocationConfiguration.get().getAdminAddress(); } - },req,rsp); + }, req, rsp); } - @Initializer(before=PLUGINS_PREPARED) + @Initializer(before = PLUGINS_PREPARED) public static void init(Jenkins h) throws IOException { h.getLog().load(); } @@ -220,6 +274,6 @@ public Object getTarget() { * Escape hatch for StaplerProxy-based access control */ @Restricted(NoExternalUse.class) - @SuppressFBWarnings("MS_SHOULD_BE_FINAL") - public static /* Script Console modifiable */ boolean SKIP_PERMISSION_CHECK = Boolean.getBoolean(LogRecorderManager.class.getName() + ".skipPermissionCheck"); + @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "for script console") + public static /* Script Console modifiable */ boolean SKIP_PERMISSION_CHECK = SystemProperties.getBoolean(LogRecorderManager.class.getName() + ".skipPermissionCheck"); } diff --git a/core/src/main/java/hudson/logging/WeakLogHandler.java b/core/src/main/java/hudson/logging/WeakLogHandler.java index 9a51f279de28..bc0cb1c349a4 100644 --- a/core/src/main/java/hudson/logging/WeakLogHandler.java +++ b/core/src/main/java/hudson/logging/WeakLogHandler.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.logging; import java.io.UnsupportedEncodingException; @@ -47,27 +48,30 @@ public WeakLogHandler(Handler target, Logger logger) { this.target = new WeakReference<>(target); } + @Override public void publish(LogRecord record) { Handler t = resolve(); - if(t!=null) + if (t != null) t.publish(record); } + @Override public void flush() { Handler t = resolve(); - if(t!=null) + if (t != null) t.flush(); } + @Override public void close() throws SecurityException { Handler t = resolve(); - if(t!=null) + if (t != null) t.close(); } private Handler resolve() { Handler r = target.get(); - if(r==null) + if (r == null) logger.removeHandler(this); return r; } @@ -76,7 +80,7 @@ private Handler resolve() { public void setFormatter(Formatter newFormatter) throws SecurityException { super.setFormatter(newFormatter); Handler t = resolve(); - if(t!=null) + if (t != null) t.setFormatter(newFormatter); } @@ -84,7 +88,7 @@ public void setFormatter(Formatter newFormatter) throws SecurityException { public void setEncoding(String encoding) throws SecurityException, UnsupportedEncodingException { super.setEncoding(encoding); Handler t = resolve(); - if(t!=null) + if (t != null) t.setEncoding(encoding); } @@ -92,7 +96,7 @@ public void setEncoding(String encoding) throws SecurityException, UnsupportedEn public void setFilter(Filter newFilter) throws SecurityException { super.setFilter(newFilter); Handler t = resolve(); - if(t!=null) + if (t != null) t.setFilter(newFilter); } @@ -100,7 +104,7 @@ public void setFilter(Filter newFilter) throws SecurityException { public void setErrorManager(ErrorManager em) { super.setErrorManager(em); Handler t = resolve(); - if(t!=null) + if (t != null) t.setErrorManager(em); } @@ -108,14 +112,14 @@ public void setErrorManager(ErrorManager em) { public void setLevel(Level newLevel) throws SecurityException { super.setLevel(newLevel); Handler t = resolve(); - if(t!=null) + if (t != null) t.setLevel(newLevel); } @Override public boolean isLoggable(LogRecord record) { Handler t = resolve(); - if(t!=null) + if (t != null) return t.isLoggable(record); else return super.isLoggable(record); diff --git a/core/src/main/java/hudson/markup/EscapedMarkupFormatter.java b/core/src/main/java/hudson/markup/EscapedMarkupFormatter.java index 664107f28f91..de83afabce6c 100644 --- a/core/src/main/java/hudson/markup/EscapedMarkupFormatter.java +++ b/core/src/main/java/hudson/markup/EscapedMarkupFormatter.java @@ -21,13 +21,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.markup; import hudson.Extension; import hudson.Util; import java.io.IOException; import java.io.Writer; - import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; diff --git a/core/src/main/java/hudson/markup/MarkupFormatter.java b/core/src/main/java/hudson/markup/MarkupFormatter.java index a64bb97ae656..e588e0cfcc8e 100644 --- a/core/src/main/java/hudson/markup/MarkupFormatter.java +++ b/core/src/main/java/hudson/markup/MarkupFormatter.java @@ -21,16 +21,17 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.markup; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.ExtensionPoint; import hudson.model.AbstractDescribableImpl; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.io.Writer; -import edu.umd.cs.findbugs.annotations.CheckForNull; -import edu.umd.cs.findbugs.annotations.NonNull; import java.util.Collections; import java.util.Map; import java.util.function.Function; @@ -38,7 +39,6 @@ import java.util.logging.Logger; import java.util.stream.Collectors; import java.util.stream.Stream; - import jenkins.util.SystemProperties; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; @@ -63,7 +63,7 @@ * Implement the following methods to enable and control CodeMirror syntax highlighting * public String getCodeMirrorMode() // return null to disable CodeMirror dynamically * public String getCodeMirrorConfig() - * + * *

    Views

    *

    * This extension point must have a valid {@code config.jelly} that feeds the constructor. @@ -93,7 +93,7 @@ public abstract class MarkupFormatter extends AbstractDescribableImpl all() { + public static DescriptorExtensionList all() { return Jenkins.get(). getDescriptorList(MarkupFormatter.class); } diff --git a/core/src/main/java/hudson/model/AbstractBuild.java b/core/src/main/java/hudson/model/AbstractBuild.java index 111384e7051d..4c02e525904d 100644 --- a/core/src/main/java/hudson/model/AbstractBuild.java +++ b/core/src/main/java/hudson/model/AbstractBuild.java @@ -21,18 +21,19 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSortedSet; +import static java.util.logging.Level.WARNING; + +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.AbortException; import hudson.EnvVars; import hudson.FilePath; import hudson.Functions; import hudson.Launcher; import hudson.Util; -import jenkins.scm.RunWithSCM; -import jenkins.util.SystemProperties; import hudson.console.ModelHyperlinkNote; import hudson.model.Fingerprint.BuildPtr; import hudson.model.Fingerprint.RangeSet; @@ -43,14 +44,13 @@ import hudson.remoting.RequestAbortedException; import hudson.scm.ChangeLogParser; import hudson.scm.ChangeLogSet; -import hudson.scm.ChangeLogSet.Entry; import hudson.scm.NullChangeLogParser; import hudson.scm.SCM; import hudson.scm.SCMRevisionState; import hudson.slaves.NodeProperty; +import hudson.slaves.OfflineCause; import hudson.slaves.WorkspaceList; import hudson.slaves.WorkspaceList.Lease; -import hudson.slaves.OfflineCause; import hudson.tasks.BuildStep; import hudson.tasks.BuildStepMonitor; import hudson.tasks.BuildTrigger; @@ -58,20 +58,15 @@ import hudson.tasks.Builder; import hudson.tasks.Fingerprinter.FingerprintAction; import hudson.tasks.Publisher; -import hudson.util.*; -import jenkins.model.Jenkins; -import org.kohsuke.stapler.HttpResponse; -import org.kohsuke.stapler.Stapler; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; -import org.kohsuke.stapler.export.Exported; -import org.xml.sax.SAXException; - -import javax.servlet.ServletException; +import hudson.util.AdaptedIterator; +import hudson.util.HttpResponses; +import hudson.util.Iterators; +import hudson.util.VariableResolver; import java.io.File; import java.io.IOException; import java.io.InterruptedIOException; import java.lang.ref.WeakReference; +import java.nio.channels.ClosedByInterruptException; import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; @@ -82,16 +77,23 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; import java.util.logging.Level; import java.util.logging.Logger; -import edu.umd.cs.findbugs.annotations.CheckForNull; -import edu.umd.cs.findbugs.annotations.NonNull; -import org.kohsuke.stapler.interceptor.RequirePOST; - -import static java.util.logging.Level.WARNING; - +import javax.servlet.ServletException; +import jenkins.model.Jenkins; import jenkins.model.lazy.BuildReference; import jenkins.model.lazy.LazyBuildMixIn; +import jenkins.scm.RunWithSCM; +import jenkins.util.SystemProperties; +import org.kohsuke.stapler.HttpResponse; +import org.kohsuke.stapler.Stapler; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.export.Exported; +import org.kohsuke.stapler.interceptor.RequirePOST; +import org.xml.sax.SAXException; /** * Base implementation of {@link Run}s that build software. @@ -101,7 +103,7 @@ * @author Kohsuke Kawaguchi * @see AbstractProject */ -public abstract class AbstractBuild

    ,R extends AbstractBuild> extends Run implements Queue.Executable, LazyBuildMixIn.LazyLoadingRun, RunWithSCM { +public abstract class AbstractBuild

    , R extends AbstractBuild> extends Run implements Queue.Executable, LazyBuildMixIn.LazyLoadingRun, RunWithSCM { /** * Set if we want the blame information to flow from upstream to downstream build. @@ -110,7 +112,7 @@ public abstract class AbstractBuild

    ,R extends Abs /** * Name of the agent this project was built on. - * Null or "" if built by the master. (null happens when we read old record that didn't have this information.) + * Null or "" if built by the built-in node. (null happens when we read old record that didn't have this information.) */ private String builtOn; @@ -133,7 +135,7 @@ public abstract class AbstractBuild

    ,R extends Abs /** * Changes in this build. */ - private transient volatile WeakReference> changeSet; + private transient volatile WeakReference> changeSet; /** * Cumulative list of people who contributed to the build problem. @@ -156,7 +158,7 @@ public abstract class AbstractBuild

    ,R extends Abs */ protected transient List buildEnvironments; - private final transient LazyBuildMixIn.RunMixIn runMixIn = new LazyBuildMixIn.RunMixIn() { + private final transient LazyBuildMixIn.RunMixIn runMixIn = new LazyBuildMixIn.RunMixIn() { @Override protected R asRun() { return _this(); } @@ -178,7 +180,7 @@ public final P getProject() { return getParent(); } - @Override public final LazyBuildMixIn.RunMixIn getRunMixIn() { + @Override public final LazyBuildMixIn.RunMixIn getRunMixIn() { return runMixIn; } @@ -207,17 +209,17 @@ public R getNextBuild() { * null, for example if the agent that this build run no longer exists. */ public @CheckForNull Node getBuiltOn() { - if (builtOn==null || builtOn.equals("")) + if (builtOn == null || builtOn.equals("")) return Jenkins.get(); else return Jenkins.get().getNode(builtOn); } /** - * Returns the name of the agent it was built on; null or "" if built by the master. + * Returns the name of the agent it was built on; null or "" if built by the built-in node. * (null happens when we read old record that didn't have this information.) */ - @Exported(name="builtOn") + @Exported(name = "builtOn") public String getBuiltOnStr() { return builtOn; } @@ -229,7 +231,7 @@ public String getBuiltOnStr() { * * @since 1.429 */ - protected void setBuiltOnStr( String builtOn ) { + protected void setBuiltOnStr(String builtOn) { this.builtOn = builtOn; } @@ -247,10 +249,16 @@ protected void setBuiltOnStr( String builtOn ) { * @since 1.421 * @see AbstractProject#getRootProject() */ - public AbstractBuild getRootBuild() { + public AbstractBuild getRootBuild() { return this; } + @Override + public Queue.Executable getParentExecutable() { + AbstractBuild rootBuild = getRootBuild(); + return rootBuild != this ? rootBuild : null; + } + /** * Used to render the side panel "Back to project" link. * @@ -264,7 +272,7 @@ public AbstractBuild getRootBuild() { * {@link #getDisplayName()}. */ public String getUpUrl() { - return Functions.getNearestAncestorUrl(Stapler.getCurrentRequest(),getParent())+'/'; + return Functions.getNearestAncestorUrl(Stapler.getCurrentRequest(), getParent()) + '/'; } /** @@ -281,9 +289,9 @@ public String getUpUrl() { * @since 1.319 */ public final @CheckForNull FilePath getWorkspace() { - if (workspace==null) return null; + if (workspace == null) return null; Node n = getBuiltOn(); - if (n==null) return null; + if (n == null) return null; return n.createPath(workspace); } @@ -303,7 +311,7 @@ protected void setWorkspace(@NonNull FilePath ws) { */ public final FilePath getModuleRoot() { FilePath ws = getWorkspace(); - if (ws==null) return null; + if (ws == null) return null; return getParent().getScm().getModuleRoot(ws, this); } @@ -316,7 +324,7 @@ public final FilePath getModuleRoot() { */ public FilePath[] getModuleRoots() { FilePath ws = getWorkspace(); - if (ws==null) return null; + if (ws == null) return null; return getParent().getScm().getModuleRoots(ws, this); } @@ -341,7 +349,7 @@ public boolean shouldCalculateCulprits() { public Set calculateCulprits() { Set c = RunWithSCM.super.calculateCulprits(); - AbstractBuild p = getPreviousCompletedBuild(); + AbstractBuild p = getPreviousCompletedBuild(); if (upstreamCulprits) { // If we have dependencies since the last successful build, add their authors to our list if (p != null && p.getPreviousNotFailedBuild() != null) { @@ -452,10 +460,11 @@ protected Lease decideWorkspace(@NonNull Node n, WorkspaceList wsl) throws Inter return wsl.allocate(ws, getBuild()); } + @Override public Result run(@NonNull BuildListener listener) throws Exception { final Node node = getCurrentNode(); - - assert builtOn==null; + + assert builtOn == null; builtOn = node.getNodeName(); hudsonVersion = Jenkins.VERSION; this.listener = listener; @@ -494,7 +503,7 @@ public Result run(@NonNull BuildListener listener) throws Exception { } else { listener.getLogger().print(Messages.AbstractBuild_Building()); } - + lease = decideWorkspace(node, Computer.currentComputer().getWorkspaceList()); workspace = lease.path.getRemote(); @@ -507,7 +516,7 @@ public Result run(@NonNull BuildListener listener) throws Exception { getProject().getScmCheckoutStrategy().preCheckout(AbstractBuild.this, launcher, this.listener); getProject().getScmCheckoutStrategy().checkout(this); - if (!preBuild(listener,project.getProperties())) + if (!preBuild(listener, project.getProperties())) return Result.FAILURE; result = doRun(listener); @@ -527,8 +536,8 @@ public Result run(@NonNull BuildListener listener) throws Exception { // this is ugly, but for historical reason, if non-null value is returned // it should become the final result. - if (result==null) result = getResult(); - if (result==null) result = Result.SUCCESS; + if (result == null) result = getResult(); + if (result == null) result = Result.SUCCESS; return result; } @@ -566,7 +575,7 @@ private Result tearDownBuildEnvironments(@NonNull BuildListener listener) throws } } catch (IOException | RuntimeException e) { // exceptions are only logged, to give a chance to all environments to tear down - if(e instanceof IOException) { + if (e instanceof IOException) { // similar to Run#handleFatalBuildProblem(BuildListener, Throwable) Util.displayIOException((IOException) e, listener); } @@ -597,24 +606,24 @@ protected Launcher createLauncher(@NonNull BuildListener listener) throws IOExce if (project instanceof BuildableItemWithBuildWrappers) { BuildableItemWithBuildWrappers biwbw = (BuildableItemWithBuildWrappers) project; for (BuildWrapper bw : biwbw.getBuildWrappersList()) - l = bw.decorateLauncher(AbstractBuild.this,l,listener); + l = bw.decorateLauncher(AbstractBuild.this, l, listener); } - for (RunListener rl: RunListener.all()) { + for (RunListener rl : RunListener.all()) { Environment environment = rl.setUpEnvironment(AbstractBuild.this, l, listener); if (environment != null) { buildEnvironments.add(environment); } } - for (NodeProperty nodeProperty: Jenkins.get().getGlobalNodeProperties()) { + for (NodeProperty nodeProperty : Jenkins.get().getGlobalNodeProperties()) { Environment environment = nodeProperty.setUp(AbstractBuild.this, l, listener); if (environment != null) { buildEnvironments.add(environment); } } - for (NodeProperty nodeProperty: currentNode.getNodeProperties()) { + for (NodeProperty nodeProperty : currentNode.getNodeProperties()) { Environment environment = nodeProperty.setUp(AbstractBuild.this, l, listener); if (environment != null) { buildEnvironments.add(environment); @@ -625,15 +634,15 @@ protected Launcher createLauncher(@NonNull BuildListener listener) throws IOExce } public void defaultCheckout() throws IOException, InterruptedException { - AbstractBuild build = AbstractBuild.this; + AbstractBuild build = AbstractBuild.this; AbstractProject project = build.getProject(); - for (int retryCount=project.getScmCheckoutRetryCount(); ; retryCount--) { + for (int retryCount = project.getScmCheckoutRetryCount(); ; retryCount--) { build.scm = NullChangeLogParser.INSTANCE; try { File changeLogFile = new File(build.getRootDir(), "changelog.xml"); - if (project.checkout(build, launcher,listener, changeLogFile)) { + if (project.checkout(build, launcher, listener, changeLogFile)) { // check out succeeded SCM scm = project.getScm(); for (SCMListener l : SCMListener.all()) { @@ -649,20 +658,20 @@ public void defaultCheckout() throws IOException, InterruptedException { for (SCMListener l : SCMListener.all()) try { - l.onChangeLogParsed(build,listener,build.getChangeSet()); + l.onChangeLogParsed(build, listener, build.getChangeSet()); } catch (Exception e) { - throw new IOException("Failed to parse changelog",e); + throw new IOException("Failed to parse changelog", e); } // Get a chance to do something after checkout and changelog is done - scm.postCheckout( build, launcher, build.getWorkspace(), listener ); + scm.postCheckout(build, launcher, build.getWorkspace(), listener); return; } } catch (AbortException e) { listener.error(e.getMessage()); - } catch (InterruptedIOException e) { - throw (InterruptedException)new InterruptedException().initCause(e); + } catch (ClosedByInterruptException | InterruptedIOException e) { + throw (InterruptedException) new InterruptedException().initCause(e); } catch (IOException e) { // checkout error not yet reported Functions.printStackTrace(e, listener.getLogger()); @@ -685,28 +694,30 @@ public void defaultCheckout() throws IOException, InterruptedException { * itself run successfully) * Return a non-null value to abort the build right there with the specified result code. */ - protected abstract Result doRun(BuildListener listener) throws Exception, RunnerAbortedException; + protected abstract Result doRun(BuildListener listener) throws Exception; /** * @see #post(BuildListener) */ protected abstract void post2(BuildListener listener) throws Exception; + @Override public final void post(BuildListener listener) throws Exception { try { post2(listener); } finally { // update the culprit list - HashSet r = new HashSet<>(); + SortedSet r = new TreeSet<>(); for (User u : getCulprits()) r.add(u.getId()); - culprits = ImmutableSortedSet.copyOf(r); + culprits = Collections.unmodifiableSet(r); CheckPoint.CULPRITS_DETERMINED.report(); } } + @Override public void cleanUp(BuildListener listener) throws Exception { - if (lease!=null) { + if (lease != null) { lease.release(); lease = null; } @@ -719,12 +730,12 @@ public void cleanUp(BuildListener listener) throws Exception { * Use {@link #performAllBuildSteps(BuildListener, Map, boolean)} */ @Deprecated - protected final void performAllBuildStep(BuildListener listener, Map buildSteps, boolean phase) throws InterruptedException, IOException { - performAllBuildSteps(listener,buildSteps.values(),phase); + protected final void performAllBuildStep(BuildListener listener, Map buildSteps, boolean phase) throws InterruptedException, IOException { + performAllBuildSteps(listener, buildSteps.values(), phase); } - protected final boolean performAllBuildSteps(BuildListener listener, Map buildSteps, boolean phase) throws InterruptedException, IOException { - return performAllBuildSteps(listener,buildSteps.values(),phase); + protected final boolean performAllBuildSteps(BuildListener listener, Map buildSteps, boolean phase) throws InterruptedException, IOException { + return performAllBuildSteps(listener, buildSteps.values(), phase); } /** @@ -733,7 +744,7 @@ protected final boolean performAllBuildSteps(BuildListener listener, Map buildSteps, boolean phase) throws InterruptedException, IOException { - performAllBuildSteps(listener,buildSteps,phase); + performAllBuildSteps(listener, buildSteps, phase); } /** @@ -747,9 +758,9 @@ protected final void performAllBuildStep(BuildListener listener, Iterable buildSteps, boolean phase) throws InterruptedException, IOException { boolean r = true; for (BuildStep bs : buildSteps) { - if ((bs instanceof Publisher && ((Publisher)bs).needsToRunAfterFinalized()) ^ phase) + if ((bs instanceof Publisher && ((Publisher) bs).needsToRunAfterFinalized()) ^ phase) try { - if (!perform(bs,listener)) { + if (!perform(bs, listener)) { LOGGER.log(Level.FINE, "{0} : {1} failed", new Object[] {AbstractBuild.this, bs}); r = false; if (phase) { @@ -841,17 +852,17 @@ private String getBuildStepName(BuildStep bs) { } } - protected final boolean preBuild(BuildListener listener,Map steps) { - return preBuild(listener,steps.values()); + protected final boolean preBuild(BuildListener listener, Map steps) { + return preBuild(listener, steps.values()); } - protected final boolean preBuild(BuildListener listener,Collection steps) { - return preBuild(listener,(Iterable)steps); + protected final boolean preBuild(BuildListener listener, Collection steps) { + return preBuild(listener, (Iterable) steps); } - protected final boolean preBuild(BuildListener listener,Iterable steps) { + protected final boolean preBuild(BuildListener listener, Iterable steps) { for (BuildStep bs : steps) - if (!bs.prebuild(AbstractBuild.this,listener)) { + if (!bs.prebuild(AbstractBuild.this, listener)) { LOGGER.log(Level.FINE, "{0} : {1} failed", new Object[] {AbstractBuild.this, bs}); return false; } @@ -866,6 +877,7 @@ protected final boolean preBuild(BuildListener listener,Iterable getChangeSet() { + @NonNull public ChangeLogSet getChangeSet() { synchronized (changeSetLock) { - if (scm==null) { - scm = NullChangeLogParser.INSTANCE; + if (scm == null) { + scm = NullChangeLogParser.INSTANCE; } } - ChangeLogSet cs = null; - if (changeSet!=null) + ChangeLogSet cs = null; + if (changeSet != null) cs = changeSet.get(); - if (cs==null) + if (cs == null) cs = calcChangeSet(); // defensive check. if the calculation fails (such as through an exception), // set a dummy value so that it'll work the next time. the exception will // be still reported, giving the plugin developer an opportunity to fix it. - if (cs==null) + if (cs == null) cs = ChangeLogSet.createEmpty(this); changeSet = new WeakReference<>(cs); @@ -910,7 +922,7 @@ public boolean tearDown(AbstractBuild build, BuildListener listener) throws IOEx @Override @NonNull public List> getChangeSets() { - ChangeLogSet cs = getChangeSet(); + ChangeLogSet cs = getChangeSet(); return cs.isEmptySet() ? Collections.emptyList() : Collections.singletonList(cs); } @@ -922,15 +934,15 @@ public boolean hasChangeSetComputed() { return changelogFile.exists(); } - private ChangeLogSet calcChangeSet() { + private ChangeLogSet calcChangeSet() { File changelogFile = new File(getRootDir(), "changelog.xml"); if (!changelogFile.exists()) return ChangeLogSet.createEmpty(this); try { - return scm.parse(this,changelogFile); + return scm.parse(this, changelogFile); } catch (IOException | SAXException e) { - LOGGER.log(WARNING, "Failed to parse "+changelogFile,e); + LOGGER.log(WARNING, "Failed to parse " + changelogFile, e); } return ChangeLogSet.createEmpty(this); } @@ -939,7 +951,7 @@ private ChangeLogSet calcChangeSet() { public EnvVars getEnvironment(TaskListener log) throws IOException, InterruptedException { EnvVars env = super.getEnvironment(log); FilePath ws = getWorkspace(); - if (ws != null) { // if this is done very early on in the build, workspace may not be decided yet. see HUDSON-3997 + if (ws != null) { // if this is done very early on in the build, workspace may not be decided yet. see JENKINS-3997 env.put("WORKSPACE", ws.getRemote()); FilePath tempDir = WorkspaceList.tempDir(ws); if (tempDir != null) { @@ -947,14 +959,14 @@ public EnvVars getEnvironment(TaskListener log) throws IOException, InterruptedE } } - project.getScm().buildEnvVars(this,env); + project.getScm().buildEnvVars(this, env); - if (buildEnvironments!=null) + if (buildEnvironments != null) for (Environment e : buildEnvironments) e.buildEnvVars(env); for (EnvironmentContributingAction a : getActions(EnvironmentContributingAction.class)) - a.buildEnvVars(this,env); + a.buildEnvVars(this, env); EnvVars.resolve(env); @@ -963,24 +975,24 @@ public EnvVars getEnvironment(TaskListener log) throws IOException, InterruptedE /** * During the build, expose the environments contributed by {@link BuildWrapper}s and others. - * + * *

    * Since 1.444, executor thread that's doing the build can access mutable underlying list, * which allows the caller to add/remove environments. The recommended way of adding * environment is through {@link BuildWrapper}, but this might be handy for build steps * who wants to expose additional environment variables to the rest of the build. - * + * * @return can be empty list, but never null. Immutable. * @since 1.437 */ public EnvironmentList getEnvironments() { Executor e = Executor.currentExecutor(); - if (e!=null && e.getCurrentExecutable()==this) { - if (buildEnvironments==null) buildEnvironments = new ArrayList<>(); - return new EnvironmentList(buildEnvironments); + if (e != null && e.getCurrentExecutable() == this) { + if (buildEnvironments == null) buildEnvironments = new ArrayList<>(); + return new EnvironmentList(buildEnvironments); } - - return new EnvironmentList(buildEnvironments==null ? Collections.emptyList() : ImmutableList.copyOf(buildEnvironments)); + + return new EnvironmentList(buildEnvironments == null ? Collections.emptyList() : Collections.unmodifiableList(new ArrayList<>(buildEnvironments))); } public Calendar due() { @@ -994,9 +1006,9 @@ public Calendar due() { @Override public void addAction(Action a) { super.addAction(a); } - + @SuppressWarnings("deprecation") - public List getPersistentActions(){ + public List getPersistentActions() { return super.getActions(); } @@ -1026,7 +1038,7 @@ public Set getSensitiveBuildVariables() { bw.makeSensitiveBuildVariables(this, s); } } - + return s; } @@ -1045,26 +1057,26 @@ public Set getSensitiveBuildVariables() { * @return * The returned map is mutable so that subtypes can put more values. */ - public Map getBuildVariables() { - Map r = new HashMap<>(); + public Map getBuildVariables() { + Map r = new HashMap<>(); ParametersAction parameters = getAction(ParametersAction.class); - if (parameters!=null) { + if (parameters != null) { // this is a rather round about way of doing this... for (ParameterValue p : parameters) { String v = p.createVariableResolver(this).resolve(p.getName()); - if (v!=null) r.put(p.getName(),v); + if (v != null) r.put(p.getName(), v); } } // allow the BuildWrappers to contribute additional build variables if (project instanceof BuildableItemWithBuildWrappers) { for (BuildWrapper bw : ((BuildableItemWithBuildWrappers) project).getBuildWrappersList()) - bw.makeBuildVariables(this,r); + bw.makeBuildVariables(this, r); } for (BuildVariableContributor bvc : BuildVariableContributor.all()) - bvc.buildVariablesFor(this,r); + bvc.buildVariablesFor(this, r); return r; } @@ -1103,6 +1115,7 @@ public Action getAggregatedTestResultAction() { /** * Invoked by {@link Executor} to performs a build. */ + @Override public abstract void run(); // @@ -1116,22 +1129,22 @@ public String getWhyKeepLog() { // if any of the downstream project is configured with 'keep dependency component', // we need to keep this log OUTER: - for (AbstractProject p : getParent().getDownstreamProjects()) { + for (AbstractProject p : getParent().getDownstreamProjects()) { if (!p.isKeepDependencies()) continue; - AbstractBuild fb = p.getFirstBuild(); - if (fb==null) continue; // no active record + AbstractBuild fb = p.getFirstBuild(); + if (fb == null) continue; // no active record // is there any active build that depends on us? for (int i : getDownstreamRelationship(p).listNumbersReverse()) { // TODO: this is essentially a "find intersection between two sparse sequences" // and we should be able to do much better. - if (i b = p.getBuildByNumber(i); - if (b!=null) + AbstractBuild b = p.getBuildByNumber(i); + if (b != null) return Messages.AbstractBuild_KeptBecause(p.hasPermission(Item.READ) ? b.toString() : "?"); } } @@ -1151,7 +1164,7 @@ public RangeSet getDownstreamRelationship(AbstractProject that) { RangeSet rs = new RangeSet(); FingerprintAction f = getAction(FingerprintAction.class); - if (f==null) return rs; + if (f == null) return rs; // look for fingerprints that point to this build as the source, and merge them all for (Fingerprint e : f.getFingerprints().values()) { @@ -1162,7 +1175,7 @@ public RangeSet getDownstreamRelationship(AbstractProject that) { rs.add(e.getRangeSet(that)); } else { BuildPtr o = e.getOriginal(); - if (o!=null && o.is(this)) + if (o != null && o.is(this)) rs.add(e.getRangeSet(that)); } } @@ -1175,13 +1188,15 @@ public RangeSet getDownstreamRelationship(AbstractProject that) { * the actual build objects, in ascending order. * @since 1.150 */ - public Iterable> getDownstreamBuilds(final AbstractProject that) { + public Iterable> getDownstreamBuilds(final AbstractProject that) { final Iterable nums = getDownstreamRelationship(that).listNumbers(); return new Iterable>() { + @Override public Iterator> iterator() { return Iterators.removeNull( - new AdaptedIterator>(nums) { + new AdaptedIterator>(nums) { + @Override protected AbstractBuild adapt(Integer item) { return that.getBuildByNumber(item); } @@ -1200,7 +1215,7 @@ public Iterable> getDownstreamBuilds(final AbstractProject getUpstreamRelationshipBuild(AbstractProject that) { + public AbstractBuild getUpstreamRelationshipBuild(AbstractProject that) { int n = getUpstreamRelationship(that); - if (n==-1) return null; + if (n == -1) return null; return that.getBuildByNumber(n); } @@ -1245,11 +1260,11 @@ public AbstractBuild getUpstreamRelationshipBuild(AbstractProject that * For each project with fingerprinting enabled, returns the range * of builds (which can be empty if no build uses the artifact from this build or downstream is not {@link AbstractProject#isFingerprintConfigured}.) */ - public Map getDownstreamBuilds() { - Map r = new HashMap<>(); + public Map getDownstreamBuilds() { + Map r = new HashMap<>(); for (AbstractProject p : getParent().getDownstreamProjects()) { if (p.isFingerprintConfigured()) - r.put(p,getDownstreamRelationship(p)); + r.put(p, getDownstreamRelationship(p)); } return r; } @@ -1260,7 +1275,7 @@ public Map getDownstreamBuilds() { * @return empty if there is no {@link FingerprintAction} (even if there is an {@link Cause.UpstreamCause}) * @see #getTransitiveUpstreamBuilds() */ - public Map getUpstreamBuilds() { + public Map getUpstreamBuilds() { return _getUpstreamBuilds(getParent().getUpstreamProjects()); } @@ -1268,16 +1283,16 @@ public Map getUpstreamBuilds() { * Works like {@link #getUpstreamBuilds()} but also includes all the transitive * dependencies as well. */ - public Map getTransitiveUpstreamBuilds() { + public Map getTransitiveUpstreamBuilds() { return _getUpstreamBuilds(getParent().getTransitiveUpstreamProjects()); } private Map _getUpstreamBuilds(Collection projects) { - Map r = new HashMap<>(); + Map r = new HashMap<>(); for (AbstractProject p : projects) { int n = getUpstreamRelationship(p); - if (n>=0) - r.put(p,n); + if (n >= 0) + r.put(p, n); } return r; } @@ -1286,23 +1301,23 @@ private Map _getUpstreamBuilds(Collection getDependencyChanges(AbstractBuild from) { - if (from==null) return Collections.emptyMap(); // make it easy to call this from views + public Map getDependencyChanges(AbstractBuild from) { + if (from == null) return Collections.emptyMap(); // make it easy to call this from views FingerprintAction n = this.getAction(FingerprintAction.class); FingerprintAction o = from.getAction(FingerprintAction.class); - if (n==null || o==null) return Collections.emptyMap(); + if (n == null || o == null) return Collections.emptyMap(); - Map ndep = n.getDependencies(true); - Map odep = o.getDependencies(true); + Map ndep = n.getDependencies(true); + Map odep = o.getDependencies(true); - Map r = new HashMap<>(); + Map r = new HashMap<>(); - for (Map.Entry entry : odep.entrySet()) { + for (Map.Entry entry : odep.entrySet()) { AbstractProject p = entry.getKey(); Integer oldNumber = entry.getValue(); Integer newNumber = ndep.get(p); - if (newNumber!=null && oldNumber.compareTo(newNumber)<0) { - r.put(p,new DependencyChange(p,oldNumber,newNumber)); + if (newNumber != null && oldNumber.compareTo(newNumber) < 0) { + r.put(p, new DependencyChange(p, oldNumber, newNumber)); } } @@ -1332,7 +1347,7 @@ public static final class DependencyChange { public final AbstractBuild to; - public DependencyChange(AbstractProject project, int fromId, int toId) { + public DependencyChange(AbstractProject project, int fromId, int toId) { this.project = project; this.fromId = fromId; this.toId = toId; @@ -1349,11 +1364,11 @@ public DependencyChange(AbstractProject project, int fromId, int toId) { public List getBuilds() { List r = new ArrayList<>(); - AbstractBuild b = project.getNearestBuild(fromId); - if (b!=null && b.getNumber()==fromId) + AbstractBuild b = project.getNearestBuild(fromId); + if (b != null && b.getNumber() == fromId) b = b.getNextBuild(); // fromId exclusive - while (b!=null && b.getNumber()<=toId) { + while (b != null && b.getNumber() <= toId) { r.add(b); b = b.getNextBuild(); } @@ -1373,7 +1388,7 @@ public List getBuilds() { @Deprecated @RequirePOST // #doStop() should be preferred, but better to be safe public void doStop(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { - doStop().generateResponse(req,rsp,this); + doStop().generateResponse(req, rsp, this); } /** @@ -1381,15 +1396,15 @@ public void doStop(StaplerRequest req, StaplerResponse rsp) throws IOException, * * If we use this/executor/stop URL, it causes 404 if the build is already killed, * as {@link #getExecutor()} returns null. - * + * * @since 1.489 */ @RequirePOST public synchronized HttpResponse doStop() throws IOException, ServletException { Executor e = getExecutor(); - if (e==null) + if (e == null) e = getOneOffExecutor(); - if (e!=null) + if (e != null) return e.doStop(); else // nothing is building @@ -1398,4 +1413,3 @@ public synchronized HttpResponse doStop() throws IOException, ServletException { private static final Logger LOGGER = Logger.getLogger(AbstractBuild.class.getName()); } - diff --git a/core/src/main/java/hudson/model/AbstractCIBase.java b/core/src/main/java/hudson/model/AbstractCIBase.java index b9f7a887a5cb..cb2332cbb0a3 100644 --- a/core/src/main/java/hudson/model/AbstractCIBase.java +++ b/core/src/main/java/hudson/model/AbstractCIBase.java @@ -27,23 +27,28 @@ package hudson.model; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.security.AccessControlled; import hudson.slaves.ComputerListener; import hudson.slaves.RetentionStrategy; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; import jenkins.model.Jenkins; +import jenkins.util.Listeners; import jenkins.util.SystemProperties; import org.kohsuke.stapler.StaplerFallback; import org.kohsuke.stapler.StaplerProxy; -import java.util.*; -import java.util.logging.Level; -import java.util.logging.Logger; -import edu.umd.cs.findbugs.annotations.CheckForNull; - public abstract class AbstractCIBase extends Node implements ItemGroup, StaplerProxy, StaplerFallback, ViewGroup, AccessControlled, DescriptorByNameOwner { - @SuppressFBWarnings("MS_SHOULD_BE_FINAL") + @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "for script console") public static boolean LOG_STARTUP_PERFORMANCE = SystemProperties.getBoolean(Jenkins.class.getName() + "." + "logStartupPerformance", false); private static final Logger LOGGER = Logger.getLogger(AbstractCIBase.class.getName()); @@ -54,6 +59,7 @@ public abstract class AbstractCIBase extends Node implements ItemGroup getDisabledAdministrativeMonitors(){ + public Set getDisabledAdministrativeMonitors() { synchronized (this.disabledAdministrativeMonitors) { return new HashSet<>(disabledAdministrativeMonitors); } @@ -118,23 +126,21 @@ public void setDisabledAdministrativeMonitors(Set disabledAdministrative /** * Returns all {@link Node}s in the system, excluding {@link jenkins.model.Jenkins} instance itself which - * represents the master. + * represents the built-in node in this context. */ public abstract List getNodes(); public abstract Queue getQueue(); - protected abstract Map getComputerMap(); + protected abstract Map getComputerMap(); /* ================================================================================================================= * Computer API uses package protection heavily * ============================================================================================================== */ - private void updateComputer(Node n, Map byNameMap, Set used, boolean automaticSlaveLaunch) { - Map computers = getComputerMap(); - Computer c; - c = byNameMap.get(n.getNodeName()); - if (c!=null) { + private void updateComputer(Node n, Map byNameMap, Set used, boolean automaticAgentLaunch) { + Computer c = byNameMap.get(n.getNodeName()); + if (c != null) { try { c.setNode(n); // reuse used.add(c); @@ -142,43 +148,54 @@ private void updateComputer(Node n, Map byNameMap, Set0 || n==Jenkins.get()) { - try { - c = n.createComputer(); - } catch(RuntimeException ex) { // Just in case there is a bogus extension - LOGGER.log(Level.WARNING, "Error retrieving computer for node " + n.getNodeName() + ", continuing", ex); - } - if (c == null) { - LOGGER.log(Level.WARNING, "Cannot create computer for node {0}, the {1}#createComputer() method returned null. Skipping this node", - new Object[]{n.getNodeName(), n.getClass().getName()}); - return; - } - - computers.put(n, c); - if (!n.isHoldOffLaunchUntilSave() && automaticSlaveLaunch) { - RetentionStrategy retentionStrategy = c.getRetentionStrategy(); - if (retentionStrategy != null) { - // if there is a retention strategy, it is responsible for deciding to start the computer - retentionStrategy.start(c); - } else { - // we should never get here, but just in case, we'll fall back to the legacy behaviour - c.connect(true); - } - } + c = createNewComputerForNode(n, automaticAgentLaunch); + if (c != null) { used.add(c); - } else { - // TODO: Maybe it should be allowed, but we would just get NPE in the original logic before JENKINS-43496 - LOGGER.log(Level.WARNING, "Node {0} has no executors. Cannot update the Computer instance of it", n.getNodeName()); } } } + @CheckForNull + private Computer createNewComputerForNode(Node n, boolean automaticAgentLaunch) { + Computer c = null; + Map computers = getComputerMap(); + // we always need Computer for the built-in node as a fallback in case there's no other Computer. + if (n.getNumExecutors() > 0 || n == Jenkins.get()) { + try { + c = n.createComputer(); + } catch (RuntimeException ex) { // Just in case there is a bogus extension + LOGGER.log(Level.WARNING, "Error retrieving computer for node " + n.getNodeName() + ", continuing", ex); + } + if (c == null) { + LOGGER.log(Level.WARNING, "Cannot create computer for node {0}, the {1}#createComputer() method returned null. Skipping this node", + new Object[]{n.getNodeName(), n.getClass().getName()}); + return null; + } + + computers.put(n, c); + if (!n.isHoldOffLaunchUntilSave() && automaticAgentLaunch) { + RetentionStrategy retentionStrategy = c.getRetentionStrategy(); + if (retentionStrategy != null) { + // if there is a retention strategy, it is responsible for deciding to start the computer + retentionStrategy.start(c); + } else { + // we should never get here, but just in case, we'll fall back to the legacy behaviour + c.connect(true); + } + } + return c; + } else { + // TODO: Maybe it should be allowed, but we would just get NPE in the original logic before JENKINS-43496 + LOGGER.log(Level.WARNING, "Node {0} has no executors. Cannot update the Computer instance of it", n.getNodeName()); + return null; + } + } + /*package*/ void removeComputer(final Computer computer) { Queue.withLock(new Runnable() { @Override public void run() { - Map computers = getComputerMap(); + Map computers = getComputerMap(); for (Map.Entry e : computers.entrySet()) { if (e.getValue() == computer) { computers.remove(e.getKey()); @@ -191,10 +208,22 @@ public void run() { } /*package*/ @CheckForNull Computer getComputer(Node n) { - Map computers = getComputerMap(); + Map computers = getComputerMap(); return computers.get(n); } + protected void updateNewComputer(final Node n, boolean automaticAgentLaunch) { + final String nodeName = n.getNodeName(); + final Map computers = getComputerMap(); + if (computers.containsKey(n)) { + LOGGER.warning("Node " + nodeName + " is not a new node skipping"); + return; + } + createNewComputerForNode(n, automaticAgentLaunch); + getQueue().scheduleMaintenance(); + Listeners.notify(ComputerListener.class, false, ComputerListener::onConfigurationChange); + } + /** * Updates Computers. * @@ -202,27 +231,27 @@ public void run() { * This method tries to reuse existing {@link Computer} objects * so that we won't upset {@link Executor}s running in it. */ - protected void updateComputerList(final boolean automaticSlaveLaunch) { - final Map computers = getComputerMap(); + protected void updateComputerList(final boolean automaticAgentLaunch) { + final Map computers = getComputerMap(); final Set old = new HashSet<>(computers.size()); Queue.withLock(new Runnable() { @Override public void run() { - Map byName = new HashMap<>(); + Map byName = new HashMap<>(); for (Computer c : computers.values()) { old.add(c); Node node = c.getNode(); if (node == null) continue; // this computer is gone - byName.put(node.getNodeName(),c); + byName.put(node.getNodeName(), c); } Set used = new HashSet<>(old.size()); - updateComputer(AbstractCIBase.this, byName, used, automaticSlaveLaunch); + updateComputer(AbstractCIBase.this, byName, used, automaticAgentLaunch); for (Node s : getNodes()) { long start = System.currentTimeMillis(); - updateComputer(s, byName, used, automaticSlaveLaunch); + updateComputer(s, byName, used, automaticAgentLaunch); if (LOG_STARTUP_PERFORMANCE && LOGGER.isLoggable(Level.FINE)) { LOGGER.fine(String.format("Took %dms to update node %s", System.currentTimeMillis() - start, s.getNodeName())); @@ -245,13 +274,7 @@ public void run() { killComputer(c); } getQueue().scheduleMaintenance(); - for (ComputerListener cl : ComputerListener.all()) { - try { - cl.onConfigurationChange(); - } catch (Throwable t) { - LOGGER.log(Level.WARNING, null, t); - } - } + Listeners.notify(ComputerListener.class, false, ComputerListener::onConfigurationChange); } } diff --git a/core/src/main/java/hudson/model/AbstractDescribableImpl.java b/core/src/main/java/hudson/model/AbstractDescribableImpl.java index b1ac6dd8477f..2e339875b940 100644 --- a/core/src/main/java/hudson/model/AbstractDescribableImpl.java +++ b/core/src/main/java/hudson/model/AbstractDescribableImpl.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import hudson.Extension; diff --git a/core/src/main/java/hudson/model/AbstractItem.java b/core/src/main/java/hudson/model/AbstractItem.java index b396da5cd807..c60530639cbf 100644 --- a/core/src/main/java/hudson/model/AbstractItem.java +++ b/core/src/main/java/hudson/model/AbstractItem.java @@ -1,19 +1,19 @@ /* * The MIT License - * + * * Copyright (c) 2004-2011, Sun Microsystems, Inc., Kohsuke Kawaguchi, * Daniel Dyer, Tom Huybrechts, Yahoo!, Inc. - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -22,87 +22,85 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import static hudson.model.queue.Executables.getParentOf; +import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST; + import com.infradna.tool.bridge_method_injector.WithBridgeMethods; +import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.AbortException; -import hudson.XmlFile; -import hudson.Util; -import hudson.Functions; import hudson.BulkChange; +import hudson.Functions; +import hudson.Util; +import hudson.XmlFile; import hudson.cli.declarative.CLIResolver; import hudson.model.Queue.Executable; import hudson.model.listeners.ItemListener; import hudson.model.listeners.SaveableListener; +import hudson.model.queue.SubTask; import hudson.model.queue.Tasks; import hudson.model.queue.WorkUnit; +import hudson.security.ACL; import hudson.security.ACLContext; import hudson.security.AccessControlled; -import hudson.security.ACL; import hudson.util.AlternativeUiTextProvider; import hudson.util.AlternativeUiTextProvider.Message; import hudson.util.AtomicFileWriter; import hudson.util.FormValidation; import hudson.util.IOUtils; import hudson.util.Secret; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.concurrent.TimeUnit; -import jenkins.model.DirectlyModifiableTopLevelItemGroup; -import jenkins.model.Jenkins; -import jenkins.model.queue.ItemDeletion; -import jenkins.security.NotReallyRoleSensitiveCallable; -import jenkins.util.xml.XMLUtils; - -import org.apache.tools.ant.taskdefs.Copy; -import org.apache.tools.ant.types.FileSet; -import org.kohsuke.stapler.HttpResponses; -import org.kohsuke.stapler.StaplerProxy; -import org.kohsuke.stapler.WebMethod; -import org.kohsuke.stapler.export.Exported; -import org.kohsuke.stapler.export.ExportedBean; - import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; import java.util.ListIterator; +import java.util.Map; +import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; -import edu.umd.cs.findbugs.annotations.NonNull; - -import org.kohsuke.stapler.HttpResponse; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; -import org.kohsuke.stapler.Stapler; -import org.kohsuke.stapler.HttpDeletable; -import org.kohsuke.args4j.Argument; -import org.kohsuke.args4j.CmdLineException; -import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.interceptor.RequirePOST; -import org.xml.sax.SAXException; - import javax.servlet.ServletException; import javax.xml.transform.Source; import javax.xml.transform.TransformerException; import javax.xml.transform.sax.SAXSource; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; - -import static hudson.model.queue.Executables.getParentOf; -import hudson.model.queue.SubTask; -import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST; - +import jenkins.model.DirectlyModifiableTopLevelItemGroup; +import jenkins.model.Jenkins; +import jenkins.model.queue.ItemDeletion; +import jenkins.security.NotReallyRoleSensitiveCallable; +import jenkins.util.SystemProperties; +import jenkins.util.xml.XMLUtils; import org.apache.commons.io.FileUtils; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.taskdefs.Copy; +import org.apache.tools.ant.types.FileSet; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.args4j.Argument; +import org.kohsuke.args4j.CmdLineException; import org.kohsuke.stapler.Ancestor; +import org.kohsuke.stapler.HttpDeletable; +import org.kohsuke.stapler.HttpResponse; +import org.kohsuke.stapler.HttpResponses; +import org.kohsuke.stapler.QueryParameter; +import org.kohsuke.stapler.Stapler; +import org.kohsuke.stapler.StaplerProxy; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.WebMethod; +import org.kohsuke.stapler.export.Exported; +import org.kohsuke.stapler.export.ExportedBean; +import org.kohsuke.stapler.interceptor.RequirePOST; import org.springframework.security.access.AccessDeniedException; +import org.xml.sax.SAXException; /** * Partial default implementation of {@link Item}. @@ -127,7 +125,7 @@ public abstract class AbstractItem extends Actionable implements Item, HttpDelet protected volatile String description; private transient ItemGroup parent; - + protected String displayName; protected AbstractItem(ItemGroup parent, String name) { @@ -135,7 +133,8 @@ protected AbstractItem(ItemGroup parent, String name) { doSetName(name); } - @Exported(visibility=999) + @Override + @Exported(visibility = 999) public String getName() { return name; } @@ -161,15 +160,16 @@ public String getTaskNoun() { * @return The display name of this object, or if it is not set, the name * of the object. */ + @Override @Exported public String getDisplayName() { - if(null!=displayName) { + if (null != displayName) { return displayName; } // if the displayName is not set, then return the name as we use to do return getName(); } - + /** * This is intended to be used by the Job configuration pages where * we want to return null if the display name is not set. @@ -180,23 +180,22 @@ public String getDisplayName() { public String getDisplayNameOrNull() { return displayName; } - + /** - * This method exists so that the Job configuration pages can use + * This method exists so that the Job configuration pages can use * getDisplayNameOrNull so that nothing is shown in the display name text * box if the display name is not set. - * @param displayName - * @throws IOException */ public void setDisplayNameOrNull(String displayName) throws IOException { setDisplayName(displayName); } - + public void setDisplayName(String displayName) throws IOException { this.displayName = Util.fixEmptyAndTrim(displayName); save(); } - + + @Override public File getRootDir() { return getParent().getRootDirFor(this); } @@ -204,7 +203,7 @@ public File getRootDir() { /** * This bridge method is to maintain binary compatibility with {@link TopLevelItem#getParent()}. */ - @WithBridgeMethods(value=Jenkins.class,castRequired=true) + @WithBridgeMethods(value = Jenkins.class, castRequired = true) @Override public @NonNull ItemGroup getParent() { if (parent == null) { throw new IllegalStateException("no parent set on " + getClass().getName() + "[" + name + "]"); @@ -283,7 +282,7 @@ public HttpResponse doConfirmRename(@QueryParameter String newName) throws IOExc // TODO: Create an Item.RENAME permission to use here, see JENKINS-18649. if (!hasPermission(Item.CONFIGURE)) { if (parent instanceof AccessControlled) { - ((AccessControlled)parent).checkPermission(Item.CREATE); + ((AccessControlled) parent).checkPermission(Item.CREATE); } checkPermission(Item.DELETE); } @@ -320,17 +319,17 @@ private void checkIfNameIsUsed(@NonNull String newName) throws Failure { if (LOGGER.isLoggable(Level.FINE)) { LOGGER.log(Level.FINE, "Unable to rename the job {0}: name {1} is already in use. " + "User {2} has no {3} permission for existing job with the same name", - new Object[] {this.getFullName(), newName, ctx.getPreviousContext2().getAuthentication().getName(), Item.DISCOVER.name} ); + new Object[] {this.getFullName(), newName, ctx.getPreviousContext2().getAuthentication().getName(), Item.DISCOVER.name}); } // Don't explicitly mention that there is another item with the same name. throw new Failure(Messages.Jenkins_NotAllowedName(newName)); } } - } catch(AccessDeniedException ex) { + } catch (AccessDeniedException ex) { if (LOGGER.isLoggable(Level.FINE)) { LOGGER.log(Level.FINE, "Unable to rename the job {0}: name {1} is already in use. " + "User {2} has {3} permission, but no {4} for existing job with the same name", - new Object[] {this.getFullName(), newName, User.current(), Item.DISCOVER.name, Item.READ.name} ); + new Object[] {this.getFullName(), newName, User.current(), Item.DISCOVER.name, Item.READ.name}); } throw new Failure(Messages.AbstractItem_NewNameInUse(newName)); } @@ -355,6 +354,7 @@ protected void checkRename(@NonNull String newName) throws Failure { * Not all the Items need to support this operation, but if you decide to do so, * you can use this method. */ + @SuppressFBWarnings(value = "SWL_SLEEP_WITH_LOCK_HELD", justification = "no big deal") protected void renameTo(final String newName) throws IOException { if (!isNameEditable()) { @@ -387,7 +387,7 @@ protected void renameTo(final String newName) throws IOException { boolean success = false; - try {// rename data files + try { // rename data files boolean interrupted = false; boolean renamed = false; @@ -421,7 +421,7 @@ protected void renameTo(final String newName) throws IOException { // shuts down there might be a new job created under the // old name. Copy cp = new Copy(); - cp.setProject(new org.apache.tools.ant.Project()); + cp.setProject(new Project()); cp.setTodir(newRoot); FileSet src = new FileSet(); src.setDir(oldRoot); @@ -471,22 +471,25 @@ public void movedTo(DirectlyModifiableTopLevelItemGroup destination, AbstractIte /** * Gets all the jobs that this {@link Item} contains as descendants. */ + @Override public abstract Collection getAllJobs(); + @Override @Exported public final String getFullName() { String n = getParent().getFullName(); - if(n.length()==0) return getName(); - else return n+'/'+getName(); + if (n.length() == 0) return getName(); + else return n + '/' + getName(); } + @Override @Exported public final String getFullDisplayName() { String n = getParent().getFullDisplayName(); - if(n.length()==0) return getDisplayName(); - else return n+" » "+getDisplayName(); + if (n.length() == 0) return getDisplayName(); + else return n + " » " + getDisplayName(); } - + /** * Gets the display name of the current item relative to the given group. * @@ -498,7 +501,7 @@ public final String getFullDisplayName() { public String getRelativeDisplayNameFrom(ItemGroup p) { return Functions.getRelativeDisplayNameFrom(this, p); } - + /** * This method only exists to disambiguate {@link #getRelativeNameFrom(ItemGroup)} and {@link #getRelativeNameFrom(Item)} * @since 1.512 @@ -512,6 +515,7 @@ public String getRelativeNameFromGroup(ItemGroup p) { * Called right after when a {@link Item} is loaded from disk. * This is an opportunity to do a post load processing. */ + @Override public void onLoad(ItemGroup parent, String name) throws IOException { this.parent = parent; doSetName(name); @@ -523,26 +527,25 @@ public void onLoad(ItemGroup parent, String name) throws IOExcep * then it will be loaded, then this method will be invoked * to perform any implementation-specific work. * - *

    - * - * * @param src * Item from which it's copied from. The same type as {@code this}. Never null. */ + @Override public void onCopiedFrom(Item src) { } + @Override public final String getUrl() { // try to stick to the current view if possible StaplerRequest req = Stapler.getCurrentRequest(); String shortUrl = getShortUrl(); String uri = req == null ? null : req.getRequestURI(); if (req != null) { - String seed = Functions.getNearestAncestorUrl(req,this); + String seed = Functions.getNearestAncestorUrl(req, this); LOGGER.log(Level.FINER, "seed={0} for {1} from {2}", new Object[] {seed, this, uri}); - if(seed!=null) { + if (seed != null) { // trim off the context path portion and leading '/', but add trailing '/' - return seed.substring(req.getContextPath().length()+1)+'/'; + return seed.substring(req.getContextPath().length() + 1) + '/'; } List ancestors = req.getAncestors(); if (!ancestors.isEmpty()) { @@ -572,18 +575,20 @@ public final String getUrl() { return base + shortUrl; } + @Override public String getShortUrl() { String prefix = getParent().getUrlChildPrefix(); String subdir = Util.rawEncode(getName()); return prefix.equals(".") ? subdir + '/' : prefix + '/' + subdir + '/'; } + @Override public String getSearchUrl() { return getShortUrl(); } @Override - @Exported(visibility=999,name="url") + @Exported(visibility = 999, name = "url") public final String getAbsoluteUrl() { return Item.super.getAbsoluteUrl(); } @@ -598,6 +603,7 @@ public final Api getApi() { /** * Returns the {@link ACL} for this object. */ + @Override public ACL getACL() { return Jenkins.get().getAuthorizationStrategy().getACL(this); } @@ -605,8 +611,9 @@ public ACL getACL() { /** * Save the settings to a file. */ + @Override public synchronized void save() throws IOException { - if(BulkChange.contains(this)) return; + if (BulkChange.contains(this)) return; getConfigFile().write(this); SaveableListener.fireOnChange(this, getConfigFile()); } @@ -618,11 +625,14 @@ public final XmlFile getConfigFile() { protected Object writeReplace() { return XmlFile.replaceIfNotAtTopLevel(this, () -> new Replacer(this)); } + private static class Replacer { private final String fullName; + Replacer(AbstractItem i) { fullName = i.getFullName(); } + private Object readResolve() { Jenkins j = Jenkins.getInstanceOrNull(); if (j == null) { @@ -637,7 +647,7 @@ private Object readResolve() { * Accepts the new description. */ @RequirePOST - public synchronized void doSubmitDescription( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException { + public synchronized void doSubmitDescription(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { checkPermission(CONFIGURE); setDescription(req.getParameter("description")); @@ -651,7 +661,7 @@ public synchronized void doSubmitDescription( StaplerRequest req, StaplerRespons * which should now be unused by core but is left in case plugins are still using it. */ @RequirePOST - public void doDoDelete( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException, InterruptedException { + public void doDoDelete(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, InterruptedException { delete(); if (req == null || rsp == null) { // CLI return; @@ -672,7 +682,8 @@ public void doDoDelete( StaplerRequest req, StaplerResponse rsp ) throws IOExcep rsp.sendRedirect2(req.getContextPath() + '/' + url); } - public void delete( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException { + @Override + public void delete(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { try { delete(); rsp.setStatus(204); @@ -689,6 +700,7 @@ public void delete( StaplerRequest req, StaplerResponse rsp ) throws IOException * Any exception indicates the deletion has failed, but {@link AbortException} would prevent the caller * from showing the stack trace. This */ + @Override public void delete() throws IOException, InterruptedException { checkPermission(DELETE); boolean responsibleForAbortingBuilds = !ItemDeletion.contains(this); @@ -729,8 +741,8 @@ public void delete() throws IOException, InterruptedException { final WorkUnit workUnit = e.getCurrentWorkUnit(); final Executable executable = workUnit != null ? workUnit.getExecutable() : null; final SubTask subtask = executable != null ? getParentOf(executable) : null; - - if (subtask != null) { + + if (subtask != null) { Item item = Tasks.getItemOf(subtask); while (item != null) { if (item == this) { @@ -814,7 +826,7 @@ public void doConfigDotXml(StaplerRequest req, StaplerResponse rsp) } if (req.getMethod().equals("POST")) { // submission - updateByXml((Source)new StreamSource(req.getReader())); + updateByXml((Source) new StreamSource(req.getReader())); return; } @@ -828,6 +840,7 @@ public void doConfigDotXml(StaplerRequest req, StaplerResponse rsp) * The user must have at least {@link #EXTENDED_READ}. * If he lacks {@link #CONFIGURE}, then any {@link Secret}s detected will be masked out. */ + @Restricted(NoExternalUse.class) public void writeConfigDotXml(OutputStream os) throws IOException { checkPermission(EXTENDED_READ); @@ -855,7 +868,7 @@ public void writeConfigDotXml(OutputStream os) throws IOException { */ @Deprecated public void updateByXml(StreamSource source) throws IOException { - updateByXml((Source)source); + updateByXml((Source) source); } /** @@ -879,13 +892,13 @@ public void updateByXml(Source source) throws IOException { // try to reflect the changes by reloading Object o = new XmlFile(Items.XSTREAM, out.getTemporaryFile()).unmarshalNullingOut(this); - if (o!=this) { + if (o != this) { // ensure that we've got the same job type. extending this code to support updating // to different job type requires destroying & creating a new job type - throw new IOException("Expecting "+this.getClass()+" but got "+o.getClass()+" instead"); + throw new IOException("Expecting " + this.getClass() + " but got " + o.getClass() + " instead"); } - Items.whileUpdatingByXml(new NotReallyRoleSensitiveCallable() { + Items.whileUpdatingByXml(new NotReallyRoleSensitiveCallable() { @Override public Void call() throws IOException { onLoad(getParent(), getRootDir().getName()); return null; @@ -946,10 +959,10 @@ public String getSearchName() { @Restricted(NoExternalUse.class) public Object getTarget() { if (!SKIP_PERMISSION_CHECK) { - if (!getACL().hasPermission(Item.DISCOVER)) { + if (!hasPermission(Item.DISCOVER)) { return null; } - getACL().checkPermission(Item.READ); + checkPermission(Item.READ); } return this; } @@ -958,18 +971,18 @@ public Object getTarget() { * Escape hatch for StaplerProxy-based access control */ @Restricted(NoExternalUse.class) - @SuppressFBWarnings("MS_SHOULD_BE_FINAL") - public static /* Script Console modifiable */ boolean SKIP_PERMISSION_CHECK = Boolean.getBoolean(AbstractItem.class.getName() + ".skipPermissionCheck"); + @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "for script console") + public static /* Script Console modifiable */ boolean SKIP_PERMISSION_CHECK = SystemProperties.getBoolean(AbstractItem.class.getName() + ".skipPermissionCheck"); /** * Used for CLI binding. */ @CLIResolver public static AbstractItem resolveForCLI( - @Argument(required=true,metaVar="NAME",usage="Item name") String name) throws CmdLineException { + @Argument(required = true, metaVar = "NAME", usage = "Item name") String name) throws CmdLineException { // TODO can this (and its pseudo-override in AbstractProject) share code with GenericItemOptionHandler, used for explicit CLICommand’s rather than CLIMethod’s? AbstractItem item = Jenkins.get().getItemByFullName(name, AbstractItem.class); - if (item==null) { + if (item == null) { AbstractItem project = Items.findNearest(AbstractItem.class, name, Jenkins.get()); throw new CmdLineException(null, project == null ? Messages.AbstractItem_NoSuchJobExistsWithoutSuggestion(name) : Messages.AbstractItem_NoSuchJobExists(name, project.getFullName())); diff --git a/core/src/main/java/hudson/model/AbstractModelObject.java b/core/src/main/java/hudson/model/AbstractModelObject.java index 847d545222a9..f6c7104f8e42 100644 --- a/core/src/main/java/hudson/model/AbstractModelObject.java +++ b/core/src/main/java/hudson/model/AbstractModelObject.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,25 +21,24 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import hudson.search.Search; import hudson.search.SearchFactory; +import hudson.search.SearchIndex; +import hudson.search.SearchIndexBuilder; +import hudson.search.SearchableModelObject; +import java.io.IOException; +import javax.servlet.ServletException; +import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; -import org.kohsuke.stapler.Stapler; - -import javax.servlet.ServletException; -import java.io.IOException; - -import hudson.search.SearchableModelObject; -import hudson.search.Search; -import hudson.search.SearchIndexBuilder; -import hudson.search.SearchIndex; import org.kohsuke.stapler.interceptor.RequirePOST; /** * {@link ModelObject} with some convenience methods. - * + * * @author Kohsuke Kawaguchi */ public abstract class AbstractModelObject implements SearchableModelObject { @@ -48,16 +47,16 @@ public abstract class AbstractModelObject implements SearchableModelObject { */ protected final void sendError(Exception e, StaplerRequest req, StaplerResponse rsp) throws ServletException, IOException { req.setAttribute("exception", e); - sendError(e.getMessage(),req,rsp); + sendError(e.getMessage(), req, rsp); } protected final void sendError(Exception e) throws ServletException, IOException { - sendError(e,Stapler.getCurrentRequest(),Stapler.getCurrentResponse()); + sendError(e, Stapler.getCurrentRequest(), Stapler.getCurrentResponse()); } protected final void sendError(String message, StaplerRequest req, StaplerResponse rsp) throws ServletException, IOException { - req.setAttribute("message",message); - rsp.forward(this,"error",req); + req.setAttribute("message", message); + rsp.forward(this, "error", req); } /** @@ -65,29 +64,29 @@ protected final void sendError(String message, StaplerRequest req, StaplerRespon * If true, the message is put in a PRE tag. */ protected final void sendError(String message, StaplerRequest req, StaplerResponse rsp, boolean pre) throws ServletException, IOException { - req.setAttribute("message",message); - if(pre) - req.setAttribute("pre",true); - rsp.forward(this,"error",req); + req.setAttribute("message", message); + if (pre) + req.setAttribute("pre", true); + rsp.forward(this, "error", req); } protected final void sendError(String message) throws ServletException, IOException { - sendError(message,Stapler.getCurrentRequest(),Stapler.getCurrentResponse()); + sendError(message, Stapler.getCurrentRequest(), Stapler.getCurrentResponse()); } /** * Convenience method to verify that the current request is a POST request. - * - * @deprecated + * + * @deprecated * Use {@link RequirePOST} on your method. */ @Deprecated protected final void requirePOST() throws ServletException { StaplerRequest req = Stapler.getCurrentRequest(); - if (req==null) return; // invoked outside the context of servlet + if (req == null) return; // invoked outside the context of servlet String method = req.getMethod(); - if(!method.equalsIgnoreCase("POST")) - throw new ServletException("Must be POST, Can't be "+method); + if (!method.equalsIgnoreCase("POST")) + throw new ServletException("Must be POST, Can't be " + method); } /** @@ -97,14 +96,16 @@ protected SearchIndexBuilder makeSearchIndex() { return new SearchIndexBuilder().addAllAnnotations(this); } + @Override public final SearchIndex getSearchIndex() { return makeSearchIndex().make(); } + @Override public Search getSearch() { for (SearchFactory sf : SearchFactory.all()) { Search s = sf.createFor(this); - if (s!=null) + if (s != null) return s; } return new Search(); @@ -113,6 +114,7 @@ public Search getSearch() { /** * Default implementation that returns the display name. */ + @Override public String getSearchName() { return getDisplayName(); } diff --git a/core/src/main/java/hudson/model/AbstractProject.java b/core/src/main/java/hudson/model/AbstractProject.java index c5e9f5bba315..9dfaf72e21d7 100644 --- a/core/src/main/java/hudson/model/AbstractProject.java +++ b/core/src/main/java/hudson/model/AbstractProject.java @@ -25,10 +25,16 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import static hudson.scm.PollingResult.BUILD_NOW; +import static hudson.scm.PollingResult.NO_CHANGES; + import antlr.ANTLRException; import com.infradna.tool.bridge_method_injector.WithBridgeMethods; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.AbortException; import hudson.CopyOnWrite; import hudson.EnvVars; @@ -53,8 +59,6 @@ import hudson.model.queue.SubTaskContributor; import hudson.scm.NullSCM; import hudson.scm.PollingResult; - -import static hudson.scm.PollingResult.*; import hudson.scm.SCM; import hudson.scm.SCMRevisionState; import hudson.scm.SCMS; @@ -94,8 +98,6 @@ import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; import java.util.logging.Level; import java.util.logging.Logger; -import edu.umd.cs.findbugs.annotations.CheckForNull; -import edu.umd.cs.findbugs.annotations.NonNull; import javax.servlet.ServletException; import jenkins.model.BlockedBecauseOfBuildInProgress; import jenkins.model.Jenkins; @@ -109,7 +111,6 @@ import jenkins.triggers.SCMTriggerItem; import jenkins.util.TimeDuration; import net.sf.json.JSONObject; -import org.jenkinsci.bytecode.AdaptField; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.DoNotUse; import org.kohsuke.accmod.restrictions.NoExternalUse; @@ -135,7 +136,7 @@ * @see AbstractBuild */ @SuppressWarnings("rawtypes") -public abstract class AbstractProject

    ,R extends AbstractBuild> extends Job implements BuildableItem, LazyBuildMixIn.LazyLoadingJob, ParameterizedJobMixIn.ParameterizedJob { +public abstract class AbstractProject

    , R extends AbstractBuild> extends Job implements BuildableItem, LazyBuildMixIn.LazyLoadingJob, ParameterizedJobMixIn.ParameterizedJob { /** * {@link SCM} associated with the project. @@ -154,7 +155,7 @@ public abstract class AbstractProject

    ,R extends A */ private transient volatile SCMRevisionState pollingBaseline = null; - private transient LazyBuildMixIn buildMixIn; + private transient LazyBuildMixIn buildMixIn; /** * All the builds keyed by their build number. @@ -230,10 +231,9 @@ public abstract class AbstractProject

    ,R extends A /** * List of all {@link Trigger}s for this project. */ - @AdaptField(was=List.class) - protected volatile DescribableList,TriggerDescriptor> triggers = new DescribableList<>(this); - private static final AtomicReferenceFieldUpdater triggersUpdater - = AtomicReferenceFieldUpdater.newUpdater(AbstractProject.class,DescribableList.class,"triggers"); + protected volatile DescribableList, TriggerDescriptor> triggers = new DescribableList<>(this); + private static final AtomicReferenceFieldUpdater triggersUpdater + = AtomicReferenceFieldUpdater.newUpdater(AbstractProject.class, DescribableList.class, "triggers"); /** * {@link Action}s contributed from subsidiary objects associated with @@ -255,7 +255,7 @@ public abstract class AbstractProject

    ,R extends A private String customWorkspace; protected AbstractProject(ItemGroup parent, String name) { - super(parent,name); + super(parent, name); buildMixIn = createBuildMixIn(); builds = buildMixIn.getRunMap(); @@ -267,19 +267,20 @@ protected AbstractProject(ItemGroup parent, String name) { } } - private LazyBuildMixIn createBuildMixIn() { - return new LazyBuildMixIn() { + private LazyBuildMixIn createBuildMixIn() { + return new LazyBuildMixIn() { @SuppressWarnings("unchecked") // untypable @Override protected P asJob() { return (P) AbstractProject.this; } + @Override protected Class getBuildClass() { return AbstractProject.this.getBuildClass(); } }; } - @Override public LazyBuildMixIn getLazyBuildMixIn() { + @Override public LazyBuildMixIn getLazyBuildMixIn() { return buildMixIn; } @@ -314,18 +315,18 @@ public void onLoad(ItemGroup parent, String name) throws IOExcep LOGGER.log(Level.WARNING, "could not start trigger while loading project '" + getFullName() + "'", e); } } - if(scm==null) + if (scm == null) scm = new NullSCM(); // perhaps it was pointing to a plugin that no longer exists. - if(transientActions==null) + if (transientActions == null) transientActions = new Vector<>(); // happens when loaded from disk updateTransientActions(); } @WithBridgeMethods(List.class) - protected DescribableList,TriggerDescriptor> triggers() { + protected DescribableList, TriggerDescriptor> triggers() { if (triggers == null) { - triggersUpdater.compareAndSet(this,null,new DescribableList,TriggerDescriptor>(this)); + triggersUpdater.compareAndSet(this, null, new DescribableList, TriggerDescriptor>(this)); } return triggers; } @@ -352,7 +353,7 @@ protected void performDelete() throws IOException, InterruptedException { // prevent a new build while a delete operation is in progress makeDisabled(true); FilePath ws = getWorkspace(); - if(ws!=null) { + if (ws != null) { Node on = getLastBuiltOn(); getScm().processWorkspaceBeforeDeletion(this, ws, on); } @@ -380,10 +381,10 @@ public void setConcurrentBuild(boolean b) throws IOException { */ @Override public @CheckForNull Label getAssignedLabel() { - if(canRoam) + if (canRoam) return null; - if(assignedNode==null) + if (assignedNode == null) return Jenkins.get().getSelfLabel(); return Jenkins.get().getLabel(assignedNode); } @@ -406,11 +407,11 @@ public Set

    * If just a file name (like "abc.gif") is returned, it will be * interpreted as a file name inside {@code /images/24x24}. * This is useful for using one of the stock images. *

    * If an absolute file name that starts from '/' is returned (like - * "/plugin/foo/abc.gif'), then it will be interpreted as a path + * "/plugin/foo/abc.gif"), then it will be interpreted as a path * from the context root of Jenkins. This is useful to pick up * image files from a plugin. *

    @@ -94,6 +97,7 @@ public interface Action extends ModelObject { * but this can be used for actions that only contribute {@code floatBox.jelly} * and no task list item. The other case where this is useful is * to avoid showing links that require a privilege when the user is anonymous. + * @see Jenkins Symbols * @see Functions#isAnonymous() * @see Functions#getIconFilePath(Action) */ @@ -107,6 +111,7 @@ public interface Action extends ModelObject { * * @return Can be null in case the action is hidden. */ + @Override @CheckForNull String getDisplayName(); /** diff --git a/core/src/main/java/hudson/model/Actionable.java b/core/src/main/java/hudson/model/Actionable.java index 5025578fad1b..6fcb173fc6ad 100644 --- a/core/src/main/java/hudson/model/Actionable.java +++ b/core/src/main/java/hudson/model/Actionable.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Stephen Connolly - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,9 +21,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.Nullable; import hudson.Util; import java.util.ArrayList; import java.util.Collection; @@ -32,8 +34,6 @@ import java.util.concurrent.CopyOnWriteArrayList; import java.util.logging.Level; import java.util.logging.Logger; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; import jenkins.model.ModelObjectWithContextMenu; import jenkins.model.TransientActionFactory; import org.kohsuke.stapler.StaplerRequest; @@ -91,7 +91,7 @@ public List getActions() { * @return an unmodifiable, possible empty list * @since 1.548 */ - @Exported(name="actions") + @Exported(name = "actions") @NonNull public final List getAllActions() { List _actions = getActions(); @@ -119,7 +119,7 @@ private Collection createFor(TransientActionFactory taf } } return result; - } catch (Exception e) { + } catch (RuntimeException e) { LOGGER.log(Level.WARNING, "Could not load actions from " + taf + " for " + this, e); return Collections.emptySet(); } @@ -146,10 +146,9 @@ public List getActions(Class type) { * Note: calls to {@link #getAllActions()} that happen before calls to this method may not see the update. * Note: this method will always modify the actions */ - @SuppressWarnings({"ConstantConditions"}) - @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE") + @SuppressWarnings("ConstantConditions") public void addAction(@NonNull Action a) { - if(a==null) { + if (a == null) { throw new IllegalArgumentException("Action must be non-null"); } getActions().add(a); @@ -170,7 +169,6 @@ public void addAction(@NonNull Action a) { * example in cases where the caller would need to persist the {@link Actionable} in order to persist the change * and there is a desire to elide unnecessary persistence of unmodified objects. */ - @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE") public void replaceAction(@NonNull Action a) { addOrReplaceAction(a); } @@ -188,8 +186,7 @@ public void replaceAction(@NonNull Action a) { * @return {@code true} if this actions changed as a result of the call * @since 2.29 */ - @SuppressWarnings({"ConstantConditions"}) - @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE") + @SuppressWarnings("ConstantConditions") public boolean addOrReplaceAction(@NonNull Action a) { if (a == null) { throw new IllegalArgumentException("Action must be non-null"); @@ -246,8 +243,7 @@ public boolean removeAction(@Nullable Action a) { * @return {@code true} if this actions changed as a result of the call * @since 2.29 */ - @SuppressWarnings({"ConstantConditions"}) - @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE") + @SuppressWarnings("ConstantConditions") public boolean removeActions(@NonNull Class clazz) { if (clazz == null) { throw new IllegalArgumentException("Action type must be non-null"); @@ -278,8 +274,7 @@ public boolean removeActions(@NonNull Class clazz) { * @return {@code true} if this actions changed as a result of the call * @since 2.29 */ - @SuppressWarnings({"ConstantConditions"}) - @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE") + @SuppressWarnings("ConstantConditions") public boolean replaceActions(@NonNull Class clazz, @NonNull Action a) { if (clazz == null) { throw new IllegalArgumentException("Action type must be non-null"); @@ -312,14 +307,13 @@ public boolean replaceActions(@NonNull Class clazz, @NonNull A /** @deprecated No clear purpose, since subclasses may have overridden {@link #getActions}, and does not consider {@link TransientActionFactory}. */ @Deprecated public Action getAction(int index) { - if(actions==null) return null; + if (actions == null) return null; return actions.get(index); } /** * Gets the action (first instance to be found) of a specified type that contributed to this build. * - * @param type * @return The action or {@code null} if no such actions exist. * @see #getActions(Class) */ @@ -343,19 +337,19 @@ public T getAction(Class type) { public Object getDynamic(String token, StaplerRequest req, StaplerResponse rsp) { for (Action a : getAllActions()) { - if(a==null) + if (a == null) continue; // be defensive String urlName = a.getUrlName(); - if(urlName==null) + if (urlName == null) continue; - if(urlName.equals(token)) + if (urlName.equals(token)) return a; } return null; } @Override public ContextMenu doContextMenu(StaplerRequest request, StaplerResponse response) throws Exception { - return new ContextMenu().from(this,request,response); + return new ContextMenu().from(this, request, response); } private static final Logger LOGGER = Logger.getLogger(Actionable.class.getName()); diff --git a/core/src/main/java/hudson/model/AdministrativeMonitor.java b/core/src/main/java/hudson/model/AdministrativeMonitor.java index 7d4d7efe4c62..3c70207ff892 100644 --- a/core/src/main/java/hudson/model/AdministrativeMonitor.java +++ b/core/src/main/java/hudson/model/AdministrativeMonitor.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,19 +21,18 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; -import hudson.ExtensionPoint; -import hudson.ExtensionList; import hudson.Extension; +import hudson.ExtensionList; +import hudson.ExtensionPoint; import hudson.ExtensionPoint.LegacyInstancesAreScopedToHudson; import hudson.security.Permission; import hudson.triggers.SCMTrigger; import hudson.triggers.TimerTrigger; - -import java.util.Set; import java.io.IOException; - +import java.util.Set; import jenkins.model.Jenkins; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; @@ -110,13 +109,15 @@ protected AdministrativeMonitor() { * Returns the URL of this monitor, relative to the context path, like "administrativeMonitor/foobar". */ public String getUrl() { - return "administrativeMonitor/"+id; + return "administrativeMonitor/" + id; } + @Override public String getDisplayName() { return id; } + @Override public final String getSearchUrl() { return getUrl(); } @@ -175,7 +176,7 @@ public boolean isSecurity() { public void doDisable(StaplerRequest req, StaplerResponse rsp) throws IOException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); disable(true); - rsp.sendRedirect2(req.getContextPath()+"/manage"); + rsp.sendRedirect2(req.getContextPath() + "/manage"); } /** @@ -201,6 +202,7 @@ public Permission getRequiredPermission() { /** * Ensure that URLs in this administrative monitor are only accessible to users with {@link #getRequiredPermission()}. */ + @Override @Restricted(NoExternalUse.class) public Object getTarget() { Jenkins.get().checkPermission(getRequiredPermission()); diff --git a/core/src/main/java/hudson/model/AllView.java b/core/src/main/java/hudson/model/AllView.java index 485b9669607b..f92773678e03 100644 --- a/core/src/main/java/hudson/model/AllView.java +++ b/core/src/main/java/hudson/model/AllView.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Tom Huybrechts - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,26 +21,25 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import edu.umd.cs.findbugs.annotations.NonNull; +import hudson.Extension; +import hudson.model.Descriptor.FormException; +import java.io.IOException; +import java.util.Collection; import java.util.List; import java.util.Locale; +import java.util.Objects; import java.util.logging.Level; import java.util.logging.Logger; -import edu.umd.cs.findbugs.annotations.NonNull; +import javax.servlet.ServletException; import jenkins.util.SystemProperties; -import org.apache.commons.lang.StringUtils; import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; - -import javax.servlet.ServletException; -import java.io.IOException; -import java.util.Collection; - -import hudson.model.Descriptor.FormException; -import hudson.Extension; import org.kohsuke.stapler.interceptor.RequirePOST; /** @@ -74,7 +73,7 @@ public AllView(String name, ViewGroup owner) { this(name); this.owner = owner; } - + @Override public boolean isEditable() { return false; @@ -96,13 +95,13 @@ public Item doCreateItem(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { ItemGroup ig = getOwner().getItemGroup(); if (ig instanceof ModifiableItemGroup) - return ((ModifiableItemGroup)ig).doCreateItem(req, rsp); + return ((ModifiableItemGroup) ig).doCreateItem(req, rsp); return null; } @Override public Collection getItems() { - return (Collection)getOwner().getItemGroup().getItems(); + return (Collection) getOwner().getItemGroup().getItems(); } @Override @@ -140,14 +139,14 @@ public static String migrateLegacyPrimaryAllViewLocalizedName(@NonNull List * This class is similar to {@link PeriodicWork}. The main difference is in re-evaluating delay interval every time. * See {@link PeriodicWork} for details. Analog of {@link AsyncPeriodicWork} is {@link AsyncAperiodicWork}. - * + * * @author vjuranek * @since 1.410 */ +@SuppressFBWarnings(value = "PREDICTABLE_RANDOM", justification = "The random is just used for an initial delay.") public abstract class AperiodicWork extends SafeTimerTask implements ExtensionPoint { - - protected final Logger logger = Logger.getLogger(getClass().getName()); - + + protected final Logger logger = Logger.getLogger(getClass().getName()); + /** * Gets the number of milliseconds between successive executions. * *

    - * Jenkins calls this method every time the timer task is scheduled. + * Jenkins calls this method every time the timer task is scheduled. * */ public abstract long getRecurrencePeriod(); /** - * Gets new instance of task to be executed. Method should return new instance each time, as there no check, if previously + * Gets new instance of task to be executed. Method should return new instance each time, as there no check, if previously * scheduled task already finished. Returning same instance could lead to throwing {@link IllegalStateException} (especially * in case of {@link AsyncAperiodicWork}) and therefore scheduling of next tasks will be broken. - * + * * @return AperiodicWork - timer task instance to be executed */ public abstract AperiodicWork getNewInstance(); - + /** * Gets the number of milliseconds till the first execution. * @@ -81,18 +82,18 @@ public abstract class AperiodicWork extends SafeTimerTask implements ExtensionPo public long getInitialDelay() { long l = RANDOM.nextLong(); // Math.abs(Long.MIN_VALUE)==Long.MIN_VALUE! - if (l==Long.MIN_VALUE) + if (l == Long.MIN_VALUE) l++; - return Math.abs(l)%getRecurrencePeriod(); + return Math.abs(l) % getRecurrencePeriod(); } @Override - public final void doRun() throws Exception{ - doAperiodicRun(); + public final void doRun() throws Exception { + doAperiodicRun(); Timer.get().schedule(getNewInstance(), getRecurrencePeriod(), TimeUnit.MILLISECONDS); } - @Initializer(after= JOB_CONFIG_ADAPTED) + @Initializer(after = JOB_CONFIG_ADAPTED) public static void init() { // start all AperidocWorks ExtensionList extensionList = all(); @@ -107,7 +108,7 @@ private static void scheduleAperiodWork(AperiodicWork ap) { } protected abstract void doAperiodicRun(); - + /** * Returns all the registered {@link AperiodicWork}s. */ diff --git a/core/src/main/java/hudson/model/Api.java b/core/src/main/java/hudson/model/Api.java index ccf30f01bcda..11db76c3581d 100644 --- a/core/src/main/java/hudson/model/Api.java +++ b/core/src/main/java/hudson/model/Api.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, Seiji Sogabe - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,13 +21,25 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import hudson.ExtensionList; -import jenkins.util.xml.FilteredFunctionContext; +import java.io.IOException; +import java.io.OutputStream; +import java.io.StringReader; +import java.io.StringWriter; +import java.net.HttpURLConnection; +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletResponse; +import javax.xml.transform.stream.StreamResult; import jenkins.model.Jenkins; import jenkins.security.SecureRequester; - +import jenkins.util.xml.FilteredFunctionContext; import org.dom4j.CharacterData; import org.dom4j.Document; import org.dom4j.DocumentException; @@ -36,27 +48,20 @@ import org.dom4j.XPath; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; -import org.kohsuke.stapler.export.*; +import org.kohsuke.stapler.export.Exported; +import org.kohsuke.stapler.export.Flavor; +import org.kohsuke.stapler.export.Model; +import org.kohsuke.stapler.export.ModelBuilder; +import org.kohsuke.stapler.export.NamedPathPruner; +import org.kohsuke.stapler.export.SchemaGenerator; +import org.kohsuke.stapler.export.TreePruner; import org.kohsuke.stapler.export.TreePruner.ByDepth; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletResponse; -import javax.xml.transform.stream.StreamResult; -import java.io.IOException; -import java.io.OutputStream; -import java.io.StringReader; -import java.io.StringWriter; -import java.net.HttpURLConnection; -import java.nio.charset.StandardCharsets; -import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; -import org.kohsuke.accmod.Restricted; -import org.kohsuke.accmod.restrictions.NoExternalUse; - /** * Used to expose remote access API for ".../api/" * @@ -78,10 +83,12 @@ public Api(Object bean) { this.bean = bean; } + @Override public String getDisplayName() { return "API"; } + @Override public String getSearchUrl() { return "api"; } @@ -98,9 +105,9 @@ public void doXml(StaplerRequest req, StaplerResponse rsp, String[] excludes = req.getParameterValues("exclude"); - if(xpath==null && excludes==null) { + if (xpath == null && excludes == null) { // serve the whole thing - rsp.serveExposedBean(req,bean,Flavor.XML); + rsp.serveExposedBean(req, bean, Flavor.XML); return; } @@ -108,8 +115,8 @@ public void doXml(StaplerRequest req, StaplerResponse rsp, // first write to String Model p = MODEL_BUILDER.get(bean.getClass()); - TreePruner pruner = (tree!=null) ? new NamedPathPruner(tree) : new ByDepth(1 - depth); - p.writeTo(bean,pruner,Flavor.XML.createDataWriter(bean,sw)); + TreePruner pruner = tree != null ? new NamedPathPruner(tree) : new ByDepth(1 - depth); + p.writeTo(bean, pruner, Flavor.XML.createDataWriter(bean, sw)); // apply XPath FilteredFunctionContext functionContext = new FilteredFunctionContext(); @@ -117,33 +124,33 @@ public void doXml(StaplerRequest req, StaplerResponse rsp, try { Document dom = new SAXReader().read(new StringReader(sw.toString())); // apply exclusions - if (excludes!=null) { + if (excludes != null) { for (String exclude : excludes) { XPath xExclude = dom.createXPath(exclude); xExclude.setFunctionContext(functionContext); - List list = (List)xExclude.selectNodes(dom); + List list = xExclude.selectNodes(dom); for (org.dom4j.Node n : list) { Element parent = n.getParent(); - if(parent!=null) + if (parent != null) parent.remove(n); } } } - - if(xpath==null) { - result = dom; + + if (xpath == null) { + result = dom; } else { XPath comp = dom.createXPath(xpath); comp.setFunctionContext(functionContext); List list = comp.selectNodes(dom); - if (wrapper!=null) { + if (wrapper != null) { // check if the wrapper is a valid entity name // First position: letter or underscore // Other positions: \w (letter, number, underscore), dash or dot String validNameRE = "^[a-zA-Z_][\\w-\\.]*$"; - if(!wrapper.matches(validNameRE)) { + if (!wrapper.matches(validNameRE)) { rsp.setStatus(HttpServletResponse.SC_BAD_REQUEST); rsp.getWriter().print(Messages.Api_WrapperParamInvalid()); return; @@ -154,7 +161,7 @@ public void doXml(StaplerRequest req, StaplerResponse rsp, if (o instanceof String) { root.addText(o.toString()); } else { - root.add(((org.dom4j.Node)o).detach()); + root.add(((org.dom4j.Node) o).detach()); } } result = root; @@ -164,7 +171,7 @@ public void doXml(StaplerRequest req, StaplerResponse rsp, return; } else if (list.size() > 1) { rsp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - rsp.getWriter().print(Messages.Api_MultipleMatch(xpath,list.size())); + rsp.getWriter().print(Messages.Api_MultipleMatch(xpath, list.size())); return; } else { result = list.get(0); @@ -172,8 +179,8 @@ public void doXml(StaplerRequest req, StaplerResponse rsp, } } catch (DocumentException e) { - LOGGER.log(Level.FINER, "Failed to do XPath/wrapper handling. XML is as follows:"+sw, e); - throw new IOException("Failed to do XPath/wrapper handling. Turn on FINER logging to view XML.",e); + LOGGER.log(Level.FINER, "Failed to do XPath/wrapper handling. XML is as follows:" + sw, e); + throw new IOException("Failed to do XPath/wrapper handling. Turn on FINER logging to view XML.", e); } @@ -220,7 +227,7 @@ public void doSchema(StaplerRequest req, StaplerResponse rsp) throws IOException public void doJson(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { if (req.getParameter("jsonp") == null || permit(req)) { setHeaders(rsp); - rsp.serveExposedBean(req,bean, req.getParameter("jsonp") == null ? Flavor.JSON : Flavor.JSONP); + rsp.serveExposedBean(req, bean, req.getParameter("jsonp") == null ? Flavor.JSON : Flavor.JSONP); } else { rsp.sendError(HttpURLConnection.HTTP_FORBIDDEN, "jsonp forbidden; implement jenkins.security.SecureRequester"); } @@ -231,7 +238,7 @@ public void doJson(StaplerRequest req, StaplerResponse rsp) throws IOException, */ public void doPython(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { setHeaders(rsp); - rsp.serveExposedBean(req,bean, Flavor.PYTHON); + rsp.serveExposedBean(req, bean, Flavor.PYTHON); } private boolean permit(StaplerRequest req) { diff --git a/core/src/main/java/hudson/model/AsyncAperiodicWork.java b/core/src/main/java/hudson/model/AsyncAperiodicWork.java index b9b705d8bc0b..294b471f990f 100644 --- a/core/src/main/java/hudson/model/AsyncAperiodicWork.java +++ b/core/src/main/java/hudson/model/AsyncAperiodicWork.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import hudson.Functions; @@ -37,8 +38,8 @@ /** * {@link AperiodicWork} that takes a long time to run. Similar to {@link AsyncPeriodicWork}, see {@link AsyncPeriodicWork} for - * details and {@link AperiodicWork} for differences between {@link AperiodicWork} and {@link PeriodicWork}. - * + * details and {@link AperiodicWork} for differences between {@link AperiodicWork} and {@link PeriodicWork}. + * * @author vjuranek * @since 1.410 */ @@ -94,8 +95,8 @@ public abstract class AsyncAperiodicWork extends AperiodicWork { protected AsyncAperiodicWork(String name) { this.name = name; this.logRotateMillis = TimeUnit.MINUTES.toMillis( - SystemProperties.getLong(getClass().getName()+".logRotateMinutes", LOG_ROTATE_MINUTES)); - this.logRotateSize = SystemProperties.getLong(getClass().getName() +".logRotateSize", LOG_ROTATE_SIZE); + SystemProperties.getLong(getClass().getName() + ".logRotateMinutes", LOG_ROTATE_MINUTES)); + this.logRotateSize = SystemProperties.getLong(getClass().getName() + ".logRotateSize", LOG_ROTATE_SIZE); } /** @@ -104,7 +105,7 @@ protected AsyncAperiodicWork(String name) { @Override public final void doAperiodicRun() { try { - if(thread!=null && thread.isAlive()) { + if (thread != null && thread.isAlive()) { logger.log(getSlowLoggingLevel(), "{0} thread is still running. Execution aborted.", name); return; } @@ -113,29 +114,24 @@ public final void doAperiodicRun() { long startTime = System.currentTimeMillis(); long stopTime; - StreamTaskListener l = createListener(); + AsyncPeriodicWork.LazyTaskListener l = new AsyncPeriodicWork.LazyTaskListener(() -> createListener(), String.format("Started at %tc", new Date(startTime))); try (ACLContext ctx = ACL.as2(ACL.SYSTEM2)) { - l.getLogger().printf("Started at %tc%n", new Date(startTime)); - execute(l); + execute(l); } catch (IOException e) { Functions.printStackTrace(e, l.fatalError(e.getMessage())); } catch (InterruptedException e) { Functions.printStackTrace(e, l.fatalError("aborted")); } finally { stopTime = System.currentTimeMillis(); - try { - l.getLogger().printf("Finished at %tc. %dms%n", new Date(stopTime), stopTime - startTime); - } finally { - l.closeQuietly(); - } + l.close(String.format("Finished at %tc. %dms", new Date(stopTime), stopTime - startTime)); } logger.log(getNormalLoggingLevel(), "Finished {0}. {1,number} ms", new Object[]{name, stopTime - startTime}); - },name+" thread"); - thread.start(); + }, name + " thread"); + thread.start(); } catch (Throwable t) { - logger.log(Level.SEVERE, name+" thread failed with error", t); + logger.log(Level.SEVERE, name + " thread failed with error", t); } } @@ -147,7 +143,7 @@ protected StreamTaskListener createListener() { } } if (f.isFile()) { - if ((lastRotateMillis + logRotateMillis < System.currentTimeMillis()) + if (lastRotateMillis + logRotateMillis < System.currentTimeMillis() || (logRotateSize > 0 && f.length() > logRotateSize)) { lastRotateMillis = System.currentTimeMillis(); File prev = null; diff --git a/core/src/main/java/hudson/model/AsyncPeriodicWork.java b/core/src/main/java/hudson/model/AsyncPeriodicWork.java index c0ae6eb5c18f..3b75984454f2 100644 --- a/core/src/main/java/hudson/model/AsyncPeriodicWork.java +++ b/core/src/main/java/hudson/model/AsyncPeriodicWork.java @@ -6,8 +6,10 @@ import hudson.util.StreamTaskListener; import java.io.File; import java.io.IOException; +import java.io.PrintStream; import java.util.Date; import java.util.concurrent.TimeUnit; +import java.util.function.Supplier; import java.util.logging.Level; import java.util.logging.LogRecord; import jenkins.model.Jenkins; @@ -81,10 +83,11 @@ protected AsyncPeriodicWork(String name) { /** * Schedules this periodic work now in a new thread, if one isn't already running. */ + @Override @SuppressWarnings("deprecation") // in this case we really want to use PeriodicWork.logger since it reports the impl class public final void doRun() { try { - if(thread!=null && thread.isAlive()) { + if (thread != null && thread.isAlive()) { logger.log(this.getSlowLoggingLevel(), "{0} thread is still running. Execution aborted.", name); return; } @@ -93,9 +96,8 @@ public final void doRun() { long startTime = System.currentTimeMillis(); long stopTime; - StreamTaskListener l = createListener(); + LazyTaskListener l = new LazyTaskListener(() -> createListener(), String.format("Started at %tc", new Date(startTime))); try { - l.getLogger().printf("Started at %tc%n", new Date(startTime)); try (ACLContext ctx = ACL.as2(ACL.SYSTEM2)) { execute(l); } @@ -105,16 +107,12 @@ public final void doRun() { Functions.printStackTrace(e, l.fatalError("aborted")); } finally { stopTime = System.currentTimeMillis(); - try { - l.getLogger().printf("Finished at %tc. %dms%n", new Date(stopTime), stopTime - startTime); - } finally { - l.closeQuietly(); - } + l.close(String.format("Finished at %tc. %dms", new Date(stopTime), stopTime - startTime)); } logger.log(getNormalLoggingLevel(), "Finished {0}. {1,number} ms", new Object[]{name, stopTime - startTime}); - },name+" thread"); + }, name + " thread"); thread.start(); } catch (Throwable t) { LogRecord lr = new LogRecord(this.getErrorLoggingLevel(), "{0} thread failed with error"); @@ -124,6 +122,38 @@ public final void doRun() { } } + static final class LazyTaskListener implements TaskListener { + + private final Supplier supplier; + private final String openingMessage; + private StreamTaskListener delegate; + + LazyTaskListener(Supplier supplier, String openingMessage) { + this.supplier = supplier; + this.openingMessage = openingMessage; + } + + @Override + public synchronized PrintStream getLogger() { + if (delegate == null) { + delegate = supplier.get(); + delegate.getLogger().println(openingMessage); + } + return delegate.getLogger(); + } + + synchronized void close(String closingMessage) { + if (delegate != null) { + try { + delegate.getLogger().println(closingMessage); + } finally { + delegate.closeQuietly(); + } + } + } + + } + protected StreamTaskListener createListener() { File f = getLogFile(); if (!f.getParentFile().isDirectory()) { @@ -132,7 +162,7 @@ protected StreamTaskListener createListener() { } } if (f.isFile()) { - if ((lastRotateMillis + logRotateMillis < System.currentTimeMillis()) + if (lastRotateMillis + logRotateMillis < System.currentTimeMillis() || (logRotateSize > 0 && f.length() > logRotateSize)) { lastRotateMillis = System.currentTimeMillis(); File prev = null; @@ -184,11 +214,11 @@ protected StreamTaskListener createListener() { protected File getLogFile() { return new File(getLogsRoot(), "/tasks/" + name + ".log"); } - + /** * Returns the logging level at which normal messages are displayed. - * - * @return + * + * @return * The logging level as @Level. * * @since 1.551 @@ -196,7 +226,7 @@ protected File getLogFile() { protected Level getNormalLoggingLevel() { return Level.INFO; } - + /** * Returns the logging level at which previous task still executing messages is displayed. * @@ -211,8 +241,8 @@ protected Level getSlowLoggingLevel() { /** * Returns the logging level at which error messages are displayed. - * - * @return + * + * @return * The logging level as @Level. * * @since 1.551 @@ -220,7 +250,7 @@ protected Level getSlowLoggingLevel() { protected Level getErrorLoggingLevel() { return Level.SEVERE; } - + /** * Executes the task. * diff --git a/core/src/main/java/hudson/model/AutoCompletionCandidates.java b/core/src/main/java/hudson/model/AutoCompletionCandidates.java index a54c6d6c7c9c..dbc3f6ea1c18 100644 --- a/core/src/main/java/hudson/model/AutoCompletionCandidates.java +++ b/core/src/main/java/hudson/model/AutoCompletionCandidates.java @@ -24,21 +24,21 @@ package hudson.model; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.search.Search; import hudson.search.UserSearchProperty; -import jenkins.model.Jenkins; -import org.kohsuke.stapler.HttpResponse; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; -import org.kohsuke.stapler.export.Flavor; - -import javax.servlet.ServletException; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import edu.umd.cs.findbugs.annotations.CheckForNull; +import javax.servlet.ServletException; +import jenkins.model.Jenkins; import org.apache.commons.lang.StringUtils; +import org.kohsuke.stapler.HttpResponse; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.export.Flavor; /** * Data representation of the auto-completion candidates. @@ -68,12 +68,13 @@ public List getValues() { return values; } + @Override public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object o) throws IOException, ServletException { Search.Result r = new Search.Result(); for (String value : values) { r.suggestions.add(new hudson.search.Search.Item(value)); } - rsp.serveExposedBean(req,r, Flavor.JSON); + rsp.serveExposedBean(req, r, Flavor.JSON); } /** @@ -91,7 +92,7 @@ public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object o) * @since 1.489 */ public static AutoCompletionCandidates ofJobNames(final Class type, final String value, @CheckForNull Item self, ItemGroup container) { - if (self==container) + if (self == container) container = self.getParent(); return ofJobNames(type, value, container); } @@ -108,6 +109,7 @@ public static AutoCompletionCandidates ofJobNames(final Class AutoCompletionCandidates ofJobNames(final Class type, final String value, ItemGroup container) { final AutoCompletionCandidates candidates = new AutoCompletionCandidates(); class Visitor extends ItemVisitor { @@ -120,7 +122,7 @@ class Visitor extends ItemVisitor { @Override public void onItem(Item i) { String itemName = contextualNameOf(i); - + //Check user's setting on whether to do case sensitive comparison, configured in user -> configure //This is the same setting that is used by the global search field, should be consistent throughout //the whole application. @@ -129,7 +131,7 @@ public void onItem(Item i) { if ((startsWithImpl(itemName, value, caseInsensitive) || startsWithImpl(value, itemName, caseInsensitive)) // 'foobar' is a valid candidate if the current value is 'foo'. // Also, we need to visit 'foo' if the current value is 'foo/bar' - && (value.length()> itemName.length() || !itemName.substring(value.length()).contains("/")) + && (value.length() > itemName.length() || !itemName.substring(value.length()).contains("/")) // but 'foobar/zot' isn't if the current value is 'foo' // we'll first show 'foobar' and then wait for the user to type '/' to show the rest && i.hasPermission(Item.READ) @@ -147,22 +149,22 @@ public void onItem(Item i) { } private String contextualNameOf(Item i) { - if (prefix.endsWith("/") || prefix.length()==0) - return prefix+i.getName(); + if (prefix.endsWith("/") || prefix.length() == 0) + return prefix + i.getName(); else - return prefix+'/'+i.getName(); + return prefix + '/' + i.getName(); } } - if (container==null || container==Jenkins.get()) { + if (container == null || container == Jenkins.get()) { new Visitor("").onItemGroup(Jenkins.get()); } else { new Visitor("").onItemGroup(container); if (value.startsWith("/")) new Visitor("/").onItemGroup(Jenkins.get()); - for ( String p="../"; value.startsWith(p); p+="../") { - container = ((Item)container).getParent(); + for (String p = "../"; value.startsWith(p); p += "../") { + container = ((Item) container).getParent(); new Visitor(p).onItemGroup(container); } } diff --git a/core/src/main/java/hudson/model/BallColor.java b/core/src/main/java/hudson/model/BallColor.java index c0872aedfce6..5913f59466f9 100644 --- a/core/src/main/java/hudson/model/BallColor.java +++ b/core/src/main/java/hudson/model/BallColor.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Simon Wiest - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,24 +21,24 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import hudson.util.ColorPalette; +import java.awt.Color; +import java.util.Locale; import jenkins.model.Jenkins; import org.jenkins.ui.icon.Icon; import org.jvnet.localizer.LocaleProvider; import org.jvnet.localizer.Localizable; import org.kohsuke.stapler.Stapler; -import java.awt.*; -import java.util.Locale; - /** * Ball color used for the build status indication. * *

    * There are four basic colors, plus their animated "bouncy" versions. - * {@link #ordinal()} is the sort order. + * {@link #ordinal()} is the sort order. * *

    * Note that multiple {@link BallColor} instances may map to the same @@ -49,27 +49,27 @@ * Hudson started to overload colors — for example grey could mean * either disabled, aborted, or not yet built. As a result, {@link BallColor} * becomes more like a "logical" color, in the sense that different {@link BallColor} - * values can map to the same RGB color. See issue #956. + * values can map to the same RGB color. See JENKINS-956. * * @author Kohsuke Kawaguchi */ public enum BallColor implements StatusIcon { - RED("red",Messages._BallColor_Failed(), ColorPalette.RED), - RED_ANIME("red_anime",Messages._BallColor_InProgress(), ColorPalette.RED), - YELLOW("yellow",Messages._BallColor_Unstable(), ColorPalette.YELLOW), - YELLOW_ANIME("yellow_anime",Messages._BallColor_InProgress(), ColorPalette.YELLOW), - BLUE("blue",Messages._BallColor_Success(), ColorPalette.BLUE), - BLUE_ANIME("blue_anime",Messages._BallColor_InProgress(), ColorPalette.BLUE), + RED("red", Messages._BallColor_Failed(), ColorPalette.RED), + RED_ANIME("red_anime", Messages._BallColor_InProgress(), ColorPalette.RED), + YELLOW("yellow", Messages._BallColor_Unstable(), ColorPalette.YELLOW), + YELLOW_ANIME("yellow_anime", Messages._BallColor_InProgress(), ColorPalette.YELLOW), + BLUE("blue", Messages._BallColor_Success(), ColorPalette.BLUE), + BLUE_ANIME("blue_anime", Messages._BallColor_InProgress(), ColorPalette.BLUE), // for historical reasons they are called grey. - GREY("grey",Messages._BallColor_Disabled(), ColorPalette.GREY), - GREY_ANIME("grey_anime",Messages._BallColor_InProgress(), ColorPalette.GREY), - - DISABLED("disabled",Messages._BallColor_Disabled(), ColorPalette.GREY), - DISABLED_ANIME("disabled_anime",Messages._BallColor_InProgress(), ColorPalette.GREY), - ABORTED("aborted",Messages._BallColor_Aborted(), ColorPalette.DARK_GREY), - ABORTED_ANIME("aborted_anime",Messages._BallColor_InProgress(), ColorPalette.DARK_GREY), - NOTBUILT("nobuilt",Messages._BallColor_NotBuilt(), ColorPalette.LIGHT_GREY), - NOTBUILT_ANIME("nobuilt_anime",Messages._BallColor_InProgress(), ColorPalette.LIGHT_GREY), + GREY("grey", Messages._BallColor_Disabled(), ColorPalette.GREY), + GREY_ANIME("grey_anime", Messages._BallColor_InProgress(), ColorPalette.GREY), + + DISABLED("disabled", Messages._BallColor_Disabled(), ColorPalette.GREY), + DISABLED_ANIME("disabled_anime", Messages._BallColor_InProgress(), ColorPalette.GREY), + ABORTED("aborted", Messages._BallColor_Aborted(), ColorPalette.DARK_GREY), + ABORTED_ANIME("aborted_anime", Messages._BallColor_InProgress(), ColorPalette.DARK_GREY), + NOTBUILT("nobuilt", Messages._BallColor_NotBuilt(), ColorPalette.LIGHT_GREY), + NOTBUILT_ANIME("nobuilt_anime", Messages._BallColor_InProgress(), ColorPalette.LIGHT_GREY) ; private final Localizable description; @@ -84,7 +84,7 @@ public enum BallColor implements StatusIcon { this.baseColor = baseColor; // name() is not usable in the constructor, so I have to repeat the name twice // in the constants definition. - this.image = image+ (image.endsWith("_anime")?".gif":".png"); + this.image = image + (image.endsWith("_anime") ? ".gif" : ".png"); this.description = description; } @@ -111,13 +111,15 @@ public String getImage() { return image; } + @Override public String getImageOf(String size) { - return Stapler.getCurrentRequest().getContextPath()+ Jenkins.RESOURCE_PATH+"/images/"+size+'/'+image; + return Stapler.getCurrentRequest().getContextPath() + Jenkins.RESOURCE_PATH + "/images/" + size + '/' + image; } /** * Gets the human-readable description used as img/@alt. */ + @Override public String getDescription() { return description.toString(LocaleProvider.getLocale()); } @@ -148,15 +150,15 @@ public String toString() { * Gets the animated version. */ public BallColor anime() { - if(isAnimated()) return this; - else return valueOf(name()+"_ANIME"); + if (isAnimated()) return this; + else return valueOf(name() + "_ANIME"); } /** * Gets the unanimated version. */ public BallColor noAnime() { - if(isAnimated()) return valueOf(name().substring(0,name().length()-"_ANIME".length())); + if (isAnimated()) return valueOf(name().substring(0, name().length() - "_ANIME".length())); else return this; } diff --git a/core/src/main/java/hudson/model/BooleanParameterDefinition.java b/core/src/main/java/hudson/model/BooleanParameterDefinition.java index a65fc4789bd6..d4958d9ea297 100644 --- a/core/src/main/java/hudson/model/BooleanParameterDefinition.java +++ b/core/src/main/java/hudson/model/BooleanParameterDefinition.java @@ -21,16 +21,19 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; -import org.jenkinsci.Symbol; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.DataBoundConstructor; -import net.sf.json.JSONObject; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.Extension; - import java.util.Objects; +import net.sf.json.JSONObject; +import org.jenkinsci.Symbol; +import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.DataBoundSetter; +import org.kohsuke.stapler.StaplerRequest; /** * {@link ParameterDefinition} that is either 'true' or 'false'. @@ -44,11 +47,11 @@ public class BooleanParameterDefinition extends SimpleParameterDefinition { * @since 2.281 */ @DataBoundConstructor - public BooleanParameterDefinition(String name) { + public BooleanParameterDefinition(@NonNull String name) { super(name); } - public BooleanParameterDefinition(String name, boolean defaultValue, String description) { + public BooleanParameterDefinition(@NonNull String name, boolean defaultValue, @CheckForNull String description) { this(name); setDefaultValue(defaultValue); setDescription(description); @@ -83,8 +86,9 @@ public ParameterValue createValue(StaplerRequest req, JSONObject jo) { return value; } + @Override public ParameterValue createValue(String value) { - return new BooleanParameterValue(getName(),Boolean.parseBoolean(value),getDescription()); + return new BooleanParameterValue(getName(), Boolean.parseBoolean(value), getDescription()); } @Override @@ -101,6 +105,7 @@ public int hashCode() { } @Override + @SuppressFBWarnings(value = "EQ_GETCLASS_AND_CLASS_CONSTANT", justification = "ParameterDefinitionTest tests that subclasses are not equal to their parent classes, so the behavior appears to be intentional") public boolean equals(Object obj) { if (BooleanParameterDefinition.class != getClass()) return super.equals(obj); @@ -120,7 +125,7 @@ public boolean equals(Object obj) { // unlike all the other ParameterDescriptors, using 'booleanParam' as the primary // to avoid picking the Java reserved word "boolean" as the primary identifier - @Extension @Symbol({"booleanParam"}) + @Extension @Symbol("booleanParam") public static class DescriptorImpl extends ParameterDescriptor { @Override public String getDisplayName() { diff --git a/core/src/main/java/hudson/model/BooleanParameterValue.java b/core/src/main/java/hudson/model/BooleanParameterValue.java index 7d69a903d7e4..d449623301cc 100644 --- a/core/src/main/java/hudson/model/BooleanParameterValue.java +++ b/core/src/main/java/hudson/model/BooleanParameterValue.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Luca Domenico Milanesio, Tom Huybrechts - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,21 +21,20 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import hudson.EnvVars; +import hudson.util.VariableResolver; +import java.util.Locale; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.export.Exported; -import java.util.Locale; - -import hudson.util.VariableResolver; - /** * {@link ParameterValue} created from {@link BooleanParameterDefinition}. */ public class BooleanParameterValue extends ParameterValue { - @Exported(visibility=4) + @Exported(visibility = 4) public final boolean value; @DataBoundConstructor @@ -57,18 +56,14 @@ public Boolean getValue() { * Exposes the name/value as an environment variable. */ @Override - public void buildEnvironment(Run build, EnvVars env) { - env.put(name,Boolean.toString(value)); - env.put(name.toUpperCase(Locale.ENGLISH),Boolean.toString(value)); // backward compatibility pre 1.345 + public void buildEnvironment(Run build, EnvVars env) { + env.put(name, Boolean.toString(value)); + env.put(name.toUpperCase(Locale.ENGLISH), Boolean.toString(value)); // backward compatibility pre 1.345 } @Override public VariableResolver createVariableResolver(AbstractBuild build) { - return new VariableResolver() { - public String resolve(String name) { - return BooleanParameterValue.this.name.equals(name) ? Boolean.toString(value) : null; - } - }; + return name -> BooleanParameterValue.this.name.equals(name) ? Boolean.toString(value) : null; } @Override @@ -91,7 +86,7 @@ public int hashCode() { @Override public String toString() { - return "(BooleanParameterValue) " + getName() + "='" + value + "'"; + return "(BooleanParameterValue) " + getName() + "='" + value + "'"; } @Override public String getShortDescription() { diff --git a/core/src/main/java/hudson/model/Build.java b/core/src/main/java/hudson/model/Build.java index 19329a1b0299..49d126b8e848 100644 --- a/core/src/main/java/hudson/model/Build.java +++ b/core/src/main/java/hudson/model/Build.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Martin Eigenbrodt - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,29 +21,29 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import static hudson.model.Result.FAILURE; + +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.Functions; import hudson.Launcher; import hudson.tasks.BuildStep; import hudson.tasks.BuildWrapper; import hudson.tasks.Builder; -import hudson.tasks.Recorder; import hudson.tasks.Notifier; -import org.kohsuke.accmod.Restricted; -import org.kohsuke.accmod.restrictions.NoExternalUse; - +import hudson.tasks.Recorder; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; import java.util.List; -import java.util.logging.Logger; import java.util.logging.Level; - -import static hudson.model.Result.FAILURE; -import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.logging.Logger; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; /** * A build of a {@link Project}. @@ -79,12 +79,12 @@ * *

    * And beyond that, the build is considered complete, and from then on {@link Build} object is there to - * keep the record of what happened in this build. + * keep the record of what happened in this build. * * @author Kohsuke Kawaguchi */ -public abstract class Build

    ,B extends Build> - extends AbstractBuild { +public abstract class Build

    , B extends Build> + extends AbstractBuild { /** * Creates a new build. @@ -101,7 +101,7 @@ protected Build(P job, Calendar timestamp) { * Loads a build from a log file. */ protected Build(P project, File buildDir) throws IOException { - super(project,buildDir); + super(project, buildDir); } // @@ -139,28 +139,29 @@ protected class BuildExecution extends AbstractRunner { deprecated class here. */ + @Override protected Result doRun(@NonNull BuildListener listener) throws Exception { - if(!preBuild(listener,project.getBuilders())) + if (!preBuild(listener, project.getBuilders())) return FAILURE; - if(!preBuild(listener,project.getPublishersList())) + if (!preBuild(listener, project.getPublishersList())) return FAILURE; Result r = null; try { List wrappers = new ArrayList<>(project.getBuildWrappers().values()); - + ParametersAction parameters = getAction(ParametersAction.class); if (parameters != null) - parameters.createBuildWrappers(Build.this,wrappers); + parameters.createBuildWrappers(Build.this, wrappers); - for( BuildWrapper w : wrappers ) { - Environment e = w.setUp((AbstractBuild)Build.this, launcher, listener); - if(e==null) - return (r = FAILURE); + for (BuildWrapper w : wrappers) { + Environment e = w.setUp((AbstractBuild) Build.this, launcher, listener); + if (e == null) + return r = FAILURE; buildEnvironments.add(e); } - if(!build(listener,project.getBuilders())) + if (!build(listener, project.getBuilders())) r = FAILURE; } catch (InterruptedException e) { r = Executor.currentExecutor().abortResult(); @@ -173,6 +174,7 @@ protected Result doRun(@NonNull BuildListener listener) throws Exception { return r; } + @Override public void post2(@NonNull BuildListener listener) throws IOException, InterruptedException { if (!performAllBuildSteps(listener, project.getPublishersList(), true)) setResult(FAILURE); @@ -193,12 +195,12 @@ public void cleanUp(@NonNull BuildListener listener) throws Exception { } private boolean build(@NonNull BuildListener listener, @NonNull Collection steps) throws IOException, InterruptedException { - for( BuildStep bs : steps ) { - if(!perform(bs,listener)) { + for (BuildStep bs : steps) { + if (!perform(bs, listener)) { LOGGER.log(Level.FINE, "{0} : {1} failed", new Object[] {Build.this, bs}); return false; } - + Executor executor = getExecutor(); if (executor != null && executor.isInterrupted()) { // someone asked build interruption, let stop the build before trying to run another build step diff --git a/core/src/main/java/hudson/model/BuildAuthorizationToken.java b/core/src/main/java/hudson/model/BuildAuthorizationToken.java index 5c31e1fadabf..f101eb3d6e74 100644 --- a/core/src/main/java/hudson/model/BuildAuthorizationToken.java +++ b/core/src/main/java/hudson/model/BuildAuthorizationToken.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,19 +21,18 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; import hudson.Util; import hudson.security.ACL; -import jenkins.model.Jenkins; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; - import java.io.IOException; import javax.servlet.http.HttpServletResponse; import jenkins.security.ApiTokenProperty; import org.kohsuke.stapler.HttpResponses; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; import org.springframework.security.access.AccessDeniedException; /** @@ -56,22 +55,19 @@ public BuildAuthorizationToken(String token) { public static BuildAuthorizationToken create(StaplerRequest req) { if (req.getParameter("pseudoRemoteTrigger") != null) { String token = Util.fixEmpty(req.getParameter("authToken")); - if(token!=null) + if (token != null) return new BuildAuthorizationToken(token); } - + return null; } - @Deprecated public static void checkPermission(AbstractProject project, BuildAuthorizationToken token, StaplerRequest req, StaplerResponse rsp) throws IOException { - checkPermission((Job) project, token, req, rsp); + @Deprecated public static void checkPermission(AbstractProject project, BuildAuthorizationToken token, StaplerRequest req, StaplerResponse rsp) throws IOException { + checkPermission((Job) project, token, req, rsp); } - public static void checkPermission(Job project, BuildAuthorizationToken token, StaplerRequest req, StaplerResponse rsp) throws IOException { - if (!Jenkins.get().isUseSecurity()) - return; // everyone is authorized - - if(token!=null && token.token != null) { + public static void checkPermission(Job project, BuildAuthorizationToken token, StaplerRequest req, StaplerResponse rsp) throws IOException { + if (token != null && token.token != null) { //check the provided token String providedToken = req.getParameter("token"); if (providedToken != null && providedToken.equals(token.token)) @@ -100,17 +96,19 @@ public String getToken() { } public static final class ConverterImpl extends AbstractSingleValueConverter { + @Override public boolean canConvert(Class type) { - return type== BuildAuthorizationToken.class; + return type == BuildAuthorizationToken.class; } + @Override public Object fromString(String str) { return new BuildAuthorizationToken(str); } @Override public String toString(Object obj) { - return ((BuildAuthorizationToken)obj).token; + return ((BuildAuthorizationToken) obj).token; } } } diff --git a/core/src/main/java/hudson/model/BuildBadgeAction.java b/core/src/main/java/hudson/model/BuildBadgeAction.java index 3a673f955835..da848424eeaf 100644 --- a/core/src/main/java/hudson/model/BuildBadgeAction.java +++ b/core/src/main/java/hudson/model/BuildBadgeAction.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; /** @@ -29,7 +30,7 @@ * *

    * This can be implemented by {@link Action}s that associate themselves - * with {@link Run}. + * with {@link Run}. * *

    * Actions with this marker should have a view {@code badge.jelly}, diff --git a/core/src/main/java/hudson/model/BuildListener.java b/core/src/main/java/hudson/model/BuildListener.java index 10043b633b22..0f8fc060f27e 100644 --- a/core/src/main/java/hudson/model/BuildListener.java +++ b/core/src/main/java/hudson/model/BuildListener.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import java.io.PrintStream; diff --git a/core/src/main/java/hudson/model/BuildTimelineWidget.java b/core/src/main/java/hudson/model/BuildTimelineWidget.java index 717052e5bf9e..563f8a18823a 100644 --- a/core/src/main/java/hudson/model/BuildTimelineWidget.java +++ b/core/src/main/java/hudson/model/BuildTimelineWidget.java @@ -21,18 +21,18 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import hudson.Util; import hudson.util.RunList; +import java.io.IOException; +import java.util.Date; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.StaplerRequest; import org.koshuke.stapler.simile.timeline.Event; import org.koshuke.stapler.simile.timeline.TimelineEventList; -import java.io.IOException; -import java.util.Date; - /** * UI widget for showing the SIMILE timeline control. * @@ -61,20 +61,17 @@ public BuildTimelineWidget(RunList builds) { public TimelineEventList doData(StaplerRequest req, @QueryParameter long min, @QueryParameter long max) throws IOException { TimelineEventList result = new TimelineEventList(); - for (Run r : builds.byTimestamp(min,max)) { + for (Run r : builds.byTimestamp(min, max)) { Event e = new Event(); e.start = new Date(r.getStartTimeInMillis()); - e.end = new Date(r.getStartTimeInMillis()+r.getDuration()); + e.end = new Date(r.getStartTimeInMillis() + r.getDuration()); // due to SimileAjax.HTML.deEntify (in simile-ajax-bundle.js), "<" are transformed back to "<", but not the "<"; // to protect against XSS e.title = Util.escape(r.getFullDisplayName()).replace("<", "<"); - // what to put in the description? - // e.description = "Longish description of event "+r.getFullDisplayName(); - // e.durationEvent = true; - e.link = req.getContextPath()+'/'+r.getUrl(); + e.link = req.getContextPath() + '/' + r.getUrl(); BallColor c = r.getIconColor(); - e.color = String.format("#%06X",c.getBaseColor().darker().getRGB()&0xFFFFFF); - e.classname = "event-"+c.noAnime().toString()+" " + (c.isAnimated()?"animated":""); + e.color = String.format("#%06X", c.getBaseColor().darker().getRGB() & 0xFFFFFF); + e.classname = "event-" + c.noAnime().toString() + " " + (c.isAnimated() ? "animated" : ""); result.add(e); } return result; diff --git a/core/src/main/java/hudson/model/BuildVariableContributor.java b/core/src/main/java/hudson/model/BuildVariableContributor.java index 83046baa5440..5054e10f48cd 100644 --- a/core/src/main/java/hudson/model/BuildVariableContributor.java +++ b/core/src/main/java/hudson/model/BuildVariableContributor.java @@ -21,13 +21,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import hudson.ExtensionList; import hudson.ExtensionPoint; import hudson.tasks.Builder; import hudson.tasks.Publisher; - import java.util.Map; /** @@ -63,7 +63,7 @@ public abstract class BuildVariableContributor implements ExtensionPoint { * Partially built variable map. Implementation of this method is expected to * add additional variables here. Never null. */ - public abstract void buildVariablesFor(AbstractBuild build, Map variables); + public abstract void buildVariablesFor(AbstractBuild build, Map variables); /** * Returns all the registered {@link BuildVariableContributor}s. diff --git a/core/src/main/java/hudson/model/BuildableItem.java b/core/src/main/java/hudson/model/BuildableItem.java index 0d65214e4378..52fbeb97df78 100644 --- a/core/src/main/java/hudson/model/BuildableItem.java +++ b/core/src/main/java/hudson/model/BuildableItem.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import hudson.model.Queue.Task; @@ -35,24 +36,25 @@ * @author Kohsuke Kawaguchi */ public interface BuildableItem extends Item, Task { - /** - * @deprecated - * Use {@link #scheduleBuild(Cause)}. Since 1.283 - */ + /** + * @deprecated + * Use {@link #scheduleBuild(Cause)}. Since 1.283 + */ @Deprecated default boolean scheduleBuild() { - return scheduleBuild(new Cause.LegacyCodeCause()); - } + return scheduleBuild(new Cause.LegacyCodeCause()); + } + + boolean scheduleBuild(Cause c); + /** + * @deprecated + * Use {@link #scheduleBuild(int, Cause)}. Since 1.283 + */ - boolean scheduleBuild(Cause c); - /** - * @deprecated - * Use {@link #scheduleBuild(int, Cause)}. Since 1.283 - */ @Deprecated - default boolean scheduleBuild(int quietPeriod) { - return scheduleBuild(quietPeriod, new Cause.LegacyCodeCause()); - } + default boolean scheduleBuild(int quietPeriod) { + return scheduleBuild(quietPeriod, new Cause.LegacyCodeCause()); + } - boolean scheduleBuild(int quietPeriod, Cause c); + boolean scheduleBuild(int quietPeriod, Cause c); } diff --git a/core/src/main/java/hudson/model/BuildableItemWithBuildWrappers.java b/core/src/main/java/hudson/model/BuildableItemWithBuildWrappers.java index 36b75a41fe4f..74f39b2928aa 100644 --- a/core/src/main/java/hudson/model/BuildableItemWithBuildWrappers.java +++ b/core/src/main/java/hudson/model/BuildableItemWithBuildWrappers.java @@ -18,7 +18,7 @@ public interface BuildableItemWithBuildWrappers extends BuildableItem { * This method must be always implemented as {@code (AbstractProject)this}, but * defining this method emphasizes the fact that this cast must be doable. */ - AbstractProject asProject(); + AbstractProject asProject(); /** * {@link BuildWrapper}s associated with this {@link AbstractProject}. @@ -27,6 +27,5 @@ public interface BuildableItemWithBuildWrappers extends BuildableItem { * can be empty but never null. This list is live, and changes to it will be reflected * to the project configuration. */ - DescribableList> getBuildWrappersList(); + DescribableList> getBuildWrappersList(); } - diff --git a/core/src/main/java/hudson/model/Cause.java b/core/src/main/java/hudson/model/Cause.java index 23bc9c8e9042..6990dd2b39e0 100644 --- a/core/src/main/java/hudson/model/Cause.java +++ b/core/src/main/java/hudson/model/Cause.java @@ -21,28 +21,28 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package hudson.model; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; +package hudson.model; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import hudson.Util; import hudson.console.ModelHyperlinkNote; import hudson.diagnosis.OldDataMonitor; import hudson.util.XStream2; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; import jenkins.model.Jenkins; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.DoNotUse; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; -import com.thoughtworks.xstream.converters.UnmarshallingContext; -import hudson.Util; -import java.io.IOException; -import java.util.HashSet; -import java.util.Objects; -import java.util.Set; -import edu.umd.cs.findbugs.annotations.CheckForNull; -import edu.umd.cs.findbugs.annotations.NonNull; /** * Cause object base class. This class hierarchy is used to keep track of why @@ -66,10 +66,12 @@ public abstract class Cause { /** * One-line human-readable text of the cause. * - *

    - * By default, this method is used to render HTML as well. + * Historically, this method's return value was used to render HTML on the UI as well. + * Since Jenkins 2.315 and 2.303.2, the return value is interpreted as text. + * To have rich HTML output on the UI, provide a custom {@code description.jelly} view for your subclass. + * See the documentation. */ - @Exported(visibility=3) + @Exported(visibility = 3) public abstract String getShortDescription(); /** @@ -95,21 +97,21 @@ public void onAddedTo(AbstractBuild build) { * this ought to be {@code transient}. * @since 1.568 */ - public void onLoad(@NonNull Run build) { + public void onLoad(@NonNull Run build) { if (build instanceof AbstractBuild) { onLoad((AbstractBuild) build); } } - void onLoad(@NonNull Job job, int buildNumber) { - Run build = job.getBuildByNumber(buildNumber); + void onLoad(@NonNull Job job, int buildNumber) { + Run build = job.getBuildByNumber(buildNumber); if (build != null) { onLoad(build); } } @Deprecated - public void onLoad(AbstractBuild build) { + public void onLoad(AbstractBuild build) { if (Util.isOverridden(Cause.class, getClass(), "onLoad", Run.class)) { onLoad((Run) build); } @@ -129,7 +131,9 @@ public void print(TaskListener listener) { */ @Deprecated public static class LegacyCodeCause extends Cause { + @SuppressFBWarnings(value = "URF_UNREAD_FIELD", justification = "for backward compatibility") private StackTraceElement [] stackTrace; + public LegacyCodeCause() { stackTrace = new Exception().getStackTrace(); } @@ -167,8 +171,8 @@ public static class UpstreamCause extends Cause { */ // for backward bytecode compatibility @Deprecated - public UpstreamCause(AbstractBuild up) { - this((Run)up); + public UpstreamCause(AbstractBuild up) { + this((Run) up); } public UpstreamCause(Run up) { @@ -190,14 +194,14 @@ private UpstreamCause(String upstreamProject, int upstreamBuild, String upstream } @Override - public void onLoad(@NonNull Job _job, int _buildNumber) { + public void onLoad(@NonNull Job _job, int _buildNumber) { Item i = Jenkins.get().getItemByFullName(this.upstreamProject); if (!(i instanceof Job)) { // cannot initialize upstream causes return; } - Job j = (Job)i; + Job j = (Job) i; for (Cause c : this.upstreamCauses) { c.onLoad(j, upstreamBuild); } @@ -250,23 +254,23 @@ public int hashCode() { /** * Returns true if this cause points to a build in the specified job. */ - public boolean pointsTo(Job j) { + public boolean pointsTo(Job j) { return j.getFullName().equals(upstreamProject); } /** * Returns true if this cause points to the specified build. */ - public boolean pointsTo(Run r) { - return r.getNumber()==upstreamBuild && pointsTo(r.getParent()); + public boolean pointsTo(Run r) { + return r.getNumber() == upstreamBuild && pointsTo(r.getParent()); } - @Exported(visibility=3) + @Exported(visibility = 3) public String getUpstreamProject() { return upstreamProject; } - @Exported(visibility=3) + @Exported(visibility = 3) public int getUpstreamBuild() { return upstreamBuild; } @@ -274,12 +278,12 @@ public int getUpstreamBuild() { /** * @since 1.505 */ - public @CheckForNull Run getUpstreamRun() { - Job job = Jenkins.get().getItemByFullName(upstreamProject, Job.class); + public @CheckForNull Run getUpstreamRun() { + Job job = Jenkins.get().getItemByFullName(upstreamProject, Job.class); return job != null ? job.getBuildByNumber(upstreamBuild) : null; } - @Exported(visibility=3) + @Exported(visibility = 3) public String getUpstreamUrl() { return upstreamUrl; } @@ -287,7 +291,7 @@ public String getUpstreamUrl() { public List getUpstreamCauses() { return upstreamCauses; } - + @Override public String getShortDescription() { return Messages.Cause_UpstreamCause_ShortDescription(upstreamProject, upstreamBuild); @@ -309,7 +313,7 @@ private void print(TaskListener listener, int depth) { listener.getLogger().println( Messages.Cause_UpstreamCause_ShortDescription( ModelHyperlinkNote.encodeTo('/' + upstreamUrl, upstreamProject), - ModelHyperlinkNote.encodeTo('/'+upstreamUrl+upstreamBuild, Integer.toString(upstreamBuild))) + ModelHyperlinkNote.encodeTo('/' + upstreamUrl + upstreamBuild, Integer.toString(upstreamBuild))) ); if (upstreamCauses != null && !upstreamCauses.isEmpty()) { indent(listener, depth); @@ -331,6 +335,7 @@ private void print(TaskListener listener, int depth) { public static class ConverterImpl extends XStream2.PassthruConverter { public ConverterImpl(XStream2 xstream) { super(xstream); } + @Override protected void callback(UpstreamCause uc, UnmarshallingContext context) { if (uc.upstreamCause != null) { uc.upstreamCauses.add(uc.upstreamCause); @@ -344,10 +349,12 @@ public static class DeeplyNestedUpstreamCause extends Cause { @Override public String getShortDescription() { return "(deeply nested causes)"; } + @Override public String toString() { return "JENKINS-14814"; } - @Override public void onLoad(@NonNull Job _job, int _buildNumber) {} + + @Override public void onLoad(@NonNull Job _job, int _buildNumber) {} } } @@ -361,6 +368,7 @@ public static class DeeplyNestedUpstreamCause extends Cause { @Deprecated public static class UserCause extends Cause { private String authenticationName; + public UserCause() { this.authenticationName = Jenkins.getAuthentication2().getName(); } @@ -370,10 +378,10 @@ public UserCause() { * @return User display name. * If the User does not exist, returns its ID. */ - @Exported(visibility=3) + @Exported(visibility = 3) public String getUserName() { - final User user = User.getById(authenticationName, false); - return user != null ? user.getDisplayName() : authenticationName; + final User user = User.getById(authenticationName, false); + return user != null ? user.getDisplayName() : authenticationName; } @Override @@ -384,7 +392,7 @@ public String getShortDescription() { @Override public boolean equals(Object o) { return o instanceof UserCause && Arrays.equals(new Object[] {authenticationName}, - new Object[] {((UserCause)o).authenticationName}); + new Object[] {((UserCause) o).authenticationName}); } @Override @@ -408,7 +416,7 @@ public static class UserIdCause extends Cause { */ public UserIdCause() { User user = User.current(); - this.userId = (user == null) ? null : user.getId(); + this.userId = user == null ? null : user.getId(); } /** @@ -425,7 +433,7 @@ public UserIdCause(@CheckForNull String userId) { public String getUserId() { return userId; } - + @NonNull private String getUserIdOrUnknown() { return userId != null ? userId : User.getUnknown().getId(); @@ -483,21 +491,17 @@ public RemoteCause(String host, String note) { @Override public String getShortDescription() { - if(note != null) { - try { - return Messages.Cause_RemoteCause_ShortDescriptionWithNote(Util.xmlEscape(addr), Jenkins.get().getMarkupFormatter().translate(note)); - } catch (IOException x) { - // ignore - } + if (note != null) { + return Messages.Cause_RemoteCause_ShortDescriptionWithNote(addr, note); } - return Messages.Cause_RemoteCause_ShortDescription(Util.xmlEscape(addr)); + return Messages.Cause_RemoteCause_ShortDescription(addr); } - + @Exported(visibility = 3) public String getAddr() { return addr; } - + @Exported(visibility = 3) public String getNote() { return note; diff --git a/core/src/main/java/hudson/model/CauseAction.java b/core/src/main/java/hudson/model/CauseAction.java index 9881a8009a38..eca42ffb6999 100644 --- a/core/src/main/java/hudson/model/CauseAction.java +++ b/core/src/main/java/hudson/model/CauseAction.java @@ -21,16 +21,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import com.thoughtworks.xstream.converters.UnmarshallingContext; import hudson.diagnosis.OldDataMonitor; import hudson.model.Queue.Task; import hudson.model.queue.FoldableAction; import hudson.util.XStream2; -import org.kohsuke.stapler.export.Exported; -import org.kohsuke.stapler.export.ExportedBean; -import com.thoughtworks.xstream.converters.UnmarshallingContext; - import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -39,6 +37,8 @@ import java.util.List; import java.util.Map; import jenkins.model.RunAction2; +import org.kohsuke.stapler.export.Exported; +import org.kohsuke.stapler.export.ExportedBean; @ExportedBean public class CauseAction implements FoldableAction, RunAction2 { @@ -53,7 +53,7 @@ public class CauseAction implements FoldableAction, RunAction2 { @Deprecated private transient List causes; - private Map causeBag = new LinkedHashMap<>(); + private Map causeBag = new LinkedHashMap<>(); public CauseAction(Cause c) { this.causeBag.put(c, 1); @@ -65,6 +65,7 @@ private void addCause(Cause c) { causeBag.put(c, cnt == null ? 1 : cnt + 1); } } + private void addCauses(Collection causes) { for (Cause cause : causes) { addCause(cause); @@ -91,10 +92,10 @@ public CauseAction(CauseAction ca) { * to create an action with multiple causes use either of the constructors that support this; * to append causes retroactively to a build you must create a new {@link CauseAction} and replace the old */ - @Exported(visibility=2) + @Exported(visibility = 2) public List getCauses() { List r = new ArrayList<>(); - for (Map.Entry entry : causeBag.entrySet()) { + for (Map.Entry entry : causeBag.entrySet()) { r.addAll(Collections.nCopies(entry.getValue(), entry.getKey())); } return Collections.unmodifiableList(r); @@ -110,15 +111,18 @@ public T findCause(Class type) { return null; } + @Override public String getDisplayName() { return "Cause"; } + @Override public String getIconFileName() { // no icon return null; } + @Override public String getUrlName() { return "cause"; } @@ -127,7 +131,7 @@ public String getUrlName() { * Get list of causes with duplicates combined into counters. * @return Map of Cause to number of occurrences of that Cause */ - public Map getCauseCounts() { + public Map getCauseCounts() { return Collections.unmodifiableMap(causeBag); } @@ -143,7 +147,7 @@ public String getShortDescription() { return causeBag.keySet().iterator().next().getShortDescription(); } - @Override public void onLoad(Run owner) { + @Override public void onLoad(Run owner) { for (Cause c : causeBag.keySet()) { if (c != null) { c.onLoad(owner); @@ -154,7 +158,7 @@ public String getShortDescription() { /** * When hooked up to build, notify {@link Cause}s. */ - @Override public void onAttached(Run owner) { + @Override public void onAttached(Run owner) { for (Cause c : causeBag.keySet()) { if (c != null) { c.onAddedTo(owner); @@ -162,9 +166,10 @@ public String getShortDescription() { } } + @Override public void foldIntoExisting(hudson.model.Queue.Item item, Task owner, List otherActions) { CauseAction existing = item.getAction(CauseAction.class); - if (existing!=null) { + if (existing != null) { existing.addCauses(getCauses()); return; } @@ -174,6 +179,7 @@ public void foldIntoExisting(hudson.model.Queue.Item item, Task owner, List { public ConverterImpl(XStream2 xstream) { super(xstream); } + @Override protected void callback(CauseAction ca, UnmarshallingContext context) { // if we are being read in from an older version if (ca.cause != null) { diff --git a/core/src/main/java/hudson/model/CheckPoint.java b/core/src/main/java/hudson/model/CheckPoint.java index ebb78223b98f..b7a7fdb9da90 100644 --- a/core/src/main/java/hudson/model/CheckPoint.java +++ b/core/src/main/java/hudson/model/CheckPoint.java @@ -21,13 +21,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import edu.umd.cs.findbugs.annotations.NonNull; +import hudson.scm.SCM; import hudson.tasks.BuildStep; -import hudson.tasks.Recorder; import hudson.tasks.Builder; -import hudson.scm.SCM; -import edu.umd.cs.findbugs.annotations.NonNull; +import hudson.tasks.Recorder; /** * Provides a mechanism for synchronizing build executions in the face of concurrent builds. @@ -60,7 +61,7 @@ * depend on its earlier result. * * @author Kohsuke Kawaguchi - * @see BuildStep#getRequiredMonitorService() + * @see BuildStep#getRequiredMonitorService() * @since 1.319 */ public final class CheckPoint { @@ -87,7 +88,7 @@ public CheckPoint(String internalName) { @Override public boolean equals(Object that) { if (that == null || getClass() != that.getClass()) return false; - return identity== ((CheckPoint) that).identity; + return identity == ((CheckPoint) that).identity; } @Override @@ -97,7 +98,7 @@ public int hashCode() { @Override public String toString() { - return "Check point "+internalName; + return "Check point " + internalName; } /** @@ -140,7 +141,7 @@ public void report() { * This method can be only called from an {@link Executor} thread. * * @throws InterruptedException - * If the build (represented by the calling executor thread) is aborted while it's waiting. + * If the build (represented by the calling executor thread) is aborted while it's waiting. */ public void block() throws InterruptedException { Run.waitForCheckpoint(this, null, null); diff --git a/core/src/main/java/hudson/model/ChoiceParameterDefinition.java b/core/src/main/java/hudson/model/ChoiceParameterDefinition.java index 25e982eebfa8..615bd84e8bba 100644 --- a/core/src/main/java/hudson/model/ChoiceParameterDefinition.java +++ b/core/src/main/java/hudson/model/ChoiceParameterDefinition.java @@ -1,28 +1,27 @@ package hudson.model; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.Nullable; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import hudson.Extension; import hudson.Util; import hudson.util.FormValidation; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import net.sf.json.JSONObject; import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.DataBoundSetter; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.export.Exported; -import org.apache.commons.lang.StringUtils; -import net.sf.json.JSONObject; -import hudson.Extension; - -import edu.umd.cs.findbugs.annotations.CheckForNull; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.util.ArrayList; -import java.util.List; -import java.util.Arrays; -import java.util.Objects; -import java.util.stream.Collectors; -import java.util.stream.Stream; /** * @author huybrechts @@ -37,26 +36,26 @@ public class ChoiceParameterDefinition extends SimpleParameterDefinition { private /* quasi-final */ List choices; private final String defaultValue; - public static boolean areValidChoices(String choices) { + public static boolean areValidChoices(@NonNull String choices) { String strippedChoices = choices.trim(); - return !StringUtils.isEmpty(strippedChoices) && strippedChoices.split(CHOICES_DELIMITER).length > 0; + return strippedChoices != null && !strippedChoices.isEmpty() && strippedChoices.split(CHOICES_DELIMITER).length > 0; } - public ChoiceParameterDefinition(@NonNull String name, @NonNull String choices, String description) { + public ChoiceParameterDefinition(@NonNull String name, @NonNull String choices, @CheckForNull String description) { super(name, description); setChoicesText(choices); defaultValue = null; } - public ChoiceParameterDefinition(@NonNull String name, @NonNull String[] choices, String description) { + public ChoiceParameterDefinition(@NonNull String name, @NonNull String[] choices, @CheckForNull String description) { super(name, description); this.choices = Stream.of(choices).map(Util::fixNull).collect(Collectors.toCollection(ArrayList::new)); defaultValue = null; } - private ChoiceParameterDefinition(@NonNull String name, @NonNull List choices, String defaultValue, String description) { + private ChoiceParameterDefinition(@NonNull String name, @NonNull List choices, String defaultValue, @CheckForNull String description) { super(name, description); - this.choices = choices; + this.choices = Util.fixNull(choices); this.defaultValue = defaultValue; } @@ -111,7 +110,7 @@ public void setChoices(Object choices) { throw new IllegalArgumentException("expected String or List, but got " + choices.getClass().getName()); } - private void setChoicesText(String choices) { + private void setChoicesText(@NonNull String choices) { this.choices = Arrays.asList(choices.split(CHOICES_DELIMITER)); } @@ -125,13 +124,14 @@ public ParameterDefinition copyWithDefaultValue(ParameterValue defaultValue) { } } + @NonNull @Exported public List getChoices() { return choices; } public String getChoicesText() { - return StringUtils.join(choices, "\n"); + return String.join("\n", choices); } @Override @@ -165,6 +165,7 @@ private void checkValue(StringParameterValue value, String value2) { } } + @Override public StringParameterValue createValue(String value) { StringParameterValue parameterValue = new StringParameterValue(getName(), value, getDescription()); checkValue(parameterValue, value); @@ -180,6 +181,7 @@ public int hashCode() { } @Override + @SuppressFBWarnings(value = "EQ_GETCLASS_AND_CLASS_CONSTANT", justification = "ParameterDefinitionTest tests that subclasses are not equal to their parent classes, so the behavior appears to be intentional") public boolean equals(Object obj) { if (ChoiceParameterDefinition.class != getClass()) return super.equals(obj); @@ -199,7 +201,7 @@ public boolean equals(Object obj) { return Objects.equals(defaultValue, other.defaultValue); } - @Extension @Symbol({"choice","choiceParam"}) + @Extension @Symbol({"choice", "choiceParam"}) public static class DescriptorImpl extends ParameterDescriptor { @Override public String getDisplayName() { diff --git a/core/src/main/java/hudson/model/Computer.java b/core/src/main/java/hudson/model/Computer.java index c93735b0a941..3e5514aae4b1 100644 --- a/core/src/main/java/hudson/model/Computer.java +++ b/core/src/main/java/hudson/model/Computer.java @@ -23,14 +23,19 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST; + +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.Nullable; +import edu.umd.cs.findbugs.annotations.OverrideMustInvoke; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.EnvVars; import hudson.Extension; import hudson.Launcher.ProcStarter; -import hudson.slaves.Cloud; -import jenkins.security.stapler.StaplerDispatchable; import hudson.Util; import hudson.cli.declarative.CLIResolver; import hudson.console.AnnotatedLargeText; @@ -51,25 +56,59 @@ import hudson.slaves.ComputerLauncher; import hudson.slaves.ComputerListener; import hudson.slaves.NodeProperty; -import hudson.slaves.RetentionStrategy; -import hudson.slaves.WorkspaceList; import hudson.slaves.OfflineCause; import hudson.slaves.OfflineCause.ByCLI; +import hudson.slaves.RetentionStrategy; +import hudson.slaves.WorkspaceList; import hudson.util.DaemonThreadFactory; import hudson.util.EditDistance; import hudson.util.ExceptionCatchingThreadFactory; -import hudson.util.RemotingDiagnostics; -import hudson.util.RemotingDiagnostics.HeapDump; -import hudson.util.RunList; import hudson.util.Futures; import hudson.util.IOUtils; import hudson.util.NamingThreadFactory; +import hudson.util.RemotingDiagnostics; +import hudson.util.RemotingDiagnostics.HeapDump; +import hudson.util.RunList; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.net.Inet4Address; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.InvalidPathException; +import java.nio.file.StandardCopyOption; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.logging.Level; +import java.util.logging.LogRecord; +import java.util.logging.Logger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.servlet.ServletException; import jenkins.model.Jenkins; +import jenkins.security.ImpersonatingExecutorService; +import jenkins.security.MasterToSlaveCallable; +import jenkins.security.stapler.StaplerDispatchable; import jenkins.util.ContextResettingExecutorService; +import jenkins.util.Listeners; import jenkins.util.SystemProperties; -import jenkins.security.MasterToSlaveCallable; -import jenkins.security.ImpersonatingExecutorService; - +import net.jcip.annotations.GuardedBy; import org.apache.commons.lang.StringUtils; import org.jenkins.ui.icon.Icon; import org.jenkins.ui.icon.IconSet; @@ -78,51 +117,20 @@ import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.args4j.Argument; import org.kohsuke.args4j.CmdLineException; +import org.kohsuke.stapler.HttpRedirect; +import org.kohsuke.stapler.HttpResponse; +import org.kohsuke.stapler.HttpResponses; +import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.StaplerProxy; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; -import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.HttpResponses; -import org.kohsuke.stapler.HttpResponse; -import org.kohsuke.stapler.HttpRedirect; import org.kohsuke.stapler.WebMethod; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; import org.kohsuke.stapler.interceptor.RequirePOST; import org.kohsuke.stapler.verb.POST; -import edu.umd.cs.findbugs.annotations.OverrideMustInvoke; -import net.jcip.annotations.GuardedBy; -import javax.servlet.ServletException; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.*; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.ExecutionException; -import java.util.logging.LogRecord; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.nio.charset.Charset; -import java.net.InetAddress; -import java.net.NetworkInterface; -import java.net.Inet4Address; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import edu.umd.cs.findbugs.annotations.CheckForNull; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; - -import static javax.servlet.http.HttpServletResponse.*; - /** * Represents the running state of a remote computer that holds {@link Executor}s. * @@ -134,7 +142,7 @@ * This object is related to {@link Node} but they have some significant differences. * {@link Computer} primarily works as a holder of {@link Executor}s, so * if a {@link Node} is configured (probably temporarily) with 0 executors, - * you won't have a {@link Computer} object for it (except for the master node, + * you won't have a {@link Computer} object for it (except for the built-in node, * which always gets its {@link Computer} in case we have no static executors and * we need to run a {@link FlyweightTask} - see JENKINS-7291 for more discussion.) * @@ -194,7 +202,7 @@ protected final Object statusChangeLock = new Object(); - private final Object logDirLock = new String("logDirLock"); + private final Object logDirLock = new Object(); /** * Keeps track of stack traces to track the termination requests for this computer. @@ -247,14 +255,14 @@ public List getTerminatedBy() { return new ArrayList<>(terminatedBy); } - public Computer(Node node) { + protected Computer(Node node) { setNode(node); } /** * Returns list of all boxes {@link ComputerPanelBox}s. */ - public List getComputerPanelBoxs(){ + public List getComputerPanelBoxs() { return ComputerPanelBox.all(this); } @@ -274,8 +282,7 @@ public List getActions() { return Collections.unmodifiableList(result); } - @SuppressWarnings({"ConstantConditions","deprecation"}) - @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE") + @SuppressWarnings({"ConstantConditions", "deprecation"}) @Override public void addAction(@NonNull Action a) { if (a == null) { @@ -293,7 +300,7 @@ public void addAction(@NonNull Action a) { * @see #relocateOldLogs() */ public @NonNull File getLogFile() { - return new File(getLogDir(),"slave.log"); + return new File(getLogDir(), "slave.log"); } /** @@ -304,7 +311,7 @@ public void addAction(@NonNull Action a) { * @since 1.613 */ protected @NonNull File getLogDir() { - File dir = new File(Jenkins.get().getRootDir(),"logs/slaves/"+nodeName); + File dir = new File(Jenkins.get().getRootDir(), "logs/slaves/" + nodeName); synchronized (logDirLock) { try { IOUtils.mkdirs(dir); @@ -337,6 +344,7 @@ public AnnotatedLargeText getLogText() { return new AnnotatedLargeText<>(getLogFile(), Charset.defaultCharset(), false, this); } + @Override public ACL getACL() { return Jenkins.get().getAuthorizationStrategy().getACL(this); } @@ -366,7 +374,7 @@ public String getOfflineCauseReason() { return ""; } // fetch the localized string for "Disconnected By" - String gsub_base = hudson.slaves.Messages.SlaveComputer_DisconnectedBy("",""); + String gsub_base = hudson.slaves.Messages.SlaveComputer_DisconnectedBy("", ""); // regex to remove commented reason base string String gsub1 = "^" + gsub_base + "[\\w\\W]* \\: "; // regex to remove non-commented reason base string @@ -400,7 +408,7 @@ public String getOfflineCauseReason() { /** * If {@link #getChannel()}==null, attempts to relaunch the agent. */ - public abstract void doLaunchSlaveAgent( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException; + public abstract void doLaunchSlaveAgent(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException; /** * @deprecated since 2009-01-06. Use {@link #connect(boolean)} @@ -457,10 +465,11 @@ public final Future connect(boolean forceReconnect) { protected abstract Future _connect(boolean forceReconnect); /** - * @deprecated Implementation of CLI command "connect-node" moved to {@link hudson.cli.ConnectNodeCommand}. * * @param force * If true cancel any currently pending connect operation and retry from scratch + * + * @deprecated Implementation of CLI command "connect-node" moved to {@link hudson.cli.ConnectNodeCommand}. */ @Deprecated public void cliConnect(boolean force) throws ExecutionException, InterruptedException { @@ -480,7 +489,7 @@ public final long getConnectTime() { /** * Disconnect this computer. * - * If this is the master, no-op. This method may return immediately + * If this is the built-in node, no-op. This method may return immediately * while the launch operation happens asynchronously. * * @param cause @@ -494,10 +503,10 @@ public final long getConnectTime() { public Future disconnect(OfflineCause cause) { recordTermination(); offlineCause = cause; - if (Util.isOverridden(Computer.class,getClass(),"disconnect")) + if (Util.isOverridden(Computer.class, getClass(), "disconnect")) return disconnect(); // legacy subtypes that extend disconnect(). - connectTime=0; + connectTime = 0; return Futures.precomputed(null); } @@ -510,19 +519,19 @@ public Future disconnect(OfflineCause cause) { @Deprecated public Future disconnect() { recordTermination(); - if (Util.isOverridden(Computer.class,getClass(),"disconnect",OfflineCause.class)) + if (Util.isOverridden(Computer.class, getClass(), "disconnect", OfflineCause.class)) // if the subtype already derives disconnect(OfflineCause), delegate to it return disconnect(null); - connectTime=0; + connectTime = 0; return Futures.precomputed(null); } /** - * @deprecated Implementation of CLI command "disconnect-node" moved to {@link hudson.cli.DisconnectNodeCommand}. - * * @param cause * Record the note about why you are disconnecting this node + * + * @deprecated Implementation of CLI command "disconnect-node" moved to {@link hudson.cli.DisconnectNodeCommand}. */ @Deprecated public void cliDisconnect(String cause) throws ExecutionException, InterruptedException { @@ -531,10 +540,10 @@ public void cliDisconnect(String cause) throws ExecutionException, InterruptedEx } /** - * @deprecated Implementation of CLI command "offline-node" moved to {@link hudson.cli.OfflineNodeCommand}. - * * @param cause * Record the note about why you are disconnecting this node + * + * @deprecated Implementation of CLI command "offline-node" moved to {@link hudson.cli.OfflineNodeCommand}. */ @Deprecated public void cliOffline(String cause) throws ExecutionException, InterruptedException { @@ -608,24 +617,9 @@ public BuildTimelineWidget getTimeline() { return new BuildTimelineWidget(getBuilds()); } - @Override - public void taskAccepted(Executor executor, Queue.Task task) { - // dummy implementation - } - - @Override - public void taskCompleted(Executor executor, Queue.Task task, long durationMS) { - // dummy implementation - } - - @Override - public void taskCompletedWithProblems(Executor executor, Queue.Task task, long durationMS, Throwable problems) { - // dummy implementation - } - @Exported public boolean isOffline() { - return temporarilyOffline || getChannel()==null; + return temporarilyOffline || getChannel() == null; } public final boolean isOnline() { @@ -695,7 +689,7 @@ public boolean isTemporarilyOffline() { */ @Deprecated public void setTemporarilyOffline(boolean temporarilyOffline) { - setTemporarilyOffline(temporarilyOffline,null); + setTemporarilyOffline(temporarilyOffline, null); } /** @@ -716,9 +710,10 @@ public void setTemporarilyOffline(boolean temporarilyOffline, OfflineCause cause synchronized (statusChangeLock) { statusChangeLock.notifyAll(); } - for (ComputerListener cl : ComputerListener.all()) { - if (temporarilyOffline) cl.onTemporarilyOffline(this,cause); - else cl.onTemporarilyOnline(this); + if (temporarilyOffline) { + Listeners.notify(ComputerListener.class, false, l -> l.onTemporarilyOffline(this, cause)); + } else { + Listeners.notify(ComputerListener.class, false, l -> l.onTemporarilyOnline(this)); } } @@ -732,10 +727,10 @@ public void setTemporarilyOffline(boolean temporarilyOffline, OfflineCause cause @Exported public String getIcon() { // The machine was taken offline by someone - if (isTemporarilyOffline() && getOfflineCause() instanceof OfflineCause.UserCause) return "computer-user-offline.png"; + if (isTemporarilyOffline() && getOfflineCause() instanceof OfflineCause.UserCause) return "symbol-computer-disconnected"; // There is a "technical" reason the computer will not accept new builds - if (isOffline() || !isAcceptingTasks()) return "computer-x.png"; - return "computer.png"; + if (isOffline() || !isAcceptingTasks()) return "symbol-computer-offline"; + return "symbol-computer"; } /** @@ -752,10 +747,10 @@ public String getIcon() { @Exported public String getIconClassName() { // The machine was taken offline by someone - if (isTemporarilyOffline() && getOfflineCause() instanceof OfflineCause.UserCause) return "icon-computer-user-offline"; + if (isTemporarilyOffline() && getOfflineCause() instanceof OfflineCause.UserCause) return "symbol-computer-disconnected"; // There is a "technical" reason the computer will not accept new builds - if (isOffline() || !isAcceptingTasks()) return "icon-computer-x"; - return "icon-computer"; + if (isOffline() || !isAcceptingTasks()) return "symbol-computer-offline"; + return "symbol-computer"; } public String getIconAltText() { @@ -776,13 +771,13 @@ public String getCaption() { } public String getUrl() { - return "computer/" + Util.rawEncode(getName()) + "/"; + return "computer/" + Util.fullEncode(getName()) + "/"; } @Exported public Set getAssignedLabels() { Node node = getNode(); - return (node != null) ? node.getAssignedLabels() : Collections.emptySet(); + return node != null ? node.getAssignedLabels() : Collections.emptySet(); } /** @@ -790,11 +785,11 @@ public Set getAssignedLabels() { */ public List getTiedJobs() { Node node = getNode(); - return (node != null) ? node.getSelfLabel().getTiedJobs() : Collections.emptyList(); + return node != null ? node.getSelfLabel().getTiedJobs() : Collections.emptyList(); } public RunList getBuilds() { - return RunList.fromJobs((Iterable)Jenkins.get().allItems(Job.class)).node(getNode()); + return RunList.fromJobs((Iterable) Jenkins.get().allItems(Job.class)).node(getNode()); } /** @@ -802,8 +797,8 @@ public RunList getBuilds() { * configuration is updated. */ protected void setNode(Node node) { - assert node!=null; - if(node instanceof Slave) + assert node != null; + if (node instanceof Slave) this.nodeName = node.getNodeName(); else this.nodeName = null; @@ -885,9 +880,9 @@ protected void onRemoved(){ @GuardedBy("hudson.model.Queue.lock") private void setNumExecutors(int n) { this.numExecutors = n; - final int diff = executors.size()-n; + final int diff = executors.size() - n; - if (diff>0) { + if (diff > 0) { // we have too many executors // send signal to all idle executors to potentially kill them off // need the Queue maintenance lock held to prevent concurrent job assignment on the idle executors @@ -900,7 +895,7 @@ private void setNumExecutors(int n) { }); } - if (diff<0) { + if (diff < 0) { // if the number is increased, add new ones addNewExecutorIfNecessary(); } @@ -936,7 +931,7 @@ Extra executors will call removeExecutor(...) and that public int countIdle() { int n = 0; for (Executor e : executors) { - if(e.isIdle()) + if (e.isIdle()) n++; } return n; @@ -946,7 +941,7 @@ public int countIdle() { * Returns the number of {@link Executor}s that are doing some work right now. */ public final int countBusy() { - return countExecutors()-countIdle(); + return countExecutors() - countIdle(); } /** @@ -1000,14 +995,14 @@ public List getDisplayExecutors() { // The size may change while we are populating, but let's start with a reasonable guess to minimize resizing List result = new ArrayList<>(executors.size() + oneOffExecutors.size()); int index = 0; - for (Executor e: executors) { + for (Executor e : executors) { if (e.isDisplayCell()) { result.add(new DisplayExecutor(Integer.toString(index + 1), String.format("executors/%d", index), e)); } index++; } index = 0; - for (OneOffExecutor e: oneOffExecutors) { + for (OneOffExecutor e : oneOffExecutors) { if (e.isDisplayCell()) { result.add(new DisplayExecutor("", String.format("oneOffExecutors/%d", index), e)); } @@ -1024,7 +1019,7 @@ public final boolean isIdle() { if (!oneOffExecutors.isEmpty()) return false; for (Executor e : executors) - if(!e.isIdle()) + if (!e.isIdle()) return false; return true; } @@ -1034,7 +1029,7 @@ public final boolean isIdle() { */ public final boolean isPartiallyIdle() { for (Executor e : executors) - if(e.isIdle()) + if (e.isIdle()) return true; return false; } @@ -1079,7 +1074,7 @@ public final long getDemandStartMilliseconds() { @Exported public @NonNull String getDescription() { Node node = getNode(); - return (node != null) ? node.getNodeDescription() : ""; + return node != null ? node.getNodeDescription() : ""; } @@ -1130,6 +1125,7 @@ public void interrupt() { }); } + @Override public String getSearchUrl() { return getUrl(); } @@ -1146,9 +1142,9 @@ public String getSearchUrl() { /** * Expose monitoring data for the remote API. */ - @Exported(inline=true) - public Map getMonitorData() { - Map r = new HashMap<>(); + @Exported(inline = true) + public Map getMonitorData() { + Map r = new HashMap<>(); if (hasPermission(CONNECT)) { for (NodeMonitor monitor : NodeMonitor.getAll()) r.put(monitor.getClass().getName(), monitor.data(this)); @@ -1160,7 +1156,7 @@ public String getSearchUrl() { * Gets the system properties of the JVM on this computer. * If this is the master, it returns the system property of the master computer. */ - public Map getSystemProperties() throws IOException, InterruptedException { + public Map getSystemProperties() throws IOException, InterruptedException { return RemotingDiagnostics.getSystemProperties(getChannel()); } @@ -1169,7 +1165,7 @@ public Map getSystemProperties() throws IOException, InterruptedE * Use {@link #getEnvironment()} instead. */ @Deprecated - public Map getEnvVars() throws IOException, InterruptedException { + public Map getEnvVars() throws IOException, InterruptedException { return getEnvironment(); } @@ -1198,19 +1194,19 @@ public EnvVars getEnvironment() throws IOException, InterruptedException { EnvVars env = new EnvVars(); Node node = getNode(); - if (node==null) return env; // bail out + if (node == null) return env; // bail out - for (NodeProperty nodeProperty: Jenkins.get().getGlobalNodeProperties()) { - nodeProperty.buildEnvVars(env,listener); + for (NodeProperty nodeProperty : Jenkins.get().getGlobalNodeProperties()) { + nodeProperty.buildEnvVars(env, listener); } - for (NodeProperty nodeProperty: node.getNodeProperties()) { - nodeProperty.buildEnvVars(env,listener); + for (NodeProperty nodeProperty : node.getNodeProperties()) { + nodeProperty.buildEnvVars(env, listener); } // TODO: hmm, they don't really belong String rootUrl = Jenkins.get().getRootUrl(); - if(rootUrl!=null) { + if (rootUrl != null) { env.put("HUDSON_URL", rootUrl); // Legacy. env.put("JENKINS_URL", rootUrl); } @@ -1223,7 +1219,7 @@ public EnvVars getEnvironment() throws IOException, InterruptedException { * @return * key is the thread name, and the value is the pre-formatted dump. */ - public Map getThreadDump() throws IOException, InterruptedException { + public Map getThreadDump() throws IOException, InterruptedException { return RemotingDiagnostics.getThreadDump(getChannel()); } @@ -1231,7 +1227,7 @@ public Map getThreadDump() throws IOException, InterruptedExcepti * Obtains the heap dump. */ public HeapDump getHeapDump() throws IOException { - return new HeapDump(this,getChannel()); + return new HeapDump(this, getChannel()); } /** @@ -1257,21 +1253,21 @@ public HeapDump getHeapDump() throws IOException { * because the agent is behind the firewall, etc.) */ public String getHostName() throws IOException, InterruptedException { - if(hostNameCached) + if (hostNameCached) // in the worst case we end up having multiple threads computing the host name simultaneously, but that's not harmful, just wasteful. return cachedHostName; VirtualChannel channel = getChannel(); - if(channel==null) return null; // can't compute right now + if (channel == null) return null; // can't compute right now - for( String address : channel.call(new ListPossibleNames())) { + for (String address : channel.call(new ListPossibleNames())) { try { InetAddress ia = InetAddress.getByName(address); - if(!(ia instanceof Inet4Address)) { + if (!(ia instanceof Inet4Address)) { LOGGER.log(Level.FINE, "{0} is not an IPv4 address", address); continue; } - if(!ComputerPinger.checkIsReachable(ia, 3)) { + if (!ComputerPinger.checkIsReachable(ia, 3)) { LOGGER.log(Level.FINE, "{0} didn't respond to ping", address); continue; } @@ -1287,7 +1283,7 @@ public String getHostName() throws IOException, InterruptedException { } } - // allow the administrator to manually specify the host name as a fallback. HUDSON-5373 + // allow the administrator to manually specify the host name as a fallback. JENKINS-5373 cachedHostName = channel.call(new GetFallbackName()); hostNameCached = true; return cachedHostName; @@ -1306,7 +1302,7 @@ public String getHostName() throws IOException, InterruptedException { oneOffExecutors.remove(e); } - private static class ListPossibleNames extends MasterToSlaveCallable,IOException> { + private static class ListPossibleNames extends MasterToSlaveCallable, IOException> { /** * In the normal case we would use {@link Computer} as the logger's name, however to * do that we would have to send the {@link Computer} class over to the remote classloader @@ -1318,6 +1314,7 @@ private static class ListPossibleNames extends MasterToSlaveCallable call() throws IOException { List names = new ArrayList<>(); @@ -1328,12 +1325,12 @@ public List call() throws IOException { Enumeration e = ni.getInetAddresses(); while (e.hasMoreElements()) { InetAddress ia = e.nextElement(); - if(ia.isLoopbackAddress()) { + if (ia.isLoopbackAddress()) { LOGGER.log(Level.FINE, "{0} is a loopback address", ia); continue; } - if(!(ia instanceof Inet4Address)) { + if (!(ia instanceof Inet4Address)) { LOGGER.log(Level.FINE, "{0} is not an IPv4 address", ia); continue; } @@ -1344,13 +1341,16 @@ public List call() throws IOException { } return names; } + private static final long serialVersionUID = 1L; } - private static class GetFallbackName extends MasterToSlaveCallable { + private static class GetFallbackName extends MasterToSlaveCallable { + @Override public String call() throws IOException { return SystemProperties.getString("host.name"); } + private static final long serialVersionUID = 1L; } @@ -1367,12 +1367,12 @@ public String call() throws IOException { // // @Restricted(DoNotUse.class) - public void doRssAll( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException { + public void doRssAll(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { RSS.rss(req, rsp, "Jenkins:" + getDisplayName() + " (all builds)", getUrl(), getBuilds()); } @Restricted(DoNotUse.class) - public void doRssFailed(StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException { + public void doRssFailed(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { RSS.rss(req, rsp, "Jenkins:" + getDisplayName() + " (failed builds)", getUrl(), getBuilds().failureOnly()); } @@ -1383,7 +1383,7 @@ public void doRssFailed(StaplerRequest req, StaplerResponse rsp ) throws IOExcep * @since 2.215 */ @Restricted(DoNotUse.class) - public void doRssLatest( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException { + public void doRssLatest(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { final List lastBuilds = new ArrayList<>(); for (AbstractProject p : Jenkins.get().allItems(AbstractProject.class)) { if (p.getLastBuild() != null) { @@ -1400,14 +1400,14 @@ public void doRssLatest( StaplerRequest req, StaplerResponse rsp ) throws IOExce @RequirePOST public HttpResponse doToggleOffline(@QueryParameter String offlineMessage) throws IOException, ServletException { - if(!temporarilyOffline) { + if (!temporarilyOffline) { checkPermission(DISCONNECT); offlineMessage = Util.fixEmptyAndTrim(offlineMessage); setTemporarilyOffline(!temporarilyOffline, new OfflineCause.UserCause(User.current(), offlineMessage)); } else { checkPermission(CONNECT); - setTemporarilyOffline(!temporarilyOffline,null); + setTemporarilyOffline(!temporarilyOffline, null); } return HttpResponses.redirectToDot(); } @@ -1428,7 +1428,7 @@ public Api getApi() { /** * Dumps the contents of the export table. */ - public void doDumpExportTable( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException, InterruptedException { + public void doDumpExportTable(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, InterruptedException { // this is a debug probe and may expose sensitive information checkPermission(Jenkins.ADMINISTER); @@ -1436,11 +1436,11 @@ public void doDumpExportTable( StaplerRequest req, StaplerResponse rsp ) throws try (PrintWriter w = new PrintWriter(rsp.getCompressedWriter(req))) { VirtualChannel vc = getChannel(); if (vc instanceof Channel) { - w.println("Master to slave"); + w.println("Controller to agent"); ((Channel) vc).dumpExportTable(w); w.flush(); // flush here once so that even if the dump from the agent fails, the client gets some useful info - w.println("\n\n\nSlave to master"); + w.println("\n\n\nAgent to controller"); w.print(vc.call(new DumpExportTableTask())); } else { w.println(Messages.Computer_BadChannel()); @@ -1448,7 +1448,8 @@ public void doDumpExportTable( StaplerRequest req, StaplerResponse rsp ) throws } } - private static final class DumpExportTableTask extends MasterToSlaveCallable { + private static final class DumpExportTableTask extends MasterToSlaveCallable { + @Override public String call() throws IOException { final Channel ch = getChannelOrFail(); StringWriter sw = new StringWriter(); @@ -1482,7 +1483,7 @@ protected void _doScript(StaplerRequest req, StaplerResponse rsp, String view) t * Accepts the update to the node configuration. */ @POST - public void doConfigSubmit( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException, FormException { + public void doConfigSubmit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, FormException { checkPermission(CONFIGURE); String proposedName = Util.fixEmptyAndTrim(req.getSubmittedForm().getString("name")); @@ -1493,13 +1494,13 @@ public void doConfigSubmit( StaplerRequest req, StaplerResponse rsp ) throws IOE throw new ServletException("No such node " + nodeName); } - if ((!proposedName.equals(nodeName)) + if (!proposedName.equals(nodeName) && Jenkins.get().getNode(proposedName) != null) { throw new FormException(Messages.ComputerSet_SlaveAlreadyExists(proposedName), "name"); } String nExecutors = req.getSubmittedForm().getString("numExecutors"); - if (StringUtils.isBlank(nExecutors) || Integer.parseInt(nExecutors)<=0) { + if (StringUtils.isBlank(nExecutors) || Integer.parseInt(nExecutors) <= 0) { throw new FormException(Messages.Slave_InvalidConfig_Executors(nodeName), "numExecutors"); } @@ -1549,7 +1550,7 @@ public void updateByXml(final InputStream source) throws IOException, ServletExc if (previous == null) { throw HttpResponses.notFound(); } - Node result = (Node)Jenkins.XSTREAM2.fromXML(source); + Node result = (Node) Jenkins.XSTREAM2.fromXML(source); if (previous.getClass() != result.getClass()) { // ensure node type doesn't change throw HttpResponses.errorWithoutStack(SC_BAD_REQUEST, "Node types do not match"); @@ -1593,7 +1594,7 @@ public void waitUntilOffline() throws InterruptedException { /** * Handles incremental log. */ - public void doProgressiveLog( StaplerRequest req, StaplerResponse rsp) throws IOException { + public void doProgressiveLog(StaplerRequest req, StaplerResponse rsp) throws IOException { getLogText().doProgressText(req, rsp); } @@ -1610,8 +1611,8 @@ public Object getTarget() { * Escape hatch for StaplerProxy-based access control */ @Restricted(NoExternalUse.class) - @SuppressFBWarnings("MS_SHOULD_BE_FINAL") - public static /* Script Console modifiable */ boolean SKIP_PERMISSION_CHECK = Boolean.getBoolean(Computer.class.getName() + ".skipPermissionCheck"); + @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "for script console") + public static /* Script Console modifiable */ boolean SKIP_PERMISSION_CHECK = SystemProperties.getBoolean(Computer.class.getName() + ".skipPermissionCheck"); /** * Gets the current {@link Computer} that the build is running. @@ -1643,10 +1644,10 @@ public boolean isAcceptingTasks() { */ @CLIResolver public static Computer resolveForCLI( - @Argument(required=true,metaVar="NAME",usage="Agent name, or empty string for master") String name) throws CmdLineException { + @Argument(required = true, metaVar = "NAME", usage = "Agent name, or empty string for built-in node") String name) throws CmdLineException { Jenkins h = Jenkins.get(); Computer item = h.getComputer(name); - if (item==null) { + if (item == null) { List names = ComputerSet.getComputerNames(); String adv = EditDistance.findNearest(name, names); throw new IllegalArgumentException(adv == null ? @@ -1664,6 +1665,7 @@ public static Computer resolveForCLI( * * @see #getLogFile() */ + // TODO(terminology) migrate from slaves/ to agents/ @Initializer public static void relocateOldLogs() { relocateOldLogs(Jenkins.get().getRootDir()); @@ -1672,18 +1674,18 @@ public static void relocateOldLogs() { /*package*/ static void relocateOldLogs(File dir) { final Pattern logfile = Pattern.compile("slave-(.*)\\.log(\\.[0-9]+)?"); File[] logfiles = dir.listFiles((dir1, name) -> logfile.matcher(name).matches()); - if (logfiles==null) return; + if (logfiles == null) return; for (File f : logfiles) { Matcher m = logfile.matcher(f.getName()); if (m.matches()) { File newLocation = new File(dir, "logs/slaves/" + m.group(1) + "/slave.log" + Util.fixNull(m.group(2))); - newLocation.getParentFile().mkdirs(); - boolean relocationSuccessful=f.renameTo(newLocation); - if (relocationSuccessful) { // The operation will fail if mkdir fails - LOGGER.log(Level.INFO, "Relocated log file {0} to {1}",new Object[] {f.getPath(),newLocation.getPath()}); - } else { - LOGGER.log(Level.WARNING, "Cannot relocate log file {0} to {1}",new Object[] {f.getPath(),newLocation.getPath()}); + try { + Util.createDirectories(newLocation.getParentFile().toPath()); + Files.move(f.toPath(), newLocation.toPath(), StandardCopyOption.REPLACE_EXISTING); + LOGGER.log(Level.INFO, "Relocated log file {0} to {1}", new Object[] {f.getPath(), newLocation.getPath()}); + } catch (IOException | InvalidPathException e) { + LOGGER.log(Level.WARNING, e, () -> "Cannot relocate log file " + f.getPath() + " to " + newLocation.getPath()); } } else { assert false; @@ -1774,6 +1776,7 @@ public int hashCode() { */ public static class TerminationRequest extends RuntimeException { private final long when; + public TerminationRequest(String message) { super(message); this.when = System.currentTimeMillis(); @@ -1790,33 +1793,64 @@ public long getWhen() { } } - public static final PermissionGroup PERMISSIONS = new PermissionGroup(Computer.class,Messages._Computer_Permissions_Title()); - public static final Permission CONFIGURE = new Permission(PERMISSIONS,"Configure", Messages._Computer_ConfigurePermission_Description(), Permission.CONFIGURE, PermissionScope.COMPUTER); + public static final PermissionGroup PERMISSIONS = new PermissionGroup(Computer.class, Messages._Computer_Permissions_Title()); + public static final Permission CONFIGURE = + new Permission( + PERMISSIONS, + "Configure", + Messages._Computer_ConfigurePermission_Description(), + Permission.CONFIGURE, + PermissionScope.COMPUTER); /** * @since 1.532 */ - public static final Permission EXTENDED_READ = new Permission(PERMISSIONS,"ExtendedRead", Messages._Computer_ExtendedReadPermission_Description(), CONFIGURE, SystemProperties.getBoolean("hudson.security.ExtendedReadPermission"), new PermissionScope[]{PermissionScope.COMPUTER}); - public static final Permission DELETE = new Permission(PERMISSIONS,"Delete", Messages._Computer_DeletePermission_Description(), Permission.DELETE, PermissionScope.COMPUTER); - public static final Permission CREATE = new Permission(PERMISSIONS,"Create", Messages._Computer_CreatePermission_Description(), Permission.CREATE, PermissionScope.JENKINS); - public static final Permission DISCONNECT = new Permission(PERMISSIONS,"Disconnect", Messages._Computer_DisconnectPermission_Description(), Jenkins.ADMINISTER, PermissionScope.COMPUTER); - public static final Permission CONNECT = new Permission(PERMISSIONS,"Connect", Messages._Computer_ConnectPermission_Description(), DISCONNECT, PermissionScope.COMPUTER); - public static final Permission BUILD = new Permission(PERMISSIONS, "Build", Messages._Computer_BuildPermission_Description(), Permission.WRITE, PermissionScope.COMPUTER); + public static final Permission EXTENDED_READ = + new Permission( + PERMISSIONS, + "ExtendedRead", + Messages._Computer_ExtendedReadPermission_Description(), + CONFIGURE, + SystemProperties.getBoolean("hudson.security.ExtendedReadPermission"), + new PermissionScope[] {PermissionScope.COMPUTER}); + public static final Permission DELETE = + new Permission( + PERMISSIONS, + "Delete", + Messages._Computer_DeletePermission_Description(), + Permission.DELETE, + PermissionScope.COMPUTER); + public static final Permission CREATE = + new Permission( + PERMISSIONS, + "Create", + Messages._Computer_CreatePermission_Description(), + Permission.CREATE, + PermissionScope.JENKINS); + public static final Permission DISCONNECT = + new Permission( + PERMISSIONS, + "Disconnect", + Messages._Computer_DisconnectPermission_Description(), + Jenkins.ADMINISTER, + PermissionScope.COMPUTER); + public static final Permission CONNECT = + new Permission( + PERMISSIONS, + "Connect", + Messages._Computer_ConnectPermission_Description(), + DISCONNECT, + PermissionScope.COMPUTER); + public static final Permission BUILD = + new Permission( + PERMISSIONS, + "Build", + Messages._Computer_BuildPermission_Description(), + Permission.WRITE, + PermissionScope.COMPUTER); @Restricted(NoExternalUse.class) // called by jelly public static final Permission[] EXTENDED_READ_AND_CONNECT = new Permission[] { EXTENDED_READ, CONNECT }; - // This permission was historically scoped to this class albeit declared in Cloud. While deserializing, Jenkins loads - // the scope class to make sure the permission is initialized and registered. since Cloud class is used rather seldom, - // it might appear the permission does not exist. Referencing the permission from here to make sure it gets loaded. - private static final @Deprecated Permission CLOUD_PROVISION = Cloud.PROVISION; - private static final Logger LOGGER = Logger.getLogger(Computer.class.getName()); - - static { - IconSet.icons.addIcon(new Icon("icon-computer-user-offline icon-sm", "16x16/computer-user-offline.png", Icon.ICON_SMALL_STYLE)); - IconSet.icons.addIcon(new Icon("icon-computer-user-offline icon-md", "24x24/computer-user-offline.png", Icon.ICON_MEDIUM_STYLE)); - IconSet.icons.addIcon(new Icon("icon-computer-user-offline icon-lg", "32x32/computer-user-offline.png", Icon.ICON_LARGE_STYLE)); - IconSet.icons.addIcon(new Icon("icon-computer-user-offline icon-xlg", "48x48/computer-user-offline.png", Icon.ICON_XLARGE_STYLE)); - } } diff --git a/core/src/main/java/hudson/model/ComputerPanelBox.java b/core/src/main/java/hudson/model/ComputerPanelBox.java index d5e7e45cba50..f75fde52d79e 100644 --- a/core/src/main/java/hudson/model/ComputerPanelBox.java +++ b/core/src/main/java/hudson/model/ComputerPanelBox.java @@ -15,19 +15,19 @@ * @see hudson.model.Computer#getComputerPanelBoxs() */ -public abstract class ComputerPanelBox implements ExtensionPoint{ - +public abstract class ComputerPanelBox implements ExtensionPoint { + private Computer computer; - - - public void setComputer(Computer computer){ + + + public void setComputer(Computer computer) { this.computer = computer; } - - public Computer getComputer(){ + + public Computer getComputer() { return computer; } - + /** * Create boxes for the given computer in its page. * @@ -38,7 +38,7 @@ public Computer getComputer(){ */ public static List all(Computer computer) { List boxs = new ArrayList<>(); - for(ComputerPanelBox box: ExtensionList.lookup(ComputerPanelBox.class)){ + for (ComputerPanelBox box : ExtensionList.lookup(ComputerPanelBox.class)) { box.setComputer(computer); boxs.add(box); } diff --git a/core/src/main/java/hudson/model/ComputerPinger.java b/core/src/main/java/hudson/model/ComputerPinger.java index 1cf4114a0022..8aaf47a843ea 100644 --- a/core/src/main/java/hudson/model/ComputerPinger.java +++ b/core/src/main/java/hudson/model/ComputerPinger.java @@ -3,7 +3,6 @@ import hudson.Extension; import hudson.ExtensionList; import hudson.ExtensionPoint; - import java.io.IOException; import java.net.InetAddress; import java.util.concurrent.TimeUnit; @@ -49,7 +48,7 @@ public static boolean checkIsReachable(InetAddress ia, int timeout) throws IOExc return false; } - + /** * Default pinger - use Java built-in functionality. This doesn't always work, * a host may be reachable even if this returns false. @@ -58,7 +57,7 @@ public static boolean checkIsReachable(InetAddress ia, int timeout) throws IOExc public static class BuiltInComputerPinger extends ComputerPinger { @Override public boolean isReachable(InetAddress ia, int timeout) throws IOException { - return ia.isReachable((int)TimeUnit.SECONDS.toMillis(timeout)); + return ia.isReachable((int) TimeUnit.SECONDS.toMillis(timeout)); } } diff --git a/core/src/main/java/hudson/model/ComputerSet.java b/core/src/main/java/hudson/model/ComputerSet.java index 7cac856f9fea..ecef09a90fc3 100644 --- a/core/src/main/java/hudson/model/ComputerSet.java +++ b/core/src/main/java/hudson/model/ComputerSet.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Stephen Connolly, Thomas J. Black - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,8 +21,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import static hudson.init.InitMilestone.JOB_CONFIG_ADAPTED; + +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.BulkChange; import hudson.DescriptorExtensionList; import hudson.Extension; @@ -37,22 +41,9 @@ import hudson.util.DescribableList; import hudson.util.FormApply; import hudson.util.FormValidation; -import jenkins.model.Jenkins; -import jenkins.model.ModelObjectWithChildren; -import jenkins.model.ModelObjectWithContextMenu.ContextMenu; -import jenkins.util.Timer; -import org.kohsuke.stapler.HttpResponse; -import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; -import org.kohsuke.stapler.export.Exported; -import org.kohsuke.stapler.export.ExportedBean; -import org.kohsuke.stapler.interceptor.RequirePOST; - -import edu.umd.cs.findbugs.annotations.NonNull; -import javax.servlet.ServletException; import java.io.File; import java.io.IOException; +import java.lang.reflect.InvocationTargetException; import java.util.AbstractList; import java.util.ArrayList; import java.util.HashMap; @@ -61,11 +52,21 @@ import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; +import javax.servlet.ServletException; +import jenkins.model.Jenkins; +import jenkins.model.ModelObjectWithChildren; +import jenkins.model.ModelObjectWithContextMenu.ContextMenu; +import jenkins.util.Timer; import net.sf.json.JSONObject; +import org.kohsuke.stapler.HttpResponse; +import org.kohsuke.stapler.QueryParameter; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.export.Exported; +import org.kohsuke.stapler.export.ExportedBean; +import org.kohsuke.stapler.interceptor.RequirePOST; import org.kohsuke.stapler.verb.POST; -import static hudson.init.InitMilestone.JOB_CONFIG_ADAPTED; - /** * Serves as the top of {@link Computer}s in the URL hierarchy. *

    @@ -79,15 +80,17 @@ public final class ComputerSet extends AbstractModelObject implements Describabl * This is the owner that persists {@link #monitors}. */ private static final Saveable MONITORS_OWNER = new Saveable() { + @Override public void save() throws IOException { getConfigFile().write(monitors); SaveableListener.fireOnChange(this, getConfigFile()); } }; - private static final DescribableList> monitors + private static final DescribableList> monitors = new DescribableList<>(MONITORS_OWNER); + @Override @Exported public String getDisplayName() { return Messages.ComputerSet_DisplayName(); @@ -102,11 +105,12 @@ public static List get_monitors() { return monitors.toList(); } - @Exported(name="computer",inline=true) + @Exported(name = "computer", inline = true) public Computer[] get_all() { return Jenkins.get().getComputers(); } + @Override public ContextMenu doChildrenContextMenu(StaplerRequest request, StaplerResponse response) throws Exception { ContextMenu m = new ContextMenu(); for (Computer c : get_all()) { @@ -118,22 +122,22 @@ public ContextMenu doChildrenContextMenu(StaplerRequest request, StaplerResponse /** * Exposing {@link NodeMonitor#all()} for Jelly binding. */ - public DescriptorExtensionList> getNodeMonitorDescriptors() { + public DescriptorExtensionList> getNodeMonitorDescriptors() { return NodeMonitor.all(); } - public static DescribableList> getMonitors() { + public static DescribableList> getMonitors() { return monitors; } /** * Returns a subset pf {@link #getMonitors()} that are {@linkplain NodeMonitor#isIgnored() not ignored}. */ - public static Map,NodeMonitor> getNonIgnoredMonitors() { - Map,NodeMonitor> r = new HashMap<>(); + public static Map, NodeMonitor> getNonIgnoredMonitors() { + Map, NodeMonitor> r = new HashMap<>(); for (NodeMonitor m : monitors) { - if(!m.isIgnored()) - r.put(m.getDescriptor(),m); + if (!m.isIgnored()) + r.put(m.getDescriptor(), m); } return r; } @@ -145,10 +149,12 @@ public List get_slaveNames() { return new AbstractList() { final List nodes = Jenkins.get().getNodes(); + @Override public String get(int index) { return nodes.get(index).getNodeName(); } + @Override public int size() { return nodes.size(); } @@ -162,9 +168,9 @@ public int size() { */ @Exported public int getTotalExecutors() { - int r=0; + int r = 0; for (Computer c : get_all()) { - if(c.isOnline()) + if (c.isOnline()) r += c.countExecutors(); } return r; @@ -175,9 +181,9 @@ public int getTotalExecutors() { */ @Exported public int getBusyExecutors() { - int r=0; + int r = 0; for (Computer c : get_all()) { - if(c.isOnline()) + if (c.isOnline()) r += c.countBusy(); } return r; @@ -187,13 +193,14 @@ public int getBusyExecutors() { * {@code getTotalExecutors()-getBusyExecutors()}, plus executors that are being brought online. */ public int getIdleExecutors() { - int r=0; + int r = 0; for (Computer c : get_all()) - if((c.isOnline() || c.isConnecting()) && c.isAcceptingTasks()) + if ((c.isOnline() || c.isConnecting()) && c.isAcceptingTasks()) r += c.countIdle(); return r; } + @Override public String getSearchUrl() { return "/computers/"; } @@ -206,8 +213,8 @@ public Computer getDynamic(String token, StaplerRequest req, StaplerResponse rsp public void do_launchAll(StaplerRequest req, StaplerResponse rsp) throws IOException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); - for(Computer c : get_all()) { - if(c.isLaunchSupported()) + for (Computer c : get_all()) { + if (c.isLaunchSupported()) c.connect(true); } rsp.sendRedirect("."); @@ -219,9 +226,9 @@ public void do_launchAll(StaplerRequest req, StaplerResponse rsp) throws IOExcep * TODO: ajax on the client side to wait until the update completion might be nice. */ @RequirePOST - public void doUpdateNow( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException { + public void doUpdateNow(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { Jenkins.get().checkPermission(Jenkins.MANAGE); - + for (NodeMonitor nodeMonitor : NodeMonitor.getAll()) { Thread t = nodeMonitor.triggerUpdate(); String columnCaption = nodeMonitor.getColumnCaption(); @@ -236,17 +243,17 @@ public void doUpdateNow( StaplerRequest req, StaplerResponse rsp ) throws IOExce * First check point in creating a new agent. */ @RequirePOST - public synchronized void doCreateItem( StaplerRequest req, StaplerResponse rsp, + public synchronized void doCreateItem(StaplerRequest req, StaplerResponse rsp, @QueryParameter String name, @QueryParameter String mode, - @QueryParameter String from ) throws IOException, ServletException { + @QueryParameter String from) throws IOException, ServletException { final Jenkins app = Jenkins.get(); app.checkPermission(Computer.CREATE); - if(mode!=null && mode.equals("copy")) { + if (mode != null && mode.equals("copy")) { name = checkName(name); Node src = app.getNode(from); - if(src==null) { + if (src == null) { if (Util.fixEmpty(from) == null) { throw new Failure(Messages.ComputerSet_SpecifySlaveToCopy()); } else { @@ -263,7 +270,7 @@ public synchronized void doCreateItem( StaplerRequest req, StaplerResponse rsp, app.addNode(result); // send the browser to the config page - rsp.sendRedirect2(result.getNodeName()+"/configure"); + rsp.sendRedirect2(result.getNodeName() + "/configure"); } else { // proceed to step 2 if (mode == null) { @@ -274,7 +281,7 @@ public synchronized void doCreateItem( StaplerRequest req, StaplerResponse rsp, if (d == null) { throw new Failure("No node type ‘" + mode + "’ is known"); } - d.handleNewNodePage(this,name,req,rsp); + d.handleNewNodePage(this, name, req, rsp); } } @@ -282,9 +289,9 @@ public synchronized void doCreateItem( StaplerRequest req, StaplerResponse rsp, * Really creates a new agent. */ @POST - public synchronized void doDoCreateItem( StaplerRequest req, StaplerResponse rsp, + public synchronized void doDoCreateItem(StaplerRequest req, StaplerResponse rsp, @QueryParameter String name, - @QueryParameter String type ) throws IOException, ServletException, FormException { + @QueryParameter String type) throws IOException, ServletException, FormException { final Jenkins app = Jenkins.get(); app.checkPermission(Computer.CREATE); String fixedName = Util.fixEmptyAndTrim(name); @@ -292,7 +299,7 @@ public synchronized void doDoCreateItem( StaplerRequest req, StaplerResponse rsp JSONObject formData = req.getSubmittedForm(); formData.put("name", fixedName); - + // TODO type is probably NodeDescriptor.id but confirm Node result = NodeDescriptor.all().find(type).newInstance(req, formData); app.addNode(result); @@ -306,13 +313,13 @@ public synchronized void doDoCreateItem( StaplerRequest req, StaplerResponse rsp * @return trimmed name if valid; throws ParseException if not */ public String checkName(String name) throws Failure { - if(name==null) + if (name == null) throw new Failure("Query parameter 'name' is required"); name = name.trim(); Jenkins.checkGoodName(name); - if(Jenkins.get().getNode(name)!=null) + if (Jenkins.get().getNode(name) != null) throw new Failure(Messages.ComputerSet_SlaveAlreadyExists(name)); // looks good @@ -325,9 +332,9 @@ public String checkName(String name) throws Failure { public FormValidation doCheckName(@QueryParameter String value) throws IOException, ServletException { Jenkins.get().checkPermission(Computer.CREATE); - if(Util.fixEmpty(value)==null) + if (Util.fixEmpty(value) == null) return FormValidation.ok(); - + try { checkName(value); return FormValidation.ok(); @@ -335,22 +342,22 @@ public FormValidation doCheckName(@QueryParameter String value) throws IOExcepti return FormValidation.error(e.getMessage()); } } - + /** * Accepts submission from the configuration page. */ @POST - public synchronized HttpResponse doConfigSubmit( StaplerRequest req) throws IOException, ServletException, FormException { + public synchronized HttpResponse doConfigSubmit(StaplerRequest req) throws IOException, ServletException, FormException { BulkChange bc = new BulkChange(MONITORS_OWNER); try { Jenkins.get().checkPermission(Jenkins.MANAGE); - monitors.rebuild(req,req.getSubmittedForm(),getNodeMonitorDescriptors()); + monitors.rebuild(req, req.getSubmittedForm(), getNodeMonitorDescriptors()); // add in the rest of instances are ignored instances for (Descriptor d : NodeMonitor.all()) - if(monitors.get(d)==null) { + if (monitors.get(d) == null) { NodeMonitor i = createDefaultInstance(d, true); - if(i!=null) + if (i != null) monitors.add(i); } @@ -369,13 +376,14 @@ public synchronized HttpResponse doConfigSubmit( StaplerRequest req) throws IOEx * {@link NodeMonitor}s are persisted in this file. */ private static XmlFile getConfigFile() { - return new XmlFile(new File(Jenkins.get().getRootDir(),"nodeMonitors.xml")); + return new XmlFile(new File(Jenkins.get().getRootDir(), "nodeMonitors.xml")); } public Api getApi() { return new Api(this); } + @Override public Descriptor getDescriptor() { return Jenkins.get().getDescriptorOrDie(ComputerSet.class); } @@ -402,10 +410,11 @@ public AutoCompletionCandidates doAutoCompleteCopyNewItemFrom(@QueryParameter fi */ public static void initialize() {} - @Initializer(after= JOB_CONFIG_ADAPTED) + @Initializer(after = JOB_CONFIG_ADAPTED) public static void init() { // start monitoring nodes, although there's no hurry. Timer.get().schedule(new SafeTimerTask() { + @Override public void doRun() { ComputerSet.initialize(); } @@ -431,14 +440,14 @@ public static List getComputerNames() { static { try { - DescribableList> r + DescribableList> r = new DescribableList<>(Saveable.NOOP); // load persisted monitors XmlFile xf = getConfigFile(); - if(xf.exists()) { - DescribableList> persisted = - (DescribableList>) xf.read(); + if (xf.exists()) { + DescribableList> persisted = + (DescribableList>) xf.read(); List sanitized = new ArrayList<>(); for (NodeMonitor nm : persisted) { try { @@ -453,9 +462,9 @@ public static List getComputerNames() { // if we have any new monitors, let's add them for (Descriptor d : NodeMonitor.all()) - if(r.get(d)==null) { - NodeMonitor i = createDefaultInstance(d,false); - if(i!=null) + if (r.get(d) == null) { + NodeMonitor i = createDefaultInstance(d, false); + if (i != null) r.add(i); } monitors.replaceBy(r.toList()); @@ -466,11 +475,11 @@ public static List getComputerNames() { private static NodeMonitor createDefaultInstance(Descriptor d, boolean ignored) { try { - NodeMonitor nm = d.clazz.newInstance(); + NodeMonitor nm = d.clazz.getDeclaredConstructor().newInstance(); nm.setIgnored(ignored); return nm; - } catch (InstantiationException | IllegalAccessException e) { - LOGGER.log(Level.SEVERE, "Failed to instantiate "+d.clazz,e); + } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) { + LOGGER.log(Level.SEVERE, "Failed to instantiate " + d.clazz, e); } return null; } diff --git a/core/src/main/java/hudson/model/DependencyGraph.java b/core/src/main/java/hudson/model/DependencyGraph.java index b5dd097acf06..3788e2aefddc 100644 --- a/core/src/main/java/hudson/model/DependencyGraph.java +++ b/core/src/main/java/hudson/model/DependencyGraph.java @@ -22,16 +22,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; -import hudson.security.ACLContext; -import jenkins.model.DependencyDeclarer; -import com.google.common.collect.ImmutableList; import hudson.security.ACL; -import jenkins.model.Jenkins; -import jenkins.util.DirectedGraph; -import jenkins.util.DirectedGraph.SCC; - +import hudson.security.ACLContext; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -41,9 +36,12 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Map; -import java.util.Map.Entry; import java.util.Set; import java.util.Stack; +import jenkins.model.DependencyDeclarer; +import jenkins.model.Jenkins; +import jenkins.util.DirectedGraph; +import jenkins.util.DirectedGraph.SCC; /** * Maintains the build dependencies between {@link AbstractProject}s @@ -75,20 +73,20 @@ public class DependencyGraph implements Comparator { private boolean built; - private Comparator> topologicalOrder; - private List> topologicallySorted; + private Comparator> topologicalOrder; + private List> topologicallySorted; /** * Builds the dependency graph. */ public DependencyGraph() { } - + public void build() { // Set full privileges while computing to avoid missing any projects the current user cannot see. - try (ACLContext ctx = ACL.as2(ACL.SYSTEM2)){ + try (ACLContext ctx = ACL.as2(ACL.SYSTEM2)) { this.computationalData = new HashMap<>(); - for( AbstractProject p : Jenkins.get().allItems(AbstractProject.class) ) + for (AbstractProject p : Jenkins.get().allItems(AbstractProject.class)) p.buildDependencyGraph(this); forward = finalize(forward); @@ -102,7 +100,7 @@ public void build() { /** * * - * See http://en.wikipedia.org/wiki/Tarjan's_strongly_connected_components_algorithm + * See https://en.wikipedia.org/wiki/Tarjan's_strongly_connected_components_algorithm */ private void topologicalDagSort() { DirectedGraph g = new DirectedGraph() { @@ -122,22 +120,17 @@ protected Collection forward(AbstractProject node) { List> sccs = g.getStronglyConnectedComponents(); - final Map topoOrder = new HashMap<>(); + final Map topoOrder = new HashMap<>(); topologicallySorted = new ArrayList<>(); - int idx=0; + int idx = 0; for (SCC scc : sccs) { for (AbstractProject n : scc) { - topoOrder.put(n,idx++); + topoOrder.put(n, idx++); topologicallySorted.add(n); } } - topologicalOrder = new Comparator>() { - @Override - public int compare(AbstractProject o1, AbstractProject o2) { - return topoOrder.get(o1)-topoOrder.get(o2); - } - }; + topologicalOrder = Comparator.comparingInt(topoOrder::get); topologicallySorted = Collections.unmodifiableList(topologicallySorted); } @@ -175,7 +168,7 @@ public T getComputationalData(Class key) { * can be empty but never null. */ public List getDownstream(AbstractProject p) { - return get(forward,p,false); + return get(forward, p, false); } /** @@ -185,12 +178,12 @@ public List getDownstream(AbstractProject p) { * can be empty but never null. */ public List getUpstream(AbstractProject p) { - return get(backward,p,true); + return get(backward, p, true); } private List get(Map> map, AbstractProject src, boolean up) { List v = map.get(src); - if(v==null) return Collections.emptyList(); + if (v == null) return Collections.emptyList(); List result = new ArrayList<>(v.size()); for (DependencyGroup d : v) result.add(up ? d.getUpstreamProject() : d.getDownstreamProject()); return result; @@ -200,26 +193,26 @@ private List get(Map> ma * @since 1.341 */ public List getDownstreamDependencies(AbstractProject p) { - return get(forward,p); + return get(forward, p); } /** * @since 1.341 */ public List getUpstreamDependencies(AbstractProject p) { - return get(backward,p); + return get(backward, p); } private List get(Map> map, AbstractProject src) { List v = map.get(src); - if(v==null) { - return ImmutableList.of(); + if (v == null) { + return Collections.emptyList(); } else { - ImmutableList.Builder builder = ImmutableList.builder(); + List builder = new ArrayList<>(); for (DependencyGroup dependencyGroup : v) { builder.addAll(dependencyGroup.getGroup()); } - return builder.build(); + return Collections.unmodifiableList(builder); } } @@ -229,16 +222,16 @@ private List get(Map> map, Ab */ @Deprecated public void addDependency(AbstractProject upstream, AbstractProject downstream) { - addDependency(new Dependency(upstream,downstream)); + addDependency(new Dependency(upstream, downstream)); } /** * Called during the dependency graph build phase to add a dependency edge. */ public void addDependency(Dependency dep) { - if(built) + if (built) throw new IllegalStateException(); - add(forward,dep.getUpstreamProject(),dep); + add(forward, dep.getUpstreamProject(), dep); add(backward, dep.getDownstreamProject(), dep); } @@ -248,7 +241,7 @@ public void addDependency(Dependency dep) { @Deprecated public void addDependency(AbstractProject upstream, Collection downstream) { for (AbstractProject p : downstream) - addDependency(upstream,p); + addDependency(upstream, p); } /** @@ -257,7 +250,7 @@ public void addDependency(AbstractProject upstream, Collection upstream, AbstractProject downstream) { for (AbstractProject p : upstream) - addDependency(p,downstream); + addDependency(p, downstream); } /** @@ -267,7 +260,7 @@ public void addDependencyDeclarers(AbstractProject upstream, Collection possi for (Object o : possibleDependecyDeclarers) { if (o instanceof DependencyDeclarer) { DependencyDeclarer dd = (DependencyDeclarer) o; - dd.buildDependencyGraph(upstream,this); + dd.buildDependencyGraph(upstream, this); } } } @@ -285,11 +278,11 @@ public boolean hasIndirectDependencies(AbstractProject src, AbstractProject dst) queue.addAll(getDownstream(src)); queue.remove(dst); - while(!queue.isEmpty()) { + while (!queue.isEmpty()) { AbstractProject p = queue.pop(); - if(p==dst) + if (p == dst) return true; - if(visited.add(p)) + if (visited.add(p)) queue.addAll(getDownstream(p)); } @@ -300,14 +293,14 @@ public boolean hasIndirectDependencies(AbstractProject src, AbstractProject dst) * Gets all the direct and indirect upstream dependencies of the given project. */ public Set getTransitiveUpstream(AbstractProject src) { - return getTransitive(backward,src,true); + return getTransitive(backward, src, true); } /** * Gets all the direct and indirect downstream dependencies of the given project. */ public Set getTransitiveDownstream(AbstractProject src) { - return getTransitive(forward,src,false); + return getTransitive(forward, src, false); } private Set getTransitive(Map> direction, AbstractProject src, boolean up) { @@ -316,11 +309,11 @@ private Set getTransitive(Map> map, AbstractProjec } private Map> finalize(Map> m) { - for (Entry> e : m.entrySet()) { + for (Map.Entry> e : m.entrySet()) { e.getValue().sort(NAME_COMPARATOR); - e.setValue( Collections.unmodifiableList(e.getValue()) ); + e.setValue(Collections.unmodifiableList(e.getValue())); } return Collections.unmodifiableMap(m); } private static final Comparator NAME_COMPARATOR = new Comparator() { + @Override public int compare(DependencyGroup lhs, DependencyGroup rhs) { int cmp = lhs.getUpstreamProject().getName().compareTo(rhs.getUpstreamProject().getName()); return cmp != 0 ? cmp : lhs.getDownstreamProject().getName().compareTo(rhs.getDownstreamProject().getName()); @@ -361,8 +355,9 @@ public int compare(DependencyGroup lhs, DependencyGroup rhs) { /** * Compare two Projects based on the topological order defined by this Dependency Graph */ + @Override public int compare(AbstractProject o1, AbstractProject o2) { - return topologicalOrder.compare(o1,o2); + return topologicalOrder.compare(o1, o2); } /** @@ -373,7 +368,7 @@ public int compare(AbstractProject o1, AbstractProject o2) { * * @since 1.521 */ - public List> getTopologicallySorted() { + public List> getTopologicallySorted() { return topologicallySorted; } @@ -419,7 +414,7 @@ public boolean shouldTriggerBuild(AbstractBuild build, TaskListener listener, * Does this method point to itself? */ public boolean pointsItself() { - return upstream==downstream; + return upstream == downstream; } @Override @@ -452,7 +447,7 @@ private static class DependencyGroup { DependencyGroup(Dependency first) { this.upstream = first.getUpstreamProject(); - this.downstream= first.getDownstreamProject(); + this.downstream = first.getDownstreamProject(); group.add(first); } diff --git a/core/src/main/java/hudson/model/Describable.java b/core/src/main/java/hudson/model/Describable.java index ae8103b3cfd9..d77054007233 100644 --- a/core/src/main/java/hudson/model/Describable.java +++ b/core/src/main/java/hudson/model/Describable.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; /** diff --git a/core/src/main/java/hudson/model/Descriptor.java b/core/src/main/java/hudson/model/Descriptor.java index eab2ab367cdb..bf0b0d5ccd0c 100644 --- a/core/src/main/java/hudson/model/Descriptor.java +++ b/core/src/main/java/hudson/model/Descriptor.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2011, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,15 +21,22 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import static hudson.util.QuotedStringTokenizer.quote; +import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND; + +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.Nullable; +import hudson.BulkChange; import hudson.DescriptorExtensionList; +import hudson.ExtensionList; import hudson.PluginWrapper; import hudson.RelativePath; -import hudson.XmlFile; -import hudson.BulkChange; -import hudson.ExtensionList; import hudson.Util; +import hudson.XmlFile; import hudson.model.listeners.SaveableListener; import hudson.security.Permission; import hudson.util.FormApply; @@ -37,52 +44,54 @@ import hudson.util.ReflectionUtils; import hudson.util.ReflectionUtils.Parameter; import hudson.views.ListViewColumn; -import jenkins.model.GlobalConfiguration; -import jenkins.model.GlobalConfigurationCategory; -import jenkins.model.Jenkins; -import jenkins.security.RedactSecretJsonInErrorMessageSanitizer; -import jenkins.util.io.OnMaster; -import net.sf.json.JSONArray; -import net.sf.json.JSONObject; -import org.kohsuke.stapler.*; -import org.kohsuke.stapler.jelly.JellyCompatibleFacet; -import org.kohsuke.stapler.lang.Klass; -import org.springframework.util.StringUtils; -import org.jvnet.tiger_types.Types; -import org.apache.commons.io.IOUtils; - -import static hudson.util.QuotedStringTokenizer.*; -import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND; - -import javax.servlet.ServletException; -import javax.servlet.RequestDispatcher; +import java.beans.Introspector; import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.IdentityHashMap; import java.util.LinkedHashMap; import java.util.List; -import java.util.Map; -import java.util.HashMap; import java.util.Locale; -import java.util.Arrays; -import java.util.Collections; +import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import java.util.logging.Logger; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.lang.reflect.Type; -import java.lang.reflect.Field; -import java.lang.reflect.ParameterizedType; -import java.beans.Introspector; -import java.util.IdentityHashMap; -import edu.umd.cs.findbugs.annotations.CheckForNull; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletException; +import jenkins.model.GlobalConfiguration; +import jenkins.model.GlobalConfigurationCategory; +import jenkins.model.Jenkins; +import jenkins.security.RedactSecretJsonInErrorMessageSanitizer; +import jenkins.util.io.OnMaster; +import net.sf.json.JSONArray; +import net.sf.json.JSONObject; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang.StringUtils; +import org.jvnet.tiger_types.Types; +import org.kohsuke.stapler.Ancestor; +import org.kohsuke.stapler.BindInterceptor; +import org.kohsuke.stapler.Facet; +import org.kohsuke.stapler.HttpResponse; +import org.kohsuke.stapler.QueryParameter; +import org.kohsuke.stapler.Stapler; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.WebApp; +import org.kohsuke.stapler.jelly.JellyCompatibleFacet; +import org.kohsuke.stapler.lang.Klass; /** * Metadata about a configurable instance. @@ -128,7 +137,7 @@ * {@link Descriptor} defines addition to the standard Java reflection * and provides reflective information about its corresponding {@link Describable}. * These are primarily used by tag libraries to - * keep the Jelly scripts concise. + * keep the Jelly scripts concise. * * @author Kohsuke Kawaguchi * @see Describable @@ -139,12 +148,12 @@ public abstract class Descriptor> implements Saveable, */ public final transient Class clazz; - private final transient Map checkMethods = new ConcurrentHashMap<>(2); + private final transient Map checkMethods = new ConcurrentHashMap<>(2); /** * Lazily computed list of properties on {@link #clazz} and on the descriptor itself. */ - private transient volatile Map propertyTypes,globalPropertyTypes; + private transient volatile Map propertyTypes, globalPropertyTypes; /** * Represents a readable property on {@link Describable}. @@ -162,35 +171,35 @@ public static final class PropertyType { } PropertyType(Field f) { - this(f.getType(),f.getGenericType(),f.toString()); + this(f.getType(), f.getGenericType(), f.toString()); } PropertyType(Method getter) { - this(getter.getReturnType(),getter.getGenericReturnType(),getter.toString()); + this(getter.getReturnType(), getter.getGenericReturnType(), getter.toString()); } public Enum[] getEnumConstants() { - return (Enum[])clazz.getEnumConstants(); + return (Enum[]) clazz.getEnumConstants(); } /** * If the property is a collection/array type, what is an item type? */ public Class getItemType() { - if(itemType==null) + if (itemType == null) itemType = computeItemType(); return itemType; } private Class computeItemType() { - if(clazz.isArray()) { + if (clazz.isArray()) { return clazz.getComponentType(); } - if(Collection.class.isAssignableFrom(clazz)) { + if (Collection.class.isAssignableFrom(clazz)) { Type col = Types.getBaseClass(type, Collection.class); if (col instanceof ParameterizedType) - return Types.erasure(Types.getTypeArgument(col,0)); + return Types.erasure(Types.getTypeArgument(col, 0)); else return Object.class; } @@ -207,11 +216,11 @@ public Descriptor getItemTypeDescriptor() { public Descriptor getItemTypeDescriptorOrDie() { Class it = getItemType(); if (it == null) { - throw new AssertionError(clazz + " is not an array/collection type in " + displayName + ". See https://jenkins.io/redirect/developer/class-is-missing-descriptor"); + throw new AssertionError(clazz + " is not an array/collection type in " + displayName + ". See https://www.jenkins.io/redirect/developer/class-is-missing-descriptor"); } Descriptor d = Jenkins.get().getDescriptor(it); - if (d==null) - throw new AssertionError(it +" is missing its descriptor in "+displayName+". See https://jenkins.io/redirect/developer/class-is-missing-descriptor"); + if (d == null) + throw new AssertionError(it + " is missing its descriptor in " + displayName + ". See https://www.jenkins.io/redirect/developer/class-is-missing-descriptor"); return d; } @@ -233,9 +242,9 @@ public List getApplicableItemDescriptors() { /** * Help file redirect, keyed by the field name to the path. * - * @see #getHelpFile(String) + * @see #getHelpFile(String) */ - private final transient Map helpRedirect = new HashMap<>(2); + private final transient Map helpRedirect = new HashMap<>(2); private static class HelpRedirect { private final Class owner; @@ -259,8 +268,8 @@ private String resolve() { * (this hack is needed since derived types can't call "getClass()" to refer to itself. */ protected Descriptor(Class clazz) { - if (clazz==self()) - clazz = (Class)getClass(); + if (clazz == self()) + clazz = (Class) getClass(); this.clazz = clazz; // doing this turns out to be very error prone, // as field initializers in derived types will override values. @@ -271,13 +280,13 @@ protected Descriptor(Class clazz) { * Infers the type of the corresponding {@link Describable} from the outer class. * This version works when you follow the common convention, where a descriptor * is written as the static nested class of the describable class. - * + * * @since 1.278 */ protected Descriptor() { - this.clazz = (Class)getClass().getEnclosingClass(); - if(clazz==null) - throw new AssertionError(getClass()+" doesn't have an outer class. Use the constructor that takes the Class object explicitly."); + this.clazz = (Class) getClass().getEnclosingClass(); + if (clazz == null) + throw new AssertionError(getClass() + " doesn't have an outer class. Use the constructor that takes the Class object explicitly."); // detect an type error Type bt = Types.getBaseClass(getClass(), Descriptor.class); @@ -285,19 +294,19 @@ protected Descriptor() { ParameterizedType pt = (ParameterizedType) bt; // this 't' is the closest approximation of T of Descriptor. Class t = Types.erasure(pt.getActualTypeArguments()[0]); - if(!t.isAssignableFrom(clazz)) - throw new AssertionError("Outer class "+clazz+" of "+getClass()+" is not assignable to "+t+". Perhaps wrong outer class?"); + if (!t.isAssignableFrom(clazz)) + throw new AssertionError("Outer class " + clazz + " of " + getClass() + " is not assignable to " + t + ". Perhaps wrong outer class?"); } // detect a type error. this Descriptor is supposed to be returned from getDescriptor(), so make sure its type match up. // this prevents a bug like http://www.nabble.com/Creating-a-new-parameter-Type-%3A-Masked-Parameter-td24786554.html try { Method getd = clazz.getMethod("getDescriptor"); - if(!getd.getReturnType().isAssignableFrom(getClass())) { - throw new AssertionError(getClass()+" must be assignable to "+getd.getReturnType()); + if (!getd.getReturnType().isAssignableFrom(getClass())) { + throw new AssertionError(getClass() + " must be assignable to " + getd.getReturnType()); } } catch (NoSuchMethodException e) { - throw new AssertionError(getClass()+" is missing getDescriptor method."); + throw new AssertionError(getClass() + " is missing getDescriptor method.", e); } } @@ -327,7 +336,7 @@ public String getDisplayName() { * * @return * Stick to valid Java identifier character, plus '.', which had to be allowed for historical reasons. - * + * * @since 1.391 */ public String getId() { @@ -345,7 +354,7 @@ public String getId() { public Class getT() { Type subTyping = Types.getBaseClass(getClass(), Descriptor.class); if (!(subTyping instanceof ParameterizedType)) { - throw new IllegalStateException(getClass()+" doesn't extend Descriptor with a type parameter."); + throw new IllegalStateException(getClass() + " doesn't extend Descriptor with a type parameter."); } return Types.erasure(Types.getTypeArgument(subTyping, 0)); } @@ -355,7 +364,7 @@ public Class getT() { * Since {@link Jenkins} is a {@link DescriptorByNameOwner}, there's always one such ancestor to any request. */ public String getDescriptorUrl() { - return "descriptorByName/"+getId(); + return "descriptorByName/" + getId(); } /** @@ -363,7 +372,7 @@ public String getDescriptorUrl() { * @since 1.406 */ public final String getDescriptorFullUrl() { - return getCurrentDescriptorByNameUrl()+'/'+getDescriptorUrl(); + return getCurrentDescriptorByNameUrl() + '/' + getDescriptorUrl(); } /** @@ -374,7 +383,7 @@ public static String getCurrentDescriptorByNameUrl() { // this override allows RenderOnDemandClosure to preserve the proper value Object url = req.getAttribute("currentDescriptorByNameUrl"); - if (url!=null) return url.toString(); + if (url != null) return url.toString(); Ancestor a = req.findAncestor(DescriptorByNameOwner.class); return a.getUrl(); @@ -397,9 +406,9 @@ public String getCheckUrl(String fieldName) { */ public CheckMethod getCheckMethod(String fieldName) { CheckMethod method = checkMethods.get(fieldName); - if(method==null) { - method = new CheckMethod(this,fieldName); - checkMethods.put(fieldName,method); + if (method == null) { + method = new CheckMethod(this, fieldName); + checkMethods.put(fieldName, method); } return method; @@ -410,41 +419,41 @@ public CheckMethod getCheckMethod(String fieldName) { * and sets that as the 'fillDependsOn' attribute. Also computes the URL of the doFillXyzItems and * sets that as the 'fillUrl' attribute. */ - public void calcFillSettings(String field, Map attributes) { + public void calcFillSettings(String field, Map attributes) { String capitalizedFieldName = StringUtils.capitalize(field); String methodName = "doFill" + capitalizedFieldName + "Items"; Method method = ReflectionUtils.getPublicMethodNamed(getClass(), methodName); - if(method==null) + if (method == null) throw new IllegalStateException(String.format("%s doesn't have the %s method for filling a drop-down list", getClass(), methodName)); // build query parameter line by figuring out what should be submitted List depends = buildFillDependencies(method, new ArrayList<>()); if (!depends.isEmpty()) - attributes.put("fillDependsOn",Util.join(depends," ")); + attributes.put("fillDependsOn", String.join(" ", depends)); attributes.put("fillUrl", String.format("%s/%s/fill%sItems", getCurrentDescriptorByNameUrl(), getDescriptorUrl(), capitalizedFieldName)); } private List buildFillDependencies(Method method, List depends) { for (Parameter p : ReflectionUtils.getParameters(method)) { QueryParameter qp = p.annotation(QueryParameter.class); - if (qp!=null) { + if (qp != null) { String name = qp.value(); - if (name.length()==0) name = p.name(); - if (name==null || name.length()==0) + if (name.length() == 0) name = p.name(); + if (name == null || name.length() == 0) continue; // unknown parameter name. we'll report the error when the form is submitted. RelativePath rp = p.annotation(RelativePath.class); - if (rp!=null) - name = rp.value()+'/'+name; + if (rp != null) + name = rp.value() + '/' + name; depends.add(name); continue; } Method m = ReflectionUtils.getPublicMethodNamed(p.type(), "fromStapler"); - if (m!=null) - buildFillDependencies(m,depends); + if (m != null) + buildFillDependencies(m, depends); } return depends; } @@ -452,11 +461,11 @@ private List buildFillDependencies(Method method, List depends) /** * Computes the auto-completion setting */ - public void calcAutoCompleteSettings(String field, Map attributes) { + public void calcAutoCompleteSettings(String field, Map attributes) { String capitalizedFieldName = StringUtils.capitalize(field); String methodName = "doAutoComplete" + capitalizedFieldName; Method method = ReflectionUtils.getPublicMethodNamed(getClass(), methodName); - if(method==null) + if (method == null) return; // no auto-completion attributes.put("autoCompleteUrl", String.format("%s/%s/autoComplete%s", getCurrentDescriptorByNameUrl(), getDescriptorUrl(), capitalizedFieldName)); @@ -467,7 +476,7 @@ public void calcAutoCompleteSettings(String field, Map attributes */ public @CheckForNull PropertyType getPropertyType(@NonNull Object instance, @NonNull String field) { // in global.jelly, instance==descriptor - return instance==this ? getGlobalPropertyType(field) : getPropertyType(field); + return instance == this ? getGlobalPropertyType(field) : getPropertyType(field); } /** @@ -490,7 +499,7 @@ public void calcAutoCompleteSettings(String field, Map attributes * Obtains the property type of the given field of {@link #clazz} */ public PropertyType getPropertyType(String field) { - if(propertyTypes==null) + if (propertyTypes == null) propertyTypes = buildPropertyTypes(clazz); return propertyTypes.get(field); } @@ -499,7 +508,7 @@ public PropertyType getPropertyType(String field) { * Obtains the property type of the given field of this descriptor. */ public PropertyType getGlobalPropertyType(String field) { - if(globalPropertyTypes==null) + if (globalPropertyTypes == null) globalPropertyTypes = buildPropertyTypes(getClass()); return globalPropertyTypes.get(field); } @@ -510,11 +519,11 @@ public PropertyType getGlobalPropertyType(String field) { private Map buildPropertyTypes(Class clazz) { Map r = new HashMap<>(); for (Field f : clazz.getFields()) - r.put(f.getName(),new PropertyType(f)); + r.put(f.getName(), new PropertyType(f)); for (Method m : clazz.getMethods()) - if(m.getName().startsWith("get")) - r.put(Introspector.decapitalize(m.getName().substring(3)),new PropertyType(m)); + if (m.getName().startsWith("get")) + r.put(Introspector.decapitalize(m.getName().substring(3)), new PropertyType(m)); return r; } @@ -523,17 +532,17 @@ private Map buildPropertyTypes(Class clazz) { * Gets the class name nicely escaped to be usable as a key in the structured form submission. */ public final String getJsonSafeClassName() { - return getId().replace('.','-'); + return getId().replace('.', '-'); } /** * @deprecated * Implement {@link #newInstance(StaplerRequest, JSONObject)} method instead. - * Deprecated as of 1.145. + * Deprecated as of 1.145. */ @Deprecated public T newInstance(StaplerRequest req) throws FormException { - throw new UnsupportedOperationException(getClass()+" should implement newInstance(StaplerRequest,JSONObject)"); + throw new UnsupportedOperationException(getClass() + " should implement newInstance(StaplerRequest,JSONObject)"); } /** @@ -559,7 +568,7 @@ public T newInstance(StaplerRequest req) throws FormException { * Always non-null (see note above.) This object includes represents the entire submission. * @param formData * The JSON object that captures the configuration data for this {@link Descriptor}. - * See http://wiki.jenkins-ci.org/display/JENKINS/Structured+Form+Submission + * See https://www.jenkins.io/doc/developer/forms/structured-form-submission/ * Always non-null. * * @throws FormException @@ -570,21 +579,19 @@ public T newInstance(@Nullable StaplerRequest req, @NonNull JSONObject formData) try { Method m = getClass().getMethod("newInstance", StaplerRequest.class); - if(!Modifier.isAbstract(m.getDeclaringClass().getModifiers())) { + if (!Modifier.isAbstract(m.getDeclaringClass().getModifiers())) { // this class overrides newInstance(StaplerRequest). // maintain the backward compatible behavior return verifyNewInstance(newInstance(req)); } else { - if (req==null) { + if (req == null) { // yes, req is supposed to be always non-null, but see the note above - return verifyNewInstance(clazz.newInstance()); + return verifyNewInstance(clazz.getDeclaredConstructor().newInstance()); } return verifyNewInstance(bindJSON(req, clazz, formData, true)); } - } catch (NoSuchMethodException e) { - throw new AssertionError(e); // impossible - } catch (InstantiationException | IllegalAccessException | RuntimeException e) { - throw new Error("Failed to instantiate "+clazz+" from "+RedactSecretJsonInErrorMessageSanitizer.INSTANCE.sanitize(formData),e); + } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException | RuntimeException e) { + throw new LinkageError("Failed to instantiate " + clazz + " from " + RedactSecretJsonInErrorMessageSanitizer.INSTANCE.sanitize(formData), e); } } @@ -628,7 +635,7 @@ private static T bindJSON(StaplerRequest req, Class type, JSONObject src, private static class NewInstanceBindInterceptor extends BindInterceptor { private final BindInterceptor oldInterceptor; - private final Map processed = new IdentityHashMap<>(); + private final IdentityHashMap processed = new IdentityHashMap<>(); NewInstanceBindInterceptor(BindInterceptor oldInterceptor) { LOGGER.log(Level.FINER, "new interceptor delegating to {0}", oldInterceptor); @@ -700,9 +707,9 @@ public Object onConvert(Type targetType, Class targetTypeErasure, Object jsonSou * See http://hudson.361315.n4.nabble.com/Help-Hint-needed-Post-build-action-doesn-t-stay-activated-td2308833.html */ private T verifyNewInstance(T t) { - if (t!=null && t.getDescriptor()!=this) { + if (t != null && t.getDescriptor() != this) { // TODO: should this be a fatal error? - LOGGER.warning("Father of "+ t+" and its getDescriptor() points to two different instances. Probably misplaced @Extension. See http://hudson.361315.n4.nabble.com/Help-Hint-needed-Post-build-action-doesn-t-stay-activated-td2308833.html"); + LOGGER.warning("Father of " + t + " and its getDescriptor() points to two different instances. Probably misplaced @Extension. See http://hudson.361315.n4.nabble.com/Help-Hint-needed-Post-build-action-doesn-t-stay-activated-td2308833.html"); } return t; } @@ -745,48 +752,48 @@ public String getHelpFile() { * locale variations. */ public String getHelpFile(final String fieldName) { - return getHelpFile(getKlass(),fieldName); + return getHelpFile(getKlass(), fieldName); } public String getHelpFile(Klass clazz, String fieldName) { HelpRedirect r = helpRedirect.get(fieldName); - if (r!=null) return r.resolve(); + if (r != null) return r.resolve(); for (Klass c : clazz.getAncestors()) { String page = "/descriptor/" + getId() + "/help"; String suffix; - if(fieldName==null) { - suffix=""; + if (fieldName == null) { + suffix = ""; } else { - page += '/'+fieldName; - suffix='-'+fieldName; + page += '/' + fieldName; + suffix = '-' + fieldName; } try { - if(Stapler.getCurrentRequest().getView(c,"help"+suffix)!=null) + if (Stapler.getCurrentRequest().getView(c, "help" + suffix) != null) return page; } catch (IOException e) { throw new Error(e); } - if(getStaticHelpUrl(c, suffix) !=null) return page; + if (getStaticHelpUrl(c, suffix) != null) return page; } return null; } - + /** * Tells Jenkins that the help file for the field 'fieldName' is defined in the help file for * the 'fieldNameToRedirectTo' in the 'owner' class. * @since 1.425 */ protected void addHelpFileRedirect(String fieldName, Class owner, String fieldNameToRedirectTo) { - helpRedirect.put(fieldName, new HelpRedirect(owner,fieldNameToRedirectTo)); + helpRedirect.put(fieldName, new HelpRedirect(owner, fieldNameToRedirectTo)); } /** * Checks if the given object is created from this {@link Descriptor}. */ - public final boolean isInstance( T instance ) { + public final boolean isInstance(T instance) { return clazz.isInstance(instance); } @@ -802,7 +809,7 @@ public final boolean isSubTypeOf(Class type) { * As of 1.239, use {@link #configure(StaplerRequest, JSONObject)}. */ @Deprecated - public boolean configure( StaplerRequest req ) throws FormException { + public boolean configure(StaplerRequest req) throws FormException { return true; } @@ -813,11 +820,11 @@ public boolean configure( StaplerRequest req ) throws FormException { * * @param json * The JSON object that captures the configuration data for this {@link Descriptor}. - * See http://wiki.jenkins-ci.org/display/JENKINS/Structured+Form+Submission + * See https://www.jenkins.io/doc/developer/forms/structured-form-submission/ * @return false * to keep the client in the same config page. */ - public boolean configure( StaplerRequest req, JSONObject json ) throws FormException { + public boolean configure(StaplerRequest req, JSONObject json) throws FormException { // compatibility return configure(req); } @@ -856,15 +863,15 @@ Permission getRequiredGlobalConfigPagePermission() { } private String getViewPage(Class clazz, String pageName, String defaultValue) { - return getViewPage(clazz,Collections.singleton(pageName),defaultValue); + return getViewPage(clazz, Collections.singleton(pageName), defaultValue); } private String getViewPage(Class clazz, Collection pageNames, String defaultValue) { - while(clazz!=Object.class && clazz!=null) { + while (clazz != Object.class && clazz != null) { for (String pageName : pageNames) { String name = clazz.getName().replace('.', '/').replace('$', '/') + "/" + pageName; - if(clazz.getClassLoader().getResource(name)!=null) - return '/'+name; + if (clazz.getClassLoader().getResource(name) != null) + return '/' + name; } clazz = clazz.getSuperclass(); } @@ -877,7 +884,7 @@ protected final String getViewPage(Class clazz, String pageName) { // it doesn't exist. // Or this error is fatal, in which case we want the developer to see what page he's missing. // so we put the page name. - return getViewPage(clazz,pageName,pageName); + return getViewPage(clazz, pageName, pageName); } protected List getPossibleViewNames(String baseName) { @@ -886,7 +893,7 @@ protected List getPossibleViewNames(String baseName) { if (f instanceof JellyCompatibleFacet) { JellyCompatibleFacet jcf = (JellyCompatibleFacet) f; for (String ext : jcf.getScriptExtensions()) - names.add(baseName +ext); + names.add(baseName + ext); } } return names; @@ -896,13 +903,14 @@ protected List getPossibleViewNames(String baseName) { /** * Saves the configuration info to the disk. */ + @Override public synchronized void save() { - if(BulkChange.contains(this)) return; + if (BulkChange.contains(this)) return; try { getConfigFile().write(this); SaveableListener.fireOnChange(this, getConfigFile()); } catch (IOException e) { - LOGGER.log(Level.WARNING, "Failed to save "+getConfigFile(),e); + LOGGER.log(Level.WARNING, "Failed to save " + getConfigFile(), e); } } @@ -916,18 +924,18 @@ public synchronized void save() { */ public synchronized void load() { XmlFile file = getConfigFile(); - if(!file.exists()) + if (!file.exists()) return; try { file.unmarshal(this); } catch (IOException e) { - LOGGER.log(Level.WARNING, "Failed to load "+file, e); + LOGGER.log(Level.WARNING, "Failed to load " + file, e); } } protected XmlFile getConfigFile() { - return new XmlFile(new File(Jenkins.get().getRootDir(),getId()+".xml")); + return new XmlFile(new File(Jenkins.get().getRootDir(), getId() + ".xml")); } /** @@ -945,32 +953,32 @@ protected PluginWrapper getPlugin() { */ public void doHelp(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { String path = req.getRestOfPath(); - if(path.contains("..")) throw new ServletException("Illegal path: "+path); + if (path.contains("..")) throw new ServletException("Illegal path: " + path); - path = path.replace('/','-'); + path = path.replace('/', '-'); PluginWrapper pw = getPlugin(); - if (pw!=null) { - rsp.setHeader("X-Plugin-Short-Name",pw.getShortName()); - rsp.setHeader("X-Plugin-Long-Name",pw.getLongName()); + if (pw != null) { + rsp.setHeader("X-Plugin-Short-Name", pw.getShortName()); + rsp.setHeader("X-Plugin-Long-Name", pw.getLongName()); rsp.setHeader("X-Plugin-From", Messages.Descriptor_From( - pw.getLongName().replace("Hudson","Jenkins").replace("hudson","jenkins"), pw.getUrl())); + pw.getLongName().replace("Hudson", "Jenkins").replace("hudson", "jenkins"), pw.getUrl())); } - for (Klass c= getKlass(); c!=null; c=c.getSuperClass()) { - RequestDispatcher rd = Stapler.getCurrentRequest().getView(c, "help"+path); - if(rd!=null) {// template based help page - rd.forward(req,rsp); + for (Klass c = getKlass(); c != null; c = c.getSuperClass()) { + RequestDispatcher rd = Stapler.getCurrentRequest().getView(c, "help" + path); + if (rd != null) { // template based help page + rd.forward(req, rsp); return; } URL url = getStaticHelpUrl(c, path); - if(url!=null) { + if (url != null) { // TODO: generalize macro expansion and perhaps even support JEXL rsp.setContentType("text/html;charset=UTF-8"); try (InputStream in = url.openStream()) { String literal = IOUtils.toString(in, StandardCharsets.UTF_8); - rsp.getWriter().println(Util.replaceMacro(literal, Collections.singletonMap("rootURL",req.getContextPath()))); + rsp.getWriter().println(Util.replaceMacro(literal, Collections.singletonMap("rootURL", req.getContextPath()))); } return; } @@ -981,15 +989,15 @@ public void doHelp(StaplerRequest req, StaplerResponse rsp) throws IOException, private URL getStaticHelpUrl(Klass c, String suffix) { Locale locale = Stapler.getCurrentRequest().getLocale(); - String base = "help"+suffix; + String base = "help" + suffix; URL url; url = c.getResource(base + '_' + locale.getLanguage() + '_' + locale.getCountry() + '_' + locale.getVariant() + ".html"); - if(url!=null) return url; + if (url != null) return url; url = c.getResource(base + '_' + locale.getLanguage() + '_' + locale.getCountry() + ".html"); - if(url!=null) return url; + if (url != null) return url; url = c.getResource(base + '_' + locale.getLanguage() + ".html"); - if(url!=null) return url; + if (url != null) return url; // default return c.getResource(base + ".html"); @@ -1002,17 +1010,17 @@ private URL getStaticHelpUrl(Klass c, String suffix) { // to work around warning when creating a generic array type - public static T[] toArray( T... values ) { + public static T[] toArray(T... values) { return values; } - public static List toList( T... values ) { + public static List toList(T... values) { return new ArrayList<>(Arrays.asList(values)); } public static > - Map,T> toMap(Iterable describables) { - Map,T> m = new LinkedHashMap<>(); + Map, T> toMap(Iterable describables) { + Map, T> m = new LinkedHashMap<>(); for (T d : describables) { Descriptor descriptor; try { @@ -1044,7 +1052,7 @@ Map,T> toMap(Iterable describables) { List newInstancesFromHeteroList(StaplerRequest req, JSONObject formData, String key, Collection> descriptors) throws FormException { - return newInstancesFromHeteroList(req,formData.get(key),descriptors); + return newInstancesFromHeteroList(req, formData.get(key), descriptors); } public static > @@ -1053,9 +1061,9 @@ List newInstancesFromHeteroList(StaplerRequest req, Object formData, List items = new ArrayList<>(); - if (formData!=null) { + if (formData != null) { for (Object o : JSONArray.fromObject(formData)) { - JSONObject jo = (JSONObject)o; + JSONObject jo = (JSONObject) o; Descriptor d = null; // 'kind' and '$class' are mutually exclusive (see class-entry.jelly), but to be more lenient on the reader side, // we check them both anyway. 'kind' (which maps to ID) is more unique than '$class', which can have multiple matching @@ -1099,7 +1107,7 @@ List newInstancesFromHeteroList(StaplerRequest req, Object formData, */ public static @CheckForNull T findById(Collection list, String id) { for (T d : list) { - if(d.getId().equals(id)) + if (d.getId().equals(id)) return d; } return null; @@ -1111,7 +1119,7 @@ List newInstancesFromHeteroList(StaplerRequest req, Object formData, */ private static @CheckForNull T findByClassName(Collection list, String className) { for (T d : list) { - if(d.getClass().getName().equals(className)) + if (d.getClass().getName().equals(className)) return d; } return null; @@ -1124,7 +1132,7 @@ List newInstancesFromHeteroList(StaplerRequest req, Object formData, */ public static @CheckForNull T findByDescribableClassName(Collection list, String className) { for (T d : list) { - if(d.clazz.getName().equals(className)) + if (d.clazz.getName().equals(className)) return d; } return null; @@ -1148,7 +1156,7 @@ List newInstancesFromHeteroList(StaplerRequest req, Object formData, */ @Deprecated public static @CheckForNull Descriptor find(String className) { - return find(ExtensionList.lookup(Descriptor.class),className); + return find(ExtensionList.lookup(Descriptor.class), className); } public static final class FormException extends Exception implements HttpResponse { @@ -1176,13 +1184,14 @@ public String getFormField() { return formField; } + @Override public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { if (FormApply.isApply(req)) { - FormApply.applyResponse("notificationBar.show(" + quote(getMessage())+ ",notificationBar.ERROR)") + FormApply.applyResponse("notificationBar.show(" + quote(getMessage()) + ",notificationBar.ERROR)") .generateResponse(req, rsp, node); } else { // for now, we can't really use the field name that caused the problem. - new Failure(getMessage()).generateResponse(req,rsp,node,getCause()); + new Failure(getMessage()).generateResponse(req, rsp, node, getCause()); } } } diff --git a/core/src/main/java/hudson/model/DescriptorByNameOwner.java b/core/src/main/java/hudson/model/DescriptorByNameOwner.java index e36f61df4d00..6dab3573d95a 100644 --- a/core/src/main/java/hudson/model/DescriptorByNameOwner.java +++ b/core/src/main/java/hudson/model/DescriptorByNameOwner.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import jenkins.model.Jenkins; diff --git a/core/src/main/java/hudson/model/DescriptorVisibilityFilter.java b/core/src/main/java/hudson/model/DescriptorVisibilityFilter.java index 89e8d1b7baab..36bcdc0606b6 100644 --- a/core/src/main/java/hudson/model/DescriptorVisibilityFilter.java +++ b/core/src/main/java/hudson/model/DescriptorVisibilityFilter.java @@ -1,5 +1,7 @@ package hudson.model; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.ExtensionList; import hudson.ExtensionPoint; import hudson.scm.SCMDescriptor; @@ -9,8 +11,6 @@ import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; -import edu.umd.cs.findbugs.annotations.CheckForNull; -import edu.umd.cs.findbugs.annotations.NonNull; import jenkins.ExtensionFilter; import jenkins.util.SystemProperties; diff --git a/core/src/main/java/hudson/model/DirectlyModifiableView.java b/core/src/main/java/hudson/model/DirectlyModifiableView.java index e12c34fa11cb..61362272c248 100644 --- a/core/src/main/java/hudson/model/DirectlyModifiableView.java +++ b/core/src/main/java/hudson/model/DirectlyModifiableView.java @@ -21,14 +21,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package hudson.model; +package hudson.model; -import java.io.IOException; import edu.umd.cs.findbugs.annotations.NonNull; +import java.io.IOException; import javax.servlet.ServletException; - import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.interceptor.RequirePOST; diff --git a/core/src/main/java/hudson/model/DirectoryBrowserSupport.java b/core/src/main/java/hudson/model/DirectoryBrowserSupport.java index 2ec571a4634c..1df1e1ab69a8 100644 --- a/core/src/main/java/hudson/model/DirectoryBrowserSupport.java +++ b/core/src/main/java/hudson/model/DirectoryBrowserSupport.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, Erik Ramfelt - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,11 +21,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.FilePath; import hudson.Util; +import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -59,9 +61,9 @@ import jenkins.util.SystemProperties; import jenkins.util.VirtualFile; import org.apache.commons.io.IOUtils; +import org.apache.commons.lang.StringUtils; import org.apache.tools.zip.ZipEntry; import org.apache.tools.zip.ZipOutputStream; -import org.apache.commons.lang.StringUtils; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.HttpResponse; @@ -73,7 +75,7 @@ * *

    * This object can be used in a mix-in style to provide a directory browsing capability - * to a {@link ModelObject}. + * to a {@link ModelObject}. * * @author Kohsuke Kawaguchi */ @@ -82,8 +84,13 @@ public final class DirectoryBrowserSupport implements HttpResponse { @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "Accessible via System Groovy Scripts") public static boolean ALLOW_SYMLINK_ESCAPE = SystemProperties.getBoolean(DirectoryBrowserSupport.class.getName() + ".allowSymlinkEscape"); + /** + * Escape hatch for the protection against SECURITY-2481. If enabled, the absolute paths on Windows will be allowed. + */ + static final String ALLOW_ABSOLUTE_PATH_PROPERTY_NAME = DirectoryBrowserSupport.class.getName() + ".allowAbsolutePath"; + public final ModelObject owner; - + public final String title; private final VirtualFile base; @@ -114,7 +121,7 @@ public DirectoryBrowserSupport(ModelObject owner, String title) { * @param base * The root of the directory that's bound to URL. * @param title - * Used in the HTML caption. + * Used in the HTML caption. * @param icon * The icon file name, like "folder.gif" * @param serveDirIndex @@ -147,15 +154,16 @@ public DirectoryBrowserSupport(ModelObject owner, VirtualFile base, String title this.serveDirIndex = serveDirIndex; } + @Override public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { if (!ResourceDomainConfiguration.isResourceRequest(req) && ResourceDomainConfiguration.isResourceDomainConfigured()) { resourceToken = ResourceDomainRootAction.get().getToken(this, req); } try { - serveFile(req,rsp,base,icon,serveDirIndex); + serveFile(req, rsp, base, icon, serveDirIndex); } catch (InterruptedException e) { - throw new IOException("interrupted",e); + throw new IOException("interrupted", e); } } @@ -188,15 +196,15 @@ public void serveFile(StaplerRequest req, StaplerResponse rsp, FilePath root, St private void serveFile(StaplerRequest req, StaplerResponse rsp, VirtualFile root, String icon, boolean serveDirIndex) throws IOException, ServletException, InterruptedException { // handle form submission String pattern = req.getParameter("pattern"); - if(pattern==null) + if (pattern == null) pattern = req.getParameter("path"); // compatibility with Hudson<1.129 - if(pattern!=null && Util.isSafeToRedirectTo(pattern)) {// avoid open redirect + if (pattern != null && Util.isSafeToRedirectTo(pattern)) { // avoid open redirect rsp.sendRedirect2(pattern); return; } String path = getPath(req); - if(path.replace('\\', '/').contains("/../")) { + if (path.replace('\\', '/').contains("/../")) { // don't serve anything other than files in the artifacts dir rsp.sendError(HttpServletResponse.SC_BAD_REQUEST); return; @@ -206,50 +214,63 @@ private void serveFile(StaplerRequest req, StaplerResponse rsp, VirtualFile root // and the GLOB portion "**/*.xml" (the rest) StringBuilder _base = new StringBuilder(); StringBuilder _rest = new StringBuilder(); - int restSize=-1; // number of ".." needed to go back to the 'base' level. - boolean zip=false; // if we are asked to serve a zip file bundle + int restSize = -1; // number of ".." needed to go back to the 'base' level. + boolean zip = false; // if we are asked to serve a zip file bundle boolean plain = false; // if asked to serve a plain text directory listing { boolean inBase = true; - StringTokenizer pathTokens = new StringTokenizer(path,"/"); - while(pathTokens.hasMoreTokens()) { + StringTokenizer pathTokens = new StringTokenizer(path, "/"); + while (pathTokens.hasMoreTokens()) { String pathElement = pathTokens.nextToken(); // Treat * and ? as wildcard unless they match a literal filename - if((pathElement.contains("?") || pathElement.contains("*")) + if ((pathElement.contains("?") || pathElement.contains("*")) && inBase && !root.child((_base.length() > 0 ? _base + "/" : "") + pathElement).exists()) inBase = false; - if(pathElement.equals("*zip*")) { + if (pathElement.equals("*zip*")) { // the expected syntax is foo/bar/*zip*/bar.zip // the last 'bar.zip' portion is to causes browses to set a good default file name. // so the 'rest' portion ends here. - zip=true; + zip = true; break; } - if(pathElement.equals("*plain*")) { + if (pathElement.equals("*plain*")) { plain = true; break; } - StringBuilder sb = inBase?_base:_rest; - if(sb.length()>0) sb.append('/'); + StringBuilder sb = inBase ? _base : _rest; + if (sb.length() > 0) sb.append('/'); sb.append(pathElement); - if(!inBase) + if (!inBase) restSize++; } } - restSize = Math.max(restSize,0); + restSize = Math.max(restSize, 0); String base = _base.toString(); String rest = _rest.toString(); // this is the base file/directory - VirtualFile baseFile = base.isEmpty() ? root : root.child(base); + VirtualFile baseFile; + if (base.isEmpty()) { + baseFile = root; + } else { + if (!SystemProperties.getBoolean(ALLOW_ABSOLUTE_PATH_PROPERTY_NAME, false)) { + boolean isAbsolute = root.run(new IsAbsolute(base)); + if (isAbsolute) { + LOGGER.info(() -> "SECURITY-2481 The path provided in the URL (" + base + ") is absolute and thus is refused."); + rsp.sendError(HttpServletResponse.SC_NOT_FOUND); + return; + } + } + baseFile = root.child(base); + } if (baseFile.hasSymlink(getNoFollowLinks())) { rsp.sendError(HttpServletResponse.SC_NOT_FOUND); return; } - if(baseFile.isDirectory()) { - if(zip) { + if (baseFile.isDirectory()) { + if (zip) { rsp.setContentType("application/zip"); String includes, prefix; if (StringUtils.isBlank(rest)) { @@ -278,10 +299,10 @@ private void serveFile(StaplerRequest req, StaplerResponse rsp, VirtualFile root return; } - if(rest.length()==0) { + if (rest.length() == 0) { // if the target page to be displayed is a directory and the path doesn't end with '/', redirect StringBuffer reqUrl = req.getRequestURL(); - if(reqUrl.charAt(reqUrl.length()-1)!='/') { + if (reqUrl.charAt(reqUrl.length() - 1) != '/') { rsp.sendRedirect2(reqUrl.append('/').toString()); return; } @@ -290,27 +311,27 @@ private void serveFile(StaplerRequest req, StaplerResponse rsp, VirtualFile root List> glob = null; boolean patternUsed = rest.length() > 0; boolean containsSymlink = false; - if(patternUsed) { + if (patternUsed) { // the rest is Ant glob pattern glob = patternScan(baseFile, rest, createBackRef(restSize)); } else - if(serveDirIndex) { + if (serveDirIndex) { // serve directory index glob = baseFile.run(new BuildChildPaths(root, baseFile, req.getLocale())); containsSymlink = baseFile.containsSymLinkChild(getNoFollowLinks()); } - if(glob!=null) { + if (glob != null) { // serve glob req.setAttribute("it", this); - List parentPaths = buildParentPath(base,restSize); - req.setAttribute("parentPath",parentPaths); + List parentPaths = buildParentPath(base, restSize); + req.setAttribute("parentPath", parentPaths); req.setAttribute("backPath", createBackRef(restSize)); - req.setAttribute("topPath", createBackRef(parentPaths.size()+restSize)); + req.setAttribute("topPath", createBackRef(parentPaths.size() + restSize)); req.setAttribute("files", glob); req.setAttribute("icon", icon); req.setAttribute("path", path); - req.setAttribute("pattern",rest); + req.setAttribute("pattern", rest); req.setAttribute("dir", baseFile); req.setAttribute("showSymlinkWarning", containsSymlink); if (ResourceDomainConfiguration.isResourceRequest(req)) { @@ -327,14 +348,14 @@ private void serveFile(StaplerRequest req, StaplerResponse rsp, VirtualFile root } //serve a single file - if(!baseFile.exists()) { + if (!baseFile.exists()) { rsp.sendError(HttpServletResponse.SC_NOT_FOUND); return; } boolean view = rest.equals("*view*"); - if(rest.equals("*fingerprint*")) { + if (rest.equals("*fingerprint*")) { try (InputStream fingerprintInput = baseFile.open()) { rsp.forward(Jenkins.get().getFingerprint(Util.getDigestOf(fingerprintInput)), "/", req); } @@ -352,8 +373,8 @@ private void serveFile(StaplerRequest req, StaplerResponse rsp, VirtualFile root long lastModified = baseFile.lastModified(); long length = baseFile.length(); - if(LOGGER.isLoggable(Level.FINE)) - LOGGER.fine("Serving "+baseFile+" with lastModified=" + lastModified + ", length=" + length); + if (LOGGER.isLoggable(Level.FINE)) + LOGGER.fine("Serving " + baseFile + " with lastModified=" + lastModified + ", length=" + length); if (view) { InputStream in; @@ -396,7 +417,20 @@ private void serveFile(StaplerRequest req, StaplerResponse rsp, VirtualFile root } } - private List> keepReadabilityOnlyOnDescendants(VirtualFile root, boolean patternUsed, List> pathFragmentsList){ + private static final class IsAbsolute extends MasterToSlaveCallable { + private final String fragment; + + IsAbsolute(String fragment) { + this.fragment = fragment; + } + + @Override + public Boolean call() throws IOException { + return new File(fragment).isAbsolute(); + } + } + + private List> keepReadabilityOnlyOnDescendants(VirtualFile root, boolean patternUsed, List> pathFragmentsList) { Stream> pathFragmentsStream = pathFragmentsList.stream().map((List pathFragments) -> { List mappedFragments = new ArrayList<>(pathFragments.size()); String relativePath = ""; @@ -407,7 +441,7 @@ private List> keepReadabilityOnlyOnDescendants(VirtualFile root, bool } else { relativePath += "/" + current.title; } - + if (!current.isReadable) { if (patternUsed) { // we do not want to leak information about existence of folders / files satisfying the pattern inside that folder @@ -430,15 +464,15 @@ private List> keepReadabilityOnlyOnDescendants(VirtualFile root, bool } return mappedFragments; }); - + if (patternUsed) { pathFragmentsStream = pathFragmentsStream.filter(Objects::nonNull); } - + return pathFragmentsStream.collect(Collectors.toList()); } - private boolean isDescendant(VirtualFile root, String relativePath){ + private boolean isDescendant(VirtualFile root, String relativePath) { try { return ALLOW_SYMLINK_ESCAPE || !root.supportIsDescendant() || root.isDescendant(relativePath); } @@ -449,7 +483,7 @@ private boolean isDescendant(VirtualFile root, String relativePath){ private String getPath(StaplerRequest req) { String path = req.getRestOfPath(); - if(path.length()==0) + if (path.length() == 0) path = "/"; return path; } @@ -462,19 +496,19 @@ private List buildParentPath(String pathList, int restSize) { List r = new ArrayList<>(); StringTokenizer tokens = new StringTokenizer(pathList, "/"); int total = tokens.countTokens(); - int current=1; - while(tokens.hasMoreTokens()) { + int current = 1; + while (tokens.hasMoreTokens()) { String token = tokens.nextToken(); - r.add(new Path(createBackRef(total-current+restSize),token,true,0, true,0)); + r.add(new Path(createBackRef(total - current + restSize), token, true, 0, true, 0)); current++; } return r; } private static String createBackRef(int times) { - if(times==0) return "./"; - StringBuilder buf = new StringBuilder(3*times); - for(int i=0; i nameToVirtualFiles = collectRecursivelyAllLegalChildren(dir); sendZipUsingMap(zos, dir, nameToVirtualFiles); @@ -524,7 +558,7 @@ private static void sendZipUsingListOfNames(ZipOutputStream zos, VirtualFile dir private static void sendOneZipEntry(ZipOutputStream zos, VirtualFile vf, String relativePath) throws IOException { // In ZIP archives "All slashes MUST be forward slashes" (http://pkware.com/documents/casestudies/APPNOTE.TXT) // TODO On Linux file names can contain backslashes which should not treated as file separators. - // Unfortunately, only the file separator char of the master is known (File.separatorChar) + // Unfortunately, only the file separator char of the controller is known (File.separatorChar) // but not the file separator char of the (maybe remote) "dir". ZipEntry e = new ZipEntry(relativePath.replace('\\', '/')); @@ -579,7 +613,7 @@ public static final class Path implements Serializable { * File size, or null if this is not a file. */ private final long size; - + /** * If the current user can read the file. */ @@ -610,7 +644,7 @@ public Path(String href, String title, boolean isFolder, long size, boolean isRe public boolean isFolder() { return isFolder; } - + public boolean isReadable() { return isReadable; } @@ -625,16 +659,16 @@ public String getTitle() { public String getIconName() { if (isReadable) - return isFolder?"folder.png":"text.png"; + return isFolder ? "folder.svg" : "document.svg"; else - return isFolder?"folder-error.png":"text-error.png"; + return isFolder ? "folder-delete.svg" : "document-delete.svg"; } public String getIconClassName() { if (isReadable) - return isFolder?"icon-folder":"icon-text"; + return isFolder ? "icon-folder" : "icon-document"; else - return isFolder?"icon-folder-error":"icon-text-error"; + return isFolder ? "icon-folder-delete" : "icon-document-delete"; } public long getSize() { @@ -664,7 +698,7 @@ public Calendar getLastModifiedAsCalendar() { return cal; } - public static Path createNotReadableVersionOf(Path that){ + public static Path createNotReadableVersionOf(Path that) { return new Path(that.href, that.title, that.isFolder, that.size, false); } @@ -680,17 +714,18 @@ private static final class FileComparator implements Comparator { this.collator = Collator.getInstance(locale); } + @Override public int compare(VirtualFile lhs, VirtualFile rhs) { // directories first, files next - int r = dirRank(lhs)-dirRank(rhs); - if(r!=0) return r; + int r = dirRank(lhs) - dirRank(rhs); + if (r != 0) return r; // otherwise alphabetical return this.collator.compare(lhs.getName(), rhs.getName()); } private int dirRank(VirtualFile f) { try { - if(f.isDirectory()) return 0; + if (f.isDirectory()) return 0; else return 1; } catch (IOException ex) { return 0; @@ -698,15 +733,17 @@ private int dirRank(VirtualFile f) { } } - private static final class BuildChildPaths extends MasterToSlaveCallable>,IOException> { + private static final class BuildChildPaths extends MasterToSlaveCallable>, IOException> { private VirtualFile root; private final VirtualFile cur; private final Locale locale; + BuildChildPaths(VirtualFile root, VirtualFile cur, Locale locale) { this.root = root; this.cur = cur; this.locale = locale; } + @Override public List> call() throws IOException { return buildChildPaths(cur, locale); } @@ -716,22 +753,24 @@ private static final class BuildChildPaths extends MasterToSlaveCallable> buildChildPaths(VirtualFile cur, Locale locale) throws IOException { List> r = new ArrayList<>(); VirtualFile[] files = cur.list(getNoFollowLinks()); - Arrays.sort(files,new FileComparator(locale)); - - for( VirtualFile f : files ) { + Arrays.sort(files, new FileComparator(locale)); + + for (VirtualFile f : files) { Path p = new Path(Util.rawEncode(f.getName()), f.getName(), f.isDirectory(), f.length(), f.canRead(), f.lastModified()); - if(!f.isDirectory()) { + if (!f.isDirectory()) { r.add(Collections.singletonList(p)); } else { // find all empty intermediate directory List l = new ArrayList<>(); l.add(p); String relPath = Util.rawEncode(f.getName()); - while(true) { + while (true) { // files that don't start with '.' qualify for 'meaningful files', nor SCM related files List sub = new ArrayList<>(); for (VirtualFile vf : f.list(getNoFollowLinks())) { @@ -740,11 +779,11 @@ private static List> buildChildPaths(VirtualFile cur, Locale locale) sub.add(vf); } } - if (sub.size() !=1 || !sub.get(0).isDirectory()) + if (sub.size() != 1 || !sub.get(0).isDirectory()) break; f = sub.get(0); - relPath += '/'+Util.rawEncode(f.getName()); - l.add(new Path(relPath,f.getName(),true, f.length(), f.canRead(), f.lastModified())); + relPath += '/' + Util.rawEncode(f.getName()); + l.add(new Path(relPath, f.getName(), true, f.length(), f.canRead(), f.lastModified())); } r.add(l); } diff --git a/core/src/main/java/hudson/model/DisplayNameListener.java b/core/src/main/java/hudson/model/DisplayNameListener.java index 94ae4afae4d5..2aee0c035c17 100644 --- a/core/src/main/java/hudson/model/DisplayNameListener.java +++ b/core/src/main/java/hudson/model/DisplayNameListener.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2011, Yahoo!, Inc. - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,17 +21,17 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import hudson.Extension; +import hudson.model.listeners.ItemListener; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; -import hudson.Extension; -import hudson.model.listeners.ItemListener; - /** * @author kingfai * @@ -42,7 +42,7 @@ public class DisplayNameListener extends ItemListener { private static final Logger LOGGER = Logger.getLogger(DisplayNameListener.class.getName()); /** - * Called after the user has clicked OK in the New Job page when + * Called after the user has clicked OK in the New Job page when * Copy existing job has been selected. * The fields in item will be displayed in when the config page is loaded * displayed. @@ -50,11 +50,11 @@ public class DisplayNameListener extends ItemListener { @Override public void onCopied(Item src, Item item) { // bug 5056825 - Display name field should be cleared when you copy a job within the same folder. - if(item instanceof AbstractItem && src.getParent() == item.getParent()) { - AbstractItem dest = (AbstractItem)item; - try { + if (item instanceof AbstractItem && src.getParent() == item.getParent()) { + AbstractItem dest = (AbstractItem) item; + try { dest.setDisplayName(null); - } catch(IOException ioe) { + } catch (IOException ioe) { LOGGER.log(Level.WARNING, String.format("onCopied():Exception while trying to clear the displayName for Item.name:%s", item.getName()), ioe); } } @@ -71,9 +71,9 @@ public void onCopied(Item src, Item item) { @Override public void onRenamed(Item item, String oldName, String newName) { // bug 5077308 - Display name field should be cleared when you rename a job. - if(item instanceof AbstractItem) { - AbstractItem abstractItem = (AbstractItem)item; - if(oldName.equals(abstractItem.getDisplayName())) { + if (item instanceof AbstractItem) { + AbstractItem abstractItem = (AbstractItem) item; + if (oldName.equals(abstractItem.getDisplayName())) { // the user renamed the job, but the old project name which is shown as the // displayname if no displayname was set, has been set into the displayname field. // This means that the displayname was never set, so we want to set it @@ -82,7 +82,7 @@ public void onRenamed(Item item, String oldName, String newName) { LOGGER.info(String.format("onRenamed():Setting displayname to null for item.name=%s", item.getName())); abstractItem.setDisplayName(null); } - catch(IOException ioe) { + catch (IOException ioe) { LOGGER.log(Level.WARNING, String.format("onRenamed():Exception while trying to clear the displayName for Item.name:%s", item.getName()), ioe); } diff --git a/core/src/main/java/hudson/model/DownloadService.java b/core/src/main/java/hudson/model/DownloadService.java index c4c62657f7f0..000ef9f48d2f 100644 --- a/core/src/main/java/hudson/model/DownloadService.java +++ b/core/src/main/java/hudson/model/DownloadService.java @@ -21,22 +21,24 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import static java.util.concurrent.TimeUnit.DAYS; + import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.Extension; import hudson.ExtensionList; import hudson.ExtensionListListener; import hudson.ExtensionPoint; import hudson.ProxyConfiguration; -import jenkins.util.SystemProperties; +import hudson.Util; import hudson.init.InitMilestone; import hudson.init.Initializer; import hudson.util.FormValidation; -import hudson.util.FormValidation.Kind; import hudson.util.TextFile; -import static java.util.concurrent.TimeUnit.DAYS; import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -46,11 +48,14 @@ import java.net.URLConnection; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.attribute.FileTime; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import jenkins.model.Jenkins; +import jenkins.util.SystemProperties; import net.sf.json.JSONException; import net.sf.json.JSONObject; import org.apache.commons.io.IOUtils; @@ -79,6 +84,7 @@ public class DownloadService { * * @deprecated browser-based download has been disabled */ + @Deprecated public String generateFragment() { return ""; @@ -90,7 +96,7 @@ public String generateFragment() { */ public Downloadable getById(String id) { for (Downloadable d : Downloadable.all()) - if(d.getId().equals(id)) + if (d.getId().equals(id)) return d; return null; } @@ -203,8 +209,8 @@ public static class Downloadable implements ExtensionPoint { private final String id; private final String url; private final long interval; - private volatile long due=0; - private volatile long lastAttempt=Long.MIN_VALUE; + private volatile long due = 0; + private volatile long lastAttempt = Long.MIN_VALUE; /** * Creates a new downloadable. @@ -285,14 +291,14 @@ public String getId() { */ @NonNull public static String idFor(@NonNull Class clazz) { - return clazz.getName().replace('$','.'); + return clazz.getName().replace('$', '.'); } /** * URL to download. */ public String getUrl() { - return Jenkins.get().getUpdateCenter().getDefaultBaseUrl()+"updates/"+url; + return Jenkins.get().getUpdateCenter().getDefaultBaseUrl() + "updates/" + url; } /** @@ -327,18 +333,18 @@ public long getInterval() { * This is where the retrieved file will be stored. */ public TextFile getDataFile() { - return new TextFile(new File(Jenkins.get().getRootDir(),"updates/"+id)); + return new TextFile(new File(Jenkins.get().getRootDir(), "updates/" + id)); } /** * When shall we retrieve this file next time? */ public long getDue() { - if(due==0) + if (due == 0) // if the file doesn't exist, this code should result // in a very small (but >0) due value, which should trigger // the retrieval immediately. - due = getDataFile().file.lastModified()+interval; + due = getDataFile().file.lastModified() + interval; return due; } @@ -348,12 +354,17 @@ public long getDue() { */ public JSONObject getData() throws IOException { TextFile df = getDataFile(); - if(df.exists()) + if (df.exists()) try { return JSONObject.fromObject(df.read()); } catch (JSONException e) { - df.delete(); // if we keep this file, it will cause repeated failures - throw new IOException("Failed to parse "+df+" into JSON",e); + IOException ioe = new IOException("Failed to parse " + df + " into JSON", e); + try { + df.delete(); // if we keep this file, it will cause repeated failures + } catch (IOException e2) { + ioe.addSuppressed(e2); + } + throw ioe; } return null; } @@ -361,8 +372,8 @@ public JSONObject getData() throws IOException { private FormValidation load(String json, long dataTimestamp) throws IOException { TextFile df = getDataFile(); df.write(json); - df.file.setLastModified(dataTimestamp); - LOGGER.info("Obtained the updated data file for "+id); + Files.setLastModifiedTime(Util.fileToPath(df.file), FileTime.fromMillis(dataTimestamp)); + LOGGER.info("Obtained the updated data file for " + id); return FormValidation.ok(); } @@ -380,14 +391,14 @@ public FormValidation updateNow() throws IOException { jsonString = loadJSONHTML(new URL(site + ".html?id=" + URLEncoder.encode(getId(), "UTF-8") + "&version=" + URLEncoder.encode(Jenkins.VERSION, "UTF-8"))); toolInstallerMetadataExists = true; } catch (Exception e) { - LOGGER.log(Level.FINE, "Could not load json from " + site, e ); + LOGGER.log(Level.FINE, "Could not load json from " + site, e); continue; } JSONObject o = JSONObject.fromObject(jsonString); if (signatureCheck) { - FormValidation e = updatesite.getJsonSignatureValidator(signatureValidatorPrefix +" '"+id+"'").verifySignature(o); - if (e.kind!= Kind.OK) { - LOGGER.log(Level.WARNING, "signature check failed for " + site, e ); + FormValidation e = updatesite.getJsonSignatureValidator(signatureValidatorPrefix + " '" + id + "'").verifySignature(o); + if (e.kind != FormValidation.Kind.OK) { + LOGGER.log(Level.WARNING, "signature check failed for " + site, e); continue; } } @@ -419,7 +430,7 @@ public JSONObject reduce(List jsonList) { * @param the generic class * @return true if the list has duplicates, false otherwise */ - public static boolean hasDuplicates (List genericList, String comparator) { + public static boolean hasDuplicates(List genericList, String comparator) { if (genericList.isEmpty()) { return false; } @@ -430,9 +441,9 @@ public static boolean hasDuplicates (List genericList, String comparator) LOGGER.warning("comparator: " + comparator + "does not exist for " + genericList.get(0).getClass() + ", " + e); return false; } - for (int i = 0; i < genericList.size(); i ++ ) { + for (int i = 0; i < genericList.size(); i++) { T data1 = genericList.get(i); - for (int j = i + 1; j < genericList.size(); j ++ ) { + for (int j = i + 1; j < genericList.size(); j++) { T data2 = genericList.get(j); try { if (field.get(data1).equals(field.get(data2))) { @@ -475,7 +486,7 @@ public static Downloadable get(@NonNull Class clazz) { @CheckForNull public static Downloadable get(String id) { for (Downloadable d : all()) { - if(d.id.equals(id)) + if (d.id.equals(id)) return d; } return null; @@ -483,16 +494,17 @@ public static Downloadable get(String id) { private static final Logger LOGGER = Logger.getLogger(Downloadable.class.getName()); private static final long DEFAULT_INTERVAL = - SystemProperties.getLong(Downloadable.class.getName()+".defaultInterval", DAYS.toMillis(1)); + SystemProperties.getLong(Downloadable.class.getName() + ".defaultInterval", DAYS.toMillis(1)); } // TODO this was previously referenced in the browser-based download, but should probably be checked for the server-based download - public static boolean neverUpdate = SystemProperties.getBoolean(DownloadService.class.getName()+".never"); + @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "Accessible via System Groovy Scripts") + public static boolean neverUpdate = SystemProperties.getBoolean(DownloadService.class.getName() + ".never"); /** * May be used to temporarily disable signature checking on {@link DownloadService} and {@link UpdateCenter}. * Useful when upstream signatures are broken, such as due to expired certificates. */ - public static boolean signatureCheck = !SystemProperties.getBoolean(DownloadService.class.getName()+".noSignatureCheck"); + @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "Accessible via System Groovy Scripts") + public static boolean signatureCheck = !SystemProperties.getBoolean(DownloadService.class.getName() + ".noSignatureCheck"); } - diff --git a/core/src/main/java/hudson/model/Environment.java b/core/src/main/java/hudson/model/Environment.java index f34ebb0505f3..987d74e7d6d2 100644 --- a/core/src/main/java/hudson/model/Environment.java +++ b/core/src/main/java/hudson/model/Environment.java @@ -21,15 +21,15 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import hudson.EnvVars; import hudson.Launcher; import hudson.model.listeners.RunListener; import hudson.slaves.NodeProperty; import hudson.tasks.BuildWrapper; import hudson.tasks.Builder; -import hudson.EnvVars; - import java.io.IOException; import java.util.Map; @@ -53,60 +53,60 @@ * @see RunListener#setUpEnvironment(AbstractBuild, Launcher, BuildListener) */ public abstract class Environment { - /** - * Adds environmental variables for the builds to the given map. - * - *

    - * If the {@link Environment} object wants to pass in information to the - * build that runs, it can do so by exporting additional environment - * variables to the map. - * - *

    - * When this method is invoked, the map already contains the current - * "planned export" list. - * - * @param env - * never null. This really should have been typed as {@link EnvVars} + /** + * Adds environmental variables for the builds to the given map. + * + *

    + * If the {@link Environment} object wants to pass in information to the + * build that runs, it can do so by exporting additional environment + * variables to the map. + * + *

    + * When this method is invoked, the map already contains the current + * "planned export" list. + * + * @param env + * never null. This really should have been typed as {@link EnvVars} * but by the time we realized it it was too late. - */ - public void buildEnvVars(Map env) { - // no-op by default - } + */ + public void buildEnvVars(Map env) { + // no-op by default + } - /** - * Runs after the {@link Builder} completes, and performs a tear down. - * - *

    - * This method is invoked even when the build failed, so that the clean up - * operation can be performed regardless of the build result (for example, - * you'll want to stop application server even if a build fails.) - * - * @param build - * The same {@link Build} object given to the set up method. - * @param listener - * The same {@link BuildListener} object given to the set up - * method. - * @return true if the build can continue, false if there was an error and - * the build needs to be failed. - * @throws IOException - * terminates the build abnormally. Jenkins will handle the - * exception and reports a nice error message. - */ - public boolean tearDown(AbstractBuild build, BuildListener listener) - throws IOException, InterruptedException { - return true; - } + /** + * Runs after the {@link Builder} completes, and performs a tear down. + * + *

    + * This method is invoked even when the build failed, so that the clean up + * operation can be performed regardless of the build result (for example, + * you'll want to stop application server even if a build fails.) + * + * @param build + * The same {@link Build} object given to the set up method. + * @param listener + * The same {@link BuildListener} object given to the set up + * method. + * @return true if the build can continue, false if there was an error and + * the build needs to be failed. + * @throws IOException + * terminates the build abnormally. Jenkins will handle the + * exception and reports a nice error message. + */ + public boolean tearDown(AbstractBuild build, BuildListener listener) + throws IOException, InterruptedException { + return true; + } /** * Creates {@link Environment} implementation that just sets the variables as given in the parameter. */ - public static Environment create(final EnvVars envVars) { - return new Environment() { - @Override - public void buildEnvVars(Map env) { - env.putAll(envVars); - } - }; - } - + public static Environment create(final EnvVars envVars) { + return new Environment() { + @Override + public void buildEnvVars(Map env) { + env.putAll(envVars); + } + }; + } + } diff --git a/core/src/main/java/hudson/model/EnvironmentContributingAction.java b/core/src/main/java/hudson/model/EnvironmentContributingAction.java index 1eed758f725d..0de322014c23 100644 --- a/core/src/main/java/hudson/model/EnvironmentContributingAction.java +++ b/core/src/main/java/hudson/model/EnvironmentContributingAction.java @@ -21,18 +21,18 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.EnvVars; import hudson.Util; import hudson.model.Queue.Task; -import hudson.tasks.Builder; import hudson.tasks.BuildWrapper; +import hudson.tasks.Builder; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.ProtectedExternally; -import edu.umd.cs.findbugs.annotations.NonNull; - /** * {@link Action} that contributes environment variables during a build. * @@ -69,12 +69,11 @@ default void buildEnvironment(@NonNull Run run, @NonNull EnvVars env) { /** * Called by {@link AbstractBuild} to allow plugins to contribute environment variables. * - * @deprecated Use {@link #buildEnvironment} instead - * * @param build * The calling build. Never null. * @param env * Environment variables should be added to this map. + * @deprecated Use {@link #buildEnvironment} instead */ @Deprecated @Restricted(ProtectedExternally.class) diff --git a/core/src/main/java/hudson/model/EnvironmentContributor.java b/core/src/main/java/hudson/model/EnvironmentContributor.java index 0a4c1ba1adf8..0fa5a96c70af 100644 --- a/core/src/main/java/hudson/model/EnvironmentContributor.java +++ b/core/src/main/java/hudson/model/EnvironmentContributor.java @@ -21,16 +21,16 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.EnvVars; import hudson.Extension; import hudson.ExtensionList; import hudson.ExtensionPoint; import hudson.scm.SCM; - import java.io.IOException; -import edu.umd.cs.findbugs.annotations.NonNull; /** * Contributes environment variables to builds. @@ -123,14 +123,17 @@ public static ExtensionList all() { */ @Extension public static class EnvVarsHtml implements RootAction { + @Override public String getIconFileName() { return null; } + @Override public String getDisplayName() { return null; } + @Override public String getUrlName() { return "env-vars.html"; } diff --git a/core/src/main/java/hudson/model/EnvironmentList.java b/core/src/main/java/hudson/model/EnvironmentList.java index 1c1b07a20573..0e11a1c51ccc 100644 --- a/core/src/main/java/hudson/model/EnvironmentList.java +++ b/core/src/main/java/hudson/model/EnvironmentList.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import java.util.AbstractList; diff --git a/core/src/main/java/hudson/model/EnvironmentSpecific.java b/core/src/main/java/hudson/model/EnvironmentSpecific.java index 32663e721491..53e127e671e5 100644 --- a/core/src/main/java/hudson/model/EnvironmentSpecific.java +++ b/core/src/main/java/hudson/model/EnvironmentSpecific.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import hudson.EnvVars; @@ -28,7 +29,7 @@ /** * Represents any concept that can be adapted for a certain environment. - * + * * Mainly for documentation purposes. * * @since 1.286 @@ -37,8 +38,8 @@ * @see NodeSpecific */ public interface EnvironmentSpecific> { - /** - * Returns a specialized copy of T for functioning in the given environment. - */ - T forEnvironment(EnvVars environment); + /** + * Returns a specialized copy of T for functioning in the given environment. + */ + T forEnvironment(EnvVars environment); } diff --git a/core/src/main/java/hudson/model/Executor.java b/core/src/main/java/hudson/model/Executor.java index 10d33101a71e..e7b14b72aebf 100644 --- a/core/src/main/java/hudson/model/Executor.java +++ b/core/src/main/java/hudson/model/Executor.java @@ -21,8 +21,17 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import static hudson.model.queue.Executables.getParentOf; +import static java.util.logging.Level.FINE; +import static java.util.logging.Level.FINER; +import static java.util.logging.Level.SEVERE; +import static java.util.logging.Level.WARNING; + +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.FilePath; import hudson.Functions; import hudson.Util; @@ -30,54 +39,49 @@ import hudson.model.queue.SubTask; import hudson.model.queue.WorkUnit; import hudson.security.ACL; +import hudson.security.ACLContext; +import hudson.security.AccessControlled; import hudson.util.InterceptingProxy; -import java.util.concurrent.TimeUnit; -import jenkins.model.CauseOfInterruption; -import jenkins.model.CauseOfInterruption.UserInterruption; -import jenkins.model.InterruptedBuildAction; -import jenkins.model.Jenkins; -import org.kohsuke.stapler.HttpResponse; -import org.kohsuke.stapler.HttpResponses; -import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; -import org.kohsuke.stapler.export.Exported; -import org.kohsuke.stapler.export.ExportedBean; -import org.kohsuke.stapler.interceptor.RequirePOST; - -import net.jcip.annotations.GuardedBy; -import javax.servlet.ServletException; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Vector; +import java.util.concurrent.Callable; +import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.logging.Level; import java.util.logging.Logger; - -import static hudson.model.queue.Executables.*; -import hudson.security.ACLContext; -import hudson.security.AccessControlled; -import java.util.Collection; -import static java.util.logging.Level.*; -import edu.umd.cs.findbugs.annotations.CheckForNull; -import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.stream.Collectors; +import javax.servlet.ServletException; +import jenkins.model.CauseOfInterruption; +import jenkins.model.CauseOfInterruption.UserInterruption; +import jenkins.model.InterruptedBuildAction; +import jenkins.model.Jenkins; import jenkins.model.queue.AsynchronousExecution; import jenkins.security.QueueItemAuthenticatorConfiguration; import jenkins.security.QueueItemAuthenticatorDescriptor; +import net.jcip.annotations.GuardedBy; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.DoNotUse; import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.stapler.HttpResponse; +import org.kohsuke.stapler.HttpResponses; +import org.kohsuke.stapler.QueryParameter; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.export.Exported; +import org.kohsuke.stapler.export.ExportedBean; +import org.kohsuke.stapler.interceptor.RequirePOST; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.core.Authentication; - /** * Thread that executes builds. * Since 1.536, {@link Executor}s start threads on-demand. @@ -144,7 +148,7 @@ public class Executor extends Thread implements ModelObject { private final List causes = new Vector<>(); public Executor(@NonNull Computer owner, int n) { - super("Executor #"+n+" for "+owner.getDisplayName()); + super("Executor #" + n + " for " + owner.getDisplayName()); this.owner = owner; this.queue = Jenkins.get().getQueue(); this.number = n; @@ -191,6 +195,7 @@ void interruptForShutdown() { * * @since 1.417 */ + public void interrupt(Result result) { interrupt(result, false); } @@ -215,7 +220,7 @@ public void interrupt(Result result, CauseOfInterruption... causes) { private void interrupt(Result result, boolean forShutdown, CauseOfInterruption... causes) { if (LOGGER.isLoggable(FINE)) - LOGGER.log(FINE, String.format("%s is interrupted(%s): %s", getDisplayName(), result, Util.join(Arrays.asList(causes),",")), new InterruptedException()); + LOGGER.log(FINE, String.format("%s is interrupted(%s): %s", getDisplayName(), result, Arrays.stream(causes).map(Object::toString).collect(Collectors.joining(","))), new InterruptedException()); lock.writeLock().lock(); try { @@ -245,7 +250,7 @@ public Result abortResult() { // this method is almost always called as a result of the current thread being interrupted // as a result we need to clean the interrupt flag so that the lock's lock method doesn't // get confused and think it was interrupted while awaiting the lock - Thread.interrupted(); + Thread.interrupted(); // we need to use a write lock as we may be repeatedly interrupted while processing and // we need the same lock as used in void interrupt(Result,boolean,CauseOfInterruption...) // JENKINS-28690 @@ -266,7 +271,7 @@ public Result abortResult() { * * @since 1.425 */ - public void recordCauseOfInterruption(Run build, TaskListener listener) { + public void recordCauseOfInterruption(Run build, TaskListener listener) { List r; // atomically get&clear causes. @@ -344,7 +349,7 @@ public void run() { SubTask task; // transition from idle to building. // perform this state change as an atomic operation wrt other queue operations - task = Queue.withLock(new java.util.concurrent.Callable() { + task = Queue.withLock(new Callable() { @Override public SubTask call() throws Exception { if (!owner.isOnline()) { @@ -360,7 +365,7 @@ public SubTask call() throws Exception { workUnit.setExecutor(Executor.this); queue.onStartExecuting(Executor.this); if (LOGGER.isLoggable(FINE)) - LOGGER.log(FINE, getName()+" grabbed "+workUnit+" from queue"); + LOGGER.log(FINE, getName() + " grabbed " + workUnit + " from queue"); SubTask task = workUnit.work; Executable executable = task.createExecutable(); if (executable == null) { @@ -389,7 +394,7 @@ public SubTask call() throws Exception { lock.readLock().unlock(); } if (LOGGER.isLoggable(FINE)) - LOGGER.log(FINE, getName()+" is going to execute "+executable); + LOGGER.log(FINE, getName() + " is going to execute " + executable); Throwable problems = null; try { @@ -406,14 +411,22 @@ public SubTask call() throws Exception { if (executable instanceof Actionable) { if (LOGGER.isLoggable(Level.FINER)) { - LOGGER.log(FINER, "when running {0} from {1} we are copying {2} actions whereas the item currently has {3}", new Object[] {executable, workUnit.context.item, workUnit.context.actions, workUnit.context.item.getAllActions()}); + LOGGER.log( + FINER, + "when running {0} from {1} we are copying {2} actions whereas the item currently has {3}", + new Object[] { + executable, + workUnit.context.item, + workUnit.context.actions, + workUnit.context.item.getAllActions(), + }); } - for (Action action: workUnit.context.actions) { + for (Action action : workUnit.context.actions) { ((Actionable) executable).addAction(action); } } - setName(getName() + " : executing " + executable.toString()); + setName(getName() + " : executing " + executable); Authentication auth = workUnit.context.item.authenticate2(); LOGGER.log(FINE, "{0} is now executing {1} as {2}", new Object[] {getName(), executable, auth}); if (LOGGER.isLoggable(FINE) && auth.equals(ACL.SYSTEM2)) { // i.e., unspecified @@ -452,10 +465,10 @@ public SubTask call() throws Exception { } } } catch (InterruptedException e) { - LOGGER.log(FINE, getName()+" interrupted",e); + LOGGER.log(FINE, getName() + " interrupted", e); // die peacefully - } catch(Exception | Error e) { - LOGGER.log(SEVERE, getName()+": Unexpected executor death", e); + } catch (Exception | Error e) { + LOGGER.log(SEVERE, getName() + ": Unexpected executor death", e); } finally { if (asynchronousExecution == null) { finish2(); @@ -522,18 +535,18 @@ public void completedAsynchronous(@CheckForNull Throwable error) { /** * Same as {@link #getCurrentExecutable} but checks {@link Item#READ}. */ - @Exported(name="currentExecutable") + @Exported(name = "currentExecutable") @Restricted(DoNotUse.class) // for exporting only public Queue.Executable getCurrentExecutableForApi() { Executable candidate = getCurrentExecutable(); return candidate instanceof AccessControlled && ((AccessControlled) candidate).hasPermission(Item.READ) ? candidate : null; } - + /** * Returns causes of interruption. * * @return Unmodifiable collection of causes of interruption. - * @since 1.617 + * @since 1.617 */ public @NonNull Collection getCausesOfInterruption() { return Collections.unmodifiableCollection(causes); @@ -580,8 +593,9 @@ public FilePath getCurrentWorkspace() { /** * Human readable name of the Jenkins executor. For the Java thread name use {@link #getName()}. */ + @Override public String getDisplayName() { - return "Executor #"+getNumber(); + return "Executor #" + getNumber(); } /** @@ -834,8 +848,8 @@ public void start() { */ @RequirePOST @Deprecated - public void doStop( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException { - doStop().generateResponse(req,rsp,this); + public void doStop(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + doStop().generateResponse(req, rsp, this); } /** @@ -867,8 +881,16 @@ public HttpResponse doStopBuild(@CheckForNull @QueryParameter(fixEmpty = true) S try { if (executable != null) { if (runExtId == null || runExtId.isEmpty() || ! (executable instanceof Run) - || (executable instanceof Run && runExtId.equals(((Run) executable).getExternalizableId()))) { - getParentOf(executable).getOwnerTask().checkAbortPermission(); + || (runExtId.equals(((Run) executable).getExternalizableId()))) { + final Queue.Task ownerTask = getParentOf(executable).getOwnerTask(); + boolean canAbort = ownerTask.hasAbortPermission(); + if (canAbort && ownerTask instanceof AccessControlled) { + if (!((AccessControlled) ownerTask).hasPermission(Item.READ)) { + // pretend the build does not exist + return HttpResponses.forwardToPreviousPage(); + } + } + ownerTask.checkAbortPermission(); interrupt(); } } @@ -893,7 +915,7 @@ public boolean hasStopPermission() { lock.readLock().lock(); try { return executable != null && getParentOf(executable).getOwnerTask().hasAbortPermission(); - } catch(Exception ex) { + } catch (RuntimeException ex) { if (!(ex instanceof AccessDeniedException)) { // Prevents UI from exploding in the case of unexpected runtime exceptions LOGGER.log(WARNING, "Unhandled exception", ex); @@ -932,16 +954,17 @@ public Api getApi() { */ public T newImpersonatingProxy(Class type, T core) { return new InterceptingProxy() { + @Override protected Object call(Object o, Method m, Object[] args) throws Throwable { final Executor old = IMPERSONATION.get(); IMPERSONATION.set(Executor.this); try { - return m.invoke(o,args); + return m.invoke(o, args); } finally { IMPERSONATION.set(old); } } - }.wrap(type,core); + }.wrap(type, core); } /** diff --git a/core/src/main/java/hudson/model/ExecutorListener.java b/core/src/main/java/hudson/model/ExecutorListener.java index 3c5e221f17f2..6500e6acc2ec 100644 --- a/core/src/main/java/hudson/model/ExecutorListener.java +++ b/core/src/main/java/hudson/model/ExecutorListener.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Stephen Connolly - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,24 +21,35 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import hudson.ExtensionPoint; import hudson.slaves.SlaveComputer; /** * A listener for task related events from executors. * A {@link Computer#getRetentionStrategy} or {@link SlaveComputer#getLauncher} may implement this interface. + * Or you may create an implementation as an extension (since TODO). * @author Stephen Connolly * @since 1.312 */ -public interface ExecutorListener { +public interface ExecutorListener extends ExtensionPoint { /** * Called whenever a task is accepted by an executor. * @param executor The executor. * @param task The task. */ - void taskAccepted(Executor executor, Queue.Task task); + default void taskAccepted(Executor executor, Queue.Task task) {} + + /** + * Called whenever a task is started by an executor. + * @param executor The executor. + * @param task The task. + * @since 2.318 + */ + default void taskStarted(Executor executor, Queue.Task task) {} /** * Called whenever a task is completed without any problems by an executor. @@ -46,7 +57,7 @@ public interface ExecutorListener { * @param task The task. * @param durationMS The number of milliseconds that the task took to complete. */ - void taskCompleted(Executor executor, Queue.Task task, long durationMS); + default void taskCompleted(Executor executor, Queue.Task task, long durationMS) {} /** * Called whenever a task is completed with some problems by an executor. @@ -55,5 +66,5 @@ public interface ExecutorListener { * @param durationMS The number of milliseconds that the task took to complete. * @param problems The exception that was thrown. */ - void taskCompletedWithProblems(Executor executor, Queue.Task task, long durationMS, Throwable problems); + default void taskCompletedWithProblems(Executor executor, Queue.Task task, long durationMS, Throwable problems) {} } diff --git a/core/src/main/java/hudson/model/Failure.java b/core/src/main/java/hudson/model/Failure.java index 53f8721311dc..71318dd0464b 100644 --- a/core/src/main/java/hudson/model/Failure.java +++ b/core/src/main/java/hudson/model/Failure.java @@ -21,24 +21,24 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import java.io.IOException; +import javax.servlet.ServletException; import jenkins.model.Jenkins; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; -import edu.umd.cs.findbugs.annotations.CheckForNull; -import javax.servlet.ServletException; -import java.io.IOException; - /** * Represents an error induced by user, encountered during HTTP request processing. * *

    * The error page is rendered into HTML, but without a stack trace. So only use * this exception when the error condition is anticipated by the program, and where - * we nor users don't need to see the stack trace to figure out the root cause. + * we nor users don't need to see the stack trace to figure out the root cause. * * @author Kohsuke Kawaguchi * @since 1.321 @@ -47,7 +47,7 @@ public class Failure extends RuntimeException implements HttpResponse { private final boolean pre; public Failure(String message) { - this(message,false); + this(message, false); } public Failure(String message, boolean pre) { @@ -62,13 +62,14 @@ public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object nod generateResponse(req, rsp, node); } + @Override public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { - req.setAttribute("message",getMessage()); - if(pre) - req.setAttribute("pre",true); + req.setAttribute("message", getMessage()); + if (pre) + req.setAttribute("pre", true); if (node instanceof AbstractItem) // Maintain ancestors - rsp.forward(Jenkins.get(), ((AbstractItem)node).getUrl() + "error", req); + rsp.forward(Jenkins.get(), ((AbstractItem) node).getUrl() + "error", req); else - rsp.forward(node instanceof AbstractModelObject ? node : Jenkins.get() ,"error", req); + rsp.forward(node instanceof AbstractModelObject ? node : Jenkins.get(), "error", req); } } diff --git a/core/src/main/java/hudson/model/FileParameterDefinition.java b/core/src/main/java/hudson/model/FileParameterDefinition.java index 37d14c620541..dcaf022b20fa 100644 --- a/core/src/main/java/hudson/model/FileParameterDefinition.java +++ b/core/src/main/java/hudson/model/FileParameterDefinition.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Seiji Sogabe, Tom Huybrechts - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,8 +21,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.Extension; import hudson.cli.CLICommand; import java.io.File; @@ -50,15 +54,16 @@ public class FileParameterDefinition extends ParameterDefinition { * @since 2.281 */ @DataBoundConstructor - public FileParameterDefinition(String name) { + public FileParameterDefinition(@NonNull String name) { super(name); } - public FileParameterDefinition(String name, String description) { + public FileParameterDefinition(@NonNull String name, @CheckForNull String description) { this(name); setDescription(description); } + @Override public FileParameterValue createValue(StaplerRequest req, JSONObject jo) { FileParameterValue p = req.bindJSON(FileParameterValue.class, jo); p.setLocation(getName()); @@ -66,7 +71,7 @@ public FileParameterValue createValue(StaplerRequest req, JSONObject jo) { return p; } - @Extension @Symbol({"file","fileParam"}) + @Extension @Symbol({"file", "fileParam"}) public static class DescriptorImpl extends ParameterDescriptor { @Override public String getDisplayName() { @@ -79,17 +84,17 @@ public String getHelpFile() { } } - @Override - public ParameterValue createValue(StaplerRequest req) { + @Override + public ParameterValue createValue(StaplerRequest req) { FileItem src; try { - src = req.getFileItem( getName() ); + src = req.getFileItem(getName()); } catch (ServletException | IOException e) { // Not sure what to do here. We might want to raise this // but that would involve changing the throws for this call return null; } - if ( src == null ) { + if (src == null) { // the requested file parameter wasn't uploaded return null; } @@ -97,14 +102,14 @@ public ParameterValue createValue(StaplerRequest req) { p.setDescription(getDescription()); p.setLocation(getName()); return p; - } + } /** * Strip off the path portion if the given path contains it. */ private String getFileName(String possiblyPathName) { - possiblyPathName = possiblyPathName.substring(possiblyPathName.lastIndexOf('/')+1); - possiblyPathName = possiblyPathName.substring(possiblyPathName.lastIndexOf('\\')+1); + possiblyPathName = possiblyPathName.substring(possiblyPathName.lastIndexOf('/') + 1); + possiblyPathName = possiblyPathName.substring(possiblyPathName.lastIndexOf('\\') + 1); return possiblyPathName; } @@ -112,7 +117,7 @@ private String getFileName(String possiblyPathName) { @Override public ParameterValue createValue(CLICommand command, String value) throws IOException, InterruptedException { // capture the file to the server - File local = File.createTempFile("jenkins","parameter"); + File local = File.createTempFile("jenkins", "parameter"); String name; if (value.isEmpty()) { FileUtils.copyInputStreamToFile(command.stdin, local); @@ -137,6 +142,7 @@ public int hashCode() { } @Override + @SuppressFBWarnings(value = "EQ_GETCLASS_AND_CLASS_CONSTANT", justification = "ParameterDefinitionTest tests that subclasses are not equal to their parent classes, so the behavior appears to be intentional") public boolean equals(Object obj) { if (FileParameterDefinition.class != getClass()) return super.equals(obj); diff --git a/core/src/main/java/hudson/model/FileParameterValue.java b/core/src/main/java/hudson/model/FileParameterValue.java index d561430cb685..e11d31c891fa 100644 --- a/core/src/main/java/hudson/model/FileParameterValue.java +++ b/core/src/main/java/hudson/model/FileParameterValue.java @@ -21,31 +21,32 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.EnvVars; import hudson.FilePath; import hudson.Launcher; +import hudson.Util; import hudson.tasks.BuildWrapper; import hudson.util.VariableResolver; - import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.io.UncheckedIOException; import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; import java.nio.file.Files; -import java.nio.file.InvalidPathException; import java.util.regex.Pattern; - +import jenkins.util.SystemProperties; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileItemHeaders; import org.apache.commons.fileupload.disk.DiskFileItem; import org.apache.commons.fileupload.util.FileItemHeadersImpl; import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; -import org.apache.commons.lang.StringUtils; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.DataBoundConstructor; @@ -73,9 +74,9 @@ public class FileParameterValue extends ParameterValue { * It's not recommended to enable for security reasons. That option is only present for backward compatibility. */ @Restricted(NoExternalUse.class) - @SuppressFBWarnings("MS_SHOULD_BE_FINAL") - public static /* Script Console modifiable */ boolean ALLOW_FOLDER_TRAVERSAL_OUTSIDE_WORKSPACE = - Boolean.getBoolean(FileParameterValue.class.getName() + ".allowFolderTraversalOutsideWorkspace"); + @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "for script console") + public static /* Script Console modifiable */ boolean ALLOW_FOLDER_TRAVERSAL_OUTSIDE_WORKSPACE = + SystemProperties.getBoolean(FileParameterValue.class.getName() + ".allowFolderTraversalOutsideWorkspace"); private final transient FileItem file; @@ -86,7 +87,7 @@ public class FileParameterValue extends ParameterValue { /** * Overrides the location in the build to place this file. Initially set to {@link #getName()} - * The location could be directly the filename or also a hierarchical path. + * The location could be directly the filename or also a hierarchical path. * The intermediate folders will be created automatically. * Take care that no escape from the current directory is allowed and will result in the failure of the build. */ @@ -126,17 +127,13 @@ public Object getValue() { * Exposes the originalFileName as an environment variable. */ @Override - public void buildEnvironment(Run build, EnvVars env) { - env.put(name,originalFileName); + public void buildEnvironment(Run build, EnvVars env) { + env.put(name, originalFileName); } @Override public VariableResolver createVariableResolver(AbstractBuild build) { - return new VariableResolver() { - public String resolve(String name) { - return FileParameterValue.this.name.equals(name) ? originalFileName : null; - } - }; + return name -> FileParameterValue.this.name.equals(name) ? originalFileName : null; } /** @@ -155,12 +152,13 @@ public FileItem getFile() { } @Override - public BuildWrapper createBuildWrapper(AbstractBuild build) { + public BuildWrapper createBuildWrapper(AbstractBuild build) { return new BuildWrapper() { + @SuppressFBWarnings(value = {"FILE_UPLOAD_FILENAME", "NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE"}, justification = "TODO needs triage") @Override public Environment setUp(AbstractBuild build, Launcher launcher, BuildListener listener) throws IOException, InterruptedException { - if (!StringUtils.isEmpty(location) && !StringUtils.isEmpty(file.getName())) { - listener.getLogger().println("Copying file to "+location); + if (location != null && !location.isEmpty() && file.getName() != null && !file.getName().isEmpty()) { + listener.getLogger().println("Copying file to " + location); FilePath ws = build.getWorkspace(); if (ws == null) { throw new IllegalStateException("The workspace should be created when setUp method is called"); @@ -172,48 +170,54 @@ public Environment setUp(AbstractBuild build, Launcher launcher, BuildListener l } FilePath locationFilePath = ws.child(location); locationFilePath.getParent().mkdirs(); - locationFilePath.copyFrom(file); + + // TODO Remove this workaround after FILEUPLOAD-293 is resolved. + if (locationFilePath.exists() && !locationFilePath.isDirectory()) { + locationFilePath.delete(); + } + + locationFilePath.copyFrom(file); locationFilePath.copyTo(new FilePath(getLocationUnderBuild(build))); - } + } return new Environment() {}; } }; } - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result - + ((location == null) ? 0 : location.hashCode()); - return result; - } - - /** - * Compares file parameters (existing files will be considered as different). - * @since 1.586 Function has been modified in order to avoid JENKINS-19017 issue (wrong merge of builds in the queue). - */ - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (!super.equals(obj)) - return false; - if (getClass() != obj.getClass()) - return false; - FileParameterValue other = (FileParameterValue) obj; - - if (location == null && other.location == null) - return true; // Consider null parameters as equal - - //TODO: check fingerprints or checksums to improve the behavior (JENKINS-25211) - // Return false even if files are equal - return false; - } + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + + (location == null ? 0 : location.hashCode()); + return result; + } + + /** + * Compares file parameters (existing files will be considered as different). + * @since 1.586 Function has been modified in order to avoid JENKINS-19017 issue (wrong merge of builds in the queue). + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (getClass() != obj.getClass()) + return false; + FileParameterValue other = (FileParameterValue) obj; + + if (location == null && other.location == null) + return true; // Consider null parameters as equal + + //TODO: check fingerprints or checksums to improve the behavior (JENKINS-25211) + // Return false even if files are equal + return false; + } @Override public String toString() { - return "(FileParameterValue) " + getName() + "='" + originalFileName + "'"; + return "(FileParameterValue) " + getName() + "='" + originalFileName + "'"; } @Override public String getShortDescription() { @@ -222,12 +226,9 @@ public String toString() { /** * Serve this file parameter in response to a {@link StaplerRequest}. - * - * @param request - * @param response */ public DirectoryBrowserSupport doDynamic(StaplerRequest request, StaplerResponse response) { - AbstractBuild build = (AbstractBuild)request.findAncestor(AbstractBuild.class).getObject(); + AbstractBuild build = (AbstractBuild) request.findAncestor(AbstractBuild.class).getObject(); File fileParameter = getFileParameterFolderUnderBuild(build); return new DirectoryBrowserSupport(build, new FilePath(fileParameter), Messages.FileParameterValue_IndexTitle(), "folder.png", false); } @@ -242,7 +243,7 @@ private File getLocationUnderBuild(AbstractBuild build) { return new File(getFileParameterFolderUnderBuild(build), location); } - private File getFileParameterFolderUnderBuild(AbstractBuild build){ + private File getFileParameterFolderUnderBuild(AbstractBuild build) { return new File(build.getRootDir(), FOLDER_NAME); } @@ -259,77 +260,88 @@ public FileItemImpl(File file) { this.file = file; } + @Override public InputStream getInputStream() throws IOException { - try { - return Files.newInputStream(file.toPath()); - } catch (InvalidPathException e) { - throw new IOException(e); - } + return Files.newInputStream(Util.fileToPath(file)); } + @Override public String getContentType() { return null; } + @Override public String getName() { return file.getName(); } + @Override public boolean isInMemory() { return false; } + @Override public long getSize() { return file.length(); } + @Override public byte[] get() { try { try (InputStream inputStream = Files.newInputStream(file.toPath())) { return IOUtils.toByteArray(inputStream); } - } catch (IOException | InvalidPathException e) { - throw new Error(e); + } catch (IOException e) { + throw new UncheckedIOException(e); } } + @Override public String getString(String encoding) throws UnsupportedEncodingException { return new String(get(), encoding); } + @Override public String getString() { - return new String(get()); + return new String(get(), Charset.defaultCharset()); } + @Override public void write(File to) throws Exception { new FilePath(file).copyTo(new FilePath(to)); } + @Override public void delete() { - file.delete(); + try { + Files.deleteIfExists(file.toPath()); + } catch (IOException e) { + throw new UncheckedIOException(e); + } } + @Override public String getFieldName() { return null; } + @Override public void setFieldName(String name) { } + @Override public boolean isFormField() { return false; } + @Override public void setFormField(boolean state) { } + @Override @Deprecated public OutputStream getOutputStream() throws IOException { - try { - return Files.newOutputStream(file.toPath()); - } catch (InvalidPathException e) { - throw new IOException(e); - } + return Files.newOutputStream(Util.fileToPath(file)); } @Override diff --git a/core/src/main/java/hudson/model/Fingerprint.java b/core/src/main/java/hudson/model/Fingerprint.java index 8331654c36ab..d4b57badaefc 100644 --- a/core/src/main/java/hudson/model/Fingerprint.java +++ b/core/src/main/java/hudson/model/Fingerprint.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Yahoo! Inc. - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,9 +21,9 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; -import com.google.common.collect.ImmutableList; import com.infradna.tool.bridge_method_injector.WithBridgeMethods; import com.thoughtworks.xstream.converters.Converter; import com.thoughtworks.xstream.converters.MarshallingContext; @@ -32,9 +32,13 @@ import com.thoughtworks.xstream.converters.collections.CollectionConverter; import com.thoughtworks.xstream.io.HierarchicalStreamReader; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.BulkChange; -import hudson.Util; import hudson.Extension; +import hudson.ExtensionList; +import hudson.Util; import hudson.model.listeners.ItemListener; import hudson.security.ACL; import hudson.security.ACLContext; @@ -43,16 +47,6 @@ import hudson.util.PersistedList; import hudson.util.RunList; import hudson.util.XStream2; - -import jenkins.fingerprints.FileFingerprintStorage; -import jenkins.fingerprints.FingerprintStorage; -import jenkins.model.FingerprintFacet; -import jenkins.model.Jenkins; -import jenkins.model.TransientFingerprintFacetFactory; -import org.apache.commons.lang.StringUtils; -import org.kohsuke.stapler.export.Exported; -import org.kohsuke.stapler.export.ExportedBean; - import java.io.File; import java.io.IOException; import java.util.AbstractCollection; @@ -64,12 +58,18 @@ import java.util.Hashtable; import java.util.Iterator; import java.util.List; -import java.util.Map.Entry; +import java.util.Map; import java.util.TreeMap; import java.util.logging.Level; import java.util.logging.Logger; -import edu.umd.cs.findbugs.annotations.CheckForNull; -import edu.umd.cs.findbugs.annotations.NonNull; +import jenkins.fingerprints.FileFingerprintStorage; +import jenkins.fingerprints.FingerprintStorage; +import jenkins.model.FingerprintFacet; +import jenkins.model.Jenkins; +import jenkins.model.TransientFingerprintFacetFactory; +import org.apache.commons.lang.StringUtils; +import org.kohsuke.stapler.export.Exported; +import org.kohsuke.stapler.export.ExportedBean; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.core.Authentication; @@ -87,7 +87,7 @@ public class Fingerprint implements ModelObject, Saveable { /** * Pointer to a {@link Build}. */ - @ExportedBean(defaultVisibility=2) + @ExportedBean(defaultVisibility = 2) public static class BuildPtr { String name; final int number; @@ -98,13 +98,13 @@ public BuildPtr(String name, int number) { } public BuildPtr(Run run) { - this( run.getParent().getFullName(), run.getNumber() ); + this(run.getParent().getFullName(), run.getNumber()); } /** * Gets {@link Job#getFullName() the full name of the job}. * Such job could be since then removed, so there might not be a corresponding {@link Job}. - * + * * @return A name of the job */ @Exported @@ -112,12 +112,12 @@ public BuildPtr(Run run) { public String getName() { return name; } - + /** * Checks if the current user has permission to see this pointer. * @return {@code true} if the job exists and user has {@link Item#READ} permissions - * or if the current user has {@link Jenkins#ADMINISTER} permissions. - * If the job exists, but the current user has no permission to discover it, + * or if the current user has {@link Jenkins#ADMINISTER} permissions. + * If the job exists, but the current user has no permission to discover it, * {@code false} will be returned. * If the job has been deleted and the user has no {@link Jenkins#ADMINISTER} permissions, * it also returns {@code false} in order to avoid the job existence fact exposure. @@ -129,22 +129,22 @@ private boolean hasPermissionToDiscoverBuild() { if (instance.hasPermission(Jenkins.ADMINISTER)) { return true; } - + return canDiscoverItem(name); } - - + + void setName(String newName) { name = newName; } - + /** * Gets the {@link Job} that this pointer points to, * or null if such a job no longer exists. */ - @WithBridgeMethods(value=AbstractProject.class, castRequired=true) - public Job getJob() { + @WithBridgeMethods(value = AbstractProject.class, castRequired = true) + public Job getJob() { return Jenkins.get().getItemByFullName(name, Job.class); } @@ -166,19 +166,19 @@ public int getNumber() { */ public Run getRun() { Job j = getJob(); - if(j==null) return null; + if (j == null) return null; return j.getBuildByNumber(number); } private boolean isAlive() { - return getRun()!=null; + return getRun() != null; } /** * Returns true if {@link BuildPtr} points to the given run. */ public boolean is(Run r) { - return r.getNumber()==number && r.getParent().getFullName().equals(name); + return r.getNumber() == number && r.getParent().getFullName().equals(name); } /** @@ -194,12 +194,12 @@ public boolean is(Job job) { * *

    * This is useful to check if an artifact in MavenModule - * belongs to MavenModuleSet. + * belongs to MavenModuleSet. */ public boolean belongsTo(Job job) { Item p = Jenkins.get().getItemByFullName(name); - while(p!=null) { - if(p==job) + while (p != null) { + if (p == job) return true; // go up the chain while we @@ -222,13 +222,13 @@ public boolean belongsTo(Job job) { /** * Range of build numbers [start,end). Immutable. */ - @ExportedBean(defaultVisibility=4) + @ExportedBean(defaultVisibility = 4) public static final class Range { final int start; final int end; public Range(int start, int end) { - assert start ranges; @@ -363,45 +363,30 @@ private RangeSet(Range initial) { public Iterable listNumbers() { final List ranges = getRanges(); return new Iterable() { + @Override public Iterator iterator() { - return new Iterators.FlattenIterator(ranges) { + return new Iterators.FlattenIterator(ranges) { + @Override protected Iterator expand(Range range) { - return Iterators.sequence(range.start,range.end).iterator(); + return Iterators.sequence(range.start, range.end).iterator(); } }; } }; } -// /** -// * List up builds. -// */ -// public ,R extends Run> Iterable listBuilds(final J job) { -// return new Iterable() { -// public Iterator iterator() { -// return new Iterators.FilterIterator(new AdaptedIterator(listNumbers().iterator()) { -// protected R adapt(Integer n) { -// return job.getBuildByNumber(n); -// } -// }) { -// protected boolean filter(R r) { -// return r!=null; -// } -// }; -// } -// }; -// } - /** * List all numbers in this range set in the descending order. */ public Iterable listNumbersReverse() { final List ranges = getRanges(); return new Iterable() { + @Override public Iterator iterator() { - return new Iterators.FlattenIterator(Iterators.reverse(ranges)) { + return new Iterators.FlattenIterator(Iterators.reverse(ranges)) { + @Override protected Iterator expand(Range range) { - return Iterators.reverseSequence(range.start,range.end).iterator(); + return Iterators.reverseSequence(range.start, range.end).iterator(); } }; } @@ -421,27 +406,27 @@ public synchronized List getRanges() { * If the set already includes this number, this will be a no-op. */ public synchronized void add(int n) { - for( int i=0; i intersection = new ArrayList<>(); - int lhs=0,rhs=0; - while(lhs sub = new ArrayList<>(); - int lhs=0,rhs=0; - while(lhs0) buf.append(','); + if (buf.length() > 0) buf.append(','); buf.append(r); } return buf.toString(); @@ -663,7 +648,7 @@ public synchronized int min() { * If this range is empty, this method throws an exception. */ public synchronized int max() { - return ranges.get(ranges.size()-1).end; + return ranges.get(ranges.size() - 1).end; } /** @@ -674,7 +659,7 @@ public synchronized int max() { * Note that {} is smaller than any n. */ public synchronized boolean isSmallerThan(int n) { - if(ranges.isEmpty()) return true; + if (ranges.isEmpty()) return true; return ranges.get(ranges.size() - 1).isSmallerThan(n); } @@ -695,8 +680,8 @@ public static RangeSet fromString(String list, boolean skipError) { return rs; } - String[] items = Util.tokenize(list,","); - if(items.length > 1 && items.length <= StringUtils.countMatches(list, ",")) { + String[] items = Util.tokenize(list, ","); + if (items.length > 1 && items.length <= StringUtils.countMatches(list, ",")) { if (!skipError) { throw new IllegalArgumentException( String.format("Unable to parse '%s', expected correct notation M,N or M-N", list)); @@ -718,8 +703,8 @@ public static RangeSet fromString(String list, boolean skipError) { continue; } - if(s.contains("-")) { - if(StringUtils.countMatches(s, "-") > 1) { + if (s.contains("-")) { + if (StringUtils.countMatches(s, "-") > 1) { if (!skipError) { throw new IllegalArgumentException(String.format( "Unable to parse '%s', expected correct notation M,N or M-N", list)); @@ -727,11 +712,11 @@ public static RangeSet fromString(String list, boolean skipError) { // ignore malformed ranges like "-5-2" or "2-5-" continue; } - String[] tokens = Util.tokenize(s,"-"); + String[] tokens = Util.tokenize(s, "-"); if (tokens.length == 2) { int left = Integer.parseInt(tokens[0]); int right = Integer.parseInt(tokens[1]); - if(left < 0 || right < 0) { + if (left < 0 || right < 0) { if (!skipError) { throw new IllegalArgumentException( String.format("Unable to parse '%s', expected number above zero", list)); @@ -739,7 +724,7 @@ public static RangeSet fromString(String list, boolean skipError) { // ignore a range which starts or ends under zero like "-5-3" continue; } - if(left > right) { + if (left > right) { if (!skipError) { throw new IllegalArgumentException(String.format( "Unable to parse '%s', expected string with a range M-N where M0) buf.append(','); - if(r.isSingle()) + if (buf.length() > 0) buf.append(','); + if (r.isSingle()) buf.append(r.start); else - buf.append(r.start).append('-').append(r.end-1); + buf.append(r.start).append('-').append(r.end - 1); } return buf.toString(); } + @Override public Object unmarshal(HierarchicalStreamReader reader, final UnmarshallingContext context) { - if(reader.hasMoreChildren()) { + if (reader.hasMoreChildren()) { /* old format where elements are nested like 1337 1479 */ - return new RangeSet((List)(collectionConv.unmarshal(reader,context))); + return new RangeSet((List) collectionConv.unmarshal(reader, context)); } else { - return RangeSet.fromString(reader.getValue(),true); + return RangeSet.fromString(reader.getValue(), true); } } } @@ -834,6 +822,7 @@ public void onLocationChanged(final Item item, final String oldName, final Strin locationChanged(item, oldName, newName); } } + private void locationChanged(Item item, String oldName, String newName) { if (item instanceof Job) { Job p = Jenkins.get().getItemByFullName(newName, Job.class); @@ -855,7 +844,7 @@ private void locationChanged(Item item, String oldName, String newName) { } private static final DateConverter DATE_CONVERTER = new DateConverter(); - + /** * Time when the fingerprint has been captured. */ @@ -874,7 +863,7 @@ private void locationChanged(Item item, String oldName, String newName) { /** * Range of builds that use this file keyed by a job full name. */ - private Hashtable usages = new Hashtable<>(); + private Hashtable usages = new Hashtable<>(); PersistedList facets = new PersistedList<>(this); @@ -884,7 +873,7 @@ private void locationChanged(Item item, String oldName, String newName) { private transient volatile List transientFacets = null; public Fingerprint(@CheckForNull Run build, @NonNull String fileName, @NonNull byte[] md5sum) throws IOException { - this(build==null ? null : new BuildPtr(build), fileName, md5sum); + this(build == null ? null : new BuildPtr(build), fileName, md5sum); save(); } @@ -915,6 +904,7 @@ public Fingerprint(@CheckForNull Run build, @NonNull String fileName, @NonNull b return null; } + @Override public @NonNull String getDisplayName() { return fileName; } @@ -930,7 +920,7 @@ public Fingerprint(@CheckForNull Run build, @NonNull String fileName, @NonNull b /** * Gets the MD5 hash string. */ - @Exported(name="hash") + @Exported(name = "hash") public @NonNull String getHashString() { return Util.toHexString(md5sum); } @@ -950,7 +940,7 @@ public Fingerprint(@CheckForNull Run build, @NonNull String fileName, @NonNull b * string like "3 minutes" "1 day" etc. */ public @NonNull String getTimestampString() { - long duration = System.currentTimeMillis()-timestamp.getTime(); + long duration = System.currentTimeMillis() - timestamp.getTime(); return Util.getTimeSpanString(duration); } @@ -963,7 +953,7 @@ public Fingerprint(@CheckForNull Run build, @NonNull String fileName, @NonNull b */ public @NonNull RangeSet getRangeSet(String jobFullName) { RangeSet r = usages.get(jobFullName); - if(r==null) r = new RangeSet(); + if (r == null) r = new RangeSet(); return r; } @@ -974,17 +964,18 @@ public RangeSet getRangeSet(Job job) { /** * Gets the sorted list of job names where this jar is used. */ - public @NonNull List getJobs() { + @NonNull + public synchronized List getJobs() { List r = new ArrayList<>(usages.keySet()); Collections.sort(r); return r; } - public @CheckForNull Hashtable getUsages() { + public @CheckForNull Hashtable getUsages() { return usages; } - @ExportedBean(defaultVisibility=2) + @ExportedBean(defaultVisibility = 2) public static final class RangeItem { @Exported public final String name; @@ -998,11 +989,11 @@ public RangeItem(String name, RangeSet ranges) { } // this is for remote API - @Exported(name="usage") + @Exported(name = "usage") public @NonNull List _getUsages() { List r = new ArrayList<>(); final Jenkins instance = Jenkins.get(); - for (Entry e : usages.entrySet()) { + for (Map.Entry e : usages.entrySet()) { final String itemName = e.getKey(); if (instance.hasPermission(Jenkins.ADMINISTER) || canDiscoverItem(itemName)) { r.add(new RangeItem(itemName, e.getValue())); @@ -1037,6 +1028,7 @@ public synchronized void add(@NonNull String jobFullName, int n) throws IOExcept } // JENKINS-49588 + @SuppressFBWarnings(value = "IS2_INCONSISTENT_SYNC", justification = "nothing should be competing with XStream during deserialization") protected Object readResolve() { if (usages == null) { usages = new Hashtable<>(); @@ -1045,11 +1037,11 @@ protected Object readResolve() { } void addWithoutSaving(@NonNull String jobFullName, int n) { - synchronized(usages) { // TODO why not synchronized (this) like some, though not all, other accesses? + synchronized (usages) { // TODO why not synchronized (this) like some, though not all, other accesses? RangeSet r = usages.get(jobFullName); - if(r==null) { + if (r == null) { r = new RangeSet(); - usages.put(jobFullName,r); + usages.put(jobFullName, r); } r.add(n); } @@ -1064,20 +1056,20 @@ void addWithoutSaving(@NonNull String jobFullName, int n) { * without losing too much information. */ public synchronized boolean isAlive() { - if(original!=null && original.isAlive()) + if (original != null && original.isAlive()) return true; - for (Entry e : usages.entrySet()) { - Job j = Jenkins.get().getItemByFullName(e.getKey(),Job.class); - if(j==null) + for (Map.Entry e : usages.entrySet()) { + Job j = Jenkins.get().getItemByFullName(e.getKey(), Job.class); + if (j == null) continue; Run firstBuild = j.getFirstBuild(); - if(firstBuild==null) + if (firstBuild == null) continue; int oldest = firstBuild.getNumber(); - if(!e.getValue().isSmallerThan(oldest)) + if (!e.getValue().isSmallerThan(oldest)) return true; } return false; @@ -1088,22 +1080,22 @@ public synchronized boolean isAlive() { * * @return true * if this record was modified. - * + * * @throws IOException Save failure */ public synchronized boolean trim() throws IOException { boolean modified = false; - for (Entry e : new Hashtable<>(usages).entrySet()) {// copy because we mutate - Job j = Jenkins.get().getItemByFullName(e.getKey(),Job.class); - if(j==null) {// no such job any more. recycle the record + for (Map.Entry e : new Hashtable<>(usages).entrySet()) { // copy because we mutate + Job j = Jenkins.get().getItemByFullName(e.getKey(), Job.class); + if (j == null) { // no such job any more. recycle the record modified = true; usages.remove(e.getKey()); continue; } Run firstBuild = j.getFirstBuild(); - if(firstBuild==null) {// no builds. recycle the whole record + if (firstBuild == null) { // no builds. recycle the whole record modified = true; usages.remove(e.getKey()); continue; @@ -1116,17 +1108,17 @@ public synchronized boolean trim() throws IOException { // that are marked as kept RangeSet kept = new RangeSet(); Run r = firstBuild; - while (r!=null && r.isKeepLog()) { + while (r != null && r.isKeepLog()) { kept.add(r.getNumber()); r = r.getNextBuild(); } - if (r==null) { + if (r == null) { // all the build records are permanently kept ones, so we'll just have to keep 'kept' out of whatever currently in 'cur' modified |= cur.retainAll(kept); } else { // otherwise we are ready to discard [0,r.number) except those marked as 'kept' - RangeSet discarding = new RangeSet(new Range(-1,r.getNumber())); + RangeSet discarding = new RangeSet(new Range(-1, r.getNumber())); discarding.removeAll(kept); modified |= cur.removeAll(discarding); } @@ -1164,12 +1156,12 @@ public synchronized boolean trim() throws IOException { * @since 1.421 */ public @NonNull Collection getFacets() { - if (transientFacets==null) { + if (transientFacets == null) { List transientFacets = new ArrayList<>(); for (TransientFingerprintFacetFactory fff : TransientFingerprintFacetFactory.all()) { - fff.createFor(this,transientFacets); + fff.createFor(this, transientFacets); } - this.transientFacets = ImmutableList.copyOf(transientFacets); + this.transientFacets = Collections.unmodifiableList(transientFacets); } return new AbstractCollection() { @@ -1196,7 +1188,7 @@ public boolean contains(Object o) { @Override public int size() { - return facets.size()+transientFacets.size(); + return facets.size() + transientFacets.size(); } }; } @@ -1212,11 +1204,12 @@ public int size() { /** * Sorts {@link FingerprintFacet}s by their timestamps. - * @return Sorted list of {@link FingerprintFacet}s + * @return Sorted list of {@link FingerprintFacet}s */ public @NonNull Collection getSortedFacets() { List r = new ArrayList<>(getFacets()); r.sort(new Comparator() { + @Override public int compare(FingerprintFacet o1, FingerprintFacet o2) { long a = o1.getTimestamp(); long b = o2.getTimestamp(); @@ -1254,20 +1247,21 @@ public int compare(FingerprintFacet o1, FingerprintFacet o2) { * Save the Fingerprint in the Fingerprint Storage * @throws IOException Save error */ + @Override public synchronized void save() throws IOException { - if(BulkChange.contains(this)) { + if (BulkChange.contains(this)) { return; } - long start=0; - if(logger.isLoggable(Level.FINE)) + long start = 0; + if (logger.isLoggable(Level.FINE)) start = System.currentTimeMillis(); FingerprintStorage configuredFingerprintStorage = FingerprintStorage.get(); - FingerprintStorage fileFingerprintStorage = FingerprintStorage.getFileFingerprintStorage(); + FingerprintStorage fileFingerprintStorage = ExtensionList.lookupSingleton(FileFingerprintStorage.class); // Implementations are expected to invoke SaveableListener on their own if relevant - // TODO: Consider improving Saveable Listener API: https://issues.jenkins-ci.org/browse/JENKINS-62543 + // TODO: Consider improving Saveable Listener API: https://issues.jenkins.io/browse/JENKINS-62543 configuredFingerprintStorage.save(this); // In the case that external fingerprint storage is configured, there may be some fingerprints in memory that @@ -1278,14 +1272,14 @@ public synchronized void save() throws IOException { fileFingerprintStorage.delete(this.getHashString()); } - if(logger.isLoggable(Level.FINE)) + if (logger.isLoggable(Level.FINE)) logger.fine("Saving fingerprint " + getHashString() + " took " + (System.currentTimeMillis() - start) + "ms"); } /** * Save the Fingerprint in the given file locally * @throws IOException Save error - * @deprecated as of TODO. Use {@link #save()} instead. + * @deprecated as of 2.242. Use {@link #save()} instead. */ @Deprecated void save(File file) throws IOException { @@ -1316,7 +1310,7 @@ public synchronized void rename(String oldName, String newName) throws IOExcepti touched = true; } } - + if (usages != null) { RangeSet r = usages.get(oldName); if (r != null) { @@ -1325,12 +1319,12 @@ public synchronized void rename(String oldName, String newName) throws IOExcepti touched = true; } } - + if (touched) { save(); } } - + public Api getApi() { return new Api(this); } @@ -1345,13 +1339,13 @@ public Api getApi() { * 2. If not found, then the local storage is polled to retrieve the fingerprint */ public static @CheckForNull Fingerprint load(@NonNull String id) throws IOException { - long start=0; - if(logger.isLoggable(Level.FINE)) { + long start = 0; + if (logger.isLoggable(Level.FINE)) { start = System.currentTimeMillis(); } FingerprintStorage configuredFingerprintStorage = FingerprintStorage.get(); - FingerprintStorage fileFingerprintStorage = FileFingerprintStorage.getFileFingerprintStorage(); + FingerprintStorage fileFingerprintStorage = ExtensionList.lookupSingleton(FileFingerprintStorage.class); Fingerprint loaded = configuredFingerprintStorage.load(id); @@ -1367,7 +1361,7 @@ public Api getApi() { initFacets(loaded); } - if(logger.isLoggable(Level.FINE)) { + if (logger.isLoggable(Level.FINE)) { logger.fine("Loading fingerprint took " + (System.currentTimeMillis() - start) + "ms"); } @@ -1376,7 +1370,7 @@ public Api getApi() { /** * Determines the file name from md5sum. - * @deprecated as of TODO. Use {@link #load(String)} instead. + * @deprecated as of 2.242. Use {@link #load(String)} instead. */ @Deprecated /*package*/ static @CheckForNull Fingerprint load(@NonNull byte[] md5sum) throws IOException { @@ -1387,7 +1381,7 @@ public Api getApi() { * Loads a {@link Fingerprint} from a file in the image. * @return Loaded {@link Fingerprint}. Null if the config file does not exist or * malformed. - * @deprecated as of TODO. Use {@link #load(String)} instead. + * @deprecated as of 2.242. Use {@link #load(String)} instead. */ @Deprecated /*package*/ static @CheckForNull Fingerprint load(@NonNull File file) throws IOException { @@ -1404,7 +1398,7 @@ public Api getApi() { */ public static void delete(@NonNull String id) throws IOException { FingerprintStorage configuredFingerprintStorage = FingerprintStorage.get(); - FingerprintStorage fileFingerprintStorage = FingerprintStorage.getFileFingerprintStorage(); + FingerprintStorage fileFingerprintStorage = ExtensionList.lookupSingleton(FileFingerprintStorage.class); configuredFingerprintStorage.delete(id); @@ -1427,9 +1421,21 @@ private static void initFacets(@CheckForNull Fingerprint fingerprint) { } @Override public String toString() { - return "Fingerprint[original=" + original + ",hash=" + getHashString() + ",fileName=" + fileName + ",timestamp=" + DATE_CONVERTER.toString(timestamp) + ",usages=" + ((usages == null) ? "null" : new TreeMap<>(getUsages())) + ",facets=" + facets + "]"; + return "Fingerprint[original=" + + original + + ",hash=" + + getHashString() + + ",fileName=" + + fileName + + ",timestamp=" + + DATE_CONVERTER.toString(timestamp) + + ",usages=" + + (usages == null ? "null" : new TreeMap<>(getUsages())) + + ",facets=" + + facets + + "]"; } - + /** * Checks if the current user can Discover the item. * If yes, it may be displayed as a text in Fingerprint UIs. @@ -1449,7 +1455,7 @@ private static boolean canDiscoverItem(@NonNull final String fullName) { if (item != null) { return true; } - + // Probably it failed due to the missing Item.DISCOVER // We try to retrieve the job using SYSTEM2 user and to check permissions manually. final Authentication userAuth = Jenkins.getAuthentication2(); @@ -1494,10 +1500,10 @@ public static XStream2 getXStream() { } static { - XSTREAM.alias("fingerprint",Fingerprint.class); - XSTREAM.alias("range",Range.class); - XSTREAM.alias("ranges",RangeSet.class); - XSTREAM.registerConverter(new HexBinaryConverter(),10); + XSTREAM.alias("fingerprint", Fingerprint.class); + XSTREAM.alias("range", Range.class); + XSTREAM.alias("ranges", RangeSet.class); + XSTREAM.registerConverter(new HexBinaryConverter(), 10); XSTREAM.registerConverter(new RangeSet.ConverterImpl( new CollectionConverter(XSTREAM.getMapper()) { @Override @@ -1505,7 +1511,7 @@ protected Object createCollection(Class type) { return new ArrayList(); } } - ),10); + ), 10); } private static final Logger logger = Logger.getLogger(Fingerprint.class.getName()); diff --git a/core/src/main/java/hudson/model/FingerprintCleanupThread.java b/core/src/main/java/hudson/model/FingerprintCleanupThread.java index fea8bb2ac0c2..6ac6a361e8f7 100644 --- a/core/src/main/java/hudson/model/FingerprintCleanupThread.java +++ b/core/src/main/java/hudson/model/FingerprintCleanupThread.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,10 +21,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import hudson.Extension; import hudson.ExtensionList; +import java.util.logging.Logger; import jenkins.fingerprints.FileFingerprintStorage; import jenkins.fingerprints.FingerprintStorage; import jenkins.fingerprints.GlobalFingerprintConfiguration; @@ -32,8 +34,6 @@ import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; -import java.util.logging.Logger; - /** * Scans the fingerprint database and remove old records * that are no longer relevant. @@ -54,6 +54,7 @@ public FingerprintCleanupThread() { super("Fingerprint cleanup"); } + @Override public long getRecurrencePeriod() { return DAY; } @@ -70,6 +71,7 @@ private static FingerprintCleanupThread getInstance() { * Initiates the cleanup of fingerprints IF enabled. * In case of configured external storage, the file system based storage cleanup is also performed. */ + @Override public void execute(TaskListener listener) { if (GlobalFingerprintConfiguration.get().isFingerprintCleanupDisabled()) { LOGGER.fine("Fingerprint cleanup is disabled. Skipping execution"); @@ -77,9 +79,10 @@ public void execute(TaskListener listener) { } FingerprintStorage.get().iterateAndCleanupFingerprints(listener); + final FileFingerprintStorage fileFingerprintStorage = ExtensionList.lookupSingleton(FileFingerprintStorage.class); if (!(FingerprintStorage.get() instanceof FileFingerprintStorage) && - FingerprintStorage.getFileFingerprintStorage().isReady()) { - FileFingerprintStorage.getFileFingerprintStorage().iterateAndCleanupFingerprints(listener); + fileFingerprintStorage.isReady()) { + fileFingerprintStorage.iterateAndCleanupFingerprints(listener); } } diff --git a/core/src/main/java/hudson/model/FingerprintMap.java b/core/src/main/java/hudson/model/FingerprintMap.java index 038d70a5f0da..b41edbb9f703 100644 --- a/core/src/main/java/hudson/model/FingerprintMap.java +++ b/core/src/main/java/hudson/model/FingerprintMap.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2011, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,17 +21,17 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.Util; import hudson.util.KeyedDataStorage; -import jenkins.fingerprints.FingerprintStorage; -import jenkins.model.Jenkins; - import java.io.IOException; import java.util.Locale; -import edu.umd.cs.findbugs.annotations.CheckForNull; -import edu.umd.cs.findbugs.annotations.NonNull; +import jenkins.fingerprints.FingerprintStorage; +import jenkins.model.Jenkins; /** * Cache of {@link Fingerprint}s. @@ -44,7 +44,7 @@ * @author Kohsuke Kawaguchi * @see Jenkins#getFingerprintMap() */ -public final class FingerprintMap extends KeyedDataStorage { +public final class FingerprintMap extends KeyedDataStorage { /** * Returns true if there's some data in the fingerprint database. @@ -61,31 +61,33 @@ public boolean isReady() { * @throws IOException Loading error */ public @NonNull Fingerprint getOrCreate(@CheckForNull AbstractBuild build, @NonNull String fileName, @NonNull byte[] md5sum) throws IOException { - return getOrCreate(build,fileName, Util.toHexString(md5sum)); + return getOrCreate(build, fileName, Util.toHexString(md5sum)); } public @NonNull Fingerprint getOrCreate(@CheckForNull AbstractBuild build, @NonNull String fileName, @NonNull String md5sum) throws IOException { - return super.getOrCreate(md5sum, new FingerprintParams(build,fileName)); + return super.getOrCreate(md5sum, new FingerprintParams(build, fileName)); } public @NonNull Fingerprint getOrCreate(@CheckForNull Run build, @NonNull String fileName, @NonNull String md5sum) throws IOException { - return super.getOrCreate(md5sum, new FingerprintParams(build,fileName)); + return super.getOrCreate(md5sum, new FingerprintParams(build, fileName)); } @Override protected Fingerprint get(String md5sum, boolean createIfNotExist, FingerprintParams createParams) throws IOException { // sanity check - if(md5sum.length()!=32) + if (md5sum.length() != 32) return null; // illegal input md5sum = md5sum.toLowerCase(Locale.ENGLISH); - return super.get(md5sum,createIfNotExist,createParams); + return super.get(md5sum, createIfNotExist, createParams); } + @Override protected @NonNull Fingerprint create(@NonNull String md5sum, @NonNull FingerprintParams createParams) throws IOException { return new Fingerprint(createParams.build, createParams.fileName, Util.fromHexString(md5sum)); } + @Override protected @CheckForNull Fingerprint load(@NonNull String key) throws IOException { return Fingerprint.load(key); } @@ -101,7 +103,7 @@ static class FingerprintParams { this.build = build; this.fileName = fileName; - assert fileName!=null; + assert fileName != null; } } } diff --git a/core/src/main/java/hudson/model/FreeStyleBuild.java b/core/src/main/java/hudson/model/FreeStyleBuild.java index 4941789ef279..d2871dc8da79 100644 --- a/core/src/main/java/hudson/model/FreeStyleBuild.java +++ b/core/src/main/java/hudson/model/FreeStyleBuild.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,15 +21,16 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; -import java.io.IOException; import java.io.File; +import java.io.IOException; /** * @author Kohsuke Kawaguchi */ -public class FreeStyleBuild extends Build { +public class FreeStyleBuild extends Build { public FreeStyleBuild(FreeStyleProject project) throws IOException { super(project); } diff --git a/core/src/main/java/hudson/model/FreeStyleProject.java b/core/src/main/java/hudson/model/FreeStyleProject.java index e1f1e154b952..814f2cf7e8a7 100644 --- a/core/src/main/java/hudson/model/FreeStyleProject.java +++ b/core/src/main/java/hudson/model/FreeStyleProject.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, id:cactusman - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,23 +21,25 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.Extension; import jenkins.model.Jenkins; +import jenkins.model.item_category.StandaloneProjectsCategory; import org.jenkins.ui.icon.Icon; import org.jenkins.ui.icon.IconSet; import org.jenkinsci.Symbol; -import jenkins.model.item_category.StandaloneProjectsCategory; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; /** * Free-style software project. - * + * * @author Kohsuke Kawaguchi */ -public class FreeStyleProject extends Project implements TopLevelItem { +public class FreeStyleProject extends Project implements TopLevelItem { /** * @deprecated as of 1.390 @@ -56,8 +58,9 @@ protected Class getBuildClass() { return FreeStyleBuild.class; } + @Override public DescriptorImpl getDescriptor() { - return (DescriptorImpl)Jenkins.get().getDescriptorOrDie(getClass()); + return (DescriptorImpl) Jenkins.get().getDescriptorOrDie(getClass()); } /** @@ -69,10 +72,12 @@ public DescriptorImpl getDescriptor() { */ @Deprecated @Restricted(NoExternalUse.class) + @SuppressFBWarnings(value = "MS_PKGPROTECT", justification = "for backward compatibility") public static /*almost final*/ DescriptorImpl DESCRIPTOR; - @Extension(ordinal=1000) @Symbol({"freeStyle","freeStyleJob"}) + @Extension(ordinal = 1000) @Symbol({"freeStyle", "freeStyleJob"}) public static class DescriptorImpl extends AbstractProjectDescriptor { + @SuppressFBWarnings(value = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD", justification = "for backward compatibility") public DescriptorImpl() { DESCRIPTOR = this; } @@ -82,8 +87,9 @@ public String getDisplayName() { return Messages.FreeStyleProject_DisplayName(); } + @Override public FreeStyleProject newInstance(ItemGroup parent, String name) { - return new FreeStyleProject(parent,name); + return new FreeStyleProject(parent, name); } @Override diff --git a/core/src/main/java/hudson/model/FullDuplexHttpChannel.java b/core/src/main/java/hudson/model/FullDuplexHttpChannel.java index 7e44ad932353..64e2428f6a71 100644 --- a/core/src/main/java/hudson/model/FullDuplexHttpChannel.java +++ b/core/src/main/java/hudson/model/FullDuplexHttpChannel.java @@ -21,11 +21,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import hudson.remoting.Channel; import hudson.remoting.PingThread; -import hudson.remoting.Channel.Mode; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -45,7 +45,7 @@ public abstract class FullDuplexHttpChannel extends FullDuplexHttpService { private Channel channel; private final boolean restricted; - public FullDuplexHttpChannel(UUID uuid, boolean restricted) throws IOException { + protected FullDuplexHttpChannel(UUID uuid, boolean restricted) throws IOException { super(uuid); this.restricted = restricted; } @@ -53,7 +53,7 @@ public FullDuplexHttpChannel(UUID uuid, boolean restricted) throws IOException { @Override protected void run(final InputStream upload, OutputStream download) throws IOException, InterruptedException { channel = new Channel("HTTP full-duplex channel " + uuid, - Computer.threadPoolForRemoting, Mode.BINARY, upload, download, null, restricted); + Computer.threadPoolForRemoting, Channel.Mode.BINARY, upload, download, null, restricted); // so that we can detect dead clients, periodically send something PingThread ping = new PingThread(channel) { diff --git a/core/src/main/java/hudson/model/HealthReport.java b/core/src/main/java/hudson/model/HealthReport.java index 461264ed6a3d..e5bb11319aa8 100644 --- a/core/src/main/java/hudson/model/HealthReport.java +++ b/core/src/main/java/hudson/model/HealthReport.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, Stephen Connolly - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,23 +21,23 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import com.thoughtworks.xstream.converters.UnmarshallingContext; import hudson.diagnosis.OldDataMonitor; import hudson.util.XStream2; +import java.io.Serializable; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import jenkins.model.Jenkins; import jenkins.util.NonLocalizable; import org.jvnet.localizer.Localizable; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; -import java.io.*; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - /** * Represents health of something (typically project). * A number between 0-100. @@ -356,6 +356,7 @@ public static HealthReport max(HealthReport a, HealthReport b) { */ public static class ConverterImpl extends XStream2.PassthruConverter { public ConverterImpl(XStream2 xstream) { super(xstream); } + @Override protected void callback(HealthReport hr, UnmarshallingContext context) { // If we are being read back in from an older version if (hr.localizibleDescription == null) { diff --git a/core/src/main/java/hudson/model/HealthReportingAction.java b/core/src/main/java/hudson/model/HealthReportingAction.java index 024c9488725f..b26277cc5143 100644 --- a/core/src/main/java/hudson/model/HealthReportingAction.java +++ b/core/src/main/java/hudson/model/HealthReportingAction.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Stephen Connolly - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; /** @@ -42,7 +43,7 @@ public interface HealthReportingAction extends Action { * Get this {@link Action}'s {@link HealthReport}. * * @return - * The health report for this instance of the Action or + * The health report for this instance of the Action or * {@code null} if the Action does not want to * contribute a HealthReport. */ diff --git a/core/src/main/java/hudson/model/Hudson.java b/core/src/main/java/hudson/model/Hudson.java index 635b8095890b..784fa47da20e 100644 --- a/core/src/main/java/hudson/model/Hudson.java +++ b/core/src/main/java/hudson/model/Hudson.java @@ -23,8 +23,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import static hudson.Util.fixEmpty; + +import edu.umd.cs.findbugs.annotations.Nullable; import hudson.ExtensionListView; import hudson.Functions; import hudson.Platform; @@ -34,6 +38,14 @@ import hudson.slaves.ComputerListener; import hudson.util.CopyOnWriteList; import hudson.util.FormValidation; +import java.io.File; +import java.io.IOException; +import java.text.NumberFormat; +import java.text.ParseException; +import java.util.List; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletResponse; import jenkins.model.Jenkins; import org.jvnet.hudson.reactor.ReactorException; import org.kohsuke.stapler.QueryParameter; @@ -42,17 +54,6 @@ import org.kohsuke.stapler.StaplerResponse; import org.kohsuke.stapler.interceptor.RequirePOST; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import java.io.File; -import java.io.IOException; -import java.text.NumberFormat; -import java.text.ParseException; -import java.util.List; - -import static hudson.Util.fixEmpty; -import edu.umd.cs.findbugs.annotations.Nullable; - public class Hudson extends Jenkins { /** @@ -74,11 +75,11 @@ public class Hudson extends Jenkins { @CLIResolver @Nullable public static Hudson getInstance() { - return (Hudson)Jenkins.get(); + return (Hudson) Jenkins.get(); } public Hudson(File root, ServletContext context) throws IOException, InterruptedException, ReactorException { - this(root,context,null); + this(root, context, null); } public Hudson(File root, ServletContext context, PluginManager pluginManager) throws IOException, InterruptedException, ReactorException { @@ -117,7 +118,7 @@ public CopyOnWriteList getComputerListeners() { public Slave getSlave(String name) { Node n = getNode(name); if (n instanceof Slave) - return (Slave)n; + return (Slave) n; return null; } @@ -127,7 +128,7 @@ public Slave getSlave(String name) { */ @Deprecated public List getSlaves() { - return (List)getNodes(); + return (List) getNodes(); } /** @@ -158,8 +159,8 @@ public TopLevelItem getJob(String name) { @Deprecated public TopLevelItem getJobCaseInsensitive(String name) { String match = Functions.toEmailSafeString(name); - for(TopLevelItem item : getItems()) { - if(Functions.toEmailSafeString(item.getName()).equalsIgnoreCase(match)) { + for (TopLevelItem item : getItems()) { + if (Functions.toEmailSafeString(item.getName()).equalsIgnoreCase(match)) { return item; } } @@ -183,9 +184,9 @@ public synchronized void doQuietDown(StaplerResponse rsp) throws IOException, Se * As on 1.267, moved to "/log/rss..." */ @Deprecated - public void doLogRss( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException { + public void doLogRss(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { String qs = req.getQueryString(); - rsp.sendRedirect2("./log/rss"+(qs==null?"":'?'+qs)); + rsp.sendRedirect2("./log/rss" + (qs == null ? "" : '?' + qs)); } /** @@ -198,7 +199,7 @@ public void doFieldCheck(StaplerRequest req, StaplerResponse rsp) throws IOExcep fixEmpty(req.getParameter("value")), fixEmpty(req.getParameter("type")), fixEmpty(req.getParameter("errorText")), - fixEmpty(req.getParameter("warningText"))).generateResponse(req,rsp,this); + fixEmpty(req.getParameter("warningText"))).generateResponse(req, rsp, this); } /** @@ -215,10 +216,10 @@ public void doFieldCheck(StaplerRequest req, StaplerResponse rsp) throws IOExcep * or define your own check method, instead of relying on this generic one. */ @Deprecated - public FormValidation doFieldCheck(@QueryParameter(fixEmpty=true) String value, - @QueryParameter(fixEmpty=true) String type, - @QueryParameter(fixEmpty=true) String errorText, - @QueryParameter(fixEmpty=true) String warningText) { + public FormValidation doFieldCheck(@QueryParameter(fixEmpty = true) String value, + @QueryParameter(fixEmpty = true) String type, + @QueryParameter(fixEmpty = true) String errorText, + @QueryParameter(fixEmpty = true) String warningText) { if (value == null) { if (errorText != null) return FormValidation.error(errorText); @@ -252,7 +253,7 @@ public FormValidation doFieldCheck(@QueryParameter(fixEmpty=true) String value, */ @Deprecated public static boolean isWindows() { - return File.pathSeparatorChar==';'; + return File.pathSeparatorChar == ';'; } /** @@ -278,10 +279,10 @@ public static boolean adminCheck() throws IOException { * Use {@link #checkPermission(hudson.security.Permission)} */ @Deprecated - public static boolean adminCheck(StaplerRequest req,StaplerResponse rsp) throws IOException { + public static boolean adminCheck(StaplerRequest req, StaplerResponse rsp) throws IOException { if (isAdmin(req)) return true; - rsp.sendError(StaplerResponse.SC_FORBIDDEN); + rsp.sendError(HttpServletResponse.SC_FORBIDDEN); return false; } @@ -305,7 +306,7 @@ public static boolean adminCheck(StaplerRequest req,StaplerResponse rsp) throws */ @Deprecated public static boolean isAdmin() { - return Jenkins.get().getACL().hasPermission(ADMINISTER); + return Jenkins.get().hasPermission(ADMINISTER); } /** @@ -319,7 +320,7 @@ public static boolean isAdmin(StaplerRequest req) { } static { - XSTREAM.alias("hudson",Hudson.class); + XSTREAM.alias("hudson", Hudson.class); } /** @@ -340,7 +341,6 @@ public CloudList(Jenkins h) { } public CloudList() {// needed for XStream deserialization - super(); } } } diff --git a/core/src/main/java/hudson/model/InvisibleAction.java b/core/src/main/java/hudson/model/InvisibleAction.java index bd0ef82b522b..2f5ce0242632 100644 --- a/core/src/main/java/hudson/model/InvisibleAction.java +++ b/core/src/main/java/hudson/model/InvisibleAction.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; /** @@ -31,21 +32,24 @@ * {@link Action} for just storing data associated with a build. * *

    - * It could also be used to reduce the amount of code required to just create an accessible url for tests + * It could also be used to reduce the amount of code required to just create an accessible url for tests * by overriding the {@link #getUrlName()} method. * * @author Kohsuke Kawaguchi * @since 1.188 */ public abstract class InvisibleAction implements Action { + @Override public final String getIconFileName() { return null; } + @Override public final String getDisplayName() { return null; } + @Override public String getUrlName() { return null; } diff --git a/core/src/main/java/hudson/model/Item.java b/core/src/main/java/hudson/model/Item.java index 57a59f95c1a7..a57011579b15 100644 --- a/core/src/main/java/hudson/model/Item.java +++ b/core/src/main/java/hudson/model/Item.java @@ -1,19 +1,19 @@ /* * The MIT License - * + * * Copyright (c) 2004-2011, Sun Microsystems, Inc., Kohsuke Kawaguchi, Yahoo! Inc., * Manufacture Francaise des Pneumatiques Michelin, Romain Seguy - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -22,28 +22,26 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.Nullable; import hudson.Functions; import hudson.Util; -import jenkins.model.Jenkins; -import jenkins.util.SystemProperties; -import hudson.security.PermissionScope; -import jenkins.util.io.OnMaster; -import jline.internal.Nullable; -import org.kohsuke.stapler.StaplerRequest; - -import java.io.IOException; -import java.util.Collection; - import hudson.search.SearchableModelObject; +import hudson.security.AccessControlled; import hudson.security.Permission; import hudson.security.PermissionGroup; -import hudson.security.AccessControlled; +import hudson.security.PermissionScope; import hudson.util.Secret; - -import edu.umd.cs.findbugs.annotations.CheckForNull; -import edu.umd.cs.findbugs.annotations.NonNull; +import java.io.IOException; +import java.util.Collection; +import jenkins.model.Jenkins; +import jenkins.util.SystemProperties; +import jenkins.util.io.OnMaster; +import org.kohsuke.stapler.StaplerRequest; /** * Basic configuration unit in Hudson. @@ -96,7 +94,7 @@ public interface Item extends PersistenceRoot, SearchableModelObject, AccessCont * This name is also used for directory name, so it cannot contain * any character that's not allowed on the file system. * - * @see #getFullName() + * @see #getFullName() */ String getName(); @@ -125,6 +123,7 @@ public interface Item extends PersistenceRoot, SearchableModelObject, AccessCont * The returned string should not include the display names * of {@link #getParent() ancestor items}. */ + @Override String getDisplayName(); /** @@ -201,9 +200,9 @@ default String getRelativeNameFrom(@NonNull Item item) { @Deprecated default String getAbsoluteUrl() { String r = Jenkins.get().getRootUrl(); - if(r==null) + if (r == null) throw new IllegalStateException("Root URL isn't configured yet. Cannot compute absolute URL."); - return Util.encode(r+getUrl()); + return Util.encode(r + getUrl()); } /** @@ -242,6 +241,7 @@ default void onCreatedFromScratch() { * or {@link AbstractItem#getConfigFile()} to obtain the file * to save the data. */ + @Override void save() throws IOException; /** @@ -249,21 +249,83 @@ default void onCreatedFromScratch() { */ void delete() throws IOException, InterruptedException; - PermissionGroup PERMISSIONS = new PermissionGroup(Item.class,Messages._Item_Permissions_Title()); - Permission CREATE = new Permission(PERMISSIONS, "Create", Messages._Item_CREATE_description(), Permission.CREATE, PermissionScope.ITEM_GROUP); - Permission DELETE = new Permission(PERMISSIONS, "Delete", Messages._Item_DELETE_description(), Permission.DELETE, PermissionScope.ITEM); - Permission CONFIGURE = new Permission(PERMISSIONS, "Configure", Messages._Item_CONFIGURE_description(), Permission.CONFIGURE, PermissionScope.ITEM); - Permission READ = new Permission(PERMISSIONS, "Read", Messages._Item_READ_description(), Permission.READ, PermissionScope.ITEM); - Permission DISCOVER = new Permission(PERMISSIONS, "Discover", Messages._AbstractProject_DiscoverPermission_Description(), READ, PermissionScope.ITEM); + PermissionGroup PERMISSIONS = new PermissionGroup(Item.class, Messages._Item_Permissions_Title()); + Permission CREATE = + new Permission( + PERMISSIONS, + "Create", + Messages._Item_CREATE_description(), + Permission.CREATE, + PermissionScope.ITEM_GROUP); + Permission DELETE = + new Permission( + PERMISSIONS, + "Delete", + Messages._Item_DELETE_description(), + Permission.DELETE, + PermissionScope.ITEM); + Permission CONFIGURE = + new Permission( + PERMISSIONS, + "Configure", + Messages._Item_CONFIGURE_description(), + Permission.CONFIGURE, + PermissionScope.ITEM); + Permission READ = + new Permission( + PERMISSIONS, + "Read", + Messages._Item_READ_description(), + Permission.READ, + PermissionScope.ITEM); + Permission DISCOVER = + new Permission( + PERMISSIONS, + "Discover", + Messages._AbstractProject_DiscoverPermission_Description(), + READ, + PermissionScope.ITEM); /** * Ability to view configuration details. * If the user lacks {@link #CONFIGURE} then any {@link Secret}s must be masked out, even in encrypted form. * @see Secret#ENCRYPTED_VALUE_PATTERN */ - Permission EXTENDED_READ = new Permission(PERMISSIONS,"ExtendedRead", Messages._AbstractProject_ExtendedReadPermission_Description(), CONFIGURE, SystemProperties.getBoolean("hudson.security.ExtendedReadPermission"), new PermissionScope[]{PermissionScope.ITEM}); + Permission EXTENDED_READ = + new Permission( + PERMISSIONS, + "ExtendedRead", + Messages._AbstractProject_ExtendedReadPermission_Description(), + CONFIGURE, + SystemProperties.getBoolean("hudson.security.ExtendedReadPermission"), + new PermissionScope[] {PermissionScope.ITEM}); // TODO the following really belong in Job, not Item, but too late to move since the owner.name is encoded in the ID: - Permission BUILD = new Permission(PERMISSIONS, "Build", Messages._AbstractProject_BuildPermission_Description(), Permission.UPDATE, PermissionScope.ITEM); - Permission WORKSPACE = new Permission(PERMISSIONS, "Workspace", Messages._AbstractProject_WorkspacePermission_Description(), Permission.READ, PermissionScope.ITEM); - Permission WIPEOUT = new Permission(PERMISSIONS, "WipeOut", Messages._AbstractProject_WipeOutPermission_Description(), null, Functions.isWipeOutPermissionEnabled(), new PermissionScope[]{PermissionScope.ITEM}); - Permission CANCEL = new Permission(PERMISSIONS, "Cancel", Messages._AbstractProject_CancelPermission_Description(), Permission.UPDATE, PermissionScope.ITEM); + Permission BUILD = + new Permission( + PERMISSIONS, + "Build", + Messages._AbstractProject_BuildPermission_Description(), + Permission.UPDATE, + PermissionScope.ITEM); + Permission WORKSPACE = + new Permission( + PERMISSIONS, + "Workspace", + Messages._AbstractProject_WorkspacePermission_Description(), + Permission.READ, + PermissionScope.ITEM); + Permission WIPEOUT = + new Permission( + PERMISSIONS, + "WipeOut", + Messages._AbstractProject_WipeOutPermission_Description(), + null, + Functions.isWipeOutPermissionEnabled(), + new PermissionScope[] {PermissionScope.ITEM}); + Permission CANCEL = + new Permission( + PERMISSIONS, + "Cancel", + Messages._AbstractProject_CancelPermission_Description(), + Permission.UPDATE, + PermissionScope.ITEM); } diff --git a/core/src/main/java/hudson/model/ItemGroup.java b/core/src/main/java/hudson/model/ItemGroup.java index b55609f910dc..6404e82626e1 100644 --- a/core/src/main/java/hudson/model/ItemGroup.java +++ b/core/src/main/java/hudson/model/ItemGroup.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,17 +21,18 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import edu.umd.cs.findbugs.annotations.CheckForNull; import hudson.model.listeners.ItemListener; +import java.io.File; import java.io.IOException; import java.util.Collection; -import java.io.File; import java.util.List; import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; -import edu.umd.cs.findbugs.annotations.CheckForNull; import org.springframework.security.access.AccessDeniedException; /** @@ -44,12 +45,12 @@ public interface ItemGroup extends PersistenceRoot, ModelObject /** * Gets the full name of this {@link ItemGroup}. * - * @see Item#getFullName() + * @see Item#getFullName() */ String getFullName(); /** - * @see Item#getFullDisplayName() + * @see Item#getFullDisplayName() */ String getFullDisplayName(); @@ -99,8 +100,9 @@ default Stream getItemsStream(Predicate pred) { /** * Gets the {@link Item} inside this group that has a given name, or null if it does not exist. + * @return an item whose {@link Item#getName} is {@code name} and whose {@link Item#getParent} is {@code this}, + * or null if there is no such item, or there is but the current user lacks both {@link Item#DISCOVER} and {@link Item#READ} on it * @throws AccessDeniedException if the current user has {@link Item#DISCOVER} but not {@link Item#READ} on this item - * @return an item whose {@link Item#getName} is {@code name} and whose {@link Item#getParent} is {@code this}, or null if there is no such item, or there is but the current user lacks both {@link Item#DISCOVER} and {@link Item#READ} on it */ @CheckForNull T getItem(String name) throws AccessDeniedException; diff --git a/core/src/main/java/hudson/model/ItemGroupMixIn.java b/core/src/main/java/hudson/model/ItemGroupMixIn.java index f34f89eb4df6..748a13cc6ec4 100644 --- a/core/src/main/java/hudson/model/ItemGroupMixIn.java +++ b/core/src/main/java/hudson/model/ItemGroupMixIn.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, CloudBees, Inc. - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import hudson.Util; @@ -30,27 +31,26 @@ import hudson.util.CopyOnWriteMap; import hudson.util.Function1; import hudson.util.Secret; -import jenkins.model.Jenkins; -import jenkins.util.xml.XMLUtils; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletResponse; -import javax.xml.transform.TransformerException; -import javax.xml.transform.stream.StreamResult; -import javax.xml.transform.stream.StreamSource; import java.io.File; -import java.io.FileFilter; import java.io.IOException; import java.io.InputStream; +import java.io.UncheckedIOException; import java.nio.file.Files; import java.nio.file.StandardCopyOption; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Matcher; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletResponse; +import javax.xml.transform.TransformerException; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; +import jenkins.model.Jenkins; import jenkins.security.NotReallyRoleSensitiveCallable; +import jenkins.util.xml.XMLUtils; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; import org.springframework.security.access.AccessDeniedException; import org.xml.sax.SAXException; @@ -98,15 +98,15 @@ protected ItemGroupMixIn(ItemGroup parent, AccessControlled acl) { * @param modulesDir * Directory that contains sub-directories for each child item. */ - public static Map loadChildren(ItemGroup parent, File modulesDir, Function1 key) { - modulesDir.mkdirs(); // make sure it exists + public static Map loadChildren(ItemGroup parent, File modulesDir, Function1 key) { + try { + Util.createDirectories(modulesDir.toPath()); + } catch (IOException e) { + throw new UncheckedIOException(e); + } - File[] subdirs = modulesDir.listFiles(new FileFilter() { - public boolean accept(File child) { - return child.isDirectory(); - } - }); - CopyOnWriteMap.Tree configurations = new CopyOnWriteMap.Tree<>(); + File[] subdirs = modulesDir.listFiles(File::isDirectory); + CopyOnWriteMap.Tree configurations = new CopyOnWriteMap.Tree<>(); for (File subdir : subdirs) { try { // Try to retain the identity of an existing child object if we can. @@ -134,17 +134,13 @@ public boolean accept(File child) { /** * {@link Item} → name function. */ - public static final Function1 KEYED_BY_NAME = new Function1() { - public String call(Item item) { - return item.getName(); - } - }; + public static final Function1 KEYED_BY_NAME = Item::getName; /** * Creates a {@link TopLevelItem} for example from the submission of the {@code /lib/hudson/newFromList/form} tag * or throws an exception if it fails. */ - public synchronized TopLevelItem createTopLevelItem( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException { + public synchronized TopLevelItem createTopLevelItem(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { acl.checkPermission(Item.CREATE); TopLevelItem result; @@ -160,38 +156,38 @@ public synchronized TopLevelItem createTopLevelItem( StaplerRequest req, Stapler || requestContentType.startsWith("text/xml")); String name = req.getParameter("name"); - if(name==null) + if (name == null) throw new Failure("Query parameter 'name' is required"); - {// check if the name looks good + { // check if the name looks good Jenkins.checkGoodName(name); name = name.trim(); - if(parent.getItem(name)!=null) + if (parent.getItem(name) != null) throw new Failure(Messages.Hudson_JobAlreadyExists(name)); } - if(mode!=null && mode.equals("copy")) { + if (mode != null && mode.equals("copy")) { String from = req.getParameter("from"); // resolve a name to Item Item src = Jenkins.get().getItem(from, parent); - if(src==null) { - if(Util.fixEmpty(from)==null) + if (src == null) { + if (Util.fixEmpty(from) == null) throw new Failure("Specify which job to copy"); else - throw new Failure("No such job: "+from); + throw new Failure("No such job: " + from); } if (!(src instanceof TopLevelItem)) - throw new Failure(from+" cannot be copied"); + throw new Failure(from + " cannot be copied"); - result = copy((TopLevelItem) src,name); + result = copy((TopLevelItem) src, name); } else { - if(isXmlSubmission) { + if (isXmlSubmission) { result = createProjectFromXML(name, req.getInputStream()); rsp.setStatus(HttpServletResponse.SC_OK); return result; } else { - if(mode==null) + if (mode == null) throw new Failure("No mode given"); TopLevelItemDescriptor descriptor = Items.all().findByName(mode); if (descriptor == null) { @@ -213,13 +209,13 @@ public synchronized TopLevelItem createTopLevelItem( StaplerRequest req, Stapler * Computes the redirection target URL for the newly created {@link TopLevelItem}. */ protected String redirectAfterCreateItem(StaplerRequest req, TopLevelItem result) throws IOException { - return req.getContextPath()+'/'+result.getUrl()+"configure"; + return req.getContextPath() + '/' + result.getUrl() + "configure"; } /** * Copies an existing {@link TopLevelItem} to a new name. */ - @SuppressWarnings({"unchecked"}) + @SuppressWarnings("unchecked") public synchronized T copy(T src, String name) throws IOException { acl.checkPermission(Item.CREATE); src.checkPermission(Item.EXTENDED_READ); @@ -229,7 +225,13 @@ public synchronized T copy(T src, String name) throws I while (matcher.find()) { if (Secret.decrypt(matcher.group(1)) != null) { // AccessDeniedException2 does not permit a custom message, and anyway redirecting the user to the login screen is obviously pointless. - throw new AccessDeniedException(Messages.ItemGroupMixIn_may_not_copy_as_it_contains_secrets_and_(src.getFullName(), Jenkins.getAuthentication2().getName(), Item.PERMISSIONS.title, Item.EXTENDED_READ.name, Item.CONFIGURE.name)); + throw new AccessDeniedException( + Messages.ItemGroupMixIn_may_not_copy_as_it_contains_secrets_and_( + src.getFullName(), + Jenkins.getAuthentication2().getName(), + Item.PERMISSIONS.title, + Item.EXTENDED_READ.name, + Item.CONFIGURE.name)); } } } @@ -238,7 +240,7 @@ public synchronized T copy(T src, String name) throws I Jenkins.checkGoodName(name); ItemListener.checkBeforeCopy(src, parent); - T result = (T)createProject(src.getDescriptor(),name,false); + T result = (T) createProject(src.getDescriptor(), name, false); // copy config Files.copy(Util.fileToPath(srcConfigFile.getFile()), Util.fileToPath(Items.getConfigFile(result).getFile()), @@ -246,7 +248,7 @@ public synchronized T copy(T src, String name) throws I // reload from the new config final File rootDir = result.getRootDir(); - result = Items.whileUpdatingByXml(new NotReallyRoleSensitiveCallable() { + result = Items.whileUpdatingByXml(new NotReallyRoleSensitiveCallable() { @Override public T call() throws IOException { return (T) Items.load(parent, rootDir); } @@ -254,7 +256,7 @@ public synchronized T copy(T src, String name) throws I result.onCopiedFrom(src); add(result); - ItemListener.fireOnCopied(src,result); + ItemListener.fireOnCopied(src, result); Jenkins.get().rebuildDependencyGraphAsync(); return result; @@ -270,13 +272,13 @@ public synchronized TopLevelItem createProjectFromXML(String name, InputStream x // place it as config.xml File configXml = Items.getConfigFile(getRootDirFor(name)).getFile(); final File dir = configXml.getParentFile(); - dir.mkdirs(); boolean success = false; try { + Util.createDirectories(dir.toPath()); XMLUtils.safeTransform(new StreamSource(xml), new StreamResult(configXml)); // load it - TopLevelItem result = Items.whileUpdatingByXml(new NotReallyRoleSensitiveCallable() { + TopLevelItem result = Items.whileUpdatingByXml(new NotReallyRoleSensitiveCallable() { @Override public TopLevelItem call() throws IOException { return (TopLevelItem) Items.load(parent, dir); } @@ -305,7 +307,7 @@ public synchronized TopLevelItem createProjectFromXML(String name, InputStream x } } - public synchronized TopLevelItem createProject( TopLevelItemDescriptor type, String name, boolean notify ) + public synchronized TopLevelItem createProject(TopLevelItemDescriptor type, String name, boolean notify) throws IOException { acl.checkPermission(Item.CREATE); type.checkApplicableIn(parent); diff --git a/core/src/main/java/hudson/model/ItemVisitor.java b/core/src/main/java/hudson/model/ItemVisitor.java index e33a6849b0ed..98e26c8023aa 100644 --- a/core/src/main/java/hudson/model/ItemVisitor.java +++ b/core/src/main/java/hudson/model/ItemVisitor.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import jenkins.model.Jenkins; @@ -46,8 +47,8 @@ public void onItemGroup(ItemGroup group) { * visits the children. */ public void onItem(Item i) { - if(i instanceof ItemGroup) - onItemGroup((ItemGroup)i); + if (i instanceof ItemGroup) + onItemGroup((ItemGroup) i); } /** diff --git a/core/src/main/java/hudson/model/Items.java b/core/src/main/java/hudson/model/Items.java index d80ad97e6a9f..7bda39bc8032 100644 --- a/core/src/main/java/hudson/model/Items.java +++ b/core/src/main/java/hudson/model/Items.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,9 +21,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import com.thoughtworks.xstream.XStream; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.DescriptorExtensionList; import hudson.Extension; import hudson.XmlFile; @@ -35,7 +38,6 @@ import hudson.triggers.Trigger; import hudson.util.DescriptorList; import hudson.util.EditDistance; -import jenkins.util.MemoryReductionUtil; import hudson.util.XStream2; import java.io.File; import java.io.IOException; @@ -48,17 +50,15 @@ import java.util.Stack; import java.util.StringTokenizer; import java.util.function.Predicate; -import edu.umd.cs.findbugs.annotations.CheckForNull; -import edu.umd.cs.findbugs.annotations.NonNull; import jenkins.model.DirectlyModifiableTopLevelItemGroup; import jenkins.model.Jenkins; +import jenkins.util.MemoryReductionUtil; import org.apache.commons.io.FileUtils; -import org.apache.commons.lang.StringUtils; import org.springframework.security.core.Authentication; /** * Convenience methods related to {@link Item}. - * + * * @author Kohsuke Kawaguchi */ public class Items { @@ -126,7 +126,7 @@ String name(Item i) { * @throws T anything {@code callable} throws * @since 1.546 */ - public static V whileUpdatingByXml(Callable callable) throws T { + public static V whileUpdatingByXml(Callable callable) throws T { updatingByXml.set(true); try { return callable.call(); @@ -148,7 +148,7 @@ public static boolean currentlyUpdatingByXml() { /** * Returns all the registered {@link TopLevelItemDescriptor}s. */ - public static DescriptorExtensionList all() { + public static DescriptorExtensionList all() { return Jenkins.get().getDescriptorList(TopLevelItem.class); } @@ -177,7 +177,7 @@ public static List all2(Authentication a, ItemGroup c) { // fall back to root acl = Jenkins.get().getACL(); } - for (TopLevelItemDescriptor d: all()) { + for (TopLevelItemDescriptor d : all()) { if (acl.hasCreatePermission2(a, c, d) && d.isApplicableIn(c)) { result.add(d); } @@ -208,7 +208,7 @@ public static TopLevelItemDescriptor getDescriptor(String fqcn) { public static String toNameList(Collection items) { StringBuilder buf = new StringBuilder(); for (Item item : items) { - if(buf.length()>0) + if (buf.length() > 0) buf.append(", "); buf.append(item.getFullName()); } @@ -221,7 +221,7 @@ public static String toNameList(Collection items) { */ @Deprecated public static List fromNameList(String list, Class type) { - return fromNameList(null,list,type); + return fromNameList(null, list, type); } /** @@ -229,15 +229,15 @@ public static List fromNameList(String list, Class type) */ public static List fromNameList(ItemGroup context, @NonNull String list, @NonNull Class type) { final Jenkins jenkins = Jenkins.get(); - + List r = new ArrayList<>(); - StringTokenizer tokens = new StringTokenizer(list,","); - while(tokens.hasMoreTokens()) { + StringTokenizer tokens = new StringTokenizer(list, ","); + while (tokens.hasMoreTokens()) { String fullName = tokens.nextToken().trim(); - if (StringUtils.isNotEmpty(fullName)) { + if (fullName != null && !fullName.isEmpty()) { T item = jenkins.getItem(fullName, context, type); - if(item!=null) + if (item != null) r.add(item); } } @@ -254,12 +254,12 @@ public static String getCanonicalName(ItemGroup context, String path) { String[] p = path.split("/"); Stack name = new Stack<>(); - for (int i=0; i newValue = new ArrayList<>(); - while(tokens.hasMoreTokens()) { + while (tokens.hasMoreTokens()) { String relativeName = tokens.nextToken().trim(); String canonicalName = getCanonicalName(context, relativeName); - if (canonicalName.equals(oldFullName) || canonicalName.startsWith(oldFullName+'/')) { + if (canonicalName.equals(oldFullName) || canonicalName.startsWith(oldFullName + '/')) { String newCanonicalName = newFullName + canonicalName.substring(oldFullName.length()); if (relativeName.startsWith("/")) { newValue.add("/" + newCanonicalName); @@ -312,7 +312,7 @@ public static String computeRelativeNamesAfterRenaming(String oldFullName, Strin newValue.add(relativeName); } } - return StringUtils.join(newValue, ","); + return String.join(",", newValue); } // Had difficulty adapting the version in Functions to use no live items, so rewrote it: @@ -372,8 +372,8 @@ static String getRelativeNameFrom(String itemFullName, String groupFullName) { * The directory that contains the config file, not the config file itself. */ public static Item load(ItemGroup parent, File dir) throws IOException { - Item item = (Item)getConfigFile(dir).read(); - item.onLoad(parent,dir.getName()); + Item item = (Item) getConfigFile(dir).read(); + item.onLoad(parent, dir.getName()); return item; } @@ -381,7 +381,7 @@ public static Item load(ItemGroup parent, File dir) throws IOException { * The file we save our configuration. */ public static XmlFile getConfigFile(File dir) { - return new XmlFile(XSTREAM,new File(dir,"config.xml")); + return new XmlFile(XSTREAM, new File(dir, "config.xml")); } /** @@ -390,7 +390,7 @@ public static XmlFile getConfigFile(File dir) { public static XmlFile getConfigFile(Item item) { return getConfigFile(item.getRootDir()); } - + /** * Gets all the {@link Item}s recursively in the {@link ItemGroup} tree * and filter them by the given type. The returned list will represent a snapshot view of the items present at some @@ -403,11 +403,11 @@ public static XmlFile getConfigFile(Item item) { * @param root Root node to start searching from * @param type Given type of of items being searched for * @return List of items matching given criteria - * + * * @since 1.512 */ public static List getAllItems(final ItemGroup root, Class type) { - return getAllItems(root ,type, t -> true); + return getAllItems(root, type, t -> true); } /** @@ -425,6 +425,7 @@ public static List getAllItems(final ItemGroup root, Class void getAllItems(final ItemGroup root, Class type, List r, Predicate pred) { List items = new ArrayList<>(((ItemGroup) root).getItems(t -> t instanceof ItemGroup || (type.isInstance(t) && pred.test(type.cast(t))))); // because we add items depth first, we can use the quicker BY_NAME comparison @@ -542,7 +543,7 @@ public static Iterable allItems(org.acegisecurity.Authentica */ public static @CheckForNull T findNearest(Class type, String name, ItemGroup context) { List names = new ArrayList<>(); - for (T item: Jenkins.get().allItems(type)) { + for (T item : Jenkins.get().allItems(type)) { names.add(item.getRelativeNameFrom(context)); } String nearest = EditDistance.findNearest(name, names); @@ -727,9 +728,9 @@ static void verifyItemDoesNotAlreadyExist(@NonNull ItemGroup parent, @NonNull /** * Alias to {@link #XSTREAM} so that one can access additional methods on {@link XStream2} more easily. */ - public static final XStream2 XSTREAM2 = (XStream2)XSTREAM; + public static final XStream2 XSTREAM2 = (XStream2) XSTREAM; static { - XSTREAM.alias("project",FreeStyleProject.class); + XSTREAM.alias("project", FreeStyleProject.class); } } diff --git a/core/src/main/java/hudson/model/JDK.java b/core/src/main/java/hudson/model/JDK.java index eeaf1e66a9d8..0c9bcbda493d 100644 --- a/core/src/main/java/hudson/model/JDK.java +++ b/core/src/main/java/hudson/model/JDK.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,36 +21,35 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; -import hudson.util.StreamTaskListener; -import hudson.util.NullStream; -import hudson.util.FormValidation; -import hudson.Launcher; -import hudson.Extension; import hudson.EnvVars; +import hudson.Extension; +import hudson.Launcher; import hudson.slaves.NodeSpecific; -import hudson.tools.ToolInstallation; import hudson.tools.ToolDescriptor; +import hudson.tools.ToolInstallation; import hudson.tools.ToolInstaller; import hudson.tools.ToolProperty; +import hudson.util.FormValidation; +import hudson.util.NullStream; +import hudson.util.StreamTaskListener; import hudson.util.XStream2; - import java.io.File; import java.io.IOException; import java.lang.reflect.Constructor; -import java.util.Map; -import java.util.List; import java.util.Arrays; import java.util.Collections; +import java.util.List; +import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; - import jenkins.model.Jenkins; import org.jenkinsci.Symbol; -import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.stapler.DataBoundConstructor; /** * Information about JDK installation. @@ -105,14 +104,15 @@ public String getJavaHome() { * Gets the path to the bin directory. */ public File getBinDir() { - return new File(getHome(),"bin"); + return new File(getHome(), "bin"); } /** * Gets the path to 'java'. */ + private File getExecutable() { - String execName = (File.separatorChar == '\\') ? "java.exe" : "java"; - return new File(getHome(),"bin/"+execName); + String execName = File.separatorChar == '\\' ? "java.exe" : "java"; + return new File(getHome(), "bin/" + execName); } /** @@ -126,13 +126,13 @@ public boolean getExists() { * @deprecated as of 1.460. Use {@link #buildEnvVars(EnvVars)} */ @Deprecated - public void buildEnvVars(Map env) { + public void buildEnvVars(Map env) { String home = getHome(); if (home == null) { return; } // see EnvVars javadoc for why this adds PATH. - env.put("PATH+JDK",home+"/bin"); + env.put("PATH+JDK", home + "/bin"); env.put("JAVA_HOME", home); } @@ -141,13 +141,15 @@ public void buildEnvVars(Map env) { */ @Override public void buildEnvVars(EnvVars env) { - buildEnvVars((Map)env); + buildEnvVars((Map) env); } + @Override public JDK forNode(Node node, TaskListener log) throws IOException, InterruptedException { return new JDK(getName(), translateFor(node, log)); } + @Override public JDK forEnvironment(EnvVars environment) { return new JDK(getName(), environment.expand(getHome())); } @@ -163,7 +165,7 @@ public static boolean isDefaultJDKValid(Node n) { try { TaskListener listener = new StreamTaskListener(new NullStream()); Launcher launcher = n.createLauncher(listener); - return launcher.launch().cmds("java","-fullversion").stdout(listener).join()==0; + return launcher.launch().cmds("java", "-fullversion").stdout(listener).join() == 0; } catch (IOException | InterruptedException e) { return false; } @@ -174,7 +176,7 @@ public static class DescriptorImpl extends ToolDescriptor { @Override public String getDisplayName() { - return "JDK"; // TODO I18N + return Messages.JDK_DisplayName(); } @Override @@ -206,13 +208,13 @@ public List getDefaultInstallers() { * Checks if the JAVA_HOME is a valid JAVA_HOME path. */ @Override protected FormValidation checkHomeDirectory(File value) { - File toolsJar = new File(value,"lib/tools.jar"); - File mac = new File(value,"lib/dt.jar"); + File toolsJar = new File(value, "lib/tools.jar"); + File mac = new File(value, "lib/dt.jar"); // JENKINS-25601: JDK 9+ no longer has tools.jar. Keep the existing dt.jar/tools.jar checks to be safe. File javac = new File(value, "bin/javac"); File javacExe = new File(value, "bin/javac.exe"); - if(!toolsJar.exists() && !mac.exists() && !javac.exists() && !javacExe.exists()) + if (!toolsJar.exists() && !mac.exists() && !javac.exists() && !javacExe.exists()) return FormValidation.error(Messages.Hudson_NotJDKDir(value)); return FormValidation.ok(); @@ -222,8 +224,9 @@ public List getDefaultInstallers() { public static class ConverterImpl extends ToolConverter { public ConverterImpl(XStream2 xstream) { super(xstream); } + @Override protected String oldHomeField(ToolInstallation obj) { - return ((JDK)obj).javaHome; + return ((JDK) obj).javaHome; } } diff --git a/core/src/main/java/hudson/model/Job.java b/core/src/main/java/hudson/model/Job.java index dc3d4edd8a8e..9b492f4f6cfa 100644 --- a/core/src/main/java/hudson/model/Job.java +++ b/core/src/main/java/hudson/model/Job.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Martin Eigenbrodt, Matthew R. Harrah, Red Hat, Inc., Stephen Connolly, Tom Huybrechts, CloudBees, Inc. - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,9 +21,16 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST; +import static javax.servlet.http.HttpServletResponse.SC_NO_CONTENT; + import com.infradna.tool.bridge_method_injector.WithBridgeMethods; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.BulkChange; import hudson.EnvVars; import hudson.Extension; @@ -66,19 +73,17 @@ import java.awt.Paint; import java.io.File; import java.io.IOException; +import java.nio.file.Files; import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; import java.util.Collections; import java.util.GregorianCalendar; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.SortedMap; import java.util.logging.Level; import java.util.logging.Logger; -import edu.umd.cs.findbugs.annotations.CheckForNull; -import edu.umd.cs.findbugs.annotations.NonNull; import javax.servlet.ServletException; import jenkins.model.BuildDiscarder; import jenkins.model.BuildDiscarderProperty; @@ -117,12 +122,9 @@ import org.kohsuke.stapler.interceptor.RequirePOST; import org.kohsuke.stapler.verb.POST; -import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST; -import static javax.servlet.http.HttpServletResponse.SC_NO_CONTENT; - /** * A job is an runnable entity under the monitoring of Hudson. - * + * *

    * Every time it "runs", it will be recorded as a {@link Run} object. * @@ -277,7 +279,7 @@ public synchronized boolean isHoldOffBuildUntilSave() { } protected synchronized void saveNextBuildNumber() throws IOException { - if (nextBuildNumber == 0) { // #3361 + if (nextBuildNumber == 0) { // JENKINS-3361 nextBuildNumber = 1; } getNextBuildNumberFile().write(String.valueOf(nextBuildNumber) + '\n'); @@ -301,16 +303,16 @@ public Queue.Item getQueueItem() { */ public boolean isBuilding() { RunT b = getLastBuild(); - return b!=null && b.isBuilding(); + return b != null && b.isBuilding(); } - + /** * Returns true if the log file is still being updated. */ public boolean isLogUpdated() { RunT b = getLastBuild(); - return b!=null && b.isLogUpdated(); - } + return b != null && b.isLogUpdated(); + } @Override public String getPronoun() { @@ -357,9 +359,9 @@ public int getNextBuildNumber() { */ public EnvVars getCharacteristicEnvVars() { EnvVars env = new EnvVars(); - env.put("JENKINS_SERVER_COOKIE",SERVER_COOKIE.get()); - env.put("HUDSON_SERVER_COOKIE",SERVER_COOKIE.get()); // Legacy compatibility - env.put("JOB_NAME",getFullName()); + env.put("JENKINS_SERVER_COOKIE", SERVER_COOKIE.get()); + env.put("HUDSON_SERVER_COOKIE", SERVER_COOKIE.get()); // Legacy compatibility + env.put("JOB_NAME", getFullName()); env.put("JOB_BASE_NAME", getName()); return env; } @@ -381,7 +383,7 @@ public EnvVars getCharacteristicEnvVars() { if (node != null) { final Computer computer = node.toComputer(); if (computer != null) { - // we need to get computer environment to inherit platform details + // we need to get computer environment to inherit platform details env = computer.getEnvironment(); env.putAll(computer.buildEnvironment(listener)); } @@ -392,11 +394,11 @@ public EnvVars getCharacteristicEnvVars() { // servlet container may have set CLASSPATH in its launch script, // so don't let that inherit to the new child process. // see http://www.nabble.com/Run-Job-with-JDK-1.4.2-tf4468601.html - env.put("CLASSPATH",""); + env.put("CLASSPATH", ""); // apply them in a reverse order so that higher ordinal ones can modify values added by lower ordinal ones for (EnvironmentContributor ec : EnvironmentContributor.all().reverseView()) - ec.buildEnvironmentFor(this,env,listener); + ec.buildEnvironmentFor(this, env, listener); return env; @@ -404,17 +406,17 @@ public EnvVars getCharacteristicEnvVars() { /** * Programmatically updates the next build number. - * + * *

    * Much of Hudson assumes that the build number is unique and monotonic, so * this method can only accept a new value that's bigger than * {@link #getLastBuild()} returns. Otherwise it'll be no-op. - * + * * @since 1.199 (before that, this method was package private.) */ public synchronized void updateNextBuildNumber(int next) throws IOException { RunT lb = getLastBuild(); - if (lb!=null ? next>lb.getNumber() : next>0) { + if (lb != null ? next > lb.getNumber() : next > 0) { this.nextBuildNumber = next; saveNextBuildNumber(); } @@ -479,6 +481,7 @@ public boolean supportsLogRotator() { @Override protected SearchIndexBuilder makeSearchIndex() { return super.makeSearchIndex().add(new SearchIndex() { + @Override public void find(String token, List result) { try { if (token.startsWith("#")) @@ -493,23 +496,25 @@ public void find(String token, List result) { } } + @Override public void suggest(String token, List result) { find(token, result); } }).add("configure", "config", "configure"); } + @Override public Collection getAllJobs() { - return Collections. singleton(this); + return Collections.singleton(this); } /** * Adds {@link JobProperty}. - * + * * @since 1.188 */ public void addProperty(JobProperty jobProp) throws IOException { - ((JobProperty)jobProp).setOwner(this); + ((JobProperty) jobProp).setOwner(this); properties.add(jobProp); save(); } @@ -557,7 +562,7 @@ public Map> getProperties() { * List of all {@link JobProperty} exposed primarily for the remoting API. * @since 1.282 */ - @Exported(name="property",inline=true) + @Exported(name = "property", inline = true) public List> getAllProperties() { return properties.getView(); } @@ -597,6 +602,7 @@ public JobProperty getProperty(String className) { * Overrides from job properties. * @see JobProperty#getJobOverrides */ + @Override public Collection getOverrides() { List r = new ArrayList<>(); for (JobProperty p : properties) @@ -618,6 +624,7 @@ protected HistoryWidget createHistoryWidget() { } public static final HistoryWidget.Adapter HISTORY_ADAPTER = new Adapter() { + @Override public int compare(Run record, String key) { try { int k = Integer.parseInt(key); @@ -627,14 +634,17 @@ public int compare(Run record, String key) { } } + @Override public String getKey(Run record) { return String.valueOf(record.getNumber()); } + @Override public boolean isBuilding(Run record) { return record.isBuilding(); } + @Override public String getNextKey(String key) { try { int k = Integer.parseInt(key); @@ -653,13 +663,9 @@ public void renameTo(String newName) throws IOException { File oldBuildDir = getBuildDir(); super.renameTo(newName); File newBuildDir = getBuildDir(); - if (oldBuildDir.isDirectory() && !newBuildDir.isDirectory()) { - if (!newBuildDir.getParentFile().isDirectory()) { - newBuildDir.getParentFile().mkdirs(); - } - if (!oldBuildDir.renameTo(newBuildDir)) { - throw new IOException("failed to rename " + oldBuildDir + " to " + newBuildDir); - } + if (Files.isDirectory(Util.fileToPath(oldBuildDir)) && !Files.isDirectory(Util.fileToPath(newBuildDir))) { + Util.createDirectories(Util.fileToPath(newBuildDir.getParentFile())); + Files.move(Util.fileToPath(oldBuildDir), Util.fileToPath(newBuildDir)); } } @@ -685,7 +691,7 @@ public static class SubItemBuildsLocationImpl extends ItemListener { public void onLocationChanged(Item item, String oldFullName, String newFullName) { final Jenkins jenkins = Jenkins.get(); if (!jenkins.isDefaultBuildDir() && item instanceof Job) { - File newBuildDir = ((Job)item).getBuildDir(); + File newBuildDir = ((Job) item).getBuildDir(); try { if (!Util.isDescendant(item.getRootDir(), newBuildDir)) { //OK builds are stored somewhere outside of the item's root, so none of the other move operations has probably moved it. @@ -720,10 +726,10 @@ public void onLocationChanged(Item item, String oldFullName, String newFullName) /** * Gets the read-only view of all the builds. - * + * * @return never null. The first entry is the latest build. */ - @Exported(name="allBuilds",visibility=-2) + @Exported(name = "allBuilds", visibility = -2) @WithBridgeMethods(List.class) public RunList getBuilds() { return RunList.fromRuns(_getRuns().values()); @@ -734,7 +740,7 @@ public RunList getBuilds() { * * @since 1.485 */ - @Exported(name="builds") + @Exported(name = "builds") public RunList getNewBuilds() { return getBuilds().limit(100); } @@ -743,10 +749,10 @@ public RunList getNewBuilds() { * Obtains all the {@link Run}s whose build numbers matches the given {@link RangeSet}. */ public synchronized List getBuilds(RangeSet rs) { - List builds = new LinkedList<>(); + List builds = new ArrayList<>(); for (Range r : rs.getRanges()) { - for (RunT b = getNearestBuild(r.start); b!=null && b.getNumber() getBuildsByTimestamp(long start, long end) { - return getBuilds().byTimestamp(start,end); + return getBuilds().byTimestamp(start, end); } @CLIResolver - public RunT getBuildForCLI(@Argument(required=true,metaVar="BUILD#",usage="Build number") String id) throws CmdLineException { + public RunT getBuildForCLI(@Argument(required = true, metaVar = "BUILD#", usage = "Build number") String id) throws CmdLineException { try { int n = Integer.parseInt(id); RunT r = getBuildByNumber(n); - if (r==null) - throw new CmdLineException(null, "No such build '#"+n+"' exists"); + if (r == null) + throw new CmdLineException(null, "No such build '#" + n + "' exists"); return r; } catch (NumberFormatException e) { - throw new CmdLineException(null, id+ "is not a number"); + throw new CmdLineException(null, id + "is not a number", e); } } /** * Gets the youngest build #m that satisfies {@code n<=m}. - * + * * This is useful when you'd like to fetch a build but the exact build might * be already gone (deleted, rotated, etc.) * @see LazyBuildMixIn#getNearestBuild @@ -827,7 +833,7 @@ public RunT getNearestBuild(int n) { /** * Gets the latest build #m that satisfies {@code m<=n}. - * + * * This is useful when you'd like to fetch a build but the exact build might * be already gone (deleted, rotated, etc.) * @see LazyBuildMixIn#getNearestOldBuild @@ -854,7 +860,7 @@ public Object getDynamic(String token, StaplerRequest req, // is this a permalink? for (Permalink p : getPermalinks()) { - if(p.getId().equals(token)) + if (p.getId().equals(token)) return p.resolve(this); } @@ -868,7 +874,7 @@ public Object getDynamic(String token, StaplerRequest req, * Some {@link Job}s may not have backing data store for {@link Run}s, but * those {@link Job}s that use file system for storing data should use this * directory for consistency. - * + * * @see RunMap */ public File getBuildDir() { @@ -884,7 +890,7 @@ public File getBuildDir() { /** * Gets all the runs. - * + * * The resulting map must be treated immutable (by employing copy-on-write * semantics.) The map is descending order, with newest builds at the top. * @see LazyBuildMixIn#_getRuns @@ -893,7 +899,7 @@ public File getBuildDir() { /** * Called from {@link Run} to remove it from this job. - * + * * The files are deleted already. So all the callee needs to do is to remove * a reference from this {@link Job}. * @see LazyBuildMixIn#removeRun @@ -931,13 +937,13 @@ public RunT getFirstBuild() { /** * Returns the last successful build, if any. Otherwise null. A successful build * would include either {@link Result#SUCCESS} or {@link Result#UNSTABLE}. - * + * * @see #getLastStableBuild() */ @Exported @QuickSilver public RunT getLastSuccessfulBuild() { - return (RunT)Permalink.LAST_SUCCESSFUL_BUILD.resolve(this); + return (RunT) Permalink.LAST_SUCCESSFUL_BUILD.resolve(this); } /** @@ -947,7 +953,7 @@ public RunT getLastSuccessfulBuild() { @Exported @QuickSilver public RunT getLastUnsuccessfulBuild() { - return (RunT)Permalink.LAST_UNSUCCESSFUL_BUILD.resolve(this); + return (RunT) Permalink.LAST_UNSUCCESSFUL_BUILD.resolve(this); } /** @@ -957,7 +963,7 @@ public RunT getLastUnsuccessfulBuild() { @Exported @QuickSilver public RunT getLastUnstableBuild() { - return (RunT)Permalink.LAST_UNSTABLE_BUILD.resolve(this); + return (RunT) Permalink.LAST_UNSTABLE_BUILD.resolve(this); } /** @@ -967,7 +973,7 @@ public RunT getLastUnstableBuild() { @Exported @QuickSilver public RunT getLastStableBuild() { - return (RunT)Permalink.LAST_STABLE_BUILD.resolve(this); + return (RunT) Permalink.LAST_STABLE_BUILD.resolve(this); } /** @@ -976,7 +982,7 @@ public RunT getLastStableBuild() { @Exported @QuickSilver public RunT getLastFailedBuild() { - return (RunT)Permalink.LAST_FAILED_BUILD.resolve(this); + return (RunT) Permalink.LAST_FAILED_BUILD.resolve(this); } /** @@ -985,12 +991,12 @@ public RunT getLastFailedBuild() { @Exported @QuickSilver public RunT getLastCompletedBuild() { - return (RunT)Permalink.LAST_COMPLETED_BUILD.resolve(this); + return (RunT) Permalink.LAST_COMPLETED_BUILD.resolve(this); } - + /** * Returns the last {@code numberOfBuilds} builds with a build result ≥ {@code threshold} - * + * * @return a list with the builds. May be smaller than 'numberOfBuilds' or even empty * if not enough builds satisfying the threshold have been found. Never null. */ @@ -998,13 +1004,13 @@ public List getLastBuildsOverThreshold(int numberOfBuilds, Result threshol RunT r = getLastBuild(); return r.getBuildsOverThreshold(numberOfBuilds, threshold); } - + /** * Returns candidate build for calculating the estimated duration of the current run. - * + * * Returns the 3 last successful (stable or unstable) builds, if there are any. * Failing to find 3 of those, it will return up to 3 last unsuccessful builds. - * + * * In any case it will not go more than 6 builds into the past to avoid costly build loading. */ protected List getEstimatedDurationCandidates() { @@ -1031,29 +1037,29 @@ protected List getEstimatedDurationCandidates() { i++; r = r.getPreviousBuild(); } - + while (candidates.size() < 3) { if (fallbackCandidates.isEmpty()) break; RunT run = fallbackCandidates.remove(0); candidates.add(run); } - + return candidates; } - + public long getEstimatedDuration() { List builds = getEstimatedDurationCandidates(); - - if(builds.isEmpty()) return -1; + + if (builds.isEmpty()) return -1; long totalDuration = 0; for (RunT b : builds) { totalDuration += b.getDuration(); } - if(totalDuration==0) return -1; + if (totalDuration == 0) return -1; - return Math.round((double)totalDuration / builds.size()); + return Math.round((double) totalDuration / builds.size()); } /** @@ -1098,13 +1104,13 @@ class FeedItem { for (SCM s : scmItem.getSCMs()) { scmNames.add(s.getDescriptor().getDisplayName()); } - scmDisplayName = " " + Util.join(scmNames, ", "); + scmDisplayName = " " + String.join(", ", scmNames); } for (RunT r = getLastBuild(); r != null; r = r.getPreviousBuild()) { int idx = 0; if (r instanceof RunWithSCM) { - for (ChangeLogSet c : ((RunWithSCM) r).getChangeSets()) { + for (ChangeLogSet c : ((RunWithSCM) r).getChangeSets()) { for (ChangeLogSet.Entry e : c) { entries.add(new FeedItem(e, idx++)); } @@ -1115,18 +1121,22 @@ class FeedItem { getDisplayName() + scmDisplayName + " changes", getUrl() + "changes", entries, new FeedAdapter() { + @Override public String getEntryTitle(FeedItem item) { return "#" + item.getBuild().number + ' ' + item.e.getMsg() + " (" + item.e.getAuthor() + ")"; } + @Override public String getEntryUrl(FeedItem item) { return item.getBuild().getUrl() + "changes#detail" + item.idx; } + @Override public String getEntryID(FeedItem item) { return getEntryUrl(item); } + @Override public String getEntryDescription(FeedItem item) { StringBuilder buf = new StringBuilder(); for (String path : item.e.getAffectedPaths()) @@ -1134,10 +1144,12 @@ public String getEntryDescription(FeedItem item) { return buf.toString(); } + @Override public Calendar getEntryTimestamp(FeedItem item) { return item.getBuild().getTimestamp(); } + @Override public String getEntryAuthor(FeedItem entry) { return JenkinsLocationConfiguration.get().getAdminAddress(); } @@ -1176,7 +1188,7 @@ public BallColor getIconColor() { /** * Get the current health report for a job. - * + * * @return the health report. Never returns null */ public HealthReport getBuildHealth() { @@ -1322,7 +1334,7 @@ public synchronized void doConfigSubmit(StaplerRequest req, DescribableList, JobPropertyDescriptor> t = new DescribableList<>(NOOP, getAllProperties()); JSONObject jsonProperties = json.optJSONObject("properties"); if (jsonProperties != null) { - t.rebuild(req,jsonProperties,JobPropertyDescriptor.getPropertyDescriptors(Job.this.getClass())); + t.rebuild(req, jsonProperties, JobPropertyDescriptor.getPropertyDescriptors(Job.this.getClass())); } else { t.clear(); } @@ -1338,7 +1350,7 @@ public synchronized void doConfigSubmit(StaplerRequest req, ItemListener.fireOnUpdated(this); final ProjectNamingStrategy namingStrategy = Jenkins.get().getProjectNamingStrategy(); - if(namingStrategy.isForceExistingJobs()){ + if (namingStrategy.isForceExistingJobs()) { namingStrategy.checkName(name); } FormApply.success(".").generateResponse(req, rsp, null); @@ -1398,64 +1410,91 @@ public String getBuildStatusIconClassName() { return getIconColor().getIconClassName(); } - public Graph getBuildTimeGraph() { - return new Graph(getLastBuildTime(),500,400) { - @Override - protected JFreeChart createGraph() { - class ChartLabel implements Comparable { - final Run run; + private static class ChartLabel implements Comparable { + final Run run; - ChartLabel(Run r) { - this.run = r; - } + ChartLabel(Run r) { + this.run = r; + } - public int compareTo(ChartLabel that) { - return this.run.number - that.run.number; - } + @Override + public int compareTo(ChartLabel that) { + return this.run.number - that.run.number; + } - @Override - public boolean equals(Object o) { - // HUDSON-2682 workaround for Eclipse compilation bug - // on (c instanceof ChartLabel) - if (o == null || !ChartLabel.class.isAssignableFrom( o.getClass() )) { - return false; - } - ChartLabel that = (ChartLabel) o; - return run == that.run; - } + @Override + public boolean equals(Object o) { + // JENKINS-2682 workaround for Eclipse compilation bug + // on (c instanceof ChartLabel) + if (o == null || !ChartLabel.class.isAssignableFrom(o.getClass())) { + return false; + } + ChartLabel that = (ChartLabel) o; + return run == that.run; + } - public Color getColor() { - // TODO: consider gradation. See - // http://www.javadrive.jp/java2d/shape/index9.html - Result r = run.getResult(); - if (r == Result.FAILURE) - return ColorPalette.RED; - else if (r == Result.UNSTABLE) - return ColorPalette.YELLOW; - else if (r == Result.ABORTED || r == Result.NOT_BUILT) - return ColorPalette.GREY; - else - return ColorPalette.BLUE; - } + public Color getColor() { + // TODO: consider gradation. See + // http://www.javadrive.jp/java2d/shape/index9.html + Result r = run.getResult(); + if (r == Result.FAILURE) + return ColorPalette.RED; + else if (r == Result.UNSTABLE) + return ColorPalette.YELLOW; + else if (r == Result.ABORTED || r == Result.NOT_BUILT) + return ColorPalette.DARK_GREY; + else + return ColorPalette.BLUE; + } - @Override - public int hashCode() { - return run.hashCode(); - } + @Override + public int hashCode() { + return run.hashCode(); + } - @Override - public String toString() { - String l = run.getDisplayName(); - if (run instanceof Build) { - String s = ((Build) run).getBuiltOnStr(); - if (s != null) - l += ' ' + s; - } - return l; - } + @Override + public String toString() { + String l = run.getDisplayName(); + if (run instanceof Build) { + String s = ((Build) run).getBuiltOnStr(); + if (s != null) + l += ' ' + s; + } + return l; + } + } - } + @SuppressFBWarnings(value = "EQ_DOESNT_OVERRIDE_EQUALS", justification = "category dataset is only relevant for coloring, not equality") + private static class ChartLabelStackedAreaRenderer2 extends StackedAreaRenderer2 { + private final CategoryDataset categoryDataset; + + ChartLabelStackedAreaRenderer2(CategoryDataset categoryDataset) { + this.categoryDataset = categoryDataset; + } + + @Override + public Paint getItemPaint(int row, int column) { + ChartLabel key = (ChartLabel) categoryDataset.getColumnKey(column); + return key.getColor(); + } + + @Override + public String generateURL(CategoryDataset dataset, int row, int column) { + ChartLabel label = (ChartLabel) dataset.getColumnKey(column); + return String.valueOf(label.run.number); + } + + @Override + public String generateToolTip(CategoryDataset dataset, int row, int column) { + ChartLabel label = (ChartLabel) dataset.getColumnKey(column); + return label.run.getDisplayName() + " : " + label.run.getDurationString(); + } + } + public Graph getBuildTimeGraph() { + return new Graph(getLastBuildTime(), 500, 400) { + @Override + protected JFreeChart createGraph() { DataSetBuilder data = new DataSetBuilder<>(); for (Run r : getNewBuilds()) { if (r.isBuilding()) @@ -1485,8 +1524,6 @@ public String toString() { plot.setBackgroundPaint(Color.WHITE); plot.setOutlinePaint(null); plot.setForegroundAlpha(0.8f); - // plot.setDomainGridlinesVisible(true); - // plot.setDomainGridlinePaint(Color.white); plot.setRangeGridlinesVisible(true); plot.setRangeGridlinePaint(Color.black); @@ -1501,28 +1538,7 @@ public String toString() { ChartUtil.adjustChebyshev(dataset, rangeAxis); rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits()); - StackedAreaRenderer ar = new StackedAreaRenderer2() { - @Override - public Paint getItemPaint(int row, int column) { - ChartLabel key = (ChartLabel) dataset.getColumnKey(column); - return key.getColor(); - } - - @Override - public String generateURL(CategoryDataset dataset, int row, - int column) { - ChartLabel label = (ChartLabel) dataset.getColumnKey(column); - return String.valueOf(label.run.number); - } - - @Override - public String generateToolTip(CategoryDataset dataset, int row, - int column) { - ChartLabel label = (ChartLabel) dataset.getColumnKey(column); - return label.run.getDisplayName() + " : " - + label.run.getDurationString(); - } - }; + StackedAreaRenderer ar = new ChartLabelStackedAreaRenderer2(dataset); plot.setRenderer(ar); // crop extra space around the graph @@ -1535,7 +1551,7 @@ public String generateToolTip(CategoryDataset dataset, int row, private Calendar getLastBuildTime() { final RunT lastBuild = getLastBuild(); - if (lastBuild ==null) { + if (lastBuild == null) { final GregorianCalendar neverBuiltCalendar = new GregorianCalendar(); neverBuiltCalendar.setTimeInMillis(0); return neverBuiltCalendar; @@ -1587,5 +1603,5 @@ public BuildTimelineWidget getTimeline() { return new BuildTimelineWidget(getBuilds()); } - private static final HexStringConfidentialKey SERVER_COOKIE = new HexStringConfidentialKey(Job.class,"serverCookie",16); + private static final HexStringConfidentialKey SERVER_COOKIE = new HexStringConfidentialKey(Job.class, "serverCookie", 16); } diff --git a/core/src/main/java/hudson/model/JobProperty.java b/core/src/main/java/hudson/model/JobProperty.java index 5ad493da8117..fe02891987e9 100644 --- a/core/src/main/java/hudson/model/JobProperty.java +++ b/core/src/main/java/hudson/model/JobProperty.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,29 +21,27 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.ExtensionPoint; import hudson.Launcher; import hudson.model.Descriptor.FormException; import hudson.model.queue.SubTask; import hudson.tasks.BuildStep; +import hudson.tasks.BuildStepMonitor; import hudson.tasks.Builder; import hudson.tasks.Publisher; -import hudson.tasks.BuildStepMonitor; - import java.io.IOException; import java.util.Collection; import java.util.Collections; - import jenkins.model.Jenkins; import jenkins.model.OptionalJobProperty; import net.sf.json.JSONObject; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.export.ExportedBean; -import edu.umd.cs.findbugs.annotations.NonNull; - /** * Extensible property of {@link Job}. * @@ -70,14 +68,14 @@ * @param * When you restrict your job property to be only applicable to a certain * subtype of {@link Job}, you can use this type parameter to improve - * the type signature of this class. See {@link JobPropertyDescriptor#isApplicable(Class)}. + * the type signature of this class. See {@link JobPropertyDescriptor#isApplicable(Class)}. * * @author Kohsuke Kawaguchi * @see JobPropertyDescriptor * @since 1.72 */ @ExportedBean -public abstract class JobProperty> implements ReconfigurableDescribable>, BuildStep, ExtensionPoint { +public abstract class JobProperty> implements ReconfigurableDescribable>, BuildStep, ExtensionPoint { /** * The {@link Job} object that owns this property. * This value will be set by the Hudson code. @@ -135,7 +133,7 @@ public Action getJobAction(J job) { public Collection getJobActions(J job) { // delegate to getJobAction (singular) for backward compatible behavior Action a = getJobAction(job); - if (a==null) return Collections.emptyList(); + if (a == null) return Collections.emptyList(); return Collections.singletonList(a); } @@ -143,7 +141,8 @@ public Collection getJobActions(J job) { // default no-op implementation // - public boolean prebuild(AbstractBuild build, BuildListener listener) { + @Override + public boolean prebuild(AbstractBuild build, BuildListener listener) { return true; } @@ -154,7 +153,7 @@ public boolean prebuild(AbstractBuild build, BuildListener listener) { * Invoked after {@link Publisher}s have run. */ @Override - public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { + public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { return true; } @@ -167,13 +166,15 @@ public BuildStepMonitor getRequiredMonitorService() { return BuildStepMonitor.NONE; } - public final Action getProjectAction(AbstractProject project) { - return getJobAction((J)project); + @Override + public final Action getProjectAction(AbstractProject project) { + return getJobAction((J) project); } + @Override @NonNull - public final Collection getProjectActions(AbstractProject project) { - return getJobActions((J)project); + public final Collection getProjectActions(AbstractProject project) { + return getJobActions((J) project); } /** @see Job#getOverrides */ @@ -181,8 +182,9 @@ public Collection getJobOverrides() { return Collections.emptyList(); } + @Override public JobProperty reconfigure(StaplerRequest req, JSONObject form) throws FormException { - return form==null ? null : getDescriptor().newInstance(req,form); + return form == null ? null : getDescriptor().newInstance(req, form); } /** diff --git a/core/src/main/java/hudson/model/JobPropertyDescriptor.java b/core/src/main/java/hudson/model/JobPropertyDescriptor.java index 03fdd7879685..1f1c3aa7e6f0 100644 --- a/core/src/main/java/hudson/model/JobPropertyDescriptor.java +++ b/core/src/main/java/hudson/model/JobPropertyDescriptor.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,24 +21,23 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package hudson.model; -import jenkins.model.Jenkins; -import org.kohsuke.stapler.StaplerRequest; -import org.jvnet.tiger_types.Types; +package hudson.model; -import java.util.List; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collection; -import java.lang.reflect.Type; -import java.lang.reflect.ParameterizedType; +import java.util.List; +import jenkins.model.Jenkins; import jenkins.model.OptionalJobProperty; - import net.sf.json.JSONObject; +import org.jvnet.tiger_types.Types; +import org.kohsuke.stapler.StaplerRequest; /** * {@link Descriptor} for {@link JobProperty}. - * + * * @author Kohsuke Kawaguchi * @since 1.72 */ @@ -64,8 +63,8 @@ protected JobPropertyDescriptor() { @Override public JobProperty newInstance(StaplerRequest req, JSONObject formData) throws FormException { // JobPropertyDescriptors are bit different in that we allow them even without any user-visible configuration parameter, - // so replace the lack of form data by an empty one. - if(formData.isNullObject()) formData=new JSONObject(); + // so replace the lack of form data by an empty one. + if (formData.isNullObject()) formData = new JSONObject(); return super.newInstance(req, formData); } @@ -73,7 +72,7 @@ public JobProperty newInstance(StaplerRequest req, JSONObject formData) throw /** * Returns true if this {@link JobProperty} type is applicable to the * given job type. - * + * *

    * The default implementation of this method checks if the given job type is assignable to {@code J} of * {@link JobProperty}{@code }, but subtypes can extend this to change this behavior. @@ -89,7 +88,7 @@ public boolean isApplicable(Class jobType) { Class applicable = Types.erasure(Types.getTypeArgument(pt, 0)); return applicable.isAssignableFrom(jobType); } else { - throw new AssertionError(clazz+" doesn't properly parameterize JobProperty. The isApplicable() method must be overridden."); + throw new AssertionError(clazz + " doesn't properly parameterize JobProperty. The isApplicable() method must be overridden."); } } @@ -99,7 +98,7 @@ public boolean isApplicable(Class jobType) { public static List getPropertyDescriptors(Class clazz) { List r = new ArrayList<>(); for (JobPropertyDescriptor p : all()) - if(p.isApplicable(clazz)) + if (p.isApplicable(clazz)) r.add(p); return r; } diff --git a/core/src/main/java/hudson/model/Jobs.java b/core/src/main/java/hudson/model/Jobs.java index e6a13e68d72d..a9452f68d8a9 100644 --- a/core/src/main/java/hudson/model/Jobs.java +++ b/core/src/main/java/hudson/model/Jobs.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Tom Huybrechts - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,16 +21,16 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; -import hudson.util.DescriptorList; import hudson.Extension; - +import hudson.util.DescriptorList; import java.util.List; /** * List of all installed {@link Job} types. - * + * * @author Kohsuke Kawaguchi * @deprecated since 1.281 */ @@ -50,5 +50,5 @@ public class Jobs { */ @Deprecated public static final List PROPERTIES = (List) - new DescriptorList>((Class)JobProperty.class); + new DescriptorList>((Class) JobProperty.class); } diff --git a/core/src/main/java/hudson/model/Label.java b/core/src/main/java/hudson/model/Label.java index 92434eda6ff2..12426e8ba9e6 100644 --- a/core/src/main/java/hudson/model/Label.java +++ b/core/src/main/java/hudson/model/Label.java @@ -21,11 +21,19 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; -import antlr.ANTLRException; import static hudson.Util.fixNull; +import antlr.ANTLRException; +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.Util; import hudson.model.labels.LabelAtom; import hudson.model.labels.LabelExpression; @@ -43,19 +51,10 @@ import hudson.model.queue.SubTask; import hudson.security.ACL; import hudson.security.ACLContext; -import hudson.slaves.NodeProvisioner; import hudson.slaves.Cloud; +import hudson.slaves.NodeProvisioner; import hudson.util.QuotedStringTokenizer; import hudson.util.VariableResolver; -import jenkins.model.Jenkins; -import jenkins.model.ModelObjectWithChildren; -import org.kohsuke.accmod.Restricted; -import org.kohsuke.accmod.restrictions.DoNotUse; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; -import org.kohsuke.stapler.export.Exported; -import org.kohsuke.stapler.export.ExportedBean; - import java.io.Serializable; import java.io.StringReader; import java.util.Collection; @@ -67,13 +66,14 @@ import java.util.TreeSet; import java.util.stream.Collectors; import java.util.stream.StreamSupport; - -import com.thoughtworks.xstream.converters.Converter; -import com.thoughtworks.xstream.converters.MarshallingContext; -import com.thoughtworks.xstream.converters.UnmarshallingContext; -import com.thoughtworks.xstream.io.HierarchicalStreamWriter; -import com.thoughtworks.xstream.io.HierarchicalStreamReader; -import edu.umd.cs.findbugs.annotations.NonNull; +import jenkins.model.Jenkins; +import jenkins.model.ModelObjectWithChildren; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.DoNotUse; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.export.Exported; +import org.kohsuke.stapler.export.ExportedBean; /** * Group of {@link Node}s. @@ -99,10 +99,10 @@ public abstract class Label extends Actionable implements Comparable

    - * This class defines methods for handling progressive text update. - * - * @author Kohsuke Kawaguchi - * @deprecated moved to stapler, as of Hudson 1.220 - */ -@Deprecated -public class LargeText { - /** - * Represents the data source of this text. - */ - private interface Source { - Session open() throws IOException; - long length(); - boolean exists(); - } - private final Source source; - - private volatile boolean completed; - - public LargeText(final File file, boolean completed) { - this.source = new Source() { - public Session open() throws IOException { - return new FileSession(file); - } - - public long length() { - return file.length(); - } - - public boolean exists() { - return file.exists(); - } - }; - this.completed = completed; - } - - @SuppressWarnings("deprecation") - public LargeText(final ByteBuffer memory, boolean completed) { - this.source = new Source() { - public Session open() throws IOException { - return new BufferSession(memory); - } - - public long length() { - return memory.length(); - } - - public boolean exists() { - return true; - } - }; - this.completed = completed; - } - - public void markAsComplete() { - completed = true; - } - - public boolean isComplete() { - return completed; - } - - /** - * Returns {@link Reader} for reading the raw bytes. - */ - public Reader readAll() throws IOException { - return new InputStreamReader(new InputStream() { - final Session session = source.open(); - public int read() throws IOException { - byte[] buf = new byte[1]; - int n = session.read(buf); - if(n==1) return buf[0]; - else return -1; // EOF - } - - @Override - public int read(byte[] buf, int off, int len) throws IOException { - return session.read(buf,off,len); - } - - @Override - public void close() throws IOException { - session.close(); - } - }); - } - - /** - * Writes the tail portion of the file to the {@link Writer}. - * - *

    - * The text file is assumed to be in the system default encoding. - * - * @param start - * The byte offset in the input file where the write operation starts. - * - * @return - * if the file is still being written, this method writes the file - * until the last newline character and returns the offset to start - * the next write operation. - */ - public long writeLogTo(long start, Writer w) throws IOException { - CountingOutputStream os = new CountingOutputStream(new WriterOutputStream(w)); - - try (Session f = source.open()) { - f.skip(start); - - if (completed) { - // write everything till EOF - byte[] buf = new byte[1024]; - int sz; - while ((sz = f.read(buf)) >= 0) - os.write(buf, 0, sz); - } else { - ByteBuf buf = new ByteBuf(null, f); - HeadMark head = new HeadMark(buf); - TailMark tail = new TailMark(buf); - - while (tail.moveToNextLine(f)) { - head.moveTo(tail, os); - } - head.finish(os); - } - } - os.flush(); - - return os.getCount()+start; - } - - /** - * Implements the progressive text handling. - * This method is used as a "web method" with progressiveText.jelly. - */ - public void doProgressText(StaplerRequest req, StaplerResponse rsp) throws IOException { - rsp.setContentType("text/plain"); - rsp.setStatus(HttpServletResponse.SC_OK); - - if(!source.exists()) { - // file doesn't exist yet - rsp.addHeader("X-Text-Size","0"); - rsp.addHeader("X-More-Data","true"); - return; - } - - long start = 0; - String s = req.getParameter("start"); - if(s!=null) - start = Long.parseLong(s); - - if(source.length() < start ) - start = 0; // text rolled over - - CharSpool spool = new CharSpool(); - long r = writeLogTo(start,spool); - - rsp.addHeader("X-Text-Size",String.valueOf(r)); - if(!completed) - rsp.addHeader("X-More-Data","true"); - - // when sending big text, try compression. don't bother if it's small - Writer w; - if(r-start>4096) - w = rsp.getCompressedWriter(req); - else - w = rsp.getWriter(); - spool.writeTo(new LineEndNormalizingWriter(w)); - w.close(); - - } - - /** - * Points to a byte in the buffer. - */ - private static class Mark { - protected ByteBuf buf; - protected int pos; - - Mark(ByteBuf buf) { - this.buf = buf; - } - } - - /** - * Points to the start of the region that's not committed - * to the output yet. - */ - private static final class HeadMark extends Mark { - HeadMark(ByteBuf buf) { - super(buf); - } - - /** - * Moves this mark to 'that' mark, and writes the data - * to {@link OutputStream} if necessary. - */ - void moveTo(Mark that, OutputStream os) throws IOException { - while(this.buf!=that.buf) { - os.write(buf.buf,0,buf.size); - buf = buf.next; - pos = 0; - } - - this.pos = that.pos; - } - - void finish(OutputStream os) throws IOException { - os.write(buf.buf,0,pos); - } - } - - /** - * Points to the end of the region. - */ - private static final class TailMark extends Mark { - TailMark(ByteBuf buf) { - super(buf); - } - - boolean moveToNextLine(Session f) throws IOException { - while(true) { - while(pos==buf.size) { - if(!buf.isFull()) { - // read until EOF - return false; - } else { - // read into the next buffer - buf = new ByteBuf(buf,f); - pos = 0; - } - } - byte b = buf.buf[pos++]; - if(b=='\r' || b=='\n') - return true; - } - } - } - - private static final class ByteBuf { - private final byte[] buf = new byte[1024]; - private int size = 0; - private ByteBuf next; - - ByteBuf(ByteBuf previous, Session f) throws IOException { - if(previous!=null) { - assert previous.next==null; - previous.next = this; - } - - while(!this.isFull()) { - int chunk = f.read(buf, size, buf.length - size); - if(chunk==-1) - return; - size+= chunk; - } - } - - public boolean isFull() { - return buf.length==size; - } - } - - /** - * Represents the read session of the {@link Source}. - * Methods generally follow the contracts of {@link InputStream}. - */ - private interface Session extends AutoCloseable { - void close() throws IOException; - void skip(long start) throws IOException; - int read(byte[] buf) throws IOException; - int read(byte[] buf, int offset, int length) throws IOException; - } - - /** - * {@link Session} implementation over {@link RandomAccessFile}. - */ - private static final class FileSession implements Session { - private final RandomAccessFile file; - - FileSession(File file) throws IOException { - this.file = new RandomAccessFile(file,"r"); - } - - public void close() throws IOException { - file.close(); - } - - public void skip(long start) throws IOException { - file.seek(file.getFilePointer()+start); - } - - public int read(byte[] buf) throws IOException { - return file.read(buf); - } - - public int read(byte[] buf, int offset, int length) throws IOException { - return file.read(buf,offset,length); - } - } - - /** - * {@link Session} implementation over {@link ByteBuffer}. - */ - private static final class BufferSession implements Session { - private final InputStream in; - - @SuppressWarnings("deprecation") - BufferSession(ByteBuffer buf) { - this.in = buf.newInputStream(); - } - - - public void close() throws IOException { - in.close(); - } - - public void skip(long n) throws IOException { - while(n>0) - n -= in.skip(n); - } - - public int read(byte[] buf) throws IOException { - return in.read(buf); - } - - public int read(byte[] buf, int offset, int length) throws IOException { - return in.read(buf,offset,length); - } - } -} diff --git a/core/src/main/java/hudson/model/ListView.java b/core/src/main/java/hudson/model/ListView.java index c37bb9a3cd09..14de68474e22 100644 --- a/core/src/main/java/hudson/model/ListView.java +++ b/core/src/main/java/hudson/model/ListView.java @@ -1,6 +1,6 @@ /* * The MIT License - * + * * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, * Erik Ramfelt, Seiji Sogabe, Martin Eigenbrodt, Alan Harder * @@ -10,10 +10,10 @@ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -22,8 +22,10 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import edu.umd.cs.findbugs.annotations.CheckForNull; import hudson.Extension; import hudson.Util; import hudson.diagnosis.OldDataMonitor; @@ -32,31 +34,33 @@ import hudson.search.SearchIndexBuilder; import hudson.security.ACL; import hudson.security.ACLContext; -import hudson.util.CaseInsensitiveComparator; import hudson.util.DescribableList; import hudson.util.FormValidation; import hudson.util.HttpResponses; import hudson.views.ListViewColumn; import hudson.views.StatusFilter; import hudson.views.ViewJobFilter; - import java.io.IOException; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; - -import edu.umd.cs.findbugs.annotations.CheckForNull; -import net.jcip.annotations.GuardedBy; import javax.servlet.ServletException; import jenkins.model.Jenkins; - +import net.jcip.annotations.GuardedBy; import net.sf.json.JSONObject; import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; - import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.DataBoundSetter; import org.kohsuke.stapler.HttpResponse; @@ -78,8 +82,8 @@ public class ListView extends View implements DirectlyModifiableView { * List of job names. This is what gets serialized. */ @GuardedBy("this") - /*package*/ /*almost-final*/ SortedSet jobNames = new TreeSet<>(CaseInsensitiveComparator.INSTANCE); - + /*package*/ /*almost-final*/ SortedSet jobNames = new TreeSet<>(String.CASE_INSENSITIVE_ORDER); + private DescribableList> jobFilters; private DescribableList> columns; @@ -88,12 +92,12 @@ public class ListView extends View implements DirectlyModifiableView { * Include regex string. */ private String includeRegex; - + /** * Whether to recurse in ItemGroups */ private boolean recurse; - + /** * Compiled include pattern from the includeRegex string. */ @@ -102,7 +106,7 @@ public class ListView extends View implements DirectlyModifiableView { /** * Filter by enabled/disabled status of jobs. * Null for no filter, true for enabled-only, false for disabled-only. - * Deprecated see {@link StatusFilter} + * @deprecated Status filter is now controlled via a {@link ViewJobFilter}, see {@link StatusFilter} */ @Deprecated private transient Boolean statusFilter; @@ -133,7 +137,7 @@ public void setJobFilters(List jobFilters) throws IOException { } protected Object readResolve() { - if(includeRegex!=null) { + if (includeRegex != null) { try { includePattern = Pattern.compile(includeRegex); } catch (PatternSyntaxException x) { @@ -141,9 +145,9 @@ protected Object readResolve() { OldDataMonitor.report(this, Collections.singleton(x)); } } - synchronized(this) { + synchronized (this) { if (jobNames == null) { - jobNames = new TreeSet<>(CaseInsensitiveComparator.INSTANCE); + jobNames = new TreeSet<>(String.CASE_INSENSITIVE_ORDER); } } initColumns(); @@ -170,11 +174,11 @@ protected void initJobFilters() { * Used to determine if we want to display the Add button. */ public boolean hasJobFilterExtensions() { - return !ViewJobFilter.all().isEmpty(); + return !ViewJobFilter.all().isEmpty(); } public DescribableList> getJobFilters() { - return jobFilters; + return jobFilters; } @Override @@ -182,7 +186,7 @@ public DescribableList> getColumns() return columns; } - public Set getJobNames() { + public synchronized Set getJobNames() { return Collections.unmodifiableSet(jobNames); } @@ -260,7 +264,7 @@ private List getItems(boolean recurse) { } // for sanity, trim off duplicates items = new ArrayList<>(new LinkedHashSet<>(items)); - + return items; } @@ -277,7 +281,7 @@ public SearchIndexBuilder makeSearchIndex() { public boolean contains(TopLevelItem item) { return getItems().contains(item); } - + public synchronized boolean jobNamesContains(TopLevelItem item) { if (item == null) return false; return jobNames.contains(item.getRelativeNameFrom(getOwner().getItemGroup())); @@ -330,7 +334,7 @@ public void setRecurse(boolean recurse) { /** * Filter by enabled/disabled status of jobs. * Null for no filter, true for enabled-only, false for disabled-only. - * Status filter is now controlled via a JobViewFilter, see {@link StatusFilter} + * @deprecated Status filter is now controlled via a {@link ViewJobFilter}, see {@link StatusFilter} */ @Deprecated public Boolean getStatusFilter() { @@ -345,7 +349,7 @@ public Boolean getStatusFilter() { @Restricted(NoExternalUse.class) // called from newJob_button-bar view @SuppressWarnings("unused") // called from newJob_button-bar view public boolean isAddToCurrentView() { - synchronized(this) { + synchronized (this) { return !jobNames.isEmpty() || // There are already items in this view specified by name (jobFilters.isEmpty() && includePattern == null) // No other way to include items is used ; @@ -369,8 +373,8 @@ private boolean needToAddToCurrentView(StaplerRequest req) throws ServletExcepti public Item doCreateItem(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { ItemGroup ig = getOwner().getItemGroup(); if (ig instanceof ModifiableItemGroup) { - TopLevelItem item = ((ModifiableItemGroup)ig).doCreateItem(req, rsp); - if (item!=null) { + TopLevelItem item = ((ModifiableItemGroup) ig).doCreateItem(req, rsp); + if (item != null) { if (needToAddToCurrentView(req)) { synchronized (this) { jobNames.add(item.getRelativeNameFrom(getOwner().getItemGroup())); @@ -387,7 +391,7 @@ public Item doCreateItem(StaplerRequest req, StaplerResponse rsp) throws IOExcep @RequirePOST public HttpResponse doAddJobToView(@QueryParameter String name) throws IOException, ServletException { checkPermission(View.CONFIGURE); - if(name==null) + if (name == null) throw new Failure("Query parameter 'name' is required"); TopLevelItem item = resolveName(name); @@ -406,11 +410,11 @@ public HttpResponse doAddJobToView(@QueryParameter String name) throws IOExcepti @RequirePOST public HttpResponse doRemoveJobFromView(@QueryParameter String name) throws IOException, ServletException { checkPermission(View.CONFIGURE); - if(name==null) + if (name == null) throw new Failure("Query parameter 'name' is required"); TopLevelItem item = resolveName(name); - if (item==null) + if (item == null) throw new Failure("Query parameter 'name' does not correspond to a known and readable item"); if (remove(item)) @@ -447,7 +451,7 @@ protected void submit(StaplerRequest req) throws ServletException, FormException } for (TopLevelItem item : items) { String relativeNameFrom = item.getRelativeNameFrom(getOwner().getItemGroup()); - if(req.getParameter(relativeNameFrom)!=null) { + if (req.getParameter(relativeNameFrom) != null) { jobNames.add(relativeNameFrom); } } @@ -461,14 +465,14 @@ protected void submit(StaplerRequest req) throws ServletException, FormException columns.rebuildHetero(req, json, ListViewColumn.all(), "columns"); if (jobFilters == null) { - jobFilters = new DescribableList<>(this); + jobFilters = new DescribableList<>(this); } jobFilters.rebuildHetero(req, json, ViewJobFilter.all(), "jobFilters"); String filter = Util.fixEmpty(req.getParameter("statusFilter")); statusFilter = filter != null ? "1".equals(filter) : null; } - + /** @since 1.526 */ @DataBoundSetter public void setIncludeRegex(String includeRegex) { @@ -485,8 +489,7 @@ public synchronized void setJobNames(Set jobNames) { } /** - * Deprecated see, {@link StatusFilter} - * @param statusFilter + * @deprecated Status filter is now controlled via a {@link ViewJobFilter}, see {@link StatusFilter} */ @Deprecated @DataBoundSetter @@ -504,7 +507,7 @@ public String getDisplayName() { /** * Checks if the include regular expression is valid. */ - public FormValidation doCheckIncludeRegex( @QueryParameter String value ) throws IOException, ServletException, InterruptedException { + public FormValidation doCheckIncludeRegex(@QueryParameter String value) throws IOException, ServletException, InterruptedException { String v = Util.fixEmpty(value); if (v != null) { try { @@ -535,6 +538,7 @@ public void onLocationChanged(final Item item, final String oldFullName, final S locationChanged(oldFullName, newFullName); } } + private void locationChanged(String oldFullName, String newFullName) { final Jenkins jenkins = Jenkins.get(); locationChanged(jenkins, oldFullName, newFullName); @@ -544,6 +548,7 @@ private void locationChanged(String oldFullName, String newFullName) { } } } + private void locationChanged(ViewGroup vg, String oldFullName, String newFullName) { for (View v : vg.getViews()) { if (v instanceof ListView) { @@ -580,6 +585,7 @@ public void onDeleted(final Item item) { deleted(item); } } + private void deleted(Item item) { final Jenkins jenkins = Jenkins.get(); deleted(jenkins, item); @@ -589,6 +595,7 @@ private void deleted(Item item) { } } } + private void deleted(ViewGroup vg, Item item) { for (View v : vg.getViews()) { if (v instanceof ListView) { diff --git a/core/src/main/java/hudson/model/LoadBalancer.java b/core/src/main/java/hudson/model/LoadBalancer.java index bd1d0b7c6307..ebe7b5154567 100644 --- a/core/src/main/java/hudson/model/LoadBalancer.java +++ b/core/src/main/java/hudson/model/LoadBalancer.java @@ -21,9 +21,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import com.google.common.collect.Maps; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.Extension; import hudson.ExtensionPoint; import hudson.model.Queue.Task; @@ -31,7 +34,6 @@ import hudson.model.queue.MappingWorksheet.ExecutorChunk; import hudson.model.queue.MappingWorksheet.Mapping; import hudson.util.ConsistentHash; - import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -58,7 +60,7 @@ public abstract class LoadBalancer implements ExtensionPoint { * The thread that invokes this method always holds a lock to {@link Queue}, so queue contents * can be safely introspected from this method, if that information is necessary to make * decisions. - * + * * @param task * The task whose execution is being considered. Never null. * @param worksheet @@ -71,24 +73,26 @@ public abstract class LoadBalancer implements ExtensionPoint { * Return null if you don't want the task to be executed right now, * in which case this method will be called some time later with the same task. */ - public abstract Mapping map(Task task, MappingWorksheet worksheet); + @CheckForNull + public abstract Mapping map(@NonNull Task task, MappingWorksheet worksheet); /** * Uses a consistent hash for scheduling. */ public static final LoadBalancer CONSISTENT_HASH = new LoadBalancer() { + @CheckForNull @Override - public Mapping map(Task task, MappingWorksheet ws) { + public Mapping map(@NonNull Task task, MappingWorksheet ws) { // build consistent hash for each work chunk List> hashes = new ArrayList<>(ws.works.size()); - for (int i=0; i hash = new ConsistentHash<>(ExecutorChunk::getName); // Build a Map to pass in rather than repeatedly calling hash.add() because each call does lots of expensive work List chunks = ws.works(i).applicableExecutorChunks(); Map toAdd = Maps.newHashMapWithExpectedSize(chunks.size()); for (ExecutorChunk ec : chunks) { - toAdd.put(ec, ec.size()*100); + toAdd.put(ec, ec.size() * 100); } hash.addAll(toAdd); @@ -97,9 +101,9 @@ public Mapping map(Task task, MappingWorksheet ws) { // do a greedy assignment Mapping m = ws.new Mapping(); - assert m.size()==ws.works.size(); // just so that you the reader of the source code don't get confused with the for loop index + assert m.size() == ws.works.size(); // just so that you the reader of the source code don't get confused with the for loop index - if (assignGreedily(m,task,hashes,0)) { + if (assignGreedily(m, task, hashes, 0)) { assert m.isCompletelyValid(); return m; } else @@ -107,7 +111,7 @@ public Mapping map(Task task, MappingWorksheet ws) { } private boolean assignGreedily(Mapping m, Task task, List> hashes, int i) { - if (i==hashes.size()) return true; // fully assigned + if (i == hashes.size()) return true; // fully assigned String key; try { @@ -121,16 +125,16 @@ private boolean assignGreedily(Mapping m, Task task, List q int q = 0; if (queue != null) { for (Queue.BuildableItem item : queue) { - + for (SubTask st : item.task.getSubTasks()) { if (matches(item, st)) q++; @@ -371,31 +372,33 @@ protected LoadStatisticsSnapshot computeSnapshot(Iterable q /** * With 0.90 decay ratio for every 10sec, half reduction is about 1 min. - * + * * Put differently, the half reduction time is {@code CLOCK*log(0.5)/log(DECAY)} */ - public static final float DECAY = Float.parseFloat(SystemProperties.getString(LoadStatistics.class.getName()+".decay","0.9")); + public static final float DECAY = Float.parseFloat(SystemProperties.getString(LoadStatistics.class.getName() + ".decay", "0.9")); /** * Load statistics clock cycle in milliseconds. Specify a small value for quickly debugging this feature and node provisioning through cloud. */ - @SuppressFBWarnings("MS_SHOULD_BE_FINAL") - public static int CLOCK = SystemProperties.getInteger(LoadStatistics.class.getName() + ".clock", (int)TimeUnit.SECONDS.toMillis(10)); + @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "for script console") + public static int CLOCK = SystemProperties.getInteger(LoadStatistics.class.getName() + ".clock", (int) TimeUnit.SECONDS.toMillis(10)); /** * Periodically update the load statistics average. */ @Extension @Symbol("loadStatistics") public static class LoadStatisticsUpdater extends PeriodicWork { + @Override public long getRecurrencePeriod() { return CLOCK; } + @Override protected void doRun() { Jenkins j = Jenkins.get(); List bis = j.getQueue().getBuildableItems(); // update statistics on agents - for( Label l : j.getLabels() ) { + for (Label l : j.getLabels()) { l.loadStatistics.updateCounts(l.loadStatistics.computeSnapshot(bis)); } @@ -406,7 +409,7 @@ protected void doRun() { } private int count(List bis, Label l) { - int q=0; + int q = 0; for (Queue.BuildableItem bi : bis) { for (SubTask st : bi.task.getSubTasks()) { if (bi.getAssignedLabelFor(st) == l) { diff --git a/core/src/main/java/hudson/model/ManageJenkinsAction.java b/core/src/main/java/hudson/model/ManageJenkinsAction.java index 81b331dedbcf..605801c42e1d 100644 --- a/core/src/main/java/hudson/model/ManageJenkinsAction.java +++ b/core/src/main/java/hudson/model/ManageJenkinsAction.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import hudson.Extension; @@ -32,19 +33,22 @@ * * @author Kohsuke Kawaguchi */ -@Extension(ordinal=100) @Symbol("manageJenkins") +@Extension(ordinal = 100) @Symbol("manageJenkins") public class ManageJenkinsAction implements RootAction { + @Override public String getIconFileName() { if (Jenkins.get().hasAnyPermission(Jenkins.MANAGE, Jenkins.SYSTEM_READ)) - return "gear2.png"; + return "symbol-settings"; else return null; } + @Override public String getDisplayName() { return Messages.ManageJenkinsAction_DisplayName(); } + @Override public String getUrlName() { return "/manage"; } diff --git a/core/src/main/java/hudson/model/ManagementLink.java b/core/src/main/java/hudson/model/ManagementLink.java index 5564a92d9e90..666c2fd12539 100644 --- a/core/src/main/java/hudson/model/ManagementLink.java +++ b/core/src/main/java/hudson/model/ManagementLink.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,27 +21,25 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; -import hudson.ExtensionPoint; -import hudson.ExtensionListView; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.Extension; import hudson.ExtensionList; +import hudson.ExtensionListView; +import hudson.ExtensionPoint; import hudson.security.Permission; -import jenkins.model.Jenkins; - import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; - +import jenkins.model.Jenkins; import org.jvnet.localizer.Localizable; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.interceptor.RequirePOST; -import edu.umd.cs.findbugs.annotations.CheckForNull; -import edu.umd.cs.findbugs.annotations.NonNull; - /** * Extension point to add icon to {@code http://server/hudson/manage} page. * @@ -60,14 +58,14 @@ public abstract class ManagementLink implements ExtensionPoint, Action { /** * Mostly works like {@link Action#getIconFileName()}, except that - * the expected icon size is 48x48, not 24x24. So if you give - * just a file name, "/images/48x48" will be assumed. + * the expected icon format is SVG. So if you give just a file name, "/images/svgs" will be assumed. * * @return * As a special case, return null to exclude this object from the management link. * This is useful for defining {@link ManagementLink} that only shows up under * certain circumstances. */ + @Override public abstract @CheckForNull String getIconFileName(); /** @@ -160,7 +158,7 @@ public boolean getRequiresPOST() { try { return Category.valueOf(getCategoryName()); } catch (RuntimeException e) { - LOGGER.log(Level.WARNING, "invalid category {0} for class {1}", new Object[]{getCategoryName() , this.getClass().getName()}); + LOGGER.log(Level.WARNING, "invalid category {0} for class {1}", new Object[]{getCategoryName(), this.getClass().getName()}); return Category.UNCATEGORIZED; } } @@ -190,7 +188,9 @@ public enum Category { */ TROUBLESHOOTING(Messages._ManagementLink_Category_TROUBLESHOOTING()), /** - * Tools are specifically tools for administrators, such as the Jenkins CLI and Script Console, as well as specific stand-alone administrative features ({@link jenkins.management.ShutdownLink}, {@link jenkins.management.ReloadLink}). + * Tools are specifically tools for administrators, + * such as the Jenkins CLI and Script Console, + * as well as specific stand-alone administrative features ({@link jenkins.management.ShutdownLink}, {@link jenkins.management.ReloadLink}). * This has nothing to do with build tools or tool installers. */ TOOLS(Messages._ManagementLink_Category_TOOLS()), @@ -203,7 +203,7 @@ public enum Category { */ UNCATEGORIZED(Messages._ManagementLink_Category_UNCATEGORIZED()); - private Localizable label; + private final Localizable label; Category(Localizable label) { this.label = label; diff --git a/core/src/main/java/hudson/model/ModelObject.java b/core/src/main/java/hudson/model/ModelObject.java index 3c71f1edd892..a25298d6cfee 100644 --- a/core/src/main/java/hudson/model/ModelObject.java +++ b/core/src/main/java/hudson/model/ModelObject.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import jenkins.security.stapler.StaplerAccessibleType; diff --git a/core/src/main/java/hudson/model/ModifiableItemGroup.java b/core/src/main/java/hudson/model/ModifiableItemGroup.java index bad275b7770b..726a0455dc74 100644 --- a/core/src/main/java/hudson/model/ModifiableItemGroup.java +++ b/core/src/main/java/hudson/model/ModifiableItemGroup.java @@ -21,14 +21,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import java.io.IOException; +import javax.servlet.ServletException; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; -import javax.servlet.ServletException; -import java.io.IOException; - /** * {@link ItemGroup} that is a general purpose container, which allows users and the rest of the program * to create arbitrary items into it. @@ -45,5 +45,5 @@ public interface ModifiableItemGroup extends ItemGroup { * The request format follows that of {@code <n:form xmlns:n="/lib/form">}. * */ - T doCreateItem( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException; + T doCreateItem(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException; } diff --git a/core/src/main/java/hudson/model/ModifiableViewGroup.java b/core/src/main/java/hudson/model/ModifiableViewGroup.java index 893318904f64..155f67cc4a17 100644 --- a/core/src/main/java/hudson/model/ModifiableViewGroup.java +++ b/core/src/main/java/hudson/model/ModifiableViewGroup.java @@ -21,11 +21,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package hudson.model; -import java.io.IOException; +package hudson.model; import edu.umd.cs.findbugs.annotations.NonNull; +import java.io.IOException; /** * {@link ViewGroup} that can be modified. diff --git a/core/src/main/java/hudson/model/MultiStageTimeSeries.java b/core/src/main/java/hudson/model/MultiStageTimeSeries.java index ebe17d6c9d60..598c39e3406d 100644 --- a/core/src/main/java/hudson/model/MultiStageTimeSeries.java +++ b/core/src/main/java/hudson/model/MultiStageTimeSeries.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,32 +21,34 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; -import java.util.concurrent.TimeUnit; -import hudson.util.NoOverlapCategoryAxis; import hudson.util.ChartUtil; - +import hudson.util.NoOverlapCategoryAxis; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Font; +import java.io.IOException; import java.io.Serializable; import java.text.DateFormat; import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Arrays; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; import java.util.List; -import java.io.IOException; -import java.awt.*; import java.util.Locale; - -import org.jfree.data.category.DefaultCategoryDataset; -import org.jfree.chart.JFreeChart; +import java.util.concurrent.TimeUnit; +import javax.servlet.ServletException; import org.jfree.chart.ChartFactory; +import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.CategoryAxis; import org.jfree.chart.axis.CategoryLabelPositions; import org.jfree.chart.axis.NumberAxis; -import org.jfree.chart.renderer.category.LineAndShapeRenderer; -import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.plot.CategoryPlot; +import org.jfree.chart.plot.PlotOrientation; +import org.jfree.chart.renderer.category.LineAndShapeRenderer; +import org.jfree.data.category.DefaultCategoryDataset; import org.jfree.ui.RectangleInsets; import org.jvnet.localizer.Localizable; import org.kohsuke.stapler.HttpResponse; @@ -55,8 +57,6 @@ import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; -import javax.servlet.ServletException; - /** * Maintains several {@link TimeSeries} with different update frequencies to satisfy three goals; * (1) retain data over long timespan, (2) save memory, and (3) retain accurate data for the recent past. @@ -108,17 +108,17 @@ public MultiStageTimeSeries(Localizable title, Color color, float initialValue, */ @Deprecated public MultiStageTimeSeries(float initialValue, float decay) { - this(Messages._MultiStageTimeSeries_EMPTY_STRING(), Color.WHITE, initialValue,decay); + this(Messages._MultiStageTimeSeries_EMPTY_STRING(), Color.WHITE, initialValue, decay); } /** * Call this method every 10 sec and supply a new data point. */ public void update(float f) { - counter = (counter+1)%360; // 1hour/10sec = 60mins/10sec=3600secs/10sec = 360 + counter = (counter + 1) % 360; // 1hour/10sec = 60mins/10sec=3600secs/10sec = 360 sec10.update(f); - if(counter%6==0) min.update(f); - if(counter==0) hour.update(f); + if (counter % 6 == 0) min.update(f); + if (counter == 0) hour.update(f); } /** @@ -179,7 +179,7 @@ public DateFormat createDateFormat() { * Parses the {@link TimeScale} from the query parameter. */ public static TimeScale parse(String type) { - if(type==null) return TimeScale.MIN; + if (type == null) return TimeScale.MIN; return Enum.valueOf(TimeScale.class, type.toUpperCase(Locale.ENGLISH)); } } @@ -211,18 +211,18 @@ protected DefaultCategoryDataset createDataset() { int dataLength = dataPoints[0].length; for (float[] dataPoint : dataPoints) - assert dataLength ==dataPoint.length; + assert dataLength == dataPoint.length; DefaultCategoryDataset ds = new DefaultCategoryDataset(); DateFormat format = timeScale.createDateFormat(); - Date dt = new Date(System.currentTimeMillis()-timeScale.tick*dataLength); - for (int i = dataLength-1; i>=0; i--) { - dt = new Date(dt.getTime()+timeScale.tick); + Date dt = new Date(System.currentTimeMillis() - timeScale.tick * dataLength); + for (int i = dataLength - 1; i >= 0; i--) { + dt = new Date(dt.getTime() + timeScale.tick); String l = format.format(dt); - for(int j=0; j ig = getOwner().getItemGroup(); if (ig instanceof ModifiableItemGroup) { - return ((ModifiableItemGroup)ig).doCreateItem(req, rsp); + return ((ModifiableItemGroup) ig).doCreateItem(req, rsp); } return null; } diff --git a/core/src/main/java/hudson/model/MyViewsProperty.java b/core/src/main/java/hudson/model/MyViewsProperty.java index b8f721359de1..4d3e4cdaec21 100644 --- a/core/src/main/java/hudson/model/MyViewsProperty.java +++ b/core/src/main/java/hudson/model/MyViewsProperty.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2010, Sun Microsystems, Inc., Tom Huybrechts - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,8 +21,10 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import edu.umd.cs.findbugs.annotations.CheckForNull; import hudson.Extension; import hudson.Util; import hudson.model.Descriptor.FormException; @@ -30,20 +32,15 @@ import hudson.util.FormValidation; import hudson.views.MyViewsTabBar; import hudson.views.ViewsTabBar; - import java.io.IOException; import java.text.ParseException; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; - -import edu.umd.cs.findbugs.annotations.CheckForNull; import javax.servlet.ServletException; - import jenkins.model.Jenkins; import net.sf.json.JSONObject; - import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; @@ -103,9 +100,14 @@ public Object readResolve() { } viewGroupMixIn = new ViewGroupMixIn(this) { + @Override protected List views() { return views; } + + @Override protected String primaryView() { return primaryViewName; } - protected void primaryView(String name) { primaryViewName=name; } + + @Override + protected void primaryView(String name) { primaryViewName = name; } }; return this; @@ -130,32 +132,39 @@ public User getUser() { } ///// ViewGroup methods ///// + @Override public String getUrl() { return user.getUrl() + "/my-views/"; } + @Override public void save() throws IOException { user.save(); } + @Override public Collection getViews() { return viewGroupMixIn.getViews(); } + @Override public View getView(String name) { return viewGroupMixIn.getView(name); } + @Override public boolean canDelete(View view) { return viewGroupMixIn.canDelete(view); } + @Override public void deleteView(View view) throws IOException { viewGroupMixIn.deleteView(view); } + @Override public void onViewRenamed(View view, String oldName, String newName) { - viewGroupMixIn.onViewRenamed(view,oldName,newName); + viewGroupMixIn.onViewRenamed(view, oldName, newName); } @Override @@ -190,29 +199,33 @@ public FormValidation doViewExistsCheck(@QueryParameter String value, @QueryPara String view = Util.fixEmpty(value); if (view == null) return FormValidation.ok(); if (exists) { - return (getView(view)!=null) ? - FormValidation.ok() : - FormValidation.error(Messages.MyViewsProperty_ViewExistsCheck_NotExist(view)); + return getView(view) != null ? + FormValidation.ok() : + FormValidation.error(Messages.MyViewsProperty_ViewExistsCheck_NotExist(view)); } else { - return (getView(view)==null) ? - FormValidation.ok() : - FormValidation.error(Messages.MyViewsProperty_ViewExistsCheck_AlreadyExists(view)); + return getView(view) == null ? + FormValidation.ok() : + FormValidation.error(Messages.MyViewsProperty_ViewExistsCheck_AlreadyExists(view)); } } + @Override public ACL getACL() { return user.getACL(); } ///// Action methods ///// + @Override public String getDisplayName() { return Messages.MyViewsProperty_DisplayName(); } + @Override public String getIconFileName() { return "user.png"; } + @Override public String getUrlName() { return "my-views"; } @@ -230,13 +243,14 @@ public UserProperty newInstance(User user) { return new MyViewsProperty(); } } - + @Override public UserProperty reconfigure(StaplerRequest req, JSONObject form) throws FormException { - req.bindJSON(this, form); - return this; + req.bindJSON(this, form); + return this; } + @Override public ViewsTabBar getViewsTabBar() { return Jenkins.get().getViewsTabBar(); } @@ -247,6 +261,7 @@ public List getViewActions() { return Collections.emptyList(); } + @Override public Object getStaplerFallback() { return getPrimaryView(); } @@ -254,27 +269,30 @@ public Object getStaplerFallback() { public MyViewsTabBar getMyViewsTabBar() { return Jenkins.get().getMyViewsTabBar(); } - + @Extension @Symbol("myView") public static class GlobalAction implements RootAction { - public String getDisplayName() { - return Messages.MyViewsProperty_GlobalAction_DisplayName(); - } - - public String getIconFileName() { - // do not show when not logged in - if (User.current() == null ) { - return null; - } - - return "user.png"; - } - - public String getUrlName() { - return "/me/my-views"; - } - + @Override + public String getDisplayName() { + return Messages.MyViewsProperty_GlobalAction_DisplayName(); + } + + @Override + public String getIconFileName() { + // do not show when not logged in + if (User.current() == null) { + return null; + } + + return "user.png"; + } + + @Override + public String getUrlName() { + return "/me/my-views"; + } + } - + } diff --git a/core/src/main/java/hudson/model/NoFingerprintMatch.java b/core/src/main/java/hudson/model/NoFingerprintMatch.java index 64bef6af48fa..7249e0155128 100644 --- a/core/src/main/java/hudson/model/NoFingerprintMatch.java +++ b/core/src/main/java/hudson/model/NoFingerprintMatch.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; /** @@ -33,6 +34,7 @@ public NoFingerprintMatch(String md5sum) { this.md5sum = md5sum; } + @Override public String getDisplayName() { return md5sum; } diff --git a/core/src/main/java/hudson/model/Node.java b/core/src/main/java/hudson/model/Node.java index 14e411f455a3..7ec5ee73b307 100644 --- a/core/src/main/java/hudson/model/Node.java +++ b/core/src/main/java/hudson/model/Node.java @@ -22,9 +22,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import com.infradna.tool.bridge_method_injector.WithBridgeMethods; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.Extension; import hudson.ExtensionPoint; @@ -59,8 +62,6 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.logging.Level; import java.util.logging.Logger; -import edu.umd.cs.findbugs.annotations.CheckForNull; -import edu.umd.cs.findbugs.annotations.NonNull; import jenkins.model.Jenkins; import jenkins.util.SystemProperties; import jenkins.util.io.OnMaster; @@ -98,8 +99,8 @@ public abstract class Node extends AbstractModelObject implements Reconfigurable private static final Logger LOGGER = Logger.getLogger(Node.class.getName()); - /** @see JENKINS-46652 */ - @SuppressFBWarnings("MS_SHOULD_BE_FINAL") + /** @see JENKINS-46652 */ + @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "for script console") public static /* not final */ boolean SKIP_BUILD_CHECK_ON_FLYWEIGHTS = SystemProperties.getBoolean(Node.class.getName() + ".SKIP_BUILD_CHECK_ON_FLYWEIGHTS", true); /** @@ -108,10 +109,12 @@ public abstract class Node extends AbstractModelObject implements Reconfigurable */ protected transient volatile boolean holdOffLaunchUntilSave; + @Override public String getDisplayName() { return getNodeName(); // default implementation } + @Override public String getSearchUrl() { Computer c = toComputer(); if (c != null) { @@ -147,7 +150,7 @@ public void save() throws IOException { * @return * "" if this is master */ - @Exported(visibility=999) + @Exported(visibility = 999) @NonNull public abstract String getNodeName(); @@ -216,12 +219,12 @@ public final Computer toComputer() { @CheckForNull public final VirtualChannel getChannel() { Computer c = toComputer(); - return c==null ? null : c.getChannel(); + return c == null ? null : c.getChannel(); } /** * Creates a new {@link Computer} object that acts as the UI peer of this {@link Node}. - * + * * Nobody but {@link Jenkins#updateComputerList()} should call this method. * @return Created instance of the computer. * Can be {@code null} if the {@link Node} implementation does not support it (e.g. {@link Cloud} agent). @@ -256,7 +259,7 @@ public void onOnline(Computer c, TaskListener listener) { // At startup, we need to restore any previously in-effect temp offline cause. // We wait until the computer is started rather than getting the data to it sooner // so that the normal computer start up processing works as expected. - if (node!= null && node.temporaryOfflineCause != null && node.temporaryOfflineCause != c.getOfflineCause()) { + if (node != null && node.temporaryOfflineCause != null && node.temporaryOfflineCause != c.getOfflineCause()) { c.setTemporarilyOffline(true, node.temporaryOfflineCause); } } @@ -279,6 +282,16 @@ void setTemporaryOfflineCause(OfflineCause cause) { } } + /** + * Get the cause if temporary offline. + * + * @return null if not temporary offline or there was no cause given. + * @since 2.340 + */ + public OfflineCause getTemporaryOfflineCause() { + return temporaryOfflineCause; + } + /** * Return the possibly empty tag cloud for the labels of this node. */ @@ -295,6 +308,7 @@ public TagCloud getLabelCloud() { * and should be called after events that will change that - e.g. a agent * connecting. */ + @Exported public Set getAssignedLabels() { Set r = Label.parse(getLabelString()); @@ -307,7 +321,6 @@ public Set getAssignedLabels() { * Return all the labels assigned dynamically to this node. * This calls all the LabelFinder implementations with the node converts * the results into Labels. - * @return HashSet

    - * If you are a {@link BuildStep}, most likely you should call {@link AbstractBuild#getBuildVariableResolver()}. + * If you are a {@link BuildStep}, most likely you should call {@link AbstractBuild#getBuildVariableResolver()}. */ - public VariableResolver createVariableResolver(AbstractBuild build) { - VariableResolver[] resolvers = new VariableResolver[getParameters().size()+1]; - int i=0; + public VariableResolver createVariableResolver(AbstractBuild build) { + VariableResolver[] resolvers = new VariableResolver[getParameters().size() + 1]; + int i = 0; for (ParameterValue p : getParameters()) { if (p == null) continue; resolvers[i++] = p.createVariableResolver(build); } - + resolvers[i] = build.getBuildVariableResolver(); return new VariableResolver.Union(resolvers); } - + + @Override public Iterator iterator() { return getParameters().iterator(); } - @Exported(visibility=2) + @Exported(visibility = 2) public List getParameters() { return Collections.unmodifiableList(filter(parameters)); } @@ -190,23 +191,27 @@ public ParameterValue getParameter(String name) { return null; } + @Override public Label getAssignedLabel(SubTask task) { for (ParameterValue p : getParameters()) { if (p == null) continue; Label l = p.getAssignedLabel(task); - if (l!=null) return l; + if (l != null) return l; } return null; } + @Override public String getDisplayName() { return Messages.ParameterAction_DisplayName(); } + @Override public String getIconFileName() { return "document-properties.png"; } + @Override public String getUrlName() { return "parameters"; } @@ -214,6 +219,7 @@ public String getUrlName() { /** * Allow an other build of the same project to be scheduled, if it has other parameters. */ + @Override public boolean shouldSchedule(List actions) { List others = Util.filter(actions, ParametersAction.class); if (others.isEmpty()) { @@ -221,7 +227,7 @@ public boolean shouldSchedule(List actions) { } else { // I don't think we need multiple ParametersActions, but let's be defensive Set params = new HashSet<>(); - for (ParametersAction other: others) { + for (ParametersAction other : others) { params.addAll(other.parameters); } return !params.equals(new HashSet<>(this.parameters)); @@ -235,7 +241,7 @@ public boolean shouldSchedule(List actions) { */ @NonNull public ParametersAction createUpdated(Collection overrides) { - if(overrides == null) { + if (overrides == null) { ParametersAction parametersAction = new ParametersAction(parameters); parametersAction.safeParameters = this.safeParameters; return parametersAction; @@ -243,7 +249,7 @@ public ParametersAction createUpdated(Collection overr List combinedParameters = new ArrayList<>(overrides); Set names = new HashSet<>(); - for(ParameterValue v : overrides) { + for (ParameterValue v : overrides) { if (v == null) continue; names.add(v.getName()); } @@ -280,6 +286,7 @@ public ParametersAction merge(@CheckForNull ParametersAction overrides) { return parametersAction; } + @SuppressFBWarnings(value = "RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE", justification = "parameters in readResolve is needed for data migration.") private Object readResolve() { if (parameters == null) { // JENKINS-39495 parameters = Collections.emptyList(); diff --git a/core/src/main/java/hudson/model/ParametersDefinitionProperty.java b/core/src/main/java/hudson/model/ParametersDefinitionProperty.java index 5eb80076d414..e09131c268a3 100644 --- a/core/src/main/java/hudson/model/ParametersDefinitionProperty.java +++ b/core/src/main/java/hudson/model/ParametersDefinitionProperty.java @@ -1,19 +1,19 @@ /* * The MIT License - * + * * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, * Jean-Baptiste Quenot, Seiji Sogabe, Tom Huybrechts - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -22,11 +22,18 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import static javax.servlet.http.HttpServletResponse.SC_CREATED; +import static javax.servlet.http.HttpServletResponse.SC_SEE_OTHER; + +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.Extension; import hudson.Util; import hudson.model.Queue.WaitingItem; +import hudson.model.queue.ScheduleResult; import java.io.IOException; import java.util.AbstractList; import java.util.ArrayList; @@ -35,10 +42,7 @@ import java.util.Collections; import java.util.List; import java.util.concurrent.TimeUnit; -import edu.umd.cs.findbugs.annotations.CheckForNull; -import edu.umd.cs.findbugs.annotations.NonNull; import javax.servlet.ServletException; -import static javax.servlet.http.HttpServletResponse.SC_CREATED; import jenkins.model.Jenkins; import jenkins.model.OptionalJobProperty; import jenkins.model.ParameterizedJobMixIn; @@ -64,7 +68,7 @@ *

    The owning job needs a {@code sidepanel.jelly} and should have web methods delegating to {@link ParameterizedJobMixIn#doBuild} and {@link ParameterizedJobMixIn#doBuildWithParameters}. * The builds also need a {@code sidepanel.jelly}. */ -@ExportedBean(defaultVisibility=2) +@ExportedBean(defaultVisibility = 2) public class ParametersDefinitionProperty extends OptionalJobProperty> implements Action { @@ -84,7 +88,7 @@ private Object readResolve() { } @Deprecated - public AbstractProject getOwner() { + public AbstractProject getOwner() { return (AbstractProject) owner; } @@ -134,12 +138,12 @@ public void _doBuild(StaplerRequest req, StaplerResponse rsp) throws IOException * This method is supposed to be invoked from {@link ParameterizedJobMixIn#doBuild(StaplerRequest, StaplerResponse, TimeDuration)}. */ public void _doBuild(StaplerRequest req, StaplerResponse rsp, @QueryParameter TimeDuration delay) throws IOException, ServletException { - if (delay==null) - delay=new TimeDuration(TimeUnit.MILLISECONDS.convert(getJob().getQuietPeriod(), TimeUnit.SECONDS)); + if (delay == null) + delay = new TimeDuration(TimeUnit.MILLISECONDS.convert(getJob().getQuietPeriod(), TimeUnit.SECONDS)); List values = new ArrayList<>(); - + JSONObject formData = req.getSubmittedForm(); JSONArray a = JSONArray.fromObject(formData.get("parameter")); @@ -148,7 +152,7 @@ public void _doBuild(StaplerRequest req, StaplerResponse rsp, @QueryParameter Ti String name = jo.getString("name"); ParameterDefinition d = getParameterDefinition(name); - if(d==null) + if (d == null) throw new IllegalArgumentException("No such parameter definition: " + name); ParameterValue parameterValue = d.createValue(req, jo); if (parameterValue != null) { @@ -158,13 +162,13 @@ public void _doBuild(StaplerRequest req, StaplerResponse rsp, @QueryParameter Ti } } - WaitingItem item = Jenkins.get().getQueue().schedule( + WaitingItem item = Jenkins.get().getQueue().schedule( getJob(), delay.getTimeInSeconds(), new ParametersAction(values), new CauseAction(new Cause.UserIdCause())); - if (item!=null) { + if (item != null) { String url = formData.optString("redirectTo"); - if (url==null || !Util.isSafeToRedirectTo(url)) // avoid open redirect - url = req.getContextPath()+'/'+item.getUrl(); - rsp.sendRedirect(formData.optInt("statusCode",SC_CREATED), url); + if (url == null || !Util.isSafeToRedirectTo(url)) // avoid open redirect + url = req.getContextPath() + '/' + item.getUrl(); + rsp.sendRedirect(formData.optInt("statusCode", SC_CREATED), url); } else // send the user back to the job top page. rsp.sendRedirect("."); @@ -173,28 +177,33 @@ public void _doBuild(StaplerRequest req, StaplerResponse rsp, @QueryParameter Ti /** @deprecated use {@link #buildWithParameters(StaplerRequest, StaplerResponse, TimeDuration)} */ @Deprecated public void buildWithParameters(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { - buildWithParameters(req,rsp,TimeDuration.fromString(req.getParameter("delay"))); + buildWithParameters(req, rsp, TimeDuration.fromString(req.getParameter("delay"))); } public void buildWithParameters(StaplerRequest req, StaplerResponse rsp, @CheckForNull TimeDuration delay) throws IOException, ServletException { List values = new ArrayList<>(); - for (ParameterDefinition d: parameterDefinitions) { - ParameterValue value = d.createValue(req); - if (value != null) { - values.add(value); - } + for (ParameterDefinition d : parameterDefinitions) { + ParameterValue value = d.createValue(req); + if (value != null) { + values.add(value); + } } - if (delay==null) - delay=new TimeDuration(TimeUnit.MILLISECONDS.convert(getJob().getQuietPeriod(), TimeUnit.SECONDS)); + if (delay == null) + delay = new TimeDuration(TimeUnit.MILLISECONDS.convert(getJob().getQuietPeriod(), TimeUnit.SECONDS)); - Queue.Item item = Jenkins.get().getQueue().schedule2( - getJob(), delay.getTimeInSeconds(), new ParametersAction(values), ParameterizedJobMixIn.getBuildCause(getJob(), req)).getItem(); + ScheduleResult scheduleResult = Jenkins.get().getQueue().schedule2( + getJob(), delay.getTimeInSeconds(), new ParametersAction(values), ParameterizedJobMixIn.getBuildCause(getJob(), req)); + Queue.Item item = scheduleResult.getItem(); + if (item != null && !scheduleResult.isCreated()) { + rsp.sendRedirect(SC_SEE_OTHER, req.getContextPath() + '/' + item.getUrl()); + return; + } if (item != null) { rsp.sendRedirect(SC_CREATED, req.getContextPath() + '/' + item.getUrl()); - } else { - rsp.sendRedirect("."); + return; } + rsp.sendRedirect("."); } /** @@ -213,7 +222,7 @@ public ParameterDefinition getParameterDefinition(String name) { public static class DescriptorImpl extends OptionalJobPropertyDescriptor { @Override public ParametersDefinitionProperty newInstance(StaplerRequest req, JSONObject formData) throws FormException { - ParametersDefinitionProperty prop = (ParametersDefinitionProperty)super.newInstance(req, formData); + ParametersDefinitionProperty prop = (ParametersDefinitionProperty) super.newInstance(req, formData); if (prop != null && prop.parameterDefinitions.isEmpty()) { return null; } @@ -231,14 +240,17 @@ public String getDisplayName() { } } + @Override public String getDisplayName() { return null; } + @Override public String getIconFileName() { return null; } + @Override public String getUrlName() { return null; } @@ -250,10 +262,12 @@ private static class DefinitionsAbstractList extends AbstractList { this.parameterDefinitions = parameterDefinitions; } + @Override public String get(int index) { return this.parameterDefinitions.get(index).getName(); } + @Override public int size() { return this.parameterDefinitions.size(); } diff --git a/core/src/main/java/hudson/model/PasswordParameterDefinition.java b/core/src/main/java/hudson/model/PasswordParameterDefinition.java index ff3464e6206c..58846ac4a2b5 100644 --- a/core/src/main/java/hudson/model/PasswordParameterDefinition.java +++ b/core/src/main/java/hudson/model/PasswordParameterDefinition.java @@ -21,19 +21,22 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; -import net.sf.json.JSONObject; -import org.jenkinsci.Symbol; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.DataBoundConstructor; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.Extension; import hudson.util.Secret; +import java.util.Objects; +import net.sf.json.JSONObject; +import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.DoNotUse; import org.kohsuke.accmod.restrictions.NoExternalUse; - -import java.util.Objects; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.StaplerRequest; /** * Parameter whose value is a {@link Secret} and is hidden from the UI. @@ -49,14 +52,14 @@ public class PasswordParameterDefinition extends SimpleParameterDefinition { private Secret defaultValue; @Deprecated - public PasswordParameterDefinition(String name, String defaultValue, String description) { + public PasswordParameterDefinition(@NonNull String name, @CheckForNull String defaultValue, @CheckForNull String description) { super(name, description); this.defaultValue = Secret.fromString(defaultValue); } // TODO consider switching @DataBoundConstructor to a PasswordParameterDefinition(String) overload @DataBoundConstructor - public PasswordParameterDefinition(String name, Secret defaultValueAsSecret, String description) { + public PasswordParameterDefinition(@NonNull String name, @CheckForNull Secret defaultValueAsSecret, @CheckForNull String description) { super(name, description); this.defaultValue = defaultValueAsSecret; } @@ -91,6 +94,7 @@ public ParameterValue getDefaultParameterValue() { return new PasswordParameterValue(getName(), getDefaultValue(), getDescription()); } + @NonNull public String getDefaultValue() { return Secret.toString(defaultValue); } @@ -114,6 +118,7 @@ public int hashCode() { } @Override + @SuppressFBWarnings(value = "EQ_GETCLASS_AND_CLASS_CONSTANT", justification = "ParameterDefinitionTest tests that subclasses are not equal to their parent classes, so the behavior appears to be intentional") public boolean equals(Object obj) { if (PasswordParameterDefinition.class != getClass()) return super.equals(obj); @@ -131,7 +136,7 @@ public boolean equals(Object obj) { return Objects.equals(defaultValue, other.defaultValue); } - @Extension @Symbol({"password"}) + @Extension @Symbol("password") public static final class ParameterDescriptorImpl extends ParameterDescriptor { @Override public String getDisplayName() { diff --git a/core/src/main/java/hudson/model/PasswordParameterValue.java b/core/src/main/java/hudson/model/PasswordParameterValue.java index 39c2c34c4074..4f761587a370 100644 --- a/core/src/main/java/hudson/model/PasswordParameterValue.java +++ b/core/src/main/java/hudson/model/PasswordParameterValue.java @@ -21,15 +21,15 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.EnvVars; import hudson.util.Secret; import hudson.util.VariableResolver; -import org.kohsuke.stapler.DataBoundConstructor; - import java.util.Locale; -import edu.umd.cs.findbugs.annotations.NonNull; +import org.kohsuke.stapler.DataBoundConstructor; /** * @author Kohsuke Kawaguchi @@ -57,19 +57,15 @@ public PasswordParameterValue(String name, Secret value, String description) { } @Override - public void buildEnvironment(Run build, EnvVars env) { + public void buildEnvironment(Run build, EnvVars env) { String v = Secret.toString(value); env.put(name, v); - env.put(name.toUpperCase(Locale.ENGLISH),v); // backward compatibility pre 1.345 + env.put(name.toUpperCase(Locale.ENGLISH), v); // backward compatibility pre 1.345 } @Override public VariableResolver createVariableResolver(AbstractBuild build) { - return new VariableResolver() { - public String resolve(String name) { - return PasswordParameterValue.this.name.equals(name) ? Secret.toString(value) : null; - } - }; + return name -> PasswordParameterValue.this.name.equals(name) ? Secret.toString(value) : null; } @Override diff --git a/core/src/main/java/hudson/model/PeriodicWork.java b/core/src/main/java/hudson/model/PeriodicWork.java index fe010efd207c..3a5bb3b4f01f 100644 --- a/core/src/main/java/hudson/model/PeriodicWork.java +++ b/core/src/main/java/hudson/model/PeriodicWork.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,24 +21,25 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import static hudson.init.InitMilestone.JOB_CONFIG_ADAPTED; + +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import hudson.Extension; +import hudson.ExtensionList; import hudson.ExtensionListListener; +import hudson.ExtensionPoint; import hudson.init.Initializer; import hudson.triggers.SafeTimerTask; -import hudson.ExtensionPoint; -import hudson.Extension; -import hudson.ExtensionList; -import jenkins.util.Timer; - +import hudson.triggers.Trigger; import java.util.HashSet; +import java.util.Random; import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.logging.Logger; -import java.util.Random; - -import static hudson.init.InitMilestone.JOB_CONFIG_ADAPTED; -import hudson.triggers.Trigger; +import jenkins.util.Timer; /** * Extension point to perform a periodic task in Hudson (through {@link Timer}.) @@ -53,11 +54,12 @@ * *

    * This class is designed to run a short task. Implementations whose periodic work takes a long time - * to run should extend from {@link AsyncPeriodicWork} instead. + * to run should extend from {@link AsyncPeriodicWork} instead. * * @author Kohsuke Kawaguchi * @see AsyncPeriodicWork */ +@SuppressFBWarnings(value = "PREDICTABLE_RANDOM", justification = "The random is just used for an initial delay.") public abstract class PeriodicWork extends SafeTimerTask implements ExtensionPoint { /** @deprecated Use your own logger, or send messages to the logger in {@link AsyncPeriodicWork#execute}. */ @@ -87,9 +89,9 @@ public abstract class PeriodicWork extends SafeTimerTask implements ExtensionPoi public long getInitialDelay() { long l = RANDOM.nextLong(); // Math.abs(Long.MIN_VALUE)==Long.MIN_VALUE! - if (l==Long.MIN_VALUE) + if (l == Long.MIN_VALUE) l++; - return Math.abs(l)%getRecurrencePeriod(); + return Math.abs(l) % getRecurrencePeriod(); } /** @@ -99,7 +101,7 @@ public static ExtensionList all() { return ExtensionList.lookup(PeriodicWork.class); } - @Initializer(after= JOB_CONFIG_ADAPTED) + @Initializer(after = JOB_CONFIG_ADAPTED) public static void init() { // start all PeriodicWorks ExtensionList extensionList = all(); @@ -114,9 +116,9 @@ private static void schedulePeriodicWork(PeriodicWork p) { } // time constants - protected static final long MIN = 1000*60; - protected static final long HOUR =60*MIN; - protected static final long DAY = 24*HOUR; + protected static final long MIN = 1000 * 60; + protected static final long HOUR = 60 * MIN; + protected static final long DAY = 24 * HOUR; private static final Random RANDOM = new Random(); diff --git a/core/src/main/java/hudson/model/PermalinkProjectAction.java b/core/src/main/java/hudson/model/PermalinkProjectAction.java index fd33bfd982cd..9013ddd5efc5 100644 --- a/core/src/main/java/hudson/model/PermalinkProjectAction.java +++ b/core/src/main/java/hudson/model/PermalinkProjectAction.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,13 +21,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package hudson.model; -import jenkins.model.PeepholePermalink; +package hudson.model; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; -import edu.umd.cs.findbugs.annotations.CheckForNull; +import jenkins.model.PeepholePermalink; /** * Optional interface for {@link Action}s that are attached @@ -51,7 +52,7 @@ public interface PermalinkProjectAction extends Action { *

    * Because {@link Permalink} is a strategy-pattern object, * this method should normally return a pre-initialized - * read-only static list object. + * read-only static list object. * * @return * can be empty, but never null. @@ -87,7 +88,7 @@ abstract class Permalink { * @return null * if the target of the permalink doesn't exist. */ - public abstract @CheckForNull Run resolve(Job job); + public abstract @CheckForNull Run resolve(Job job); /** * List of {@link Permalink}s that are built into Jenkins. @@ -95,95 +96,111 @@ abstract class Permalink { public static final List BUILTIN = new CopyOnWriteArrayList<>(); public static final Permalink LAST_BUILD = new Permalink() { + @Override public String getDisplayName() { return Messages.Permalink_LastBuild(); } + @Override public String getId() { return "lastBuild"; } - public Run resolve(Job job) { + @Override + public Run resolve(Job job) { return job.getLastBuild(); } }; public static final Permalink LAST_STABLE_BUILD = new PeepholePermalink() { + @Override public String getDisplayName() { return Messages.Permalink_LastStableBuild(); } + @Override public String getId() { return "lastStableBuild"; } @Override public boolean apply(Run run) { - return !run.isBuilding() && run.getResult()==Result.SUCCESS; + return !run.isBuilding() && run.getResult() == Result.SUCCESS; } }; public static final Permalink LAST_SUCCESSFUL_BUILD = new PeepholePermalink() { + @Override public String getDisplayName() { return Messages.Permalink_LastSuccessfulBuild(); } + @Override public String getId() { return "lastSuccessfulBuild"; } + @SuppressFBWarnings(value = "NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE", justification = "TODO needs triage") @Override public boolean apply(Run run) { return !run.isBuilding() && run.getResult().isBetterOrEqualTo(Result.UNSTABLE); } }; public static final Permalink LAST_FAILED_BUILD = new PeepholePermalink() { + @Override public String getDisplayName() { return Messages.Permalink_LastFailedBuild(); } + @Override public String getId() { return "lastFailedBuild"; } @Override public boolean apply(Run run) { - return !run.isBuilding() && run.getResult()==Result.FAILURE; + return !run.isBuilding() && run.getResult() == Result.FAILURE; } }; public static final Permalink LAST_UNSTABLE_BUILD = new PeepholePermalink() { + @Override public String getDisplayName() { return Messages.Permalink_LastUnstableBuild(); } + @Override public String getId() { return "lastUnstableBuild"; } @Override public boolean apply(Run run) { - return !run.isBuilding() && run.getResult()==Result.UNSTABLE; + return !run.isBuilding() && run.getResult() == Result.UNSTABLE; } }; public static final Permalink LAST_UNSUCCESSFUL_BUILD = new PeepholePermalink() { + @Override public String getDisplayName() { return Messages.Permalink_LastUnsuccessfulBuild(); } + @Override public String getId() { return "lastUnsuccessfulBuild"; } @Override public boolean apply(Run run) { - return !run.isBuilding() && run.getResult()!=Result.SUCCESS; + return !run.isBuilding() && run.getResult() != Result.SUCCESS; } }; public static final Permalink LAST_COMPLETED_BUILD = new PeepholePermalink() { + @Override public String getDisplayName() { return Messages.Permalink_LastCompletedBuild(); } + @Override public String getId() { return "lastCompletedBuild"; } diff --git a/core/src/main/java/hudson/model/PersistenceRoot.java b/core/src/main/java/hudson/model/PersistenceRoot.java index 4e417d053963..759094428f34 100644 --- a/core/src/main/java/hudson/model/PersistenceRoot.java +++ b/core/src/main/java/hudson/model/PersistenceRoot.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import java.io.File; diff --git a/core/src/main/java/hudson/model/PersistentDescriptor.java b/core/src/main/java/hudson/model/PersistentDescriptor.java index 80a2f829e491..908752151279 100644 --- a/core/src/main/java/hudson/model/PersistentDescriptor.java +++ b/core/src/main/java/hudson/model/PersistentDescriptor.java @@ -1,6 +1,6 @@ package hudson.model; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; /** * Marker interface for Descriptors which use xml persistent data, and as such need to load from disk when instantiated. diff --git a/core/src/main/java/hudson/model/Project.java b/core/src/main/java/hudson/model/Project.java index ff1119b5e234..7dc8b692d940 100644 --- a/core/src/main/java/hudson/model/Project.java +++ b/core/src/main/java/hudson/model/Project.java @@ -1,19 +1,19 @@ /* * The MIT License - * + * * Copyright (c) 2004-2011, Sun Microsystems, Inc., Kohsuke Kawaguchi, * Jorg Heymans, Stephen Connolly, Tom Huybrechts - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -22,6 +22,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import hudson.Util; @@ -32,18 +33,13 @@ import hudson.tasks.BuildWrappers; import hudson.tasks.Builder; import hudson.tasks.Fingerprinter; -import hudson.tasks.Publisher; import hudson.tasks.Maven; -import hudson.tasks.Maven.ProjectWithMaven; import hudson.tasks.Maven.MavenInstallation; +import hudson.tasks.Maven.ProjectWithMaven; +import hudson.tasks.Publisher; import hudson.triggers.SCMTrigger; import hudson.triggers.Trigger; import hudson.util.DescribableList; -import net.sf.json.JSONObject; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; - -import javax.servlet.ServletException; import java.io.IOException; import java.util.Collection; import java.util.HashSet; @@ -53,43 +49,46 @@ import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; import java.util.logging.Level; import java.util.logging.Logger; - +import javax.servlet.ServletException; import jenkins.triggers.SCMTriggerItem; +import net.sf.json.JSONObject; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; /** * Buildable software project. * * @author Kohsuke Kawaguchi */ -public abstract class Project

    ,B extends Build> - extends AbstractProject implements SCMTriggerItem, Saveable, ProjectWithMaven, BuildableItemWithBuildWrappers { +public abstract class Project

    , B extends Build> + extends AbstractProject implements SCMTriggerItem, Saveable, ProjectWithMaven, BuildableItemWithBuildWrappers { /** * List of active {@link Builder}s configured for this project. */ - private volatile DescribableList> builders; - private static final AtomicReferenceFieldUpdater buildersSetter - = AtomicReferenceFieldUpdater.newUpdater(Project.class,DescribableList.class,"builders"); + private volatile DescribableList> builders; + private static final AtomicReferenceFieldUpdater buildersSetter + = AtomicReferenceFieldUpdater.newUpdater(Project.class, DescribableList.class, "builders"); /** * List of active {@link Publisher}s configured for this project. */ - private volatile DescribableList> publishers; - private static final AtomicReferenceFieldUpdater publishersSetter - = AtomicReferenceFieldUpdater.newUpdater(Project.class,DescribableList.class,"publishers"); + private volatile DescribableList> publishers; + private static final AtomicReferenceFieldUpdater publishersSetter + = AtomicReferenceFieldUpdater.newUpdater(Project.class, DescribableList.class, "publishers"); /** * List of active {@link BuildWrapper}s configured for this project. */ - private volatile DescribableList> buildWrappers; - private static final AtomicReferenceFieldUpdater buildWrappersSetter - = AtomicReferenceFieldUpdater.newUpdater(Project.class,DescribableList.class,"buildWrappers"); + private volatile DescribableList> buildWrappers; + private static final AtomicReferenceFieldUpdater buildWrappersSetter + = AtomicReferenceFieldUpdater.newUpdater(Project.class, DescribableList.class, "buildWrappers"); /** * Creates a new project. */ - public Project(ItemGroup parent,String name) { - super(parent,name); + protected Project(ItemGroup parent, String name) { + super(parent, name); } @Override @@ -100,6 +99,7 @@ public void onLoad(ItemGroup parent, String name) throws IOExcep getBuildWrappersList().setOwner(this); } + @Override public AbstractProject asProject() { return this; } @@ -126,31 +126,33 @@ public List getBuilders() { * Use {@link #getPublishersList()} instead. */ @Deprecated - public Map,Publisher> getPublishers() { + public Map, Publisher> getPublishers() { return getPublishersList().toMap(); } - public DescribableList> getBuildersList() { + public DescribableList> getBuildersList() { if (builders == null) { - buildersSetter.compareAndSet(this,null,new DescribableList>(this)); + buildersSetter.compareAndSet(this, null, new DescribableList>(this)); } return builders; } - - public DescribableList> getPublishersList() { + + @Override + public DescribableList> getPublishersList() { if (publishers == null) { - publishersSetter.compareAndSet(this,null,new DescribableList>(this)); + publishersSetter.compareAndSet(this, null, new DescribableList>(this)); } return publishers; } - public Map,BuildWrapper> getBuildWrappers() { + public Map, BuildWrapper> getBuildWrappers() { return getBuildWrappersList().toMap(); } + @Override public DescribableList> getBuildWrappersList() { if (buildWrappers == null) { - buildWrappersSetter.compareAndSet(this,null,new DescribableList>(this)); + buildWrappersSetter.compareAndSet(this, null, new DescribableList>(this)); } return buildWrappers; } @@ -160,9 +162,9 @@ protected Set getResourceActivities() { final Set activities = new HashSet<>(); activities.addAll(super.getResourceActivities()); - activities.addAll(Util.filter(getBuildersList(),ResourceActivity.class)); - activities.addAll(Util.filter(getPublishersList(),ResourceActivity.class)); - activities.addAll(Util.filter(getBuildWrappersList(),ResourceActivity.class)); + activities.addAll(Util.filter(getBuildersList(), ResourceActivity.class)); + activities.addAll(Util.filter(getPublishersList(), ResourceActivity.class)); + activities.addAll(Util.filter(getBuildWrappersList(), ResourceActivity.class)); return activities; } @@ -191,7 +193,7 @@ public void removePublisher(Descriptor descriptor) throws IOException public Publisher getPublisher(Descriptor descriptor) { for (Publisher p : getPublishersList()) { - if(p.getDescriptor()==descriptor) + if (p.getDescriptor() == descriptor) return p; } return null; @@ -199,19 +201,20 @@ public Publisher getPublisher(Descriptor descriptor) { @Override protected void buildDependencyGraph(DependencyGraph graph) { super.buildDependencyGraph(graph); - getPublishersList().buildDependencyGraph(this,graph); - getBuildersList().buildDependencyGraph(this,graph); - getBuildWrappersList().buildDependencyGraph(this,graph); + getPublishersList().buildDependencyGraph(this, graph); + getBuildersList().buildDependencyGraph(this, graph); + getBuildWrappersList().buildDependencyGraph(this, graph); } @Override public boolean isFingerprintConfigured() { - return getPublishersList().get(Fingerprinter.class)!=null; + return getPublishersList().get(Fingerprinter.class) != null; } + @Override public MavenInstallation inferMavenInstallation() { Maven m = getBuildersList().get(Maven.class); - if (m!=null) return m.getMaven(); + if (m != null) return m.getMaven(); return null; } @@ -221,13 +224,13 @@ public MavenInstallation inferMavenInstallation() { // // @Override - protected void submit( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException, FormException { - super.submit(req,rsp); + protected void submit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, FormException { + super.submit(req, rsp); JSONObject json = req.getSubmittedForm(); - getBuildWrappersList().rebuild(req,json, BuildWrappers.getFor(this)); - getBuildersList().rebuildHetero(req,json, Builder.all(), "builder"); + getBuildWrappersList().rebuild(req, json, BuildWrappers.getFor(this)); + getBuildersList().rebuildHetero(req, json, Builder.all(), "builder"); getPublishersList().rebuildHetero(req, json, Publisher.all(), "publisher"); } @@ -238,28 +241,28 @@ protected List createTransientActions() { for (BuildStep step : getBuildersList()) { try { r.addAll(step.getProjectActions(this)); - } catch (Exception e) { + } catch (RuntimeException e) { LOGGER.log(Level.SEVERE, "Error loading build step.", e); } } for (BuildStep step : getPublishersList()) { try { r.addAll(step.getProjectActions(this)); - } catch (Exception e) { + } catch (RuntimeException e) { LOGGER.log(Level.SEVERE, "Error loading publisher.", e); } } for (BuildWrapper step : getBuildWrappers().values()) { try { r.addAll(step.getProjectActions(this)); - } catch (Exception e) { + } catch (RuntimeException e) { LOGGER.log(Level.SEVERE, "Error loading build wrapper.", e); } } for (Trigger trigger : triggers()) { try { r.addAll(trigger.getProjectActions()); - } catch (Exception e) { + } catch (RuntimeException e) { LOGGER.log(Level.SEVERE, "Error loading trigger.", e); } } diff --git a/core/src/main/java/hudson/model/ProminentProjectAction.java b/core/src/main/java/hudson/model/ProminentProjectAction.java index 082f87580ed3..6d3e48aef31d 100644 --- a/core/src/main/java/hudson/model/ProminentProjectAction.java +++ b/core/src/main/java/hudson/model/ProminentProjectAction.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import hudson.tasks.BuildStep; diff --git a/core/src/main/java/hudson/model/ProxyView.java b/core/src/main/java/hudson/model/ProxyView.java index 18162f3231e8..3f33302744dc 100644 --- a/core/src/main/java/hudson/model/ProxyView.java +++ b/core/src/main/java/hudson/model/ProxyView.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Tom Huybrechts - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import hudson.Extension; @@ -30,7 +31,6 @@ import java.io.IOException; import java.util.Collection; import javax.servlet.ServletException; - import jenkins.model.Jenkins; import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; @@ -43,9 +43,9 @@ /** * A view that delegates to another. - * + * * TODO: this does not respond to renaming or deleting the proxied view. - * + * * @author Tom Huybrechts * */ @@ -118,9 +118,9 @@ public FormValidation doViewExistsCheck(@QueryParameter String value) { checkPermission(View.CREATE); String view = Util.fixEmpty(value); - if(view==null) return FormValidation.ok(); + if (view == null) return FormValidation.ok(); - if(Jenkins.get().getView(view)!=null) + if (Jenkins.get().getView(view) != null) return FormValidation.ok(); else return FormValidation.error(Messages.ProxyView_NoSuchViewExists(value)); @@ -133,15 +133,16 @@ public static class DescriptorImpl extends ViewDescriptor { public String getDisplayName() { return Messages.ProxyView_DisplayName(); } - + @Override public boolean isInstantiable() { - // doesn't make sense to add a ProxyView to the global views - return !(Stapler.getCurrentRequest().findAncestorObject(ViewGroup.class) instanceof Jenkins); + // doesn't make sense to add a ProxyView to the global views + return !(Stapler.getCurrentRequest().findAncestorObject(ViewGroup.class) instanceof Jenkins); } } + @Override public Object getStaplerFallback() { return getProxiedView(); } diff --git a/core/src/main/java/hudson/model/Queue.java b/core/src/main/java/hudson/model/Queue.java index ee8287810004..50ad97232bd5 100644 --- a/core/src/main/java/hudson/model/Queue.java +++ b/core/src/main/java/hudson/model/Queue.java @@ -22,66 +22,66 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import static hudson.init.InitMilestone.JOB_CONFIG_ADAPTED; +import static hudson.util.Iterators.reverse; + import com.google.common.annotations.VisibleForTesting; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import com.infradna.tool.bridge_method_injector.WithBridgeMethods; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.BulkChange; import hudson.Extension; import hudson.ExtensionList; import hudson.ExtensionPoint; import hudson.Util; import hudson.XmlFile; -import hudson.init.Initializer; - -import static hudson.init.InitMilestone.JOB_CONFIG_ADAPTED; -import static hudson.util.Iterators.reverse; - import hudson.cli.declarative.CLIResolver; +import hudson.init.Initializer; +import hudson.model.Node.Mode; import hudson.model.labels.LabelAssignmentAction; +import hudson.model.listeners.SaveableListener; +import hudson.model.queue.CauseOfBlockage; +import hudson.model.queue.CauseOfBlockage.BecauseLabelIsBusy; +import hudson.model.queue.CauseOfBlockage.BecauseLabelIsOffline; +import hudson.model.queue.CauseOfBlockage.BecauseNodeIsBusy; +import hudson.model.queue.CauseOfBlockage.BecauseNodeIsOffline; import hudson.model.queue.Executables; -import hudson.model.queue.QueueListener; -import hudson.model.queue.QueueTaskFuture; -import hudson.model.queue.ScheduleResult; -import hudson.model.queue.ScheduleResult.Created; -import hudson.model.queue.SubTask; +import hudson.model.queue.FoldableAction; import hudson.model.queue.FutureImpl; import hudson.model.queue.MappingWorksheet; import hudson.model.queue.MappingWorksheet.Mapping; +import hudson.model.queue.QueueListener; import hudson.model.queue.QueueSorter; import hudson.model.queue.QueueTaskDispatcher; +import hudson.model.queue.QueueTaskFuture; +import hudson.model.queue.ScheduleResult; +import hudson.model.queue.ScheduleResult.Created; +import hudson.model.queue.SubTask; import hudson.model.queue.Tasks; import hudson.model.queue.WorkUnit; -import hudson.model.Node.Mode; -import hudson.model.listeners.SaveableListener; -import hudson.model.queue.CauseOfBlockage; -import hudson.model.queue.FoldableAction; -import hudson.model.queue.CauseOfBlockage.BecauseLabelIsBusy; -import hudson.model.queue.CauseOfBlockage.BecauseNodeIsOffline; -import hudson.model.queue.CauseOfBlockage.BecauseLabelIsOffline; -import hudson.model.queue.CauseOfBlockage.BecauseNodeIsBusy; import hudson.model.queue.WorkUnitContext; import hudson.security.ACL; import hudson.security.AccessControlled; - import hudson.security.Permission; -import hudson.util.Futures; -import jenkins.security.QueueItemAuthenticatorProvider; -import jenkins.security.stapler.StaplerAccessibleType; -import jenkins.util.SystemProperties; -import jenkins.util.Timer; import hudson.triggers.SafeTimerTask; -import java.util.concurrent.TimeUnit; -import hudson.util.XStream2; import hudson.util.ConsistentHash; -import hudson.util.ConsistentHash.Hash; - +import hudson.util.Futures; +import hudson.util.XStream2; import java.io.File; import java.io.IOException; import java.lang.ref.WeakReference; import java.nio.channels.ClosedByInterruptException; +import java.nio.file.Files; +import java.nio.file.InvalidPathException; +import java.nio.file.StandardCopyOption; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; @@ -100,40 +100,35 @@ import java.util.TreeSet; import java.util.concurrent.Callable; import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; - -import edu.umd.cs.findbugs.annotations.NonNull; -import net.jcip.annotations.GuardedBy; import javax.servlet.ServletException; - +import javax.servlet.http.HttpServletResponse; import jenkins.model.Jenkins; +import jenkins.model.queue.AsynchronousExecution; +import jenkins.model.queue.CompositeCauseOfBlockage; import jenkins.security.QueueItemAuthenticator; +import jenkins.security.QueueItemAuthenticatorProvider; +import jenkins.security.stapler.StaplerAccessibleType; import jenkins.util.AtmostOneTaskExecutor; -import org.jenkinsci.bytecode.AdaptField; +import jenkins.util.Listeners; +import jenkins.util.SystemProperties; +import jenkins.util.Timer; +import net.jcip.annotations.GuardedBy; import org.jenkinsci.remoting.RoleChecker; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.DoNotUse; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.HttpResponses; +import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; - -import org.kohsuke.accmod.Restricted; -import org.kohsuke.accmod.restrictions.DoNotUse; - -import com.thoughtworks.xstream.XStream; -import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import edu.umd.cs.findbugs.annotations.CheckForNull; -import javax.servlet.http.HttpServletResponse; - -import jenkins.model.queue.AsynchronousExecution; -import jenkins.model.queue.CompositeCauseOfBlockage; -import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.interceptor.RequirePOST; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.core.Authentication; @@ -217,7 +212,7 @@ public class Queue extends ResourceController implements Saveable { * * This map is forgetful, since we can't remember everything that executed in the past. */ - private final Cache leftItems = CacheBuilder.newBuilder().expireAfterWrite(5*60, TimeUnit.SECONDS).build(); + private final Cache leftItems = CacheBuilder.newBuilder().expireAfterWrite(5 * 60, TimeUnit.SECONDS).build(); /** * Data structure created for each idle {@link Executor}. @@ -305,6 +300,7 @@ public boolean canTake(BuildableItem item) { /** * Is this executor ready to accept some tasks? */ + @Override public boolean isAvailable() { return workUnit == null && !executor.getOwner().isOffline() && executor.getOwner().isAcceptingTasks(); } @@ -320,7 +316,7 @@ public boolean isNotExclusive() { @Override public String toString() { - return String.format("JobOffer[%s #%d]",executor.getOwner().getName(), executor.getNumber()); + return String.format("JobOffer[%s #%d]", executor.getOwner().getName(), executor.getNumber()); } } @@ -389,7 +385,7 @@ public void load() { pendings.clear(); File queueFile = getXMLQueueFile(); - if (queueFile.exists()) { + if (Files.exists(queueFile.toPath())) { Object unmarshaledObj = new XmlFile(XSTREAM, queueFile).read(); List items; @@ -403,7 +399,7 @@ public void load() { long maxId = 0; for (Object o : items) { if (o instanceof Item) { - maxId = Math.max(maxId, ((Item)o).id); + maxId = Math.max(maxId, ((Item) o).id); } } WaitingItem.COUNTER.set(maxId); @@ -412,9 +408,9 @@ public void load() { for (Object o : items) { if (o instanceof Task) { // backward compatibility - schedule((Task)o, 0); + schedule((Task) o, 0); } else if (o instanceof Item) { - Item item = (Item)o; + Item item = (Item) o; if (item.task == null) { continue; // botched persistence. throw this one away @@ -438,11 +434,9 @@ public void load() { // I don't know how this problem happened, but to diagnose this problem better // when it happens again, save the old queue file for introspection. File bk = new File(queueFile.getPath() + ".bak"); - bk.delete(); - queueFile.renameTo(bk); - queueFile.delete(); + Files.move(queueFile.toPath(), bk.toPath(), StandardCopyOption.REPLACE_EXISTING); } - } catch (IOException e) { + } catch (IOException | InvalidPathException e) { LOGGER.log(Level.WARNING, "Failed to load the queue file " + getXMLQueueFile(), e); } finally { updateSnapshot(); } } finally { lock.unlock(); @@ -452,8 +446,9 @@ public void load() { /** * Persists the queue contents to the disk. */ + @Override public void save() { - if(BulkChange.contains(this)) return; + if (BulkChange.contains(this)) return; if (Jenkins.getInstanceOrNull() == null) { return; } @@ -466,8 +461,8 @@ public void save() { state.counter = WaitingItem.COUNTER.longValue(); // write out the tasks on the queue - for (Item item: getItems()) { - if(item.task instanceof TransientTask) continue; + for (Item item : getItems()) { + if (item.task instanceof TransientTask) continue; state.items.add(item); } @@ -511,7 +506,7 @@ public void clear() { */ @Deprecated public boolean add(AbstractProject p) { - return schedule(p)!=null; + return schedule(p) != null; } /** @@ -534,7 +529,7 @@ public boolean add(AbstractProject p) { */ @Deprecated public boolean add(AbstractProject p, int quietPeriod) { - return schedule(p, quietPeriod)!=null; + return schedule(p, quietPeriod) != null; } /** @@ -611,7 +606,7 @@ public WaitingItem schedule(Task p, int quietPeriod, List actions) { shouldScheduleItem |= action.shouldSchedule(actions); } for (QueueAction action : Util.filter(actions, QueueAction.class)) { - shouldScheduleItem |= action.shouldSchedule((new ArrayList<>(item.getAllActions()))); + shouldScheduleItem |= action.shouldSchedule(new ArrayList<>(item.getAllActions())); } if (!shouldScheduleItem) { duplicatesInQueue.add(item); @@ -671,7 +666,7 @@ public WaitingItem schedule(Task p, int quietPeriod, List actions) { */ @Deprecated public boolean add(Task p, int quietPeriod) { - return schedule(p, quietPeriod)!=null; + return schedule(p, quietPeriod) != null; } public @CheckForNull WaitingItem schedule(Task p, int quietPeriod) { @@ -684,7 +679,7 @@ public boolean add(Task p, int quietPeriod) { */ @Deprecated public boolean add(Task p, int quietPeriod, Action... actions) { - return schedule(p, quietPeriod, actions)!=null; + return schedule(p, quietPeriod, actions) != null; } /** @@ -747,9 +742,12 @@ public boolean cancel(Item item) { @RequirePOST public HttpResponse doCancelItem(@QueryParameter long id) throws IOException, ServletException { Item item = getItem(id); + if (item != null && !hasReadPermission(item, true)) { + item = null; + } if (item != null) { - if(item.hasCancelPermission()){ - if(cancel(item)) { + if (item.hasCancelPermission()) { + if (cancel(item)) { return HttpResponses.status(HttpServletResponse.SC_NO_CONTENT); } return HttpResponses.error(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Could not cancel run for id " + id); @@ -775,15 +773,15 @@ private WaitingItem peek() { * Generally speaking the array is sorted such that the items that are most likely built sooner are * at the end. */ - @Exported(inline=true) + @Exported(inline = true) public Item[] getItems() { Snapshot s = this.snapshot; List r = new ArrayList<>(); - for(WaitingItem p : s.waitingList) { + for (WaitingItem p : s.waitingList) { r = checkPermissionsAndAddToList(r, p); } - for (BlockedItem p : s.blockedProjects){ + for (BlockedItem p : s.blockedProjects) { r = checkPermissionsAndAddToList(r, p); } for (BuildableItem p : reverse(s.buildables)) { @@ -798,14 +796,27 @@ public Item[] getItems() { } private List checkPermissionsAndAddToList(List r, Item t) { - if (t.task instanceof AccessControlled) { - AccessControlled taskAC = (AccessControlled) t.task; + // TODO Changing the second arg to 'true' should reveal some tasks currently hidden for no obvious reason + if (hasReadPermission(t.task, false)) { + r.add(t); + } + return r; + } + + private static boolean hasReadPermission(Item t, boolean valueIfNotAccessControlled) { + return hasReadPermission(t.task, valueIfNotAccessControlled); + } + + private static boolean hasReadPermission(Queue.Task t, boolean valueIfNotAccessControlled) { + if (t instanceof AccessControlled) { + AccessControlled taskAC = (AccessControlled) t; if (taskAC.hasPermission(hudson.model.Item.READ) - || taskAC.hasPermission(Permission.READ)) { - r.add(t); + || taskAC.hasPermission(Permission.READ)) { // TODO should be unnecessary given the 'implies' relationship + return true; } + return false; } - return r; + return valueIfNotAccessControlled; } /** @@ -815,15 +826,15 @@ private List checkPermissionsAndAddToList(List r, Item t) { * at the end. */ @Restricted(NoExternalUse.class) - @Exported(inline=true) + @Exported(inline = true) public StubItem[] getDiscoverableItems() { Snapshot s = this.snapshot; List r = new ArrayList<>(); - for(WaitingItem p : s.waitingList) { + for (WaitingItem p : s.waitingList) { r = filterDiscoverableItemListBasedOnPermissions(r, p); } - for (BlockedItem p : s.blockedProjects){ + for (BlockedItem p : s.blockedProjects) { r = filterDiscoverableItemListBasedOnPermissions(r, p); } for (BuildableItem p : reverse(s.buildables)) { @@ -840,7 +851,7 @@ public StubItem[] getDiscoverableItems() { private List filterDiscoverableItemListBasedOnPermissions(List r, Item t) { if (t.task instanceof hudson.model.Item) { hudson.model.Item taskAsItem = (hudson.model.Item) t.task; - if (!taskAsItem.hasPermission(hudson.model.Item.READ) + if (!taskAsItem.hasPermission(hudson.model.Item.READ) && taskAsItem.hasPermission(hudson.model.Item.DISCOVER)) { r.add(new StubItem(new StubTask(t.task))); } @@ -937,7 +948,7 @@ public List getPendingItems() { protected List getBlockedItems() { return new ArrayList<>(snapshot.blockedProjects); } - + /** * Returns the snapshot of all {@link LeftItem}s. * @@ -1000,7 +1011,7 @@ public boolean isPending(Task t) { * @param l Label to be checked. If null, any label will be accepted. * If you want to count {@link BuildableItem}s without assigned labels, * use {@link #strictCountBuildableItemsFor(hudson.model.Label)}. - * @return Number of {@link BuildableItem}s for the specified label. + * @return Number of {@link BuildableItem}s for the specified label. */ public /* @java.annotation.Nonnegative */ int countBuildableItemsFor(@CheckForNull Label l) { Snapshot snapshot = this.snapshot; @@ -1015,7 +1026,7 @@ public boolean isPending(Task t) { r++; return r; } - + /** * How many {@link BuildableItem}s are assigned for the given label? *

    @@ -1139,7 +1150,7 @@ public List getItems(Task t) { * Returns true if this queue contains the said project. */ public boolean contains(Task t) { - return getItem(t)!=null; + return getItem(t) != null; } /** @@ -1199,7 +1210,7 @@ private CauseOfBlockage getCauseOfBlockageForItem(Item i) { return causeOfBlockage; } - if(!(i instanceof BuildableItem)) { + if (!(i instanceof BuildableItem)) { // Make sure we don't queue two tasks of the same project to be built // unless that project allows concurrent builds. Once item is buildable it's ok. // @@ -1321,11 +1332,12 @@ public static boolean tryWithLock(Runnable runnable) { } } /** - * Wraps a {@link Runnable} with the {@link Queue} lock held. + * Wraps a {@link Runnable} with the {@link Queue} lock held. * * @param runnable the operation to wrap. * @since 1.618 */ + public static Runnable wrapWithLock(Runnable runnable) { final Jenkins jenkins = Jenkins.getInstanceOrNull(); // TODO confirm safe to assume non-null and use getInstance() @@ -1334,7 +1346,7 @@ public static Runnable wrapWithLock(Runnable runnable) { } /** - * Wraps a {@link hudson.remoting.Callable} with the {@link Queue} lock held. + * Wraps a {@link hudson.remoting.Callable} with the {@link Queue} lock held. * * @param callable the operation to wrap. * @since 1.618 @@ -1347,7 +1359,7 @@ public static hudson.remoting.Callable wrapWithLo } /** - * Wraps a {@link java.util.concurrent.Callable} with the {@link Queue} lock held. + * Wraps a {@link java.util.concurrent.Callable} with the {@link Queue} lock held. * * @param callable the operation to wrap. * @since 1.618 @@ -1360,6 +1372,7 @@ public static java.util.concurrent.Callable wrapWithLock(java.util.concur } @Override + @SuppressFBWarnings(value = "WA_AWAIT_NOT_IN_LOOP", justification = "the caller does indeed call this method in a loop") protected void _await() throws InterruptedException { condition.await(); } @@ -1471,7 +1484,7 @@ public void maintain() { // The executors that are currently waiting for a job to run. Map parked = new HashMap<>(); - {// update parked (and identify any pending items whose executor has disappeared) + { // update parked (and identify any pending items whose executor has disappeared) List lostPendings = new ArrayList<>(pendings); for (Computer c : jenkins.getComputers()) { for (Executor e : c.getAllExecutors()) { @@ -1496,7 +1509,7 @@ public void maintain() { } } // pending -> buildable - for (BuildableItem p: lostPendings) { + for (BuildableItem p : lostPendings) { if (LOGGER.isLoggable(Level.FINE)) { LOGGER.log(Level.FINE, "BuildableItem {0}: pending -> buildable as the assigned executor disappeared", @@ -1510,7 +1523,7 @@ public void maintain() { final QueueSorter s = sorter; - {// blocked -> buildable + { // blocked -> buildable // copy as we'll mutate the list and we want to process in a potentially different order List blockedItems = new ArrayList<>(blockedProjects.values()); // if facing a cycle of blocked tasks, ensure we process in the desired sort order @@ -1582,13 +1595,13 @@ public void maintain() { LOGGER.log(Level.WARNING, "s.sortBuildableItems() threw Throwable: {0}", e); } } - + // Ensure that identification of blocked tasks is using the live state: JENKINS-27708 & JENKINS-27871 updateSnapshot(); - + // allocate buildable jobs to executors for (BuildableItem p : new ArrayList<>( - buildables)) {// copy as we'll mutate the list in the loop + buildables)) { // copy as we'll mutate the list in the loop // one last check to make sure this build is not blocked. CauseOfBlockage causeOfBlockage = getCauseOfBlockageForItem(p); if (causeOfBlockage != null) { @@ -1667,8 +1680,8 @@ public void maintain() { // of getCauseOfBlockageForItem(p) will become a bottleneck before updateSnapshot() will. Additionally // since the snapshot itself only ever has at most one reference originating outside of the stack // it should remain in the eden space and thus be cheap to GC. - // See https://jenkins-ci.org/issue/27708?focusedCommentId=225819&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-225819 - // or https://jenkins-ci.org/issue/27708?focusedCommentId=225906&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-225906 + // See https://issues.jenkins.io/browse/JENKINS-27708?focusedCommentId=225819&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-225819 + // or https://issues.jenkins.io/browse/JENKINS-27708?focusedCommentId=225906&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-225906 // for alternative fixes of this issue. updateSnapshot(); } @@ -1690,7 +1703,7 @@ public void maintain() { Runnable runnable = makeFlyWeightTaskBuildable(p); LOGGER.log(Level.FINEST, "Converting flyweight task: {0} into a BuildableRunnable", taskDisplayName); - if(runnable != null){ + if (runnable != null) { return runnable; } @@ -1716,7 +1729,7 @@ public void maintain() { * @return a Runnable if there is an executor that can take the task, null otherwise */ @CheckForNull - private Runnable makeFlyWeightTaskBuildable(final BuildableItem p){ + private Runnable makeFlyWeightTaskBuildable(final BuildableItem p) { //we double check if this is a flyweight task if (p.task instanceof FlyweightTask) { Jenkins h = Jenkins.get(); @@ -1754,7 +1767,7 @@ private Runnable makeFlyWeightTaskBuildable(final BuildableItem p){ if (c == null || c.isOffline()) { continue; } - if (lbl!=null && !lbl.contains(n)) { + if (lbl != null && !lbl.contains(n)) { continue; } if (n.canTake(p) != null) { @@ -1778,7 +1791,7 @@ private Runnable createFlyWeightTaskRunnable(final BuildableItem p, final Comput }; } - private static final Hash NODE_HASH = Node::getNodeName; + private static final ConsistentHash.Hash NODE_HASH = Node::getNodeName; private boolean makePending(BuildableItem p) { // LOGGER.info("Making "+p.task+" pending"); // REMOVE @@ -1906,9 +1919,8 @@ default CauseOfBlockage getCauseOfBlockage() { * amongst all the free executors on all possibly suitable nodes. * NOTE: To be able to re-use the same node during the next run this key should not change from one run to * another. You probably want to compute that key based on the job's name. - *

    - * @return by default: {@link #getFullDisplayName()} * + * @return by default: {@link #getFullDisplayName()} * @see hudson.model.LoadBalancer */ default String getAffinityKey() { return getFullDisplayName(); } @@ -2063,6 +2075,17 @@ public interface Executable extends Runnable { */ @NonNull SubTask getParent(); + /** + * An umbrella executable (such as a {@link Run}) of which this is one part. + * If {@link #getParent} has a distinct {@link SubTask#getOwnerTask}, + * then it should be the case that {@code getParentExecutable().getParent() == getParent().getOwnerTask()}. + * @return a distinct executable (never {@code this}, unlike the default of {@link SubTask#getOwnerTask}!); or null if this executable was already at top level + * @since 2.313, but implementations can already implement this with a lower core dependency. + */ + default @CheckForNull Executable getParentExecutable() { + return null; + } + /** * Called by {@link Executor} to perform the task. * @throws AsynchronousExecution if you would like to continue without consuming a thread @@ -2098,7 +2121,6 @@ public abstract static class Item extends Actionable { * Unique ID (per master) that tracks the {@link Task} as it moves through different stages * in the queue (each represented by different subtypes of {@link Item} and into any subsequent * {@link Run} instance (see {@link Run#getQueueId()}). - * @return * @since 1.601 */ @Exported @@ -2106,7 +2128,6 @@ public long getId() { return id; } - @AdaptField(was=int.class, name="id") @Deprecated public int getIdLegacy() { if (id > Integer.MAX_VALUE) { @@ -2188,7 +2209,7 @@ public String getInQueueForString() { public Label getAssignedLabel() { for (LabelAssignmentAction laa : getActions(LabelAssignmentAction.class)) { Label l = laa.getAssignedLabel(task); - if (l!=null) return l; + if (l != null) return l; } return task.getAssignedLabel(); } @@ -2197,7 +2218,7 @@ public Label getAssignedLabel() { * Test if the specified {@link SubTask} needs to be run on a node with a particular label. *

    * This method takes {@link LabelAssignmentAction} into account, the first - * non-null assignment will be returned. + * non-null assignment will be returned. * Otherwise falls back to {@link SubTask#getAssignedLabel()} * @param st {@link SubTask} to be checked. * @return Required {@link Label}. Otherwise null, indicating it can run on anywhere. @@ -2206,7 +2227,7 @@ public Label getAssignedLabel() { public @CheckForNull Label getAssignedLabelFor(@NonNull SubTask st) { for (LabelAssignmentAction laa : getActions(LabelAssignmentAction.class)) { Label l = laa.getAssignedLabel(st); - if (l!=null) return l; + if (l != null) return l; } return st.getAssignedLabel(); } @@ -2219,7 +2240,7 @@ public Label getAssignedLabel() { */ public final List getCauses() { CauseAction ca = getAction(CauseAction.class); - if (ca!=null) + if (ca != null) return Collections.unmodifiableList(ca.getCauses()); return Collections.emptyList(); } @@ -2239,7 +2260,7 @@ protected Item(Task task, List actions, long id, FutureImpl future) { this.id = id; this.future = future; this.inQueueSince = System.currentTimeMillis(); - for (Action action: actions) addAction(action); + for (Action action : actions) addAction(action); } protected Item(Task task, List actions, long id, FutureImpl future, long inQueueSince) { @@ -2247,7 +2268,7 @@ protected Item(Task task, List actions, long id, FutureImpl future, long this.id = id; this.future = future; this.inQueueSince = inQueueSince; - for (Action action: actions) addAction(action); + for (Action action : actions) addAction(action); } @SuppressWarnings("deprecation") // JENKINS-51584 @@ -2265,7 +2286,7 @@ protected Item(Item item) { */ @Exported public String getUrl() { - return "queue/item/"+id+'/'; + return "queue/item/" + id + '/'; } /** @@ -2274,7 +2295,7 @@ public String getUrl() { @Exported public final String getWhy() { CauseOfBlockage cob = getCauseOfBlockage(); - return cob!=null ? cob.getShortDescription() : null; + return cob != null ? cob.getShortDescription() : null; } /** @@ -2305,10 +2326,12 @@ public boolean hasCancelPermission() { return task.hasAbortPermission(); } + @Override public String getDisplayName() { return null; } + @Override public String getSearchUrl() { return null; } @@ -2317,7 +2340,7 @@ public String getSearchUrl() { @Deprecated @RequirePOST public HttpResponse doCancelQueue() { - if(hasCancelPermission()){ + if (hasCancelPermission()) { Jenkins.get().getQueue().cancel(this); } return HttpResponses.status(HttpServletResponse.SC_NO_CONTENT); @@ -2337,7 +2360,7 @@ public HttpResponse doCancelQueue() { public Authentication authenticate2() { for (QueueItemAuthenticator auth : QueueItemAuthenticatorProvider.authenticators()) { Authentication a = auth.authenticate2(this); - if (a!=null) + if (a != null) return a; } return task.getDefaultAuthentication2(this); @@ -2433,8 +2456,8 @@ public String getName() { */ @Restricted(NoExternalUse.class) @ExportedBean(defaultVisibility = 999) - @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD", justification = "it is exported, so it might be used") - public class StubItem { + @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD", justification = "read by Stapler") + public static class StubItem { @Exported public StubTask task; @@ -2443,7 +2466,7 @@ public StubItem(StubTask task) { } } - + /** * An optional interface for actions on Queue.Item. * Lets the action cooperate in queue management. @@ -2511,6 +2534,7 @@ static int getCurrentCounterValue() { return COUNTER.intValue(); } + @Override public int compareTo(WaitingItem that) { int r = this.timestamp.getTime().compareTo(that.timestamp.getTime()); if (r != 0) return r; @@ -2518,6 +2542,7 @@ public int compareTo(WaitingItem that) { return Long.compare(this.getId(), that.getId()); } + @Override public CauseOfBlockage getCauseOfBlockage() { long diff = timestamp.getTimeInMillis() - System.currentTimeMillis(); if (diff >= 0) @@ -2529,14 +2554,7 @@ public CauseOfBlockage getCauseOfBlockage() { @Override /*package*/ void enter(Queue q) { if (q.waitingList.add(this)) { - for (QueueListener ql : QueueListener.all()) { - try { - ql.onEnterWaiting(this); - } catch (Throwable e) { - // don't let this kill the queue - LOGGER.log(Level.WARNING, "QueueListener failed while processing "+this,e); - } - } + Listeners.notify(QueueListener.class, true, l -> l.onEnterWaiting(this)); } } @@ -2544,14 +2562,7 @@ public CauseOfBlockage getCauseOfBlockage() { /*package*/ boolean leave(Queue q) { boolean r = q.waitingList.remove(this); if (r) { - for (QueueListener ql : QueueListener.all()) { - try { - ql.onLeaveWaiting(this); - } catch (Throwable e) { - // don't let this kill the queue - LOGGER.log(Level.WARNING, "QueueListener failed while processing "+this,e); - } - } + Listeners.notify(QueueListener.class, true, l -> l.onLeaveWaiting(this)); } return r; } @@ -2608,6 +2619,7 @@ void setCauseOfBlockage(CauseOfBlockage causeOfBlockage) { this.causeOfBlockage = causeOfBlockage; } + @Override public CauseOfBlockage getCauseOfBlockage() { if (causeOfBlockage != null) { return causeOfBlockage; @@ -2617,31 +2629,19 @@ public CauseOfBlockage getCauseOfBlockage() { return getCauseOfBlockageForItem(this); } + @Override /*package*/ void enter(Queue q) { LOGGER.log(Level.FINE, "{0} is blocked", this); blockedProjects.add(this); - for (QueueListener ql : QueueListener.all()) { - try { - ql.onEnterBlocked(this); - } catch (Throwable e) { - // don't let this kill the queue - LOGGER.log(Level.WARNING, "QueueListener failed while processing "+this,e); - } - } + Listeners.notify(QueueListener.class, true, l -> l.onEnterBlocked(this)); } + @Override /*package*/ boolean leave(Queue q) { boolean r = blockedProjects.remove(this); if (r) { LOGGER.log(Level.FINE, "{0} no longer blocked", this); - for (QueueListener ql : QueueListener.all()) { - try { - ql.onLeaveBlocked(this); - } catch (Throwable e) { - // don't let this kill the queue - LOGGER.log(Level.WARNING, "QueueListener failed while processing "+this,e); - } - } + Listeners.notify(QueueListener.class, true, l -> l.onLeaveBlocked(this)); } return r; } @@ -2670,9 +2670,10 @@ public BuildableItem(NotWaitingItem ni) { super(ni); } + @Override public CauseOfBlockage getCauseOfBlockage() { Jenkins jenkins = Jenkins.get(); - if(isBlockedByShutdown(task)) + if (isBlockedByShutdown(task)) return CauseOfBlockage.fromMessage(Messages._Queue_HudsonIsAboutToShutDown()); List causesOfBlockage = transientCausesOfBlockage; @@ -2704,18 +2705,18 @@ public CauseOfBlockage getCauseOfBlockage() { @Override public boolean isStuck() { Label label = getAssignedLabel(); - if(label!=null && label.isOffline()) + if (label != null && label.isOffline()) // no executor online to process this job. definitely stuck. return true; long d = task.getEstimatedDuration(); - long elapsed = System.currentTimeMillis()-buildableStartMilliseconds; - if(d>=0) { + long elapsed = System.currentTimeMillis() - buildableStartMilliseconds; + if (d >= 0) { // if we were running elsewhere, we would have done this build ten times. - return elapsed > Math.max(d,60000L)*10; + return elapsed > Math.max(d, 60000L) * 10; } else { // more than a day in the queue - return TimeUnit.MILLISECONDS.toHours(elapsed)>24; + return TimeUnit.MILLISECONDS.toHours(elapsed) > 24; } } @@ -2727,14 +2728,7 @@ public boolean isPending() { @Override /*package*/ void enter(Queue q) { q.buildables.add(this); - for (QueueListener ql : QueueListener.all()) { - try { - ql.onEnterBuildable(this); - } catch (Throwable e) { - // don't let this kill the queue - LOGGER.log(Level.WARNING, "QueueListener failed while processing "+this,e); - } - } + Listeners.notify(QueueListener.class, true, l -> l.onEnterBuildable(this)); } @Override @@ -2742,14 +2736,7 @@ public boolean isPending() { boolean r = q.buildables.remove(this); if (r) { LOGGER.log(Level.FINE, "{0} no longer blocked", this); - for (QueueListener ql : QueueListener.all()) { - try { - ql.onLeaveBuildable(this); - } catch (Throwable e) { - // don't let this kill the queue - LOGGER.log(Level.WARNING, "QueueListener failed while processing "+this,e); - } - } + Listeners.notify(QueueListener.class, true, l -> l.onLeaveBuildable(this)); } return r; } @@ -2791,7 +2778,7 @@ public CauseOfBlockage getCauseOfBlockage() { */ @Exported public @CheckForNull Executable getExecutable() { - return outcome!=null ? outcome.getPrimaryWorkUnit().getExecutable() : null; + return outcome != null ? outcome.getPrimaryWorkUnit().getExecutable() : null; } /** @@ -2799,20 +2786,13 @@ public CauseOfBlockage getCauseOfBlockage() { */ @Exported public boolean isCancelled() { - return outcome==null; + return outcome == null; } @Override void enter(Queue q) { - q.leftItems.put(getId(),this); - for (QueueListener ql : QueueListener.all()) { - try { - ql.onLeft(this); - } catch (Throwable e) { - // don't let this kill the queue - LOGGER.log(Level.WARNING, "QueueListener failed while processing "+this,e); - } - } + q.leftItems.put(getId(), this); + Listeners.notify(QueueListener.class, true, l -> l.onLeft(this)); } @Override @@ -2840,7 +2820,7 @@ public boolean canConvert(Class klazz) { @Override public Object fromString(String string) { Object item = Jenkins.get().getItemByFullName(string); - if(item==null) throw new NoSuchElementException("No such job exists: "+string); + if (item == null) throw new NoSuchElementException("No such job exists: " + string); return item; } @@ -2861,16 +2841,16 @@ public Object fromString(String string) { String[] split = string.split("#"); String projectName = split[0]; int buildNumber = Integer.parseInt(split[1]); - Job job = (Job) Jenkins.get().getItemByFullName(projectName); - if(job==null) throw new NoSuchElementException("No such job exists: "+projectName); - Run run = job.getBuildByNumber(buildNumber); - if(run==null) throw new NoSuchElementException("No such build: "+string); + Job job = (Job) Jenkins.get().getItemByFullName(projectName); + if (job == null) throw new NoSuchElementException("No such job exists: " + projectName); + Run run = job.getBuildByNumber(buildNumber); + if (run == null) throw new NoSuchElementException("No such build: " + string); return run; } @Override public String toString(Object object) { - Run run = (Run) object; + Run run = (Run) object; return run.getParent().getFullName() + "#" + run.getNumber(); } }); @@ -2912,6 +2892,7 @@ private void periodic() { Timer.get().scheduleWithFixedDelay(this, interval, interval, TimeUnit.MILLISECONDS); } + @Override protected void doRun() { Queue q = queue.get(); if (q != null) @@ -2926,7 +2907,7 @@ protected void doRun() { */ private class ItemList extends ArrayList { public T get(Task task) { - for (T item: this) { + for (T item : this) { if (item.task.equals(task)) { return item; } @@ -2936,7 +2917,7 @@ public T get(Task task) { public List getAll(Task task) { List result = new ArrayList<>(); - for (T item: this) { + for (T item : this) { if (item.task.equals(task)) { result.add(item); } @@ -2974,7 +2955,7 @@ public ItemList values() { */ public T cancel(Task p) { T x = get(p); - if(x!=null) x.cancel(Queue.this); + if (x != null) x.cancel(Queue.this); return x; } @@ -3007,7 +2988,7 @@ public String toString() { return "Queue.Snapshot{waitingList=" + waitingList + ";blockedProjects=" + blockedProjects + ";buildables=" + buildables + ";pendings=" + pendings + "}"; } } - + private static class LockedRunnable implements Runnable { private final Runnable delegate; @@ -3048,11 +3029,11 @@ public V call() throws Exception { } } - private static class LockedHRCallable implements hudson.remoting.Callable { + private static class LockedHRCallable implements hudson.remoting.Callable { private static final long serialVersionUID = 1L; - private final hudson.remoting.Callable delegate; + private final hudson.remoting.Callable delegate; - private LockedHRCallable(hudson.remoting.Callable delegate) { + private LockedHRCallable(hudson.remoting.Callable delegate) { this.delegate = delegate; } @@ -3075,9 +3056,14 @@ public static Queue getInstance() { /** * Restores the queue content during the start up. */ - @Initializer(after=JOB_CONFIG_ADAPTED) + @Initializer(after = JOB_CONFIG_ADAPTED) public static void init(Jenkins h) { - h.getQueue().load(); + Queue queue = h.getQueue(); + Item[] items = queue.getItems(); + if (items.length > 0) { + LOGGER.warning(() -> "Loading queue will discard previously scheduled items: " + Arrays.toString(items)); + } + queue.load(); } /** diff --git a/core/src/main/java/hudson/model/RSS.java b/core/src/main/java/hudson/model/RSS.java index b68606971f6c..19727656e729 100644 --- a/core/src/main/java/hudson/model/RSS.java +++ b/core/src/main/java/hudson/model/RSS.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,19 +21,19 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import hudson.FeedAdapter; import hudson.util.RunList; +import java.io.IOException; +import java.util.Collection; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletResponse; import jenkins.model.Jenkins; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.util.Collection; - /** * RSS related code. * @@ -54,13 +54,13 @@ public final class RSS { * Controls how to render entries to RSS. */ public static void forwardToRss(String title, String url, Collection entries, FeedAdapter adapter, StaplerRequest req, HttpServletResponse rsp) throws IOException, ServletException { - req.setAttribute("adapter",adapter); - req.setAttribute("title",title); - req.setAttribute("url",url); - req.setAttribute("entries",entries); + req.setAttribute("adapter", adapter); + req.setAttribute("title", title); + req.setAttribute("url", url); + req.setAttribute("entries", entries); String flavor = req.getParameter("flavor"); - if(flavor==null) flavor="atom"; + if (flavor == null) flavor = "atom"; flavor = flavor.replace('/', '_'); // Don't allow path to any jelly if (flavor.equals("atom")) { @@ -69,7 +69,7 @@ public static void forwardToRss(String title, String url, CollectionUse Cases - *

    Invisible Property

    *

    + * Invisible Property: * This mechanism can be used to create an entirely invisible {@link Describable}, which is handy * for {@link NodeProperty}, {@link JobProperty}, etc. To do so, define an empty config.jelly to prevent it from * showing up in the config UI, then implement {@link #reconfigure(StaplerRequest, JSONObject)} * and simply return {@code this}. * - *

    Passing some values without going through clients

    *

    + * Passing some values without going through clients: * Sometimes your {@link Describable} object may have some expensive objects that you might want to * hand over to the next instance. This hook lets you do that. * diff --git a/core/src/main/java/hudson/model/Resource.java b/core/src/main/java/hudson/model/Resource.java index cb1e06a9cc82..b407f6df99d6 100644 --- a/core/src/main/java/hudson/model/Resource.java +++ b/core/src/main/java/hudson/model/Resource.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import edu.umd.cs.findbugs.annotations.CheckForNull; @@ -63,14 +64,14 @@ public final class Resource { public final int numConcurrentWrite; public Resource(@CheckForNull Resource parent, @NonNull String displayName) { - this(parent,displayName,1); + this(parent, displayName, 1); } /** * @since 1.155 */ public Resource(@CheckForNull Resource parent, @NonNull String displayName, int numConcurrentWrite) { - if(numConcurrentWrite<1) + if (numConcurrentWrite < 1) throw new IllegalArgumentException(); this.parent = parent; @@ -79,7 +80,7 @@ public Resource(@CheckForNull Resource parent, @NonNull String displayName, int } public Resource(@NonNull String displayName) { - this(null,displayName); + this(null, displayName); } /** @@ -90,12 +91,12 @@ public Resource(@NonNull String displayName) { * For R/W conflict test, this value should be set to {@link Integer#MAX_VALUE}. */ public boolean isCollidingWith(Resource that, int count) { - assert that!=null; - for(Resource r=that; r!=null; r=r.parent) - if(this.equals(r) && r.numConcurrentWrite resourceView = new AbstractCollection() { + @Override public Iterator iterator() { - return new AdaptedIterator(inProgress.iterator()) { + return new AdaptedIterator(inProgress.iterator()) { + @Override protected ResourceList adapt(ResourceActivity item) { return item.getResourceList(); } }; } + @Override public int size() { return inProgress.size(); } @@ -76,9 +80,9 @@ public int size() { * @throws InterruptedException * the thread can be interrupted while waiting for the available resources. */ - public void execute(@NonNull Runnable task, final ResourceActivity activity ) throws InterruptedException { + public void execute(@NonNull Runnable task, final ResourceActivity activity) throws InterruptedException { final ResourceList resources = activity.getResourceList(); - _withLock(new NotReallyRoleSensitiveCallable() { + _withLock(new NotReallyRoleSensitiveCallable() { @Override public Void call() throws InterruptedException { while (inUse.isCollidingWith(resources)) { @@ -126,7 +130,7 @@ public Boolean call() { } }); } catch (Exception e) { - throw new IllegalStateException("Inner callable does not throw exception"); + throw new IllegalStateException("Inner callable does not throw exception", e); } } @@ -147,7 +151,7 @@ public Resource call() { } }); } catch (Exception e) { - throw new IllegalStateException("Inner callable does not throw exception"); + throw new IllegalStateException("Inner callable does not throw exception", e); } } @@ -159,11 +163,12 @@ public Resource call() { public ResourceActivity getBlockingActivity(ResourceActivity activity) { ResourceList res = activity.getResourceList(); for (ResourceActivity a : inProgress) - if(res.isCollidingWith(a.getResourceList())) + if (res.isCollidingWith(a.getResourceList())) return a; return null; } + @SuppressFBWarnings(value = "WA_NOT_IN_LOOP", justification = "the caller does indeed call this method in a loop") protected void _await() throws InterruptedException { wait(); } @@ -184,10 +189,9 @@ protected V _withLock(java.util.concurrent.Callable callable) throws Exce } } - protected V _withLock(hudson.remoting.Callable callable) throws T { + protected V _withLock(hudson.remoting.Callable callable) throws T { synchronized (this) { return callable.call(); } } } - diff --git a/core/src/main/java/hudson/model/ResourceList.java b/core/src/main/java/hudson/model/ResourceList.java index d3fdb9302ec2..e94a91996a13 100644 --- a/core/src/main/java/hudson/model/ResourceList.java +++ b/core/src/main/java/hudson/model/ResourceList.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,15 +21,15 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; -import java.util.Set; -import java.util.HashSet; -import java.util.Map; -import java.util.HashMap; import java.util.Arrays; import java.util.Collection; -import java.util.Map.Entry; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; import java.util.logging.Logger; /** @@ -40,7 +40,7 @@ * As with usual reader/writer pattern, multiple read accesses can * co-exist concurrently, but write access requires exclusive access * (the number of allowed concurrent write activity is determined by - * {@link Resource#numConcurrentWrite}. + * {@link Resource#numConcurrentWrite}. * * @author Kohsuke Kawaguchi * @since 1.121 @@ -60,7 +60,7 @@ public final class ResourceList { * The values are mostly supposed to be 1, but when {@link ResourceController} * uses a list to keep track of the union of all the activities, it can get larger. */ - private final Map write = new HashMap<>(); + private final Map write = new HashMap<>(); private static final Integer MAX_INT = Integer.MAX_VALUE; /** @@ -74,7 +74,7 @@ public static ResourceList union(ResourceList... lists) { * Creates union of all resources. */ public static ResourceList union(Collection lists) { - switch(lists.size()) { + switch (lists.size()) { case 0: return EMPTY; case 1: @@ -83,8 +83,8 @@ public static ResourceList union(Collection lists) { ResourceList r = new ResourceList(); for (ResourceList l : lists) { r.all.addAll(l.all); - for (Entry e : l.write.entrySet()) - r.write.put(e.getKey(), unbox(r.write.get(e.getKey()))+e.getValue()); + for (Map.Entry e : l.write.entrySet()) + r.write.put(e.getKey(), unbox(r.write.get(e.getKey())) + e.getValue()); } return r; } @@ -103,7 +103,7 @@ public ResourceList r(Resource r) { */ public ResourceList w(Resource r) { all.add(r); - write.put(r, unbox(write.get(r))+1); + write.put(r, unbox(write.get(r)) + 1); return this; } @@ -112,27 +112,27 @@ public ResourceList w(Resource r) { * resource access. */ public boolean isCollidingWith(ResourceList that) { - return getConflict(that)!=null; + return getConflict(that) != null; } /** * Returns the resource in this list that's colliding with the given resource list. */ public Resource getConflict(ResourceList that) { - Resource r = _getConflict(this,that); - if(r!=null) return r; - return _getConflict(that,this); + Resource r = _getConflict(this, that); + if (r != null) return r; + return _getConflict(that, this); } private Resource _getConflict(ResourceList lhs, ResourceList rhs) { - for (Entry r : lhs.write.entrySet()) { + for (Map.Entry r : lhs.write.entrySet()) { for (Resource l : rhs.all) { Integer v = rhs.write.get(l); - if(v!=null) // this is write/write conflict. + if (v != null) // this is write/write conflict. v += r.getValue(); else // Otherwise set it to a very large value, since it's read/write conflict v = MAX_INT; - if(r.getKey().isCollidingWith(l,unbox(v))) { + if (r.getKey().isCollidingWith(l, unbox(v))) { LOGGER.info("Collision with " + r + " and " + l); return r.getKey(); } @@ -143,11 +143,11 @@ private Resource _getConflict(ResourceList lhs, ResourceList rhs) { @Override public String toString() { - Map m = new HashMap<>(); + Map m = new HashMap<>(); for (Resource r : all) - m.put(r,"R"); - for (Entry e : write.entrySet()) - m.put(e.getKey(),"W"+e.getValue()); + m.put(r, "R"); + for (Map.Entry e : write.entrySet()) + m.put(e.getKey(), "W" + e.getValue()); return m.toString(); } @@ -155,7 +155,7 @@ public String toString() { * {@link Integer} unbox operation that treats null as 0. */ private static int unbox(Integer x) { - return x==null ? 0 : x; + return x == null ? 0 : x; } /** diff --git a/core/src/main/java/hudson/model/RestartListener.java b/core/src/main/java/hudson/model/RestartListener.java index 4ae2242a1c05..828eeb0d2e2e 100644 --- a/core/src/main/java/hudson/model/RestartListener.java +++ b/core/src/main/java/hudson/model/RestartListener.java @@ -3,9 +3,8 @@ import hudson.Extension; import hudson.ExtensionList; import hudson.ExtensionPoint; -import jenkins.model.Jenkins; - import java.io.IOException; +import jenkins.model.Jenkins; import jenkins.model.queue.AsynchronousExecution; /** @@ -64,6 +63,7 @@ public boolean isReadyToRestart() throws IOException, InterruptedException { } return true; } + private static boolean blocksRestart(Executor e) { if (e.isBusy()) { AsynchronousExecution execution = e.getAsynchronousExecution(); diff --git a/core/src/main/java/hudson/model/Result.java b/core/src/main/java/hudson/model/Result.java index da80df7d49b3..b56867e37ed0 100644 --- a/core/src/main/java/hudson/model/Result.java +++ b/core/src/main/java/hudson/model/Result.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,29 +21,28 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import com.thoughtworks.xstream.converters.SingleValueConverter; import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; - +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.cli.declarative.OptionHandlerExtension; import hudson.init.Initializer; import hudson.util.EditDistance; - +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; import org.apache.commons.beanutils.Converter; import org.kohsuke.args4j.CmdLineException; import org.kohsuke.args4j.CmdLineParser; import org.kohsuke.args4j.OptionDef; -import org.kohsuke.args4j.spi.*; +import org.kohsuke.args4j.spi.OptionHandler; +import org.kohsuke.args4j.spi.Parameters; +import org.kohsuke.args4j.spi.Setter; import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.export.CustomExportedBean; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -import edu.umd.cs.findbugs.annotations.NonNull; - /** * The build outcome. * @@ -53,30 +52,30 @@ public final class Result implements Serializable, CustomExportedBean { /** * The build had no errors. */ - public static final @NonNull Result SUCCESS = new Result("SUCCESS",BallColor.BLUE,0,true); + public static final @NonNull Result SUCCESS = new Result("SUCCESS", BallColor.BLUE, 0, true); /** * The build had some errors but they were not fatal. * For example, some tests failed. */ - public static final @NonNull Result UNSTABLE = new Result("UNSTABLE",BallColor.YELLOW,1,true); + public static final @NonNull Result UNSTABLE = new Result("UNSTABLE", BallColor.YELLOW, 1, true); /** * The build had a fatal error. */ - public static final @NonNull Result FAILURE = new Result("FAILURE",BallColor.RED,2,true); + public static final @NonNull Result FAILURE = new Result("FAILURE", BallColor.RED, 2, true); /** * The module was not built. *

    * This status code is used in a multi-stage build (like maven2) * where a problem in earlier stage prevented later stages from building. */ - public static final @NonNull Result NOT_BUILT = new Result("NOT_BUILT",BallColor.NOTBUILT,3,false); + public static final @NonNull Result NOT_BUILT = new Result("NOT_BUILT", BallColor.NOTBUILT, 3, false); /** * The build was manually aborted. * * If you are catching {@link InterruptedException} and interpreting it as {@link #ABORTED}, * you should check {@link Executor#abortResult()} instead (starting 1.417.) */ - public static final @NonNull Result ABORTED = new Result("ABORTED",BallColor.ABORTED,4,false); + public static final @NonNull Result ABORTED = new Result("ABORTED", BallColor.ABORTED, 4, false); private final @NonNull String name; @@ -89,7 +88,7 @@ public final class Result implements Serializable, CustomExportedBean { * Default ball color for this status. */ public final @NonNull BallColor color; - + /** * Is this a complete build - i.e. did it run to the end (not aborted)? * @since 1.526 @@ -107,7 +106,7 @@ private Result(@NonNull String name, @NonNull BallColor color, /*@java.annotatio * Combines two {@link Result}s and returns the worse one. */ public @NonNull Result combine(@NonNull Result that) { - if(this.ordinal < that.ordinal) + if (this.ordinal < that.ordinal) return that; else return this; @@ -151,7 +150,7 @@ public boolean isBetterThan(@NonNull Result that) { public boolean isBetterOrEqualTo(@NonNull Result that) { return this.ordinal <= that.ordinal; } - + /** * Is this a complete build - i.e. did it run to the end (not aborted)? * @since 1.526 @@ -165,10 +164,11 @@ public boolean isCompleteBuild() { return name; } + @Override public @NonNull String toExportedObject() { return name; } - + public static @NonNull Result fromString(@NonNull String s) { for (Result r : all) if (s.equalsIgnoreCase(r.name)) @@ -186,19 +186,19 @@ public boolean isCompleteBuild() { // Maintain each Result as a singleton deserialized (like build result from an agent node) private Object readResolve() { for (Result r : all) - if (ordinal==r.ordinal) + if (ordinal == r.ordinal) return r; return FAILURE; } private static final long serialVersionUID = 1L; - private static final Result[] all = new Result[] {SUCCESS,UNSTABLE,FAILURE,NOT_BUILT,ABORTED}; + private static final Result[] all = new Result[] {SUCCESS, UNSTABLE, FAILURE, NOT_BUILT, ABORTED}; - public static final SingleValueConverter conv = new AbstractSingleValueConverter () { + public static final SingleValueConverter conv = new AbstractSingleValueConverter() { @Override public boolean canConvert(Class clazz) { - return clazz==Result.class; + return clazz == Result.class; } @Override @@ -217,8 +217,8 @@ public OptionHandlerImpl(CmdLineParser parser, OptionDef option, Setter build) { - return getResultTrend((Run)build); + return getResultTrend((Run) build); } /** * Returns the result trend of a run. - * + * * @param run the run * @return the result trend - * + * * @since 1.441 */ public static ResultTrend getResultTrend(Run run) { - + Result result = run.getResult(); - + if (result == Result.ABORTED) { return ABORTED; } else if (result == Result.NOT_BUILT) { return NOT_BUILT; } - + if (result == Result.SUCCESS) { if (isFix(run)) { return FIXED; @@ -128,14 +128,14 @@ public static ResultTrend getResultTrend(Run run) { return SUCCESS; } } - + Run previousBuild = getPreviousNonAbortedBuild(run); if (result == Result.UNSTABLE) { if (previousBuild == null) { return UNSTABLE; } - - + + if (previousBuild.getResult() == Result.UNSTABLE) { return STILL_UNSTABLE; } else if (previousBuild.getResult() == Result.FAILURE) { @@ -150,10 +150,10 @@ public static ResultTrend getResultTrend(Run run) { return FAILURE; } } - + throw new IllegalArgumentException("Unknown result: '" + result + "' for build: " + run); } - + /** * Returns the previous 'not aborted' build (i.e. ignores ABORTED and NOT_BUILT builds) * or null. @@ -161,10 +161,10 @@ public static ResultTrend getResultTrend(Run run) { private static Run getPreviousNonAbortedBuild(Run build) { Run previousBuild = build.getPreviousBuild(); while (previousBuild != null) { - if (previousBuild.getResult() == null + if (previousBuild.getResult() == null || previousBuild.getResult() == Result.ABORTED || previousBuild.getResult() == Result.NOT_BUILT) { - + previousBuild = previousBuild.getPreviousBuild(); } else { return previousBuild; @@ -172,7 +172,7 @@ public static ResultTrend getResultTrend(Run run) { } return previousBuild; } - + /** * Returns true if this build represents a 'fix'. * I.e. it is the first successful build after previous @@ -183,7 +183,7 @@ private static boolean isFix(Run build) { if (build.getResult() != Result.SUCCESS) { return false; } - + Run previousBuild = getPreviousNonAbortedBuild(build); if (previousBuild != null) { return previousBuild.getResult().isWorseThan(Result.SUCCESS); diff --git a/core/src/main/java/hudson/model/RootAction.java b/core/src/main/java/hudson/model/RootAction.java index 9806d155d84d..9c431ee635ff 100644 --- a/core/src/main/java/hudson/model/RootAction.java +++ b/core/src/main/java/hudson/model/RootAction.java @@ -21,10 +21,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; -import hudson.ExtensionPoint; import hudson.Extension; +import hudson.ExtensionPoint; /** * Marker interface for actions that are added to {@link jenkins.model.Jenkins}. diff --git a/core/src/main/java/hudson/model/Run.java b/core/src/main/java/hudson/model/Run.java index c2ca62d549a2..85629405de80 100644 --- a/core/src/main/java/hudson/model/Run.java +++ b/core/src/main/java/hudson/model/Run.java @@ -1,22 +1,22 @@ /* * The MIT License - * + * * Copyright (c) 2004-2012, Sun Microsystems, Inc., Kohsuke Kawaguchi, * Daniel Dyer, Red Hat, Inc., Tom Huybrechts, Romain Seguy, Yahoo! Inc., * Darek Ostolski, CloudBees, Inc. * Copyright (c) 2012, Martin Schroeder, Intel Mobile Communications GmbH * Copyright (c) 2019 Intel Corporation - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -25,10 +25,18 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import static java.util.logging.Level.FINE; +import static java.util.logging.Level.FINER; +import static java.util.logging.Level.SEVERE; +import static java.util.logging.Level.WARNING; + import com.jcraft.jzlib.GZIPInputStream; import com.thoughtworks.xstream.XStream; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.AbortException; import hudson.BulkChange; @@ -37,18 +45,14 @@ import hudson.ExtensionPoint; import hudson.FeedAdapter; import hudson.Functions; +import hudson.Util; +import hudson.XmlFile; +import hudson.cli.declarative.CLIMethod; import hudson.console.AnnotatedLargeText; import hudson.console.ConsoleLogFilter; import hudson.console.ConsoleNote; import hudson.console.ModelHyperlinkNote; import hudson.console.PlainTextConsoleOutputStream; -import java.nio.file.Files; -import java.nio.file.InvalidPathException; -import java.nio.file.StandardOpenOption; -import jenkins.util.SystemProperties; -import hudson.Util; -import hudson.XmlFile; -import hudson.cli.declarative.CLIMethod; import hudson.model.Descriptor.FormException; import hudson.model.listeners.RunListener; import hudson.model.listeners.SaveableListener; @@ -65,7 +69,6 @@ import hudson.util.LogTaskListener; import hudson.util.ProcessTree; import hudson.util.XStream2; - import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.File; @@ -78,7 +81,10 @@ import java.io.Reader; import java.io.Serializable; import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.InvalidPathException; import java.nio.file.StandardCopyOption; +import java.nio.file.StandardOpenOption; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -95,13 +101,10 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.logging.Level; -import static java.util.logging.Level.*; - import java.util.logging.Logger; -import edu.umd.cs.findbugs.annotations.CheckForNull; -import edu.umd.cs.findbugs.annotations.NonNull; import javax.servlet.ServletException; import javax.servlet.http.HttpServletResponse; import jenkins.model.ArtifactManager; @@ -115,6 +118,7 @@ import jenkins.model.lazy.BuildReference; import jenkins.model.lazy.LazyBuildMixIn; import jenkins.security.MasterToSlaveCallable; +import jenkins.util.SystemProperties; import jenkins.util.VirtualFile; import jenkins.util.io.OnMaster; import net.sf.json.JSONObject; @@ -148,7 +152,7 @@ * @see RunListener */ @ExportedBean -public abstract class Run ,RunT extends Run> +public abstract class Run, RunT extends Run> extends Actionable implements ExtensionPoint, Comparable, AccessControlled, PersistenceRoot, DescriptorByNameOwner, OnMaster, StaplerProxy { /** @@ -208,7 +212,7 @@ public abstract class Run ,RunT extends Run getTransientActions() { List actions = new ArrayList<>(); - for (TransientBuildActionFactory factory: TransientBuildActionFactory.all()) { + for (TransientBuildActionFactory factory : TransientBuildActionFactory.all()) { for (Action created : factory.createFor(this)) { if (created == null) { LOGGER.log(WARNING, "null action added by {0}", factory); @@ -432,16 +436,17 @@ public void addAction(@NonNull Action a) { /** * Obtains 'this' in a more type safe signature. - */ - @SuppressWarnings({"unchecked"}) + */ + @SuppressWarnings("unchecked") protected @NonNull RunT _this() { - return (RunT)this; + return (RunT) this; } /** * Ordering based on build numbers. * If numbers are equal order based on names of parent projects. */ + @Override public int compareTo(@NonNull RunT that) { final int res = this.number - that.number; if (res == 0) @@ -499,7 +504,7 @@ public void setResult(@NonNull Result r) { } // result can only get worse - if (result==null || r.isWorseThan(result)) { + if (result == null || r.isWorseThan(result)) { result = r; LOGGER.log(FINE, this + " in " + getRootDir() + ": result is set to " + r, LOGGER.isLoggable(Level.FINER) ? new Exception() : null); } @@ -510,7 +515,7 @@ public void setResult(@NonNull Result r) { */ public @NonNull List getBadgeActions() { List r = getActions(BuildBadgeAction.class); - if(isKeepLog()) { + if (isKeepLog()) { r = new ArrayList<>(r); r.add(new KeepLogBuildBadge()); } @@ -545,14 +550,14 @@ public boolean isLogUpdated() { /** * Gets the {@link Executor} building this job, if it's being built. * Otherwise null. - * + * * This method looks for {@link Executor} who's {@linkplain Executor#getCurrentExecutable() assigned to this build}, * and because of that this might not be necessarily in sync with the return value of {@link #isBuilding()} — * an executor holds on to {@link Run} some more time even after the build is finished (for example to * perform {@linkplain Run.State#POST_PRODUCTION post-production processing}.) * @see Executor#of */ - @Exported + @Exported public @CheckForNull Executor getExecutor() { return this instanceof Queue.Executable ? Executor.of((Queue.Executable) this) : null; } @@ -560,12 +565,12 @@ public boolean isLogUpdated() { /** * Gets the one off {@link Executor} building this job, if it's being built. * Otherwise null. - * @since 1.433 + * @since 1.433 */ public @CheckForNull Executor getOneOffExecutor() { - for( Computer c : Jenkins.get().getComputers() ) { + for (Computer c : Jenkins.get().getComputers()) { for (Executor e : c.getOneOffExecutors()) { - if(e.getCurrentExecutable()==this) + if (e.getCurrentExecutable() == this) return e; } } @@ -576,9 +581,9 @@ public boolean isLogUpdated() { * Gets the charset in which the log file is written. * @return never null. * @since 1.257 - */ + */ public final @NonNull Charset getCharset() { - if(charset==null) return Charset.defaultCharset(); + if (charset == null) return Charset.defaultCharset(); return Charset.forName(charset); } @@ -595,7 +600,7 @@ public boolean isLogUpdated() { */ public @NonNull List getCauses() { CauseAction a = getAction(CauseAction.class); - if (a==null) return Collections.emptyList(); + if (a == null) return Collections.emptyList(); return Collections.unmodifiableList(a.getCauses()); } @@ -603,7 +608,7 @@ public boolean isLogUpdated() { * Returns a {@link Cause} of a particular type. * * @since 1.362 - */ + */ public @CheckForNull T getCause(Class type) { for (Cause c : getCauses()) if (type.isInstance(c)) @@ -618,22 +623,22 @@ public boolean isLogUpdated() { */ @Exported public final boolean isKeepLog() { - return getWhyKeepLog()!=null; + return getWhyKeepLog() != null; } /** * If {@link #isKeepLog()} returns true, returns a short, human-readable * sentence that explains why it's being kept. - */ + */ public @CheckForNull String getWhyKeepLog() { - if(keepLog) + if (keepLog) return Messages.Run_MarkedExplicitly(); return null; // not marked at all } /** * The project this build is for. - */ + */ public @NonNull JobT getParent() { return project; } @@ -642,7 +647,7 @@ public final boolean isKeepLog() { * When the build is scheduled. * * @see #getStartTimeInMillis() - */ + */ @Exported public @NonNull Calendar getTimestamp() { GregorianCalendar c = new GregorianCalendar(); @@ -652,7 +657,7 @@ public final boolean isKeepLog() { /** * Same as {@link #getTimestamp()} but in a different type. - */ + */ public final @NonNull Date getTime() { return new Date(timestamp); } @@ -673,7 +678,7 @@ public final long getTimeInMillis() { * @see #getTimestamp() */ public final long getStartTimeInMillis() { - if (startTime==0) return timestamp; // fallback: approximate by the queuing time + if (startTime == 0) return timestamp; // fallback: approximate by the queuing time return startTime; } @@ -713,9 +718,9 @@ public String getDescription() { int displayChars = 0; int lastTruncatablePoint = -1; - for (int i=0; i') { inTag = false; @@ -740,9 +745,9 @@ public String getDescription() { if (displayChars >= maxDescrLength) { truncDesc = truncDesc.substring(0, lastTruncatablePoint) + ending; } - + return truncDesc; - + } /** @@ -752,7 +757,7 @@ public String getDescription() { * string like "3 minutes" "1 day" etc. */ public @NonNull String getTimestampString() { - long duration = new GregorianCalendar().getTimeInMillis()-timestamp; + long duration = new GregorianCalendar().getTimeInMillis() - timestamp; return Util.getTimeSpanString(duration); } @@ -771,7 +776,7 @@ public String getDescription() { return Messages.Run_NotStartedYet(); } else if (isBuilding()) { return Messages.Run_InProgressDuration( - Util.getTimeSpanString(System.currentTimeMillis()-startTime)); + Util.getTimeSpanString(System.currentTimeMillis() - startTime)); } return Util.getTimeSpanString(duration); } @@ -788,7 +793,7 @@ public long getDuration() { * Gets the icon color for display. */ public @NonNull BallColor getIconColor() { - if(!isBuilding()) { + if (!isBuilding()) { // already built return getResult().color; } @@ -796,7 +801,7 @@ public long getDuration() { // a new build is in progress BallColor baseColor; RunT pb = getPreviousBuild(); - if(pb==null) + if (pb == null) baseColor = BallColor.NOTBUILT; else baseColor = pb.getIconColor(); @@ -808,9 +813,10 @@ public long getDuration() { * Returns true if the build is still queued and hasn't started yet. */ public boolean hasntStartedYet() { - return state ==State.NOT_STARTED; + return state == State.NOT_STARTED; } + @SuppressFBWarnings(value = "RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE", justification = "see JENKINS-45892") @Override public String toString() { if (project == null) { @@ -821,16 +827,17 @@ public String toString() { @Exported public String getFullDisplayName() { - return project.getFullDisplayName()+' '+getDisplayName(); + return project.getFullDisplayName() + ' ' + getDisplayName(); } + @Override @Exported public String getDisplayName() { - return displayName!=null ? displayName : "#"+number; + return displayName != null ? displayName : "#" + number; } public boolean hasCustomDisplayName() { - return displayName!=null; + return displayName != null; } /** @@ -843,7 +850,7 @@ public void setDisplayName(String value) throws IOException { save(); } - @Exported(visibility=2) + @Exported(visibility = 2) public int getNumber() { return number; } @@ -853,7 +860,7 @@ public int getNumber() { * @return Reference to the build. Never null * @see jenkins.model.lazy.LazyBuildMixIn.RunMixIn#createReference * @since 1.556 - */ + */ protected @NonNull BuildReference createReference() { return new BuildReference<>(getId(), _this()); } @@ -865,26 +872,26 @@ public int getNumber() { * @since 1.556 */ protected void dropLinks() { - if(nextBuild!=null) + if (nextBuild != null) nextBuild.previousBuild = previousBuild; - if(previousBuild!=null) + if (previousBuild != null) previousBuild.nextBuild = nextBuild; } /** * @see jenkins.model.lazy.LazyBuildMixIn.RunMixIn#getPreviousBuild - */ + */ public @CheckForNull RunT getPreviousBuild() { return previousBuild; } /** * Gets the most recent {@linkplain #isBuilding() completed} build excluding 'this' Run itself. - */ + */ public final @CheckForNull RunT getPreviousCompletedBuild() { - RunT r=getPreviousBuild(); - while (r!=null && r.isBuilding()) - r=r.getPreviousBuild(); + RunT r = getPreviousBuild(); + while (r != null && r.isBuilding()) + r = r.getPreviousBuild(); return r; } @@ -895,20 +902,20 @@ protected void dropLinks() { *

    * We basically follow the existing skip list, and wherever we find a non-optimal pointer, we remember them * in 'fixUp' and update them later. - */ + */ public final @CheckForNull RunT getPreviousBuildInProgress() { - if(previousBuildInProgress==this) return null; // the most common case + if (previousBuildInProgress == this) return null; // the most common case List fixUp = new ArrayList<>(); RunT r = _this(); // 'r' is the source of the pointer (so that we can add it to fix up if we find that the target of the pointer is inefficient.) RunT answer; while (true) { RunT n = r.previousBuildInProgress; - if (n==null) {// no field computed yet. - n=r.getPreviousBuild(); + if (n == null) { // no field computed yet. + n = r.getPreviousBuild(); fixUp.add(r); } - if (r==n || n==null) { + if (r == n || n == null) { // this indicates that we know there's no build in progress beyond this point answer = null; break; @@ -925,38 +932,38 @@ protected void dropLinks() { // fix up so that the next look up will run faster for (RunT f : fixUp) - f.previousBuildInProgress = answer==null ? f : answer; + f.previousBuildInProgress = answer == null ? f : answer; return answer; } /** * Returns the last build that was actually built - i.e., skipping any with Result.NOT_BUILT - */ + */ public @CheckForNull RunT getPreviousBuiltBuild() { - RunT r=getPreviousBuild(); + RunT r = getPreviousBuild(); // in certain situations (aborted m2 builds) r.getResult() can still be null, although it should theoretically never happen - while( r!=null && (r.getResult() == null || r.getResult()==Result.NOT_BUILT) ) - r=r.getPreviousBuild(); + while (r != null && (r.getResult() == null || r.getResult() == Result.NOT_BUILT)) + r = r.getPreviousBuild(); return r; } /** * Returns the last build that didn't fail before this build. - */ + */ public @CheckForNull RunT getPreviousNotFailedBuild() { - RunT r=getPreviousBuild(); - while( r!=null && r.getResult()==Result.FAILURE ) - r=r.getPreviousBuild(); + RunT r = getPreviousBuild(); + while (r != null && r.getResult() == Result.FAILURE) + r = r.getPreviousBuild(); return r; } /** * Returns the last failed build before this build. - */ + */ public @CheckForNull RunT getPreviousFailedBuild() { - RunT r=getPreviousBuild(); - while( r!=null && r.getResult()!=Result.FAILURE ) - r=r.getPreviousBuild(); + RunT r = getPreviousBuild(); + while (r != null && r.getResult() != Result.FAILURE) + r = r.getPreviousBuild(); return r; } @@ -965,22 +972,22 @@ protected void dropLinks() { * @since 1.383 */ public @CheckForNull RunT getPreviousSuccessfulBuild() { - RunT r=getPreviousBuild(); - while( r!=null && r.getResult()!=Result.SUCCESS ) - r=r.getPreviousBuild(); + RunT r = getPreviousBuild(); + while (r != null && r.getResult() != Result.SUCCESS) + r = r.getPreviousBuild(); return r; } /** * Returns the last {@code numberOfBuilds} builds with a build result ≥ {@code threshold}. - * + * * @param numberOfBuilds the desired number of builds * @param threshold the build result threshold * @return a list with the builds (youngest build first). * May be smaller than 'numberOfBuilds' or even empty * if not enough builds satisfying the threshold have been found. Never null. * @since 1.383 - */ + */ public @NonNull List getPreviousBuildsOverThreshold(int numberOfBuilds, @NonNull Result threshold) { RunT r = getPreviousBuild(); if (r != null) { @@ -1005,7 +1012,7 @@ protected void dropLinks() { RunT r = _this(); while (r != null && builds.size() < numberOfBuilds) { if (!r.isBuilding() && - (r.getResult() != null && r.getResult().isBetterOrEqualTo(threshold))) { + r.getResult() != null && r.getResult().isBetterOrEqualTo(threshold)) { builds.add(r); } r = r.getPreviousBuild(); @@ -1016,7 +1023,7 @@ protected void dropLinks() { /** * @see jenkins.model.lazy.LazyBuildMixIn.RunMixIn#getNextBuild - */ + */ public @CheckForNull RunT getNextBuild() { return nextBuild; } @@ -1025,7 +1032,7 @@ protected void dropLinks() { * Returns the URL of this {@link Run}, relative to the context root of Hudson. * * @return - * String like "job/foo/32/" with trailing slash but no leading slash. + * String like "job/foo/32/" with trailing slash but no leading slash. */ // I really messed this up. I'm hoping to fix this some time // it shouldn't have trailing '/', and instead it should have leading '/' @@ -1036,14 +1043,14 @@ protected void dropLinks() { // @see also {@link AbstractItem#getUrl} StaplerRequest req = Stapler.getCurrentRequest(); if (req != null) { - String seed = Functions.getNearestAncestorUrl(req,this); - if(seed!=null) { + String seed = Functions.getNearestAncestorUrl(req, this); + if (seed != null) { // trim off the context path portion and leading '/', but add trailing '/' - return seed.substring(req.getContextPath().length()+1)+'/'; + return seed.substring(req.getContextPath().length() + 1) + '/'; } } - return project.getUrl()+getNumber()+'/'; + return project.getUrl() + getNumber() + '/'; } /** @@ -1054,14 +1061,15 @@ protected void dropLinks() { * misconfiguration to break this value, with network set up like Apache reverse proxy. * This method is only intended for the remote API clients who cannot resolve relative references. */ - @Exported(visibility=2,name="url") + @Exported(visibility = 2, name = "url") @Deprecated public final @NonNull String getAbsoluteUrl() { - return project.getAbsoluteUrl()+getNumber()+'/'; + return project.getAbsoluteUrl() + getNumber() + '/'; } + @Override public final @NonNull String getSearchUrl() { - return getNumber()+"/"; + return getNumber() + "/"; } /** @@ -1072,11 +1080,11 @@ protected void dropLinks() { public @NonNull String getId() { return id != null ? id : Integer.toString(number); } - + /** - * Get the root directory of this {@link Run} on the master. + * Get the root directory of this {@link Run} on the controller. * Files related to this {@link Run} should be stored below this directory. - * @return Root directory of this {@link Run} on the master. Never null + * @return Root directory of this {@link Run} on the controller. Never null */ @Override public @NonNull File getRootDir() { @@ -1131,14 +1139,14 @@ protected void dropLinks() { */ @Deprecated public File getArtifactsDir() { - return new File(getRootDir(),"archive"); + return new File(getRootDir(), "archive"); } /** * Gets the artifacts (relative to {@link #getArtifactsDir()}. * @return The list can be empty but never null - */ - @Exported + */ + @Exported public @NonNull List getArtifacts() { return getArtifactsUpTo(Integer.MAX_VALUE); } @@ -1146,7 +1154,7 @@ public File getArtifactsDir() { /** * Gets the first N artifacts. * @return The list can be empty but never null - */ + */ public @NonNull List getArtifactsUpTo(int artifactsNumber) { SerializableArtifactList sal; VirtualFile root = getArtifactManager().root(); @@ -1175,10 +1183,12 @@ private static final class AddArtifacts extends MasterToSlaveCallable=upTo) break; + n += addArtifacts(sub, childPath + '/', childHref + '/', r, a, upTo - n); + if (n >= upTo) break; } else { // Don't store collapsed path in ArrayList (for correct data in external API) r.add(collapsed ? new SerializableArtifact(child, a.relativePath, a.href, length, a.treeNodeId) : a); - if (++n>=upTo) break; + if (++n >= upTo) break; } } return n; } - + /** * Maximum number of artifacts to list before using switching to the tree view. */ @@ -1237,7 +1247,7 @@ private static int addArtifacts(@NonNull VirtualFile dir, public static final int TREE_CUTOFF = Integer.parseInt(SystemProperties.getString("hudson.model.Run.ArtifactList.treeCutoff", "40")); // ..and then "too many" - + /** {@link Run.Artifact} without the implicit link to {@link Run} */ private static final class SerializableArtifact implements Serializable { private static final long serialVersionUID = 1L; @@ -1246,6 +1256,7 @@ private static final class SerializableArtifact implements Serializable { final String href; final String length; final String treeNodeId; + SerializableArtifact(String name, String relativePath, String href, String length, String treeNodeId) { this.name = name; this.relativePath = relativePath; @@ -1268,7 +1279,7 @@ public final class ArtifactList extends ArrayList { * Map of Artifact to treeNodeId of parent node in tree view. * Contains Artifact objects for directories and files (the ArrayList contains only files). */ - private LinkedHashMap tree = new LinkedHashMap<>(); + private LinkedHashMap tree = new LinkedHashMap<>(); void updateFrom(SerializableArtifactList clone) { Map artifacts = new HashMap<>(); // need to share objects between tree and list, since computeDisplayName mutates displayPath @@ -1288,65 +1299,43 @@ void updateFrom(SerializableArtifactList clone) { } } - public Map getTree() { + public Map getTree() { return tree; } public void computeDisplayName() { - if(size()>LIST_CUTOFF) return; // we are not going to display file names, so no point in computing this + if (size() > LIST_CUTOFF) return; // we are not going to display file names, so no point in computing this int maxDepth = 0; int[] len = new int[size()]; String[][] tokens = new String[size()][]; - for( int i=0; i names = new HashMap<>(); + Map names = new HashMap<>(); for (int i = 0; i < tokens.length; i++) { String[] token = tokens[i]; - String displayName = combineLast(token,len[i]); + String displayName = combineLast(token, len[i]); Integer j = names.put(displayName, i); - if(j!=null) { + if (j != null) { collision = true; - if(j>=0) + if (j >= 0) len[j]++; len[i]++; - names.put(displayName,-1); // occupy this name but don't let len[i] incremented with additional collisions + names.put(displayName, -1); // occupy this name but don't let len[i] incremented with additional collisions } } - } while(collision && depth++ names = new HashSet(); -// for (String[] token : tokens) { -// if(!names.add(combineLast(token,n))) -// continue OUTER; // collision. Increase n and try again -// } -// -// // this n successfully disambiguates -// for (int i = 0; i < tokens.length; i++) { -// String[] token = tokens[i]; -// get(i).displayPath = combineLast(token,n); -// } -// return; -// } - -// // it's impossible to get here, as that means -// // we have the same artifacts archived twice, but be defensive -// for (Artifact a : this) -// a.displayPath = a.relativePath; + get(i).displayPath = combineLast(tokens[i], len[i]); } /** @@ -1354,8 +1343,8 @@ public void computeDisplayName() { */ private String combineLast(String[] token, int n) { StringBuilder buf = new StringBuilder(); - for( int i=Math.max(0,token.length-n); i0) buf.append('/'); + for (int i = Math.max(0, token.length - n); i < token.length; i++) { + if (buf.length() > 0) buf.append('/'); buf.append(token[i]); } return buf.toString(); @@ -1370,7 +1359,7 @@ public class Artifact { /** * Relative path name from artifacts root. */ - @Exported(visibility=3) + @Exported(visibility = 3) public final String relativePath; /** @@ -1397,7 +1386,7 @@ public class Artifact { private String treeNodeId; /** - *length of this artifact for files. + * length of this artifact for files. */ private String length; @@ -1419,18 +1408,18 @@ public class Artifact { */ @Deprecated public @NonNull File getFile() { - return new File(getArtifactsDir(),relativePath); + return new File(getArtifactsDir(), relativePath); } /** * Returns just the file name portion, without the path. */ - @Exported(visibility=3) + @Exported(visibility = 3) public String getFileName() { return name; } - @Exported(visibility=3) + @Exported(visibility = 3) public String getDisplayPath() { return displayPath; } @@ -1442,8 +1431,8 @@ public String getHref() { public String getLength() { return length; } - - public long getFileSize(){ + + public long getFileSize() { try { return Long.decode(length); } @@ -1477,11 +1466,12 @@ public Collection getBuildFingerprints() { } return Collections.emptyList(); } - + /** * Returns the log file. * @return The file may reference both uncompressed or compressed logs - * @deprecated Assumes file-based storage of the log, which is not necessarily the case for Pipelines after JEP-210. Use other methods giving various kinds of streams such as {@link Run#getLogReader()}, {@link Run#getLogInputStream()}, or {@link Run#getLogText()}. + * @deprecated Assumes file-based storage of the log, which is not necessarily the case for Pipelines after JEP-210. + * Use other methods giving various kinds of streams such as {@link Run#getLogReader()}, {@link Run#getLogInputStream()}, or {@link Run#getLogText()}. */ @Deprecated public @NonNull File getLogFile() { @@ -1501,16 +1491,15 @@ public Collection getBuildFingerprints() { * Returns an input stream that reads from the log file. * It will use a gzip-compressed log file (log.gz) if that exists. * - * @throws IOException - * @return An input stream from the log file. + * @return An input stream from the log file. * If the log file does not exist, the error message will be returned to the output. * @since 1.349 */ public @NonNull InputStream getLogInputStream() throws IOException { - File logFile = getLogFile(); - - if (logFile.exists() ) { - // Checking if a ".gz" file was return + File logFile = getLogFile(); + + if (logFile.exists()) { + // Checking if a ".gz" file was return try { InputStream fis = Files.newInputStream(logFile.toPath()); if (logFile.getName().endsWith(".gz")) { @@ -1521,15 +1510,15 @@ public Collection getBuildFingerprints() { } catch (InvalidPathException e) { throw new IOException(e); } - } - + } + String message = "No such file: " + logFile; - return new ByteArrayInputStream(charset != null ? message.getBytes(charset) : message.getBytes()); + return new ByteArrayInputStream(charset != null ? message.getBytes(charset) : message.getBytes(Charset.defaultCharset())); } - + public @NonNull Reader getLogReader() throws IOException { - if (charset==null) return new InputStreamReader(getLogInputStream()); - else return new InputStreamReader(getLogInputStream(),charset); + if (charset == null) return new InputStreamReader(getLogInputStream(), Charset.defaultCharset()); + else return new InputStreamReader(getLogInputStream(), charset); } /** @@ -1537,6 +1526,7 @@ public Collection getBuildFingerprints() { * * @since 1.349 */ + @SuppressFBWarnings(value = "RV_RETURN_VALUE_IGNORED", justification = "method signature does not permit plumbing through the return value") public void writeLogTo(long offset, @NonNull XMLOutput out) throws IOException { long start = offset; if (offset > 0) { @@ -1545,7 +1535,7 @@ public void writeLogTo(long offset, @NonNull XMLOutput out) throws IOException { int r; do { r = bufferedInputStream.read(); - start = (r == -1)? 0 : start + 1; + start = r == -1 ? 0 : start + 1; } while (r != -1 && r != '\n'); } } @@ -1579,9 +1569,9 @@ public void writeWholeLogTo(@NonNull OutputStream out) throws IOException, Inter /** * Used to URL-bind {@link AnnotatedLargeText}. * @return A {@link Run} log with annotations - */ + */ public @NonNull AnnotatedLargeText getLogText() { - return new AnnotatedLargeText(getLogFile(),getCharset(),!isLogUpdated(),this); + return new AnnotatedLargeText(getLogFile(), getCharset(), !isLogUpdated(), this); } @Override @@ -1590,7 +1580,7 @@ public void writeWholeLogTo(@NonNull OutputStream out) throws IOException, Inter .add("console") .add("changes"); for (Action a : getAllActions()) { - if(a.getIconFileName()!=null) + if (a.getIconFileName() != null) builder.add(a.getUrlName()); } return builder; @@ -1607,7 +1597,7 @@ public ACL getACL() { } /** - * Deletes this build's artifacts. + * Deletes this build's artifacts. * * @throws IOException * if we fail to delete. @@ -1630,7 +1620,7 @@ public synchronized void deleteArtifacts() throws IOException { */ public void delete() throws IOException { synchronized (this) { - // Avoid concurrent delete. See https://issues.jenkins-ci.org/browse/JENKINS-61687 + // Avoid concurrent delete. See https://issues.jenkins.io/browse/JENKINS-61687 if (isPendingDelete) { return; } @@ -1653,17 +1643,17 @@ public void delete() throws IOException { } return; } - + //The root dir exists and is a directory that needs to be purged RunListener.fireDeleted(this); - + if (artifactManager != null) { deleteArtifacts(); } // for StandardArtifactManager, deleting the whole build dir suffices - + synchronized (this) { // avoid holding a lock while calling plugin impls of onDeleted - File tmp = new File(rootDir.getParentFile(),'.'+rootDir.getName()); - + File tmp = new File(rootDir.getParentFile(), '.' + rootDir.getName()); + if (tmp.exists()) { Util.deleteRecursive(tmp); } @@ -1674,9 +1664,9 @@ public void delete() throws IOException { StandardCopyOption.ATOMIC_MOVE ); } catch (UnsupportedOperationException | SecurityException ex) { - throw new IOException(rootDir + " is in use"); + throw new IOException(rootDir + " is in use", ex); } - + Util.deleteRecursive(tmp); // some user reported that they see some left-over .xyz files in the workspace, // so just to make sure we've really deleted it, schedule the deletion on VM exit, too. @@ -1690,7 +1680,7 @@ public void delete() throws IOException { @SuppressWarnings("unchecked") // seems this is too clever for Java's type system? private void removeRunFromParent() { - getParent().removeRun((RunT)this); + getParent().removeRun((RunT) this); } @@ -1698,7 +1688,7 @@ private void removeRunFromParent() { * @see CheckPoint#report() */ /*package*/ static void reportCheckpoint(@NonNull CheckPoint id) { - Run.RunExecution exec = RunnerStack.INSTANCE.peek(); + Run.RunExecution exec = RunnerStack.INSTANCE.peek(); if (exec == null) { return; } @@ -1709,20 +1699,20 @@ private void removeRunFromParent() { * @see CheckPoint#block() */ /*package*/ static void waitForCheckpoint(@NonNull CheckPoint id, @CheckForNull BuildListener listener, @CheckForNull String waiter) throws InterruptedException { - while(true) { - Run.RunExecution exec = RunnerStack.INSTANCE.peek(); + while (true) { + Run.RunExecution exec = RunnerStack.INSTANCE.peek(); if (exec == null) { return; } Run b = exec.getBuild().getPreviousBuildInProgress(); - if(b==null) return; // no pending earlier build + if (b == null) return; // no pending earlier build Run.RunExecution runner = b.runner; - if(runner==null) { + if (runner == null) { // polled at the wrong moment. try again. Thread.sleep(0); continue; } - if(runner.checkpoints.waitForCheckPoint(id, listener, waiter)) + if (runner.checkpoints.waitForCheckPoint(id, listener, waiter)) return; // confirmed that the previous build reached the check point // the previous build finished without ever reaching the check point. try again. @@ -1742,7 +1732,7 @@ protected abstract class Runner extends RunExecution {} */ public abstract class RunExecution { /** - * Keeps track of the check points attained by a build, and abstracts away the synchronization needed to + * Keeps track of the check points attained by a build, and abstracts away the synchronization needed to * maintain this data structure. */ private final class CheckpointSet { @@ -1789,7 +1779,7 @@ private synchronized void allDone() { private final CheckpointSet checkpoints = new CheckpointSet(); - private final Map attributes = new HashMap<>(); + private final Map attributes = new HashMap<>(); /** * Performs the main build and returns the status code. @@ -1797,7 +1787,7 @@ private synchronized void allDone() { * @throws Exception * exception will be recorded and the build will be considered a failure. */ - public abstract @NonNull Result run(@NonNull BuildListener listener ) throws Exception, RunnerAbortedException; + public abstract @NonNull Result run(@NonNull BuildListener listener) throws Exception; /** * Performs the post-build action. @@ -1809,7 +1799,7 @@ private synchronized void allDone() { * even if the build is successful, this build still won't be picked up * by {@link Job#getLastSuccessfulBuild()}. */ - public abstract void post(@NonNull BuildListener listener ) throws Exception; + public abstract void post(@NonNull BuildListener listener) throws Exception; /** * Performs final clean up action. @@ -1837,7 +1827,7 @@ private synchronized void allDone() { * * @since 1.473 */ - public @NonNull Map getAttributes() { + public @NonNull Map getAttributes() { return attributes; } } @@ -1861,11 +1851,11 @@ protected final void run(@NonNull Runner job) { } protected final void execute(@NonNull RunExecution job) { - if(result!=null) + if (result != null) return; // already built. OutputStream logger = null; - StreamBuildListener listener=null; + StreamBuildListener listener = null; runner = job; onStartBuilding(); @@ -1901,7 +1891,7 @@ protected final void execute(@NonNull RunExecution job) { listener.getLogger().println(Messages.Run_running_as_(id)); } - RunListener.fireStarted(this,listener); + RunListener.fireStarted(this, listener); setResult(job.run(listener)); @@ -1909,50 +1899,50 @@ protected final void execute(@NonNull RunExecution job) { CheckPoint.MAIN_COMPLETED.report(); } catch (ThreadDeath t) { throw t; - } catch( AbortException e ) {// orderly abortion. + } catch (AbortException e) { // orderly abortion. result = Result.FAILURE; listener.error(e.getMessage()); - LOGGER.log(FINE, "Build "+this+" aborted",e); - } catch( RunnerAbortedException e ) {// orderly abortion. + LOGGER.log(FINE, "Build " + this + " aborted", e); + } catch (RunnerAbortedException e) { // orderly abortion. result = Result.FAILURE; - LOGGER.log(FINE, "Build "+this+" aborted",e); - } catch( InterruptedException e) { + LOGGER.log(FINE, "Build " + this + " aborted", e); + } catch (InterruptedException e) { // aborted result = Executor.currentExecutor().abortResult(); listener.getLogger().println(Messages.Run_BuildAborted()); - Executor.currentExecutor().recordCauseOfInterruption(Run.this,listener); + Executor.currentExecutor().recordCauseOfInterruption(Run.this, listener); LOGGER.log(Level.INFO, this + " aborted", e); - } catch( Throwable e ) { - handleFatalBuildProblem(listener,e); + } catch (Throwable e) { + handleFatalBuildProblem(listener, e); result = Result.FAILURE; } // even if the main build fails fatally, try to run post build processing - job.post(listener); + job.post(Objects.requireNonNull(listener)); } catch (ThreadDeath t) { throw t; - } catch( Throwable e ) { - handleFatalBuildProblem(listener,e); + } catch (Throwable e) { + handleFatalBuildProblem(listener, e); result = Result.FAILURE; } finally { long end = System.currentTimeMillis(); - duration = Math.max(end - start, 0); // @see HUDSON-5844 + duration = Math.max(end - start, 0); // @see JENKINS-5844 // advance the state. // the significance of doing this is that Jenkins // will now see this build as completed. // things like triggering other builds requires this as pre-condition. - // see issue #980. + // see issue JENKINS-980. LOGGER.log(FINER, "moving into POST_PRODUCTION on {0}", this); state = State.POST_PRODUCTION; if (listener != null) { - RunListener.fireCompleted(this,listener); + RunListener.fireCompleted(this, listener); try { job.cleanUp(listener); } catch (Exception e) { - handleFatalBuildProblem(listener,e); + handleFatalBuildProblem(listener, e); // too late to update the result now } listener.finished(result); @@ -1962,14 +1952,14 @@ protected final void execute(@NonNull RunExecution job) { try { save(); } catch (IOException e) { - LOGGER.log(Level.SEVERE, "Failed to save build record",e); + LOGGER.log(Level.SEVERE, "Failed to save build record", e); } } try { getParent().logRotate(); } catch (Exception e) { - LOGGER.log(Level.SEVERE, "Failed to rotate log",e); + LOGGER.log(Level.SEVERE, "Failed to rotate log", e); } } finally { onEndBuilding(); @@ -2010,7 +2000,7 @@ private StreamBuildListener createBuildListener(@NonNull RunExecution job, Outpu } } - return new StreamBuildListener(logger,charset); + return new StreamBuildListener(logger, charset); } /** @@ -2023,15 +2013,15 @@ public final void updateSymlinks(@NonNull TaskListener listener) throws Interrup * Handles a fatal build problem (exception) that occurred during the build. */ private void handleFatalBuildProblem(@NonNull BuildListener listener, @NonNull Throwable e) { - if(listener!=null) { - LOGGER.log(FINE, getDisplayName()+" failed to build",e); + if (listener != null) { + LOGGER.log(FINE, getDisplayName() + " failed to build", e); - if(e instanceof IOException) - Util.displayIOException((IOException)e,listener); + if (e instanceof IOException) + Util.displayIOException((IOException) e, listener); Functions.printStackTrace(e, listener.fatalError(e.getMessage())); } else { - LOGGER.log(SEVERE, getDisplayName()+" failed to build and we don't even have a listener",e); + LOGGER.log(SEVERE, getDisplayName() + " failed to build and we don't even have a listener", e); } } @@ -2042,7 +2032,7 @@ protected void onStartBuilding() { LOGGER.log(FINER, "moving to BUILDING on {0}", this); state = State.BUILDING; startTime = System.currentTimeMillis(); - if (runner!=null) + if (runner != null) RunnerStack.INSTANCE.push(runner); RunListener.fireInitialize(this); } @@ -2054,7 +2044,7 @@ protected void onEndBuilding() { // signal that we've finished building. state = State.COMPLETED; LOGGER.log(FINER, "moving to COMPLETED on {0}", this); - if (runner!=null) { + if (runner != null) { // MavenBuilds may be created without their corresponding runners. runner.checkpoints.allDone(); runner = null; @@ -2071,24 +2061,28 @@ protected void onEndBuilding() { /** * Save the settings to a file. */ + @Override public synchronized void save() throws IOException { - if(BulkChange.contains(this)) return; + if (BulkChange.contains(this)) return; getDataFile().write(this); SaveableListener.fireOnChange(this, getDataFile()); } private @NonNull XmlFile getDataFile() { - return new XmlFile(XSTREAM,new File(getRootDir(),"build.xml")); + return new XmlFile(XSTREAM, new File(getRootDir(), "build.xml")); } protected Object writeReplace() { return XmlFile.replaceIfNotAtTopLevel(this, () -> new Replacer(this)); } + private static class Replacer { private final String id; + Replacer(Run r) { id = r.getExternalizableId(); } + private Object readResolve() { return fromExternalizableId(id); } @@ -2103,7 +2097,7 @@ private Object readResolve() { */ @Deprecated public @NonNull String getLog() throws IOException { - return Util.loadFile(getLogFile(),getCharset()); + return Util.loadFile(getLogFile(), getCharset()); } /** @@ -2154,7 +2148,7 @@ private Object readResolve() { // Use set (replaces the first element) rather than add so that // the list doesn't grow beyond the specified maximum number of lines. if (lines == maxLines) { - lastLines.set(0, "[...truncated " + Functions.humanReadableByteSize(filePointer)+ "...]"); + lastLines.set(0, "[...truncated " + Functions.humanReadableByteSize(filePointer) + "...]"); } return ConsoleNote.removeNotes(lastLines); @@ -2166,8 +2160,8 @@ private String convertBytesToString(List bytes) { return new String(ArrayUtils.toPrimitive(byteArray), getCharset()); } - public void doBuildStatus( StaplerRequest req, StaplerResponse rsp ) throws IOException { - rsp.sendRedirect2(req.getContextPath()+"/images/48x48/"+getBuildStatusUrl()); + public void doBuildStatus(StaplerRequest req, StaplerResponse rsp) throws IOException { + rsp.sendRedirect2(req.getContextPath() + "/images/48x48/" + getBuildStatusUrl()); } public @NonNull String getBuildStatusUrl() { @@ -2202,7 +2196,7 @@ public abstract static class StatusSummarizer implements ExtensionPoint { * @param trend the result of {@link ResultTrend#getResultTrend(hudson.model.Run)} on {@code run} (precomputed for efficiency) * @return a summary, or null to fall back to other summarizers or built-in behavior */ - public abstract @CheckForNull Summary summarize(@NonNull Run run, @NonNull ResultTrend trend); + public abstract @CheckForNull Summary summarize(@NonNull Run run, @NonNull ResultTrend trend); } /** @@ -2214,9 +2208,9 @@ public abstract static class StatusSummarizer implements ExtensionPoint { if (isBuilding()) { return new Summary(false, Messages.Run_Summary_Unknown()); } - + ResultTrend trend = ResultTrend.getResultTrend(this); - + for (StatusSummarizer summarizer : ExtensionList.lookup(StatusSummarizer.class)) { Summary summary = summarizer.summarize(this, trend); if (summary != null) { @@ -2225,34 +2219,34 @@ public abstract static class StatusSummarizer implements ExtensionPoint { } switch (trend) { - case ABORTED : return new Summary(false, Messages.Run_Summary_Aborted()); - - case NOT_BUILT : return new Summary(false, Messages.Run_Summary_NotBuilt()); - - case FAILURE : return new Summary(true, Messages.Run_Summary_BrokenSinceThisBuild()); - - case STILL_FAILING : + case ABORTED: return new Summary(false, Messages.Run_Summary_Aborted()); + + case NOT_BUILT: return new Summary(false, Messages.Run_Summary_NotBuilt()); + + case FAILURE: return new Summary(true, Messages.Run_Summary_BrokenSinceThisBuild()); + + case STILL_FAILING: RunT since = getPreviousNotFailedBuild(); - if(since==null) + if (since == null) return new Summary(false, Messages.Run_Summary_BrokenForALongTime()); RunT failedBuild = since.getNextBuild(); return new Summary(false, Messages.Run_Summary_BrokenSince(failedBuild.getDisplayName())); - + case NOW_UNSTABLE: - case STILL_UNSTABLE : + case STILL_UNSTABLE: return new Summary(false, Messages.Run_Summary_Unstable()); - case UNSTABLE : + case UNSTABLE: return new Summary(true, Messages.Run_Summary_Unstable()); - - case SUCCESS : + + case SUCCESS: return new Summary(false, Messages.Run_Summary_Stable()); - - case FIXED : + + case FIXED: return new Summary(false, Messages.Run_Summary_BackToNormal()); - + + default: + return new Summary(false, Messages.Run_Summary_Unknown()); } - - return new Summary(false, Messages.Run_Summary_Unknown()); } /** @@ -2260,7 +2254,7 @@ public abstract static class StatusSummarizer implements ExtensionPoint { * @throws AccessDeniedException Access denied */ public @NonNull DirectoryBrowserSupport doArtifact() { - if(Functions.isArtifactsPermissionEnabled()) { + if (Functions.isArtifactsPermissionEnabled()) { checkPermission(ARTIFACTS); } return new DirectoryBrowserSupport(this, getArtifactManager().root(), Messages.Run_ArtifactsBrowserTitle(project.getDisplayName(), getDisplayName()), "package.png", true); @@ -2279,13 +2273,13 @@ public void doBuildNumber(StaplerResponse rsp) throws IOException { /** * Returns the build time stamp in the body. */ - public void doBuildTimestamp( StaplerRequest req, StaplerResponse rsp, @QueryParameter String format) throws IOException { + public void doBuildTimestamp(StaplerRequest req, StaplerResponse rsp, @QueryParameter String format) throws IOException { rsp.setContentType("text/plain"); rsp.setCharacterEncoding("US-ASCII"); rsp.setStatus(HttpServletResponse.SC_OK); - DateFormat df = format==null ? - DateFormat.getDateTimeInstance(DateFormat.SHORT,DateFormat.SHORT, Locale.ENGLISH) : - new SimpleDateFormat(format,req.getLocale()); + DateFormat df = format == null ? + DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, Locale.ENGLISH) : + new SimpleDateFormat(format, req.getLocale()); rsp.getWriter().print(df.format(getTime())); } @@ -2307,8 +2301,8 @@ public void doConsoleText(StaplerRequest req, StaplerResponse rsp) throws IOExce * Use {@code getLogText().doProgressiveText(req,rsp)} */ @Deprecated - public void doProgressiveLog( StaplerRequest req, StaplerResponse rsp) throws IOException { - getLogText().doProgressText(req,rsp); + public void doProgressiveLog(StaplerRequest req, StaplerResponse rsp) throws IOException { + getLogText().doProgressText(req, rsp); } /** @@ -2329,7 +2323,7 @@ public boolean canToggleLogKeep() { } @RequirePOST - public void doToggleLogKeep( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException { + public void doToggleLogKeep(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { keepLog(!keepLog); rsp.forwardToPreviousPage(req); } @@ -2337,7 +2331,7 @@ public void doToggleLogKeep( StaplerRequest req, StaplerResponse rsp ) throws IO /** * Marks this build to be kept. */ - @CLIMethod(name="keep-build") + @CLIMethod(name = "keep-build") public final void keepLog() throws IOException { keepLog(true); } @@ -2352,27 +2346,27 @@ public void keepLog(boolean newValue) throws IOException { * Deletes the build when the button is pressed. */ @RequirePOST - public void doDoDelete( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException { + public void doDoDelete(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { checkPermission(DELETE); // We should not simply delete the build if it has been explicitly // marked to be preserved, or if the build should not be deleted // due to dependencies! String why = getWhyKeepLog(); - if (why!=null) { + if (why != null) { sendError(Messages.Run_UnableToDelete(getFullDisplayName(), why), req, rsp); return; } - try{ + try { delete(); } - catch(IOException ex){ + catch (IOException ex) { req.setAttribute("stackTraces", Functions.printThrowable(ex)); - req.getView(this, "delete-retry.jelly").forward(req, rsp); + req.getView(this, "delete-retry.jelly").forward(req, rsp); return; } - rsp.sendRedirect2(req.getContextPath()+'/' + getParent().getUrl()); + rsp.sendRedirect2(req.getContextPath() + '/' + getParent().getUrl()); } public void setDescription(String description) throws IOException { @@ -2380,12 +2374,12 @@ public void setDescription(String description) throws IOException { this.description = description; save(); } - + /** * Accepts the new description. */ @RequirePOST - public synchronized void doSubmitDescription( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException { + public synchronized void doSubmitDescription(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { setDescription(req.getParameter("description")); rsp.sendRedirect("."); // go to the top page } @@ -2395,7 +2389,7 @@ public synchronized void doSubmitDescription( StaplerRequest req, StaplerRespons * Use {@link #getEnvironment(TaskListener)} instead. */ @Deprecated - public Map getEnvVars() { + public Map getEnvVars() { LOGGER.log(WARNING, "deprecated call to Run.getEnvVars\n\tat {0}", new Throwable().getStackTrace()[1]); try { return getEnvironment(new LogTaskListener(LOGGER, Level.INFO)); @@ -2425,20 +2419,20 @@ public EnvVars getEnvironment() throws IOException, InterruptedException { *

    * Unlike earlier {@link #getEnvVars()}, this map contains the whole environment, * not just the overrides, so one can introspect values to change its behavior. - * + * * @return the map with the environmental variables. * @since 1.305 */ public @NonNull EnvVars getEnvironment(@NonNull TaskListener listener) throws IOException, InterruptedException { Computer c = Computer.currentComputer(); - Node n = c==null ? null : c.getNode(); + Node n = c == null ? null : c.getNode(); - EnvVars env = getParent().getEnvironment(n,listener); + EnvVars env = getParent().getEnvironment(n, listener); env.putAll(getCharacteristicEnvVars()); // apply them in a reverse order so that higher ordinal ones can modify values added by lower ordinal ones for (EnvironmentContributor ec : EnvironmentContributor.all().reverseView()) - ec.buildEnvironmentFor(this,env,listener); + ec.buildEnvironmentFor(this, env, listener); if (!(this instanceof AbstractBuild)) { for (EnvironmentContributingAction a : getActions(EnvironmentContributingAction.class)) { @@ -2455,9 +2449,9 @@ public EnvVars getEnvironment() throws IOException, InterruptedException { */ public @NonNull final EnvVars getCharacteristicEnvVars() { EnvVars env = getParent().getCharacteristicEnvVars(); - env.put("BUILD_NUMBER",String.valueOf(number)); - env.put("BUILD_ID",getId()); - env.put("BUILD_TAG","jenkins-"+getParent().getFullName().replace('/', '-')+"-"+number); + env.put("BUILD_NUMBER", String.valueOf(number)); + env.put("BUILD_ID", getId()); + env.put("BUILD_TAG", "jenkins-" + getParent().getFullName().replace('/', '-') + "-" + number); return env; } @@ -2477,7 +2471,7 @@ public EnvVars getEnvironment() throws IOException, InterruptedException { * @throws IllegalArgumentException if the ID is malformed * @throws AccessDeniedException as per {@link ItemGroup#getItem} */ - public @CheckForNull static Run fromExternalizableId(String id) throws IllegalArgumentException, AccessDeniedException { + public @CheckForNull static Run fromExternalizableId(String id) throws IllegalArgumentException, AccessDeniedException { int hash = id.lastIndexOf('#'); if (hash <= 0) { throw new IllegalArgumentException("Invalid id"); @@ -2493,7 +2487,7 @@ public EnvVars getEnvironment() throws IOException, InterruptedException { if (j == null) { return null; } - Job job = j.getItemByFullName(jobName, Job.class); + Job job = j.getItemByFullName(jobName, Job.class); if (job == null) { return null; } @@ -2504,7 +2498,7 @@ public EnvVars getEnvironment() throws IOException, InterruptedException { * Returns the estimated duration for this run if it is currently running. * Default to {@link Job#getEstimatedDuration()}, may be overridden in subclasses * if duration may depend on run specific parameters (like incremental Maven builds). - * + * * @return the estimated duration in milliseconds * @since 1.383 */ @@ -2514,7 +2508,7 @@ public long getEstimatedDuration() { } @POST - public @NonNull HttpResponse doConfigSubmit( StaplerRequest req ) throws IOException, ServletException, FormException { + public @NonNull HttpResponse doConfigSubmit(StaplerRequest req) throws IOException, ServletException, FormException { checkPermission(UPDATE); try (BulkChange bc = new BulkChange(this)) { JSONObject json = req.getSubmittedForm(); @@ -2534,19 +2528,20 @@ protected void submit(JSONObject json) throws IOException { /** * Alias to {@link #XSTREAM} so that one can access additional methods on {@link XStream2} more easily. */ - public static final XStream2 XSTREAM2 = (XStream2)XSTREAM; + public static final XStream2 XSTREAM2 = (XStream2) XSTREAM; static { - XSTREAM.alias("build",FreeStyleBuild.class); + XSTREAM.alias("build", FreeStyleBuild.class); XSTREAM.registerConverter(Result.conv); } private static final Logger LOGGER = Logger.getLogger(Run.class.getName()); /** - * Sort by date. Newer ones first. + * Sort by date. Newer ones first. */ public static final Comparator ORDER_BY_DATE = new Comparator() { + @Override public int compare(@NonNull Run lhs, @NonNull Run rhs) { long lt = lhs.getTimeInMillis(); long rt = rhs.getTimeInMillis(); @@ -2570,7 +2565,7 @@ public int compare(@NonNull Run lhs, @NonNull Run rhs) { @Override public String getEntryID(Run e) { // can't use a meaningful year field unless we remember when the job was created. - return "tag:hudson.dev.java.net,2008:"+e.getParent().getAbsoluteUrl(); + return "tag:hudson.dev.java.net,2008:" + e.getParent().getAbsoluteUrl(); } }; @@ -2578,42 +2573,54 @@ public String getEntryID(Run e) { * {@link BuildBadgeAction} that shows the build is being kept. */ public final class KeepLogBuildBadge implements BuildBadgeAction { + @Override public @CheckForNull String getIconFileName() { return null; } + + @Override public @CheckForNull String getDisplayName() { return null; } + + @Override public @CheckForNull String getUrlName() { return null; } + public @CheckForNull String getWhyKeepLog() { return Run.this.getWhyKeepLog(); } } - public static final PermissionGroup PERMISSIONS = new PermissionGroup(Run.class,Messages._Run_Permissions_Title()); - public static final Permission DELETE = new Permission(PERMISSIONS,"Delete",Messages._Run_DeletePermission_Description(),Permission.DELETE, PermissionScope.RUN); - public static final Permission UPDATE = new Permission(PERMISSIONS,"Update",Messages._Run_UpdatePermission_Description(),Permission.UPDATE, PermissionScope.RUN); + public static final PermissionGroup PERMISSIONS = new PermissionGroup(Run.class, Messages._Run_Permissions_Title()); + public static final Permission DELETE = new Permission(PERMISSIONS, "Delete", Messages._Run_DeletePermission_Description(), Permission.DELETE, PermissionScope.RUN); + public static final Permission UPDATE = new Permission(PERMISSIONS, "Update", Messages._Run_UpdatePermission_Description(), Permission.UPDATE, PermissionScope.RUN); /** See {@link hudson.Functions#isArtifactsPermissionEnabled} */ - public static final Permission ARTIFACTS = new Permission(PERMISSIONS,"Artifacts",Messages._Run_ArtifactsPermission_Description(), null, + public static final Permission ARTIFACTS = new Permission(PERMISSIONS, "Artifacts", Messages._Run_ArtifactsPermission_Description(), null, Functions.isArtifactsPermissionEnabled(), new PermissionScope[]{PermissionScope.RUN}); private static class DefaultFeedAdapter implements FeedAdapter { + @Override public String getEntryTitle(Run entry) { - return entry.getFullDisplayName()+" ("+entry.getBuildStatusSummary().message+")"; + return entry.getFullDisplayName() + " (" + entry.getBuildStatusSummary().message + ")"; } + @Override public String getEntryUrl(Run entry) { return entry.getUrl(); } + @Override public String getEntryID(Run entry) { return "tag:" + "hudson.dev.java.net," + entry.getTimestamp().get(Calendar.YEAR) + ":" - + entry.getParent().getFullName()+':'+entry.getId(); + + entry.getParent().getFullName() + ':' + entry.getId(); } + @Override public String getEntryDescription(Run entry) { return entry.getDescription(); } + @Override public Calendar getEntryTimestamp(Run entry) { return entry.getTimestamp(); } + @Override public String getEntryAuthor(Run entry) { return JenkinsLocationConfiguration.get().getAdminAddress(); } @@ -2622,9 +2629,9 @@ public String getEntryAuthor(Run entry) { @Override public Object getDynamic(String token, StaplerRequest req, StaplerResponse rsp) { Object returnedResult = super.getDynamic(token, req, rsp); - if (returnedResult == null){ + if (returnedResult == null) { //check transient actions too - for(Action action: getTransientActions()){ + for (Action action : getTransientActions()) { String urlName = action.getUrlName(); if (urlName == null) { continue; @@ -2658,8 +2665,8 @@ public Object getTarget() { * Escape hatch for StaplerProxy-based access control */ @Restricted(NoExternalUse.class) - @SuppressFBWarnings("MS_SHOULD_BE_FINAL") - public static /* Script Console modifiable */ boolean SKIP_PERMISSION_CHECK = Boolean.getBoolean(Run.class.getName() + ".skipPermissionCheck"); + @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "for script console") + public static /* Script Console modifiable */ boolean SKIP_PERMISSION_CHECK = SystemProperties.getBoolean(Run.class.getName() + ".skipPermissionCheck"); public static class RedirectUp { diff --git a/core/src/main/java/hudson/model/RunAction.java b/core/src/main/java/hudson/model/RunAction.java index 995a12d52e2b..f02008bb5077 100644 --- a/core/src/main/java/hudson/model/RunAction.java +++ b/core/src/main/java/hudson/model/RunAction.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import jenkins.model.RunAction2; @@ -32,7 +33,7 @@ public interface RunAction extends Action { /** * Called after the build is loaded and the object is added to the build list. - * + * * Because {@link RunAction}s are persisted with {@link Run}, the implementation * can keep a reference to {@link Run} in a field (which is set via {@link #onAttached(Run)}) */ diff --git a/core/src/main/java/hudson/model/RunMap.java b/core/src/main/java/hudson/model/RunMap.java index ea45b651576d..955037ab3555 100644 --- a/core/src/main/java/hudson/model/RunMap.java +++ b/core/src/main/java/hudson/model/RunMap.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Tom Huybrechts - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,10 +21,18 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import static java.util.logging.Level.FINEST; +import static jenkins.model.lazy.AbstractLazyLoadRunMap.Direction.ASC; +import static jenkins.model.lazy.AbstractLazyLoadRunMap.Direction.DESC; + +import hudson.Util; import java.io.File; import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.file.Files; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; @@ -32,15 +40,11 @@ import java.util.NoSuchElementException; import java.util.SortedMap; import java.util.logging.Level; - -import static java.util.logging.Level.*; import java.util.logging.Logger; import jenkins.model.RunIdMigrator; import jenkins.model.lazy.AbstractLazyLoadRunMap; -import static jenkins.model.lazy.AbstractLazyLoadRunMap.Direction.*; import jenkins.model.lazy.BuildReference; import jenkins.model.lazy.LazyBuildMixIn; -import org.apache.commons.collections.comparators.ReverseComparator; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; @@ -54,11 +58,11 @@ * * @author Kohsuke Kawaguchi */ -public final class RunMap> extends AbstractLazyLoadRunMap implements Iterable { +public final class RunMap> extends AbstractLazyLoadRunMap implements Iterable { /** * Read-only view of this map. */ - private final SortedMap view = Collections.unmodifiableSortedMap(this); + private final SortedMap view = Collections.unmodifiableSortedMap(this); private Constructor cons; @@ -95,18 +99,21 @@ public boolean remove(R run) { /** * Walks through builds, newer ones first. */ + @Override public Iterator iterator() { return new Iterator() { R last = null; R next = newestBuild(); + @Override public boolean hasNext() { - return next!=null; + return next != null; } + @Override public R next() { last = next; - if (last!=null) + if (last != null) next = last.getPreviousBuild(); else throw new NoSuchElementException(); @@ -115,7 +122,7 @@ public R next() { @Override public void remove() { - if (last==null) + if (last == null) throw new UnsupportedOperationException(); removeValue(last); } @@ -132,7 +139,7 @@ public boolean removeValue(R run) { /** * Gets the read-only view of this map. */ - public SortedMap getView() { + public SortedMap getView() { return view; } @@ -152,19 +159,15 @@ public R oldestValue() { /** * @deprecated as of 1.485 - * Use {@link ReverseComparator} + * Use {@link Comparator#reverseOrder} */ @Deprecated - public static final Comparator COMPARATOR = new Comparator() { - public int compare(Comparable o1, Comparable o2) { - return o2.compareTo(o1); - } - }; + public static final Comparator COMPARATOR = Comparator.reverseOrder(); /** * {@link Run} factory. */ - public interface Constructor> { + public interface Constructor> { R create(File dir) throws IOException; } @@ -186,13 +189,17 @@ protected String getIdOf(R r) { public R put(R r) { // Defense against JENKINS-23152 and its ilk. File rootDir = r.getRootDir(); - if (rootDir.isDirectory()) { + if (Files.isDirectory(rootDir.toPath())) { throw new IllegalStateException("JENKINS-23152: " + rootDir + " already existed; will not overwrite with " + r); } if (!r.getClass().getName().equals("hudson.matrix.MatrixRun")) { // JENKINS-26739: grandfathered in proposeNewNumber(r.getNumber()); } - rootDir.mkdirs(); + try { + Util.createDirectories(rootDir.toPath()); + } catch (IOException e) { + throw new UncheckedIOException(e); + } return super._put(r); } @@ -219,7 +226,7 @@ protected BuildReference createReference(R r) { @Override protected R retrieve(File d) throws IOException { - if(new File(d,"build.xml").exists()) { + if (new File(d, "build.xml").exists()) { // if the build result file isn't in the directory, ignore it. try { R b = cons.create(d); diff --git a/core/src/main/java/hudson/model/RunParameterDefinition.java b/core/src/main/java/hudson/model/RunParameterDefinition.java index 1d8c19d0b180..3ac138a8761c 100644 --- a/core/src/main/java/hudson/model/RunParameterDefinition.java +++ b/core/src/main/java/hudson/model/RunParameterDefinition.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Tom Huybrechts, Geoff Cummings - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,22 +21,25 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import hudson.Extension; +import hudson.util.EnumConverter; +import hudson.util.RunList; import java.util.Objects; import java.util.logging.Logger; import jenkins.model.Jenkins; import net.sf.json.JSONObject; - import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.QueryParameter; +import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.export.Exported; -import hudson.Extension; -import hudson.util.EnumConverter; -import hudson.util.RunList; -import org.kohsuke.stapler.Stapler; -import org.kohsuke.stapler.QueryParameter; public class RunParameterDefinition extends SimpleParameterDefinition { @@ -58,7 +61,7 @@ public String getName() { Stapler.CONVERT_UTILS.register(new EnumConverter(), RunParameterFilter.class); } } - + private final String projectName; private final String runId; private final RunParameterFilter filter; @@ -68,7 +71,7 @@ public String getName() { * @since 1.517 */ @DataBoundConstructor - public RunParameterDefinition(String name, String projectName, String description, RunParameterFilter filter) { + public RunParameterDefinition(@NonNull String name, String projectName, @CheckForNull String description, @CheckForNull RunParameterFilter filter) { super(name, description); this.projectName = projectName; this.runId = null; @@ -77,14 +80,14 @@ public RunParameterDefinition(String name, String projectName, String descriptio /** * @deprecated as of 1.517 - */ + */ @Deprecated - public RunParameterDefinition(String name, String projectName, String description) { - // delegate to updated constructor with additional RunParameterFilter parameter defaulted to ALL. - this(name, projectName, description, RunParameterFilter.ALL); + public RunParameterDefinition(@NonNull String name, String projectName, @CheckForNull String description) { + // delegate to updated constructor with additional RunParameterFilter parameter defaulted to ALL. + this(name, projectName, description, RunParameterFilter.ALL); } - private RunParameterDefinition(String name, String projectName, String runId, String description, RunParameterFilter filter) { + private RunParameterDefinition(@NonNull String name, String projectName, String runId, @CheckForNull String description, @CheckForNull RunParameterFilter filter) { super(name, description); this.projectName = projectName; this.runId = runId; @@ -116,8 +119,8 @@ public Job getProject() { */ @Exported public RunParameterFilter getFilter() { - // if filter is null, default to RunParameterFilter.ALL - return (null == filter) ? RunParameterFilter.ALL : filter; + // if filter is null, default to RunParameterFilter.ALL + return null == filter ? RunParameterFilter.ALL : filter; } /** @@ -131,14 +134,14 @@ public RunList getBuilds() { return getProject().getBuilds().overThresholdOnly(Result.ABORTED).completedOnly(); case SUCCESSFUL: return getProject().getBuilds().overThresholdOnly(Result.UNSTABLE).completedOnly(); - case STABLE : + case STABLE: return getProject().getBuilds().overThresholdOnly(Result.SUCCESS).completedOnly(); default: return getProject().getBuilds(); } } - @Extension @Symbol({"run","runParam"}) + @Extension @Symbol({"run", "runParam"}) public static class DescriptorImpl extends ParameterDescriptor { @Override public String getDisplayName() { @@ -154,7 +157,7 @@ public String getHelpFile() { public ParameterDefinition newInstance(StaplerRequest req, JSONObject formData) throws FormException { return req.bindJSON(RunParameterDefinition.class, formData); } - + public AutoCompletionCandidates doAutoCompleteProjectName(@QueryParameter String value) { return AutoCompletionCandidates.ofJobNames(Job.class, value, null, Jenkins.get()); } @@ -167,7 +170,7 @@ public ParameterValue getDefaultParameterValue() { return createValue(runId); } - Run lastBuild; + Run lastBuild; Job project = getProject(); if (project == null) { @@ -182,7 +185,7 @@ public ParameterValue getDefaultParameterValue() { case SUCCESSFUL: lastBuild = project.getLastSuccessfulBuild(); break; - case STABLE : + case STABLE: lastBuild = project.getLastStableBuild(); break; default: @@ -191,9 +194,9 @@ public ParameterValue getDefaultParameterValue() { } if (lastBuild != null) { - return createValue(lastBuild.getExternalizableId()); + return createValue(lastBuild.getExternalizableId()); } else { - return null; + return null; } } @@ -204,6 +207,7 @@ public ParameterValue createValue(StaplerRequest req, JSONObject jo) { return value; } + @Override public RunParameterValue createValue(String value) { return new RunParameterValue(getName(), value, getDescription()); } @@ -217,6 +221,7 @@ public int hashCode() { } @Override + @SuppressFBWarnings(value = "EQ_GETCLASS_AND_CLASS_CONSTANT", justification = "ParameterDefinitionTest tests that subclasses are not equal to their parent classes, so the behavior appears to be intentional") public boolean equals(Object obj) { if (RunParameterDefinition.class != getClass()) return super.equals(obj); diff --git a/core/src/main/java/hudson/model/RunParameterValue.java b/core/src/main/java/hudson/model/RunParameterValue.java index 39e152666d18..23e94f66746c 100644 --- a/core/src/main/java/hudson/model/RunParameterValue.java +++ b/core/src/main/java/hudson/model/RunParameterValue.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Tom Huybrechts, Geoff Cummings - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,16 +21,16 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import edu.umd.cs.findbugs.annotations.CheckForNull; import hudson.EnvVars; +import java.util.Locale; import jenkins.model.Jenkins; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.export.Exported; -import edu.umd.cs.findbugs.annotations.CheckForNull; -import java.util.Locale; - public class RunParameterValue extends ParameterValue { private final String runId; @@ -64,7 +64,7 @@ private static String check(String runId) { public String getRunId() { return runId; } - + private String[] split() { if (runId == null) { return null; @@ -79,13 +79,13 @@ private String[] split() { @Exported public String getJobName() { String[] r = split(); - return r == null ? null : r[0]; + return r == null ? null : r[0]; } - + @Exported public String getNumber() { String[] r = split(); - return r == null ? null : r[1]; + return r == null ? null : r[1]; } @Override @@ -97,36 +97,36 @@ public Run getValue() { * Exposes the name/value as an environment variable. */ @Override - public void buildEnvironment(Run build, EnvVars env) { + public void buildEnvironment(Run build, EnvVars env) { Run run = getRun(); - - String value = (null == run) ? "UNKNOWN" : Jenkins.get().getRootUrl() + run.getUrl(); + + String value = null == run ? "UNKNOWN" : Jenkins.get().getRootUrl() + run.getUrl(); env.put(name, value); env.put(name + ".jobName", getJobName()); // undocumented, left for backward compatibility env.put(name + "_JOBNAME", getJobName()); // prefer this version - env.put(name + ".number" , getNumber ()); // same as above - env.put(name + "_NUMBER" , getNumber ()); - + env.put(name + ".number", getNumber()); // same as above + env.put(name + "_NUMBER", getNumber()); + // if run is null, default to the standard '#1' display name format - env.put(name + "_NAME", (null == run) ? "#" + getNumber() : run.getDisplayName()); // since 1.504 + env.put(name + "_NAME", null == run ? "#" + getNumber() : run.getDisplayName()); // since 1.504 - String buildResult = (null == run || null == run.getResult()) ? "UNKNOWN" : run.getResult().toString(); + String buildResult = null == run || null == run.getResult() ? "UNKNOWN" : run.getResult().toString(); env.put(name + "_RESULT", buildResult); // since 1.517 - env.put(name.toUpperCase(Locale.ENGLISH),value); // backward compatibility pre 1.345 + env.put(name.toUpperCase(Locale.ENGLISH), value); // backward compatibility pre 1.345 } - + @Override public String toString() { - return "(RunParameterValue) " + getName() + "='" + getRunId() + "'"; + return "(RunParameterValue) " + getName() + "='" + getRunId() + "'"; } @Override public String getShortDescription() { Run run = getRun(); - return name + "=" + ((null == run) ? getJobName() + " #" + getNumber() : run.getFullDisplayName()); + return name + "=" + (null == run ? getJobName() + " #" + getNumber() : run.getFullDisplayName()); } } diff --git a/core/src/main/java/hudson/model/RunnerStack.java b/core/src/main/java/hudson/model/RunnerStack.java index 0e93b5316824..6f4c57b242bf 100644 --- a/core/src/main/java/hudson/model/RunnerStack.java +++ b/core/src/main/java/hudson/model/RunnerStack.java @@ -21,14 +21,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import edu.umd.cs.findbugs.annotations.CheckForNull; import hudson.model.Run.RunExecution; - -import java.util.Stack; import java.util.Map; +import java.util.Stack; import java.util.WeakHashMap; -import edu.umd.cs.findbugs.annotations.CheckForNull; /** * Keeps track of {@link RunExecution}s that are currently executing on the given thread @@ -38,7 +38,7 @@ * @since 1.319 */ final class RunnerStack { - private final Map> stack = new WeakHashMap<>(); + private final Map> stack = new WeakHashMap<>(); synchronized void push(RunExecution r) { Executor e = Executor.currentExecutor(); @@ -50,7 +50,7 @@ synchronized void pop() { Executor e = Executor.currentExecutor(); Stack s = stack.get(e); s.pop(); - if(s.isEmpty()) stack.remove(e); + if (s.isEmpty()) stack.remove(e); } /** diff --git a/core/src/main/java/hudson/model/SCMedItem.java b/core/src/main/java/hudson/model/SCMedItem.java index 142e4f51535d..2cfd0dde7079 100644 --- a/core/src/main/java/hudson/model/SCMedItem.java +++ b/core/src/main/java/hudson/model/SCMedItem.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import hudson.scm.PollingResult; @@ -48,7 +49,7 @@ public interface SCMedItem extends BuildableItem { * This method must be always implemented as {@code (AbstractProject)this}, but * defining this method emphasizes the fact that this cast must be doable. */ - AbstractProject asProject(); + AbstractProject asProject(); /** * Checks if there's any update in SCM, and returns true if any is found. @@ -57,7 +58,7 @@ public interface SCMedItem extends BuildableItem { * Use {@link #poll(TaskListener)} instead. */ @Deprecated - boolean pollSCMChanges( TaskListener listener ); + boolean pollSCMChanges(TaskListener listener); /** * Checks if there's any update in SCM, and returns true if any is found. diff --git a/core/src/main/java/hudson/model/Saveable.java b/core/src/main/java/hudson/model/Saveable.java index a27d35e27dd2..c98900d99d64 100644 --- a/core/src/main/java/hudson/model/Saveable.java +++ b/core/src/main/java/hudson/model/Saveable.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import hudson.BulkChange; @@ -52,8 +53,6 @@ public interface Saveable { * {@link Saveable} that doesn't save anything. * @since 1.301. */ - Saveable NOOP = new Saveable() { - public void save() throws IOException { - } + Saveable NOOP = () -> { }; } diff --git a/core/src/main/java/hudson/model/SimpleParameterDefinition.java b/core/src/main/java/hudson/model/SimpleParameterDefinition.java index 647a588ebb5b..0be175bb4a86 100644 --- a/core/src/main/java/hudson/model/SimpleParameterDefinition.java +++ b/core/src/main/java/hudson/model/SimpleParameterDefinition.java @@ -1,10 +1,11 @@ package hudson.model; -import org.kohsuke.stapler.StaplerRequest; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.cli.CLICommand; - import java.io.IOException; import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.StaplerRequest; /** * Convenient base class for {@link ParameterDefinition} whose value can be represented in a context-independent single string token. @@ -12,7 +13,7 @@ * @author Kohsuke Kawaguchi */ public abstract class SimpleParameterDefinition extends ParameterDefinition { - protected SimpleParameterDefinition(String name) { + protected SimpleParameterDefinition(@NonNull String name) { super(name); } @@ -20,7 +21,7 @@ protected SimpleParameterDefinition(String name) { * @deprecated Prefer {@link #SimpleParameterDefinition(String)} with a {@link DataBoundConstructor} and allow {@link #setDescription} to be used as needed */ @Deprecated - protected SimpleParameterDefinition(String name, String description) { + protected SimpleParameterDefinition(@NonNull String name, @CheckForNull String description) { super(name, description); } diff --git a/core/src/main/java/hudson/model/Slave.java b/core/src/main/java/hudson/model/Slave.java index 1f33ba3e7a43..0517e73d7dcc 100644 --- a/core/src/main/java/hudson/model/Slave.java +++ b/core/src/main/java/hudson/model/Slave.java @@ -22,9 +22,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; -import com.google.common.collect.ImmutableSet; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.DescriptorExtensionList; import hudson.EnvVars; import hudson.FilePath; @@ -57,15 +59,16 @@ import java.net.URL; import java.net.URLConnection; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.jar.JarFile; import java.util.jar.Manifest; import java.util.logging.Level; import java.util.logging.Logger; -import edu.umd.cs.findbugs.annotations.CheckForNull; -import edu.umd.cs.findbugs.annotations.NonNull; import javax.servlet.ServletException; import jenkins.model.Jenkins; import jenkins.security.MasterToSlaveCallable; @@ -91,18 +94,18 @@ * *

    * TODO: move out more stuff to {@link DumbSlave}. - * + * * On February, 2016 a general renaming was done internally: the "slave" term was replaced by * "Agent". This change was applied in: UI labels/HTML pages, javadocs and log messages. * Java classes, fields, methods, etc were not renamed to avoid compatibility issues. - * See JENKINS-27268. + * See JENKINS-27268. * * @author Kohsuke Kawaguchi */ public abstract class Slave extends Node implements Serializable { - + private static final Logger LOGGER = Logger.getLogger(Slave.class.getName()); - + /** * Name of this agent node. */ @@ -115,7 +118,7 @@ public abstract class Slave extends Node implements Serializable { /** * Path to the root of the workspace from the view point of this node, such as "/hudson", this need not - * be absolute provided that the launcher establishes a consistent working directory, such as "./.jenkins-slave" + * be absolute provided that the launcher establishes a consistent working directory, such as "./.jenkins-agent" * when used with an SSH launcher. * * NOTE: if the administrator is using a relative path they are responsible for ensuring that the launcher used @@ -146,13 +149,13 @@ public abstract class Slave extends Node implements Serializable { /** * Whitespace-separated labels. */ - private String label=""; + private String label = ""; - private /*almost final*/ DescribableList,NodePropertyDescriptor> nodeProperties = + private /*almost final*/ DescribableList, NodePropertyDescriptor> nodeProperties = new DescribableList<>(this); /** - * Removed with no replacement. + * @deprecated Removed with no replacement. */ @Deprecated private transient String userId; @@ -162,21 +165,21 @@ public abstract class Slave extends Node implements Serializable { * @deprecated since 2.184 */ @Deprecated - public Slave(String name, String nodeDescription, String remoteFS, String numExecutors, + protected Slave(String name, String nodeDescription, String remoteFS, String numExecutors, Mode mode, String labelString, ComputerLauncher launcher, RetentionStrategy retentionStrategy, List> nodeProperties) throws FormException, IOException { - this(name,nodeDescription,remoteFS,Util.tryParseNumber(numExecutors, 1).intValue(),mode,labelString,launcher,retentionStrategy, nodeProperties); + this(name, nodeDescription, remoteFS, Util.tryParseNumber(numExecutors, 1).intValue(), mode, labelString, launcher, retentionStrategy, nodeProperties); } /** * @deprecated since 2009-02-20. */ @Deprecated - public Slave(String name, String nodeDescription, String remoteFS, int numExecutors, + protected Slave(String name, String nodeDescription, String remoteFS, int numExecutors, Mode mode, String labelString, ComputerLauncher launcher, RetentionStrategy retentionStrategy) throws FormException, IOException { - this(name, nodeDescription, remoteFS, numExecutors, mode, labelString, launcher, retentionStrategy, new ArrayList()); + this(name, nodeDescription, remoteFS, numExecutors, mode, labelString, launcher, retentionStrategy, new ArrayList()); } - public Slave(@NonNull String name, String remoteFS, ComputerLauncher launcher) throws FormException, IOException { + protected Slave(@NonNull String name, String remoteFS, ComputerLauncher launcher) throws FormException, IOException { this.name = name; this.remoteFS = remoteFS; this.launcher = launcher; @@ -187,7 +190,7 @@ public Slave(@NonNull String name, String remoteFS, ComputerLauncher launcher) t * Use {@link #Slave(String, String, ComputerLauncher)} and set the rest through setters. */ @Deprecated - public Slave(@NonNull String name, String nodeDescription, String remoteFS, int numExecutors, + protected Slave(@NonNull String name, String nodeDescription, String remoteFS, int numExecutors, Mode mode, String labelString, ComputerLauncher launcher, RetentionStrategy retentionStrategy, List> nodeProperties) throws FormException, IOException { this.name = name; this.description = nodeDescription; @@ -204,10 +207,7 @@ public Slave(@NonNull String name, String nodeDescription, String remoteFS, int if (name.equals("")) throw new FormException(Messages.Slave_InvalidConfig_NoName(), null); -// if (remoteFS.equals("")) -// throw new FormException(Messages.Slave_InvalidConfig_NoRemoteDir(name), null); - - if (this.numExecutors<=0) + if (this.numExecutors <= 0) throw new FormException(Messages.Slave_InvalidConfig_Executors(name), null); } @@ -237,7 +237,7 @@ public void setUserId(String userId){ } public ComputerLauncher getLauncher() { - if (launcher == null && !StringUtils.isEmpty(agentCommand)) { + if (launcher == null && agentCommand != null && !agentCommand.isEmpty()) { try { launcher = (ComputerLauncher) Jenkins.get().getPluginManager().uberClassLoader.loadClass("hudson.slaves.CommandLauncher").getConstructor(String.class, EnvVars.class).newInstance(agentCommand, null); agentCommand = null; @@ -258,6 +258,8 @@ public String getRemoteFS() { return remoteFS; } + @NonNull + @Override public String getNodeName() { return name; } @@ -266,6 +268,7 @@ public String getNodeName() { return getClass().getName() + "[" + name + "]"; } + @Override public void setNodeName(String name) { this.name = name; } @@ -275,10 +278,12 @@ public void setNodeDescription(String value) { this.description = value; } + @Override public String getNodeDescription() { return description; } + @Override public int getNumExecutors() { return numExecutors; } @@ -288,6 +293,7 @@ public void setNumExecutors(int n) { this.numExecutors = n; } + @Override public Mode getMode() { return mode; } @@ -297,9 +303,10 @@ public void setMode(Mode mode) { this.mode = mode; } + @Override public DescribableList, NodePropertyDescriptor> getNodeProperties() { assert nodeProperties != null; - return nodeProperties; + return nodeProperties; } @DataBoundSetter @@ -316,6 +323,7 @@ public void setRetentionStrategy(RetentionStrategy availabilityStrategy) { this.retentionStrategy = availabilityStrategy; } + @Override public String getLabelString() { return Util.fixNull(label).trim(); } @@ -329,14 +337,16 @@ public void setLabelString(String labelString) throws IOException { } @Override - public Callable getClockDifferenceCallable() { + public Callable getClockDifferenceCallable() { return new GetClockDifference1(); } + @Override public Computer createComputer() { return new SlaveComputer(this); } + @Override public FilePath getWorkspaceFor(TopLevelItem item) { for (WorkspaceLocator l : WorkspaceLocator.all()) { FilePath workspace = l.locate(item, this); @@ -346,10 +356,11 @@ public FilePath getWorkspaceFor(TopLevelItem item) { } FilePath r = getWorkspaceRoot(); - if(r==null) return null; // offline + if (r == null) return null; // offline return r.child(item.getFullName()); } + @Override @CheckForNull public FilePath getRootPath() { final SlaveComputer computer = getComputer(); @@ -368,7 +379,7 @@ public FilePath getRootPath() { */ public @CheckForNull FilePath getWorkspaceRoot() { FilePath r = getRootPath(); - if(r==null) return null; + if (r == null) return null; return r.child(WORKSPACE_ROOT); } @@ -382,7 +393,7 @@ public JnlpJar(String fileName) { this.fileName = fileName; } - public void doIndex( StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doIndex(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { URLConnection con = connect(); // since we end up redirecting users to jnlpJars/foo.jar/, set the content disposition // so that browsers can download them in the right file name. @@ -393,8 +404,9 @@ public void doIndex( StaplerRequest req, StaplerResponse rsp) throws IOException } } + @Override public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { - doIndex(req,rsp); + doIndex(req, rsp); } private URLConnection connect() throws IOException { @@ -404,7 +416,7 @@ private URLConnection connect() throws IOException { public URL getURL() throws IOException { String name = fileName; - + // Prevent the access to war contents & prevent the folder escaping (SECURITY-195) if (!ALLOWED_JNLPJARS_FILES.contains(name)) { throw new MalformedURLException("The specified file path " + fileName + " is not allowed due to security reasons"); @@ -427,9 +439,9 @@ public URL getURL() throws IOException { } } } - + URL res = Jenkins.get().servletContext.getResource("/WEB-INF/" + name); - if(res==null) { + if (res == null) { throw new FileNotFoundException(name); // giving up } else { LOGGER.log(Level.FINE, "found {0}", res); @@ -473,6 +485,7 @@ public byte[] readFully() throws IOException { * If there is no computer it will return a {@link hudson.Launcher.DummyLauncher}, otherwise it * will return a {@link hudson.Launcher.RemoteLauncher} instead. */ + @Override @NonNull public Launcher createLauncher(TaskListener listener) { SlaveComputer c = getComputer(); @@ -480,9 +493,9 @@ public Launcher createLauncher(TaskListener listener) { listener.error("Issue with creating launcher for agent " + name + ". Computer has been disconnected"); return new Launcher.DummyLauncher(listener); } else { - // TODO: ideally all the logic below should be inside the SlaveComputer class with proper locking to prevent race conditions, + // TODO: ideally all the logic below should be inside the SlaveComputer class with proper locking to prevent race conditions, // but so far there is no locks for setNode() hence it requires serious refactoring - + // Ensure that the Computer instance still points to this node // Otherwise we may end up running the command on a wrong (reconnected) Node instance. Slave node = c.getNode(); @@ -493,10 +506,10 @@ public Launcher createLauncher(TaskListener listener) { } return new Launcher.DummyLauncher(listener); } - + // RemoteLauncher requires an active Channel instance to operate correctly final Channel channel = c.getChannel(); - if (channel == null) { + if (channel == null) { reportLauncherCreateError("The agent has not been fully initialized yet", "No remoting channel to the agent OR it has not been fully initialized yet", listener); return new Launcher.DummyLauncher(listener); @@ -511,22 +524,22 @@ public Launcher createLauncher(TaskListener listener) { // isUnix is always set when the channel is not null, so it should never happen reportLauncherCreateError("The agent has not been fully initialized yet", "Cannot determine if the agent is a Unix one, the System status request has not completed yet. " + - "It is an invalid channel state, please report a bug to Jenkins if you see it.", + "It is an invalid channel state, please report a bug to Jenkins if you see it.", listener); return new Launcher.DummyLauncher(listener); } - + return new RemoteLauncher(listener, channel, isUnix).decorateFor(this); } } - + private void reportLauncherCreateError(@NonNull String humanReadableMsg, @CheckForNull String exceptionDetails, @NonNull TaskListener listener) { String message = "Issue with creating launcher for agent " + name + ". " + humanReadableMsg; listener.error(message); if (LOGGER.isLoggable(Level.WARNING)) { // Send stacktrace to the log as well in order to diagnose the root cause of issues like JENKINS-38527 LOGGER.log(Level.WARNING, message - + "Probably there is a race condition with Agent reconnection or disconnection, check other log entries", + + "Probably there is a race condition with Agent reconnection or disconnection, check other log entries", new IllegalStateException(exceptionDetails != null ? exceptionDetails : humanReadableMsg)); } } @@ -540,7 +553,7 @@ private void reportLauncherCreateError(@NonNull String humanReadableMsg, @CheckF */ @CheckForNull public SlaveComputer getComputer() { - return (SlaveComputer)toComputer(); + return (SlaveComputer) toComputer(); } @Override @@ -562,16 +575,17 @@ public int hashCode() { * Invoked by XStream when this object is read into memory. */ protected Object readResolve() { - if(nodeProperties==null) + if (nodeProperties == null) nodeProperties = new DescribableList<>(this); return this; } + @Override public SlaveDescriptor getDescriptor() { Descriptor d = Jenkins.get().getDescriptorOrDie(getClass()); if (d instanceof SlaveDescriptor) return (SlaveDescriptor) d; - throw new IllegalStateException(d.getClass()+" needs to extend from SlaveDescriptor"); + throw new IllegalStateException(d.getClass() + " needs to extend from SlaveDescriptor"); } public abstract static class SlaveDescriptor extends NodeDescriptor { @@ -583,10 +597,10 @@ public FormValidation doCheckNumExecutors(@QueryParameter String value) { * Performs syntactical check on the remote FS for agents. */ public FormValidation doCheckRemoteFS(@QueryParameter String value) throws IOException, ServletException { - if(Util.fixEmptyAndTrim(value)==null) + if (Util.fixEmptyAndTrim(value) == null) return FormValidation.error(Messages.Slave_Remote_Director_Mandatory()); - if(value.startsWith("\\\\") || value.startsWith("/net/")) + if (value.startsWith("\\\\") || value.startsWith("/net/")) return FormValidation.warning(Messages.Slave_Network_Mounted_File_System_Warning()); if (Util.isRelativePath(value)) { @@ -599,7 +613,7 @@ public FormValidation doCheckRemoteFS(@QueryParameter String value) throws IOExc /** * Returns the list of {@link ComputerLauncher} descriptors appropriate to the supplied {@link Slave}. * - * @param it the {@link Slave} or {@code null} to assume the slave is of type {@link #clazz}. + * @param it the {@link Slave} or {@code null} to assume the agent is of type {@link #clazz}. * @return the filtered list * @since 2.12 */ @@ -630,7 +644,7 @@ public final List>> retentionStrategyDescriptors /** * Returns the list of {@link NodePropertyDescriptor} appropriate to the supplied {@link Slave}. * - * @param it the {@link Slave} or {@code null} to assume the slave is of type {@link #clazz}. + * @param it the {@link Slave} or {@code null} to assume the agent is of type {@link #clazz}. * @return the filtered list * @since 2.12 */ @@ -659,11 +673,11 @@ public final List nodePropertyDescriptors(@CheckForNull // /** * Command line to launch the agent, like - * "ssh myslave java -jar /path/to/hudson-remoting.jar" + * "ssh myagent java -jar /path/to/hudson-remoting.jar" * @deprecated in 1.216 */ @Deprecated - private transient String agentCommand; + private transient String agentCommand; // this was called 'agentCommand' from the beginning; not an accidental 2016 rename /** * Obtains the clock difference between this side and that side of the channel. @@ -678,7 +692,8 @@ public final List nodePropertyDescriptors(@CheckForNull *

  • When it's read on this side as a return value, it morphs itself into {@link ClockDifference}. * */ - private static final class GetClockDifference1 extends MasterToSlaveCallable { + private static final class GetClockDifference1 extends MasterToSlaveCallable { + @Override public ClockDifference call() { // this method must be being invoked locally, which means the clock is in sync return new ClockDifference(0); @@ -691,13 +706,14 @@ private Object writeReplace() { private static final long serialVersionUID = 1L; } - private static final class GetClockDifference2 extends MasterToSlaveCallable { + private static final class GetClockDifference2 extends MasterToSlaveCallable { /** - * Capture the time on the master when this object is sent to remote, which is when + * Capture the time on the controller when this object is sent to remote, which is when * {@link GetClockDifference1#writeReplace()} is run. */ private final long startTime = System.currentTimeMillis(); + @Override public GetClockDifference3 call() { return new GetClockDifference3(startTime); } @@ -715,17 +731,17 @@ private static final class GetClockDifference3 implements Serializable { private Object readResolve() { long endTime = System.currentTimeMillis(); - return new ClockDifference((startTime + endTime)/2-remoteTime); + return new ClockDifference((startTime + endTime) / 2 - remoteTime); } } /** * Determines the workspace root file name for those who really really need the shortest possible path name. */ - private static final String WORKSPACE_ROOT = SystemProperties.getString(Slave.class.getName()+".workspaceRoot","workspace"); + private static final String WORKSPACE_ROOT = SystemProperties.getString(Slave.class.getName() + ".workspaceRoot", "workspace"); /** * Provides a collection of file names, which are accessible via /jnlpJars link. */ - private static final Set ALLOWED_JNLPJARS_FILES = ImmutableSet.of("agent.jar", "slave.jar", "remoting.jar", "jenkins-cli.jar", "hudson-cli.jar"); + private static final Set ALLOWED_JNLPJARS_FILES = Collections.unmodifiableSet(new HashSet<>(Arrays.asList("agent.jar", "slave.jar", "remoting.jar", "jenkins-cli.jar", "hudson-cli.jar"))); } diff --git a/core/src/main/java/hudson/model/StatusIcon.java b/core/src/main/java/hudson/model/StatusIcon.java index 458955c2bec8..b4c4bc749628 100644 --- a/core/src/main/java/hudson/model/StatusIcon.java +++ b/core/src/main/java/hudson/model/StatusIcon.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; /** diff --git a/core/src/main/java/hudson/model/StockStatusIcon.java b/core/src/main/java/hudson/model/StockStatusIcon.java index a10173e6011f..00ce50b0453b 100644 --- a/core/src/main/java/hudson/model/StockStatusIcon.java +++ b/core/src/main/java/hudson/model/StockStatusIcon.java @@ -26,10 +26,17 @@ public StockStatusIcon(String image, Localizable description) { this.description = description; } + @Override public String getImageOf(String size) { - return Stapler.getCurrentRequest().getContextPath()+ Jenkins.RESOURCE_PATH+"/images/"+size+'/'+image; + if (image.endsWith(".svg")) { + return Stapler.getCurrentRequest().getContextPath() + Jenkins.RESOURCE_PATH + "/images/svgs/" + image; + } else { + return Stapler.getCurrentRequest().getContextPath() + Jenkins.RESOURCE_PATH + + "/images/" + size + "/" + image; + } } + @Override public String getDescription() { return description.toString(LocaleProvider.getLocale()); } diff --git a/core/src/main/java/hudson/model/StreamBuildListener.java b/core/src/main/java/hudson/model/StreamBuildListener.java index 226f06ba26aa..efa1204fe11f 100644 --- a/core/src/main/java/hudson/model/StreamBuildListener.java +++ b/core/src/main/java/hudson/model/StreamBuildListener.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,10 +21,10 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import hudson.util.StreamTaskListener; - import java.io.File; import java.io.IOException; import java.io.OutputStream; @@ -35,7 +35,7 @@ * {@link BuildListener} that writes to an {@link OutputStream}. * * This class is remotable. - * + * * @author Kohsuke Kawaguchi */ public class StreamBuildListener extends StreamTaskListener implements BuildListener { @@ -47,6 +47,12 @@ public StreamBuildListener(File out, Charset charset) throws IOException { super(out, charset); } + /** + * @deprecated as of TODO + * The caller should use {@link #StreamBuildListener(OutputStream, Charset)} to pass in + * the charset and output stream separately, so that this class can handle encoding correctly. + */ + @Deprecated public StreamBuildListener(OutputStream w) { super(w); } @@ -62,7 +68,7 @@ public StreamBuildListener(PrintStream w) { } public StreamBuildListener(PrintStream w, Charset charset) { - super(w,charset); + super(w, charset); } private static final long serialVersionUID = 1L; diff --git a/core/src/main/java/hudson/model/StringParameterDefinition.java b/core/src/main/java/hudson/model/StringParameterDefinition.java index 32595ef77ba1..8a5dfa9f1b04 100644 --- a/core/src/main/java/hudson/model/StringParameterDefinition.java +++ b/core/src/main/java/hudson/model/StringParameterDefinition.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Luca Domenico Milanesio, Seiji Sogabe, Tom Huybrechts - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,20 +21,22 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.Extension; import hudson.Util; -import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Objects; import net.sf.json.JSONObject; import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.DoNotUse; import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.StaplerRequest; - -import java.util.Objects; import org.kohsuke.stapler.DataBoundSetter; +import org.kohsuke.stapler.StaplerRequest; /** * Parameter whose value is a string value. @@ -48,24 +50,24 @@ public class StringParameterDefinition extends SimpleParameterDefinition { * @since 2.281 */ @DataBoundConstructor - public StringParameterDefinition(String name) { + public StringParameterDefinition(@NonNull String name) { super(name); } - public StringParameterDefinition(String name, String defaultValue, String description, boolean trim) { + public StringParameterDefinition(@NonNull String name, @CheckForNull String defaultValue, @CheckForNull String description, boolean trim) { this(name); setDefaultValue(defaultValue); setDescription(description); setTrim(trim); } - public StringParameterDefinition(String name, String defaultValue, String description) { + public StringParameterDefinition(@NonNull String name, @CheckForNull String defaultValue, @CheckForNull String description) { this(name); setDefaultValue(defaultValue); setDescription(description); } - - public StringParameterDefinition(String name, String defaultValue) { + + public StringParameterDefinition(@NonNull String name, @CheckForNull String defaultValue) { this(name); setDefaultValue(defaultValue); } @@ -80,12 +82,13 @@ public ParameterDefinition copyWithDefaultValue(ParameterValue defaultValue) { } } + @NonNull public String getDefaultValue() { return defaultValue; } /** - * + * * @return original or trimmed defaultValue (depending on trim) */ @Restricted(DoNotUse.class) // Jelly @@ -97,12 +100,12 @@ public String getDefaultValue4Build() { } @DataBoundSetter - public void setDefaultValue(String defaultValue) { + public void setDefaultValue(@CheckForNull String defaultValue) { this.defaultValue = Util.fixEmpty(defaultValue); } /** - * + * * @return trim - {@code true}, if trim options has been selected, else return {@code false}. * Trimming will happen when creating {@link StringParameterValue}s, * the value in the config will not be changed. @@ -119,7 +122,7 @@ public boolean isTrim() { public void setTrim(boolean trim) { this.trim = trim; } - + @Override public StringParameterValue getDefaultParameterValue() { StringParameterValue value = new StringParameterValue(getName(), defaultValue, getDescription()); @@ -129,7 +132,7 @@ public StringParameterValue getDefaultParameterValue() { return value; } - @Extension @Symbol({"string","stringParam"}) + @Extension @Symbol({"string", "stringParam"}) public static class DescriptorImpl extends ParameterDescriptor { @Override @NonNull @@ -146,13 +149,14 @@ public String getHelpFile() { @Override public ParameterValue createValue(StaplerRequest req, JSONObject jo) { StringParameterValue value = req.bindJSON(StringParameterValue.class, jo); - if (isTrim() && value!=null) { + if (isTrim()) { value.doTrim(); } value.setDescription(getDescription()); return value; } + @Override public ParameterValue createValue(String str) { StringParameterValue value = new StringParameterValue(getName(), str, getDescription()); if (isTrim()) { @@ -170,6 +174,7 @@ public int hashCode() { } @Override + @SuppressFBWarnings(value = "EQ_GETCLASS_AND_CLASS_CONSTANT", justification = "ParameterDefinitionTest tests that subclasses are not equal to their parent classes, so the behavior appears to be intentional") public boolean equals(Object obj) { if (StringParameterDefinition.class != getClass()) return super.equals(obj); diff --git a/core/src/main/java/hudson/model/StringParameterValue.java b/core/src/main/java/hudson/model/StringParameterValue.java index 1b6a06ee1311..f5e0583ed562 100644 --- a/core/src/main/java/hudson/model/StringParameterValue.java +++ b/core/src/main/java/hudson/model/StringParameterValue.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Luca Domenico Milanesio, Tom Huybrechts - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,24 +21,24 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import hudson.EnvVars; import hudson.Util; -import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.export.Exported; - -import java.util.Locale; - import hudson.util.VariableResolver; +import java.util.Locale; +import java.util.Objects; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.export.Exported; /** * {@link ParameterValue} created from {@link StringParameterDefinition}. */ public class StringParameterValue extends ParameterValue { - @Exported(visibility=4) + @Exported(visibility = 4) @Restricted(NoExternalUse.class) public String value; @@ -56,63 +56,57 @@ public StringParameterValue(String name, String value, String description) { * Exposes the name/value as an environment variable. */ @Override - public void buildEnvironment(Run build, EnvVars env) { - env.put(name,value); - env.put(name.toUpperCase(Locale.ENGLISH),value); // backward compatibility pre 1.345 + public void buildEnvironment(Run build, EnvVars env) { + env.put(name, value); + env.put(name.toUpperCase(Locale.ENGLISH), value); // backward compatibility pre 1.345 } @Override public VariableResolver createVariableResolver(AbstractBuild build) { - return new VariableResolver() { - public String resolve(String name) { - return StringParameterValue.this.name.equals(name) ? value : null; - } - }; + return name -> StringParameterValue.this.name.equals(name) ? value : null; } @Override public String getValue() { return value; } - + /** * Trimming for value * @since 2.90 */ public void doTrim() { if (value != null) { - value = value.trim(); - } + value = value.trim(); + } } @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((value == null) ? 0 : value.hashCode()); - return result; - } + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + (value == null ? 0 : value.hashCode()); + return result; + } - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (!super.equals(obj)) - return false; - if (getClass() != obj.getClass()) - return false; - StringParameterValue other = (StringParameterValue) obj; - if (value == null) { - if (other.value != null) - return false; - } else if (!value.equals(other.value)) - return false; - return true; - } + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (getClass() != obj.getClass()) + return false; + StringParameterValue other = (StringParameterValue) obj; + if (!Objects.equals(value, other.value)) { + return false; + } + return true; + } @Override public String toString() { - return "(StringParameterValue) " + getName() + "='" + value + "'"; + return "(StringParameterValue) " + getName() + "='" + value + "'"; } @Override public String getShortDescription() { diff --git a/core/src/main/java/hudson/model/TaskAction.java b/core/src/main/java/hudson/model/TaskAction.java index 76b045845cd4..60ca66ac0536 100644 --- a/core/src/main/java/hudson/model/TaskAction.java +++ b/core/src/main/java/hudson/model/TaskAction.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Jorg Heymans - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,20 +21,19 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import hudson.console.AnnotatedLargeText; -import org.kohsuke.stapler.framework.io.LargeText; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; - +import hudson.security.ACL; +import hudson.security.Permission; +import java.io.IOException; +import java.lang.ref.WeakReference; import javax.servlet.ServletException; import javax.servlet.http.HttpServletResponse; -import java.lang.ref.WeakReference; -import java.io.IOException; - -import hudson.security.Permission; -import hudson.security.ACL; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.framework.io.LargeText; import org.kohsuke.stapler.interceptor.RequirePOST; /** @@ -98,10 +97,11 @@ public LargeText getLog() { */ public AnnotatedLargeText obtainLog() { WeakReference l = log; - if(l==null) return null; + if (l == null) return null; return l.get(); } + @Override public String getSearchUrl() { return getUrlName(); } @@ -113,10 +113,10 @@ public TaskThread getWorkerThread() { /** * Handles incremental log output. */ - public void doProgressiveLog( StaplerRequest req, StaplerResponse rsp) throws IOException { + public void doProgressiveLog(StaplerRequest req, StaplerResponse rsp) throws IOException { AnnotatedLargeText text = obtainLog(); - if(text!=null) { - text.doProgressText(req,rsp); + if (text != null) { + text.doProgressText(req, rsp); return; } rsp.setStatus(HttpServletResponse.SC_OK); @@ -125,10 +125,10 @@ public void doProgressiveLog( StaplerRequest req, StaplerResponse rsp) throws IO /** * Handles incremental log output. */ - public void doProgressiveHtml( StaplerRequest req, StaplerResponse rsp) throws IOException { + public void doProgressiveHtml(StaplerRequest req, StaplerResponse rsp) throws IOException { AnnotatedLargeText text = obtainLog(); - if(text!=null) { - text.doProgressiveHtml(req,rsp); + if (text != null) { + text.doProgressiveHtml(req, rsp); return; } rsp.setStatus(HttpServletResponse.SC_OK); @@ -141,9 +141,8 @@ public void doProgressiveHtml( StaplerRequest req, StaplerResponse rsp) throws I public synchronized void doClearError(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { getACL().checkPermission(getPermission()); - if(workerThread!=null && !workerThread.isRunning()) + if (workerThread != null && !workerThread.isRunning()) workerThread = null; rsp.sendRedirect("."); } } - diff --git a/core/src/main/java/hudson/model/TaskListener.java b/core/src/main/java/hudson/model/TaskListener.java index 29f2d82163f4..17269432f955 100644 --- a/core/src/main/java/hudson/model/TaskListener.java +++ b/core/src/main/java/hudson/model/TaskListener.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,14 +21,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.console.ConsoleNote; import hudson.console.HyperlinkNote; import hudson.remoting.Channel; -import hudson.util.NullStream; import hudson.util.StreamTaskListener; - import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintStream; @@ -36,7 +36,6 @@ import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.Formatter; -import edu.umd.cs.findbugs.annotations.NonNull; import org.jenkinsci.remoting.SerializableOnlyOverRemoting; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; @@ -91,7 +90,7 @@ default PrintWriter _error(String prefix, String msg) { out.println(msg); Charset charset = getCharset(); - return new PrintWriter(charset != null ? new OutputStreamWriter(out, charset) : new OutputStreamWriter(out), true); + return new PrintWriter(new OutputStreamWriter(out, charset), true); } /** @@ -131,7 +130,7 @@ default PrintWriter error(String msg) { */ @NonNull default PrintWriter error(String format, Object... args) { - return error(String.format(format,args)); + return error(String.format(format, args)); } /** @@ -156,5 +155,5 @@ default PrintWriter fatalError(String format, Object... args) { /** * {@link TaskListener} that discards the output. */ - TaskListener NULL = new StreamTaskListener(new NullStream()); + TaskListener NULL = new NullTaskListener(); } diff --git a/core/src/main/java/hudson/model/TaskThread.java b/core/src/main/java/hudson/model/TaskThread.java index 9fb5ba25e9dc..2991da6211b0 100644 --- a/core/src/main/java/hudson/model/TaskThread.java +++ b/core/src/main/java/hudson/model/TaskThread.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Red Hat, Inc. - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,19 +21,19 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import hudson.Functions; import hudson.console.AnnotatedLargeText; import hudson.util.StreamTaskListener; - import java.io.File; import java.io.IOException; import java.io.Reader; import java.lang.ref.WeakReference; import java.nio.charset.Charset; -import org.kohsuke.stapler.framework.io.LargeText; import org.kohsuke.stapler.framework.io.ByteBuffer; +import org.kohsuke.stapler.framework.io.LargeText; /** * {@link Thread} for performing one-off task. @@ -41,7 +41,7 @@ *

    * Designed to be used inside {@link TaskAction}. * - * + * * * @author Kohsuke Kawaguchi * @since 1.191 @@ -76,7 +76,7 @@ public abstract class TaskThread extends Thread { */ protected TaskThread(TaskAction owner, ListenerAndText output) { //FIXME this failed to compile super(owner.getBuild().toString()+' '+owner.getDisplayName()); - //Please implement more general way how to get information about action owner, + //Please implement more general way how to get information about action owner, //if you want it in the thread's name. super(owner.getDisplayName()); this.owner = owner; @@ -128,14 +128,14 @@ public final void run() { try { perform(listener); listener.getLogger().println("Completed"); - owner.workerThread = null; + owner.workerThread = null; } catch (InterruptedException e) { listener.getLogger().println("Aborted"); } catch (Exception e) { Functions.printStackTrace(e, listener.getLogger()); } finally { listener = null; - isRunning =false; + isRunning = false; } log.markAsComplete(); } @@ -176,7 +176,7 @@ public static ListenerAndText forMemory() { */ @Deprecated public static ListenerAndText forFile(File f) throws IOException { - return forFile(f,null); + return forFile(f, null); } /** @@ -193,7 +193,7 @@ public static ListenerAndText forMemory(TaskAction context) { } /** - * Creates one that's backed by a file. + * Creates one that's backed by a file. */ public static ListenerAndText forFile(File f, TaskAction context) throws IOException { return new ListenerAndText( diff --git a/core/src/main/java/hudson/model/TextParameterDefinition.java b/core/src/main/java/hudson/model/TextParameterDefinition.java index 598a8d4c8c3f..4db836a7b7e5 100644 --- a/core/src/main/java/hudson/model/TextParameterDefinition.java +++ b/core/src/main/java/hudson/model/TextParameterDefinition.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Luca Domenico Milanesio, Seiji Sogabe, Tom Huybrechts - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,16 +21,19 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.Extension; +import java.util.Objects; import net.sf.json.JSONObject; import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.StaplerRequest; -import java.util.Objects; - /** * {@link StringParameterDefinition} that uses textarea, instead of text box. */ @@ -40,17 +43,17 @@ public class TextParameterDefinition extends StringParameterDefinition { * @since 2.281 */ @DataBoundConstructor - public TextParameterDefinition(String name) { + public TextParameterDefinition(@NonNull String name) { super(name); } - public TextParameterDefinition(String name, String defaultValue, String description) { + public TextParameterDefinition(@NonNull String name, @CheckForNull String defaultValue, @CheckForNull String description) { this(name); setDefaultValue(defaultValue); setDescription(description); } - @Extension @Symbol({"text","textParam"}) + @Extension @Symbol({"text", "textParam"}) public static class DescriptorImpl extends ParameterDescriptor { @Override public String getDisplayName() { @@ -58,6 +61,11 @@ public String getDisplayName() { } } + @Override + public StringParameterValue getDefaultParameterValue() { + return new TextParameterValue(getName(), getDefaultValue(), getDescription()); + } + @Override public ParameterValue createValue(StaplerRequest req, JSONObject jo) { TextParameterValue value = req.bindJSON(TextParameterValue.class, jo); @@ -79,6 +87,7 @@ public int hashCode() { } @Override + @SuppressFBWarnings(value = "EQ_GETCLASS_AND_CLASS_CONSTANT", justification = "ParameterDefinitionTest tests that subclasses are not equal to their parent classes, so the behavior appears to be intentional") public boolean equals(Object obj) { if (TextParameterDefinition.class != getClass()) return super.equals(obj); diff --git a/core/src/main/java/hudson/model/TextParameterValue.java b/core/src/main/java/hudson/model/TextParameterValue.java index 1e2227e303c0..2830e9128ead 100644 --- a/core/src/main/java/hudson/model/TextParameterValue.java +++ b/core/src/main/java/hudson/model/TextParameterValue.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import org.kohsuke.stapler.DataBoundConstructor; diff --git a/core/src/main/java/hudson/model/TimeSeries.java b/core/src/main/java/hudson/model/TimeSeries.java index 8039ebcb1cf9..bcf524b42812 100644 --- a/core/src/main/java/hudson/model/TimeSeries.java +++ b/core/src/main/java/hudson/model/TimeSeries.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,13 +21,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import hudson.CopyOnWrite; -import org.kohsuke.stapler.export.ExportedBean; -import org.kohsuke.stapler.export.Exported; - import java.io.Serializable; +import org.kohsuke.stapler.export.Exported; +import org.kohsuke.stapler.export.ExportedBean; /** * Scalar value that changes over the time (such as load average, Q length, # of executors, etc.) @@ -71,10 +71,10 @@ public TimeSeries(float initialValue, float decay, int historySize) { * the raw data stream. */ public void update(float newData) { - float data = history[0]*decay + newData*(1-decay); + float data = history[0] * decay + newData * (1 - decay); - float[] r = new float[Math.min(history.length+1,historySize)]; - System.arraycopy(history,0,r,1,Math.min(history.length,r.length-1)); + float[] r = new float[Math.min(history.length + 1, historySize)]; + System.arraycopy(history, 0, r, 1, Math.min(history.length, r.length - 1)); r[0] = data; history = r; } diff --git a/core/src/main/java/hudson/model/TimeZoneProperty.java b/core/src/main/java/hudson/model/TimeZoneProperty.java index 0a75b473ed41..bdf39c58527e 100644 --- a/core/src/main/java/hudson/model/TimeZoneProperty.java +++ b/core/src/main/java/hudson/model/TimeZoneProperty.java @@ -1,25 +1,24 @@ package hudson.model; -import hudson.Extension; -import hudson.util.ListBoxModel; -import hudson.util.ListBoxModel.Option; import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; +import hudson.Extension; import hudson.Util; import hudson.util.FormValidation; +import hudson.util.ListBoxModel; +import hudson.util.ListBoxModel.Option; import java.text.DateFormat; import java.util.Date; import java.util.TimeZone; -import java.util.logging.Logger; import java.util.logging.Level; +import java.util.logging.Logger; import org.jenkinsci.Symbol; -import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.stapler.AncestorInPath; +import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.QueryParameter; - /** * A UserProperty that allows a user to specify a time zone for displaying time. */ @@ -47,6 +46,11 @@ public void setTimeZoneName(@CheckForNull String timeZoneName) { this.timeZoneName = timeZoneName; } + @CheckForNull + public String getTimeZoneName() { + return timeZoneName; + } + @Extension @Symbol("timezone") public static class DescriptorImpl extends UserPropertyDescriptor { @@ -77,12 +81,12 @@ public boolean isEnabled() { return true; } - public ListBoxModel doFillTimeZoneNameItems() { - String current = forCurrentUser(); + public ListBoxModel doFillTimeZoneNameItems(@AncestorInPath User user) { + String userTimezone = user != null ? forUser(user) : forCurrentUser(); ListBoxModel items = new ListBoxModel(); items.add(Messages.TimeZoneProperty_DisplayDefaultTimeZone(), ""); for (String id : TimeZone.getAvailableIDs()) { - if (id.equalsIgnoreCase(current)) { + if (id.equalsIgnoreCase(userTimezone)) { items.add(new Option(id, id, true)); } else { items.add(id); @@ -104,15 +108,19 @@ public FormValidation doCheckTimeZoneName(@QueryParameter String timeZoneName) { } - @Nullable + @CheckForNull public static String forCurrentUser() { final User current = User.current(); if (current == null) { return null; } + return forUser(current); + } - TimeZoneProperty tzp = current.getProperty(TimeZoneProperty.class); - if(tzp.timeZoneName == null || tzp.timeZoneName.isEmpty()) { + @CheckForNull + private static String forUser(User user) { + TimeZoneProperty tzp = user.getProperty(TimeZoneProperty.class); + if (tzp.timeZoneName == null || tzp.timeZoneName.isEmpty()) { return null; } @@ -121,7 +129,7 @@ public static String forCurrentUser() { //TimeZone.getTimeZone returns GMT on invalid time zone so //warn the user if the time zone returned is different from //the one they specified. - LOGGER.log(Level.WARNING, "Invalid user time zone {0} for {1}", new Object[]{tzp.timeZoneName, current.getId()}); + LOGGER.log(Level.WARNING, "Invalid user time zone {0} for {1}", new Object[]{tzp.timeZoneName, user.getId()}); return null; } diff --git a/core/src/main/java/hudson/model/TopLevelItem.java b/core/src/main/java/hudson/model/TopLevelItem.java index ce362a9b79e3..66f3bc7d4a2e 100644 --- a/core/src/main/java/hudson/model/TopLevelItem.java +++ b/core/src/main/java/hudson/model/TopLevelItem.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import hudson.Extension; @@ -43,5 +44,6 @@ public interface TopLevelItem extends Item, ExtensionPoint, Describable createFor(Run target) { if (target instanceof AbstractBuild) - return createFor((AbstractBuild)target); + return createFor((AbstractBuild) target); else return Collections.emptyList(); } diff --git a/core/src/main/java/hudson/model/TransientComputerActionFactory.java b/core/src/main/java/hudson/model/TransientComputerActionFactory.java index 1506da71352c..5e7b16ee66df 100644 --- a/core/src/main/java/hudson/model/TransientComputerActionFactory.java +++ b/core/src/main/java/hudson/model/TransientComputerActionFactory.java @@ -21,11 +21,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import hudson.ExtensionList; import hudson.ExtensionPoint; - import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -63,13 +63,13 @@ public static ExtensionList all() { /** * Creates {@link Action}s for a node, using all registered {@link TransientComputerActionFactory}s. */ - public static List createAllFor(Computer target) { - List result = new ArrayList<>(); - for (TransientComputerActionFactory f: all()) { - result.addAll(f.createFor(target)); - } - return result; - } + public static List createAllFor(Computer target) { + List result = new ArrayList<>(); + for (TransientComputerActionFactory f : all()) { + result.addAll(f.createFor(target)); + } + return result; + } } diff --git a/core/src/main/java/hudson/model/TransientProjectActionFactory.java b/core/src/main/java/hudson/model/TransientProjectActionFactory.java index 23fd0a138c78..0d8979437646 100644 --- a/core/src/main/java/hudson/model/TransientProjectActionFactory.java +++ b/core/src/main/java/hudson/model/TransientProjectActionFactory.java @@ -21,13 +21,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import hudson.Extension; import hudson.ExtensionList; import hudson.ExtensionPoint; import hudson.tasks.BuildStep; - import java.util.Collection; import jenkins.model.TransientActionFactory; diff --git a/core/src/main/java/hudson/model/TransientUserActionFactory.java b/core/src/main/java/hudson/model/TransientUserActionFactory.java index c0354892336d..273a6903efb2 100644 --- a/core/src/main/java/hudson/model/TransientUserActionFactory.java +++ b/core/src/main/java/hudson/model/TransientUserActionFactory.java @@ -21,12 +21,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import hudson.Extension; import hudson.ExtensionList; import hudson.ExtensionPoint; - import java.util.Collection; import java.util.Collections; diff --git a/core/src/main/java/hudson/model/TransientViewActionFactory.java b/core/src/main/java/hudson/model/TransientViewActionFactory.java index d5fa9dcfc2f5..c1af0fe387d8 100644 --- a/core/src/main/java/hudson/model/TransientViewActionFactory.java +++ b/core/src/main/java/hudson/model/TransientViewActionFactory.java @@ -2,7 +2,6 @@ import hudson.ExtensionList; import hudson.ExtensionPoint; - import java.util.ArrayList; import java.util.List; @@ -13,29 +12,27 @@ */ public abstract class TransientViewActionFactory implements ExtensionPoint { - /** - * returns a list of (transient) actions never null, may be empty - * - * @param v - */ - public abstract List createFor(View v); - + /** + * returns a list of (transient) actions never null, may be empty + */ + public abstract List createFor(View v); + /** * Returns all the registered {@link TransientViewActionFactory}s. */ - public static ExtensionList all() { - return ExtensionList.lookup(TransientViewActionFactory.class); - } - + public static ExtensionList all() { + return ExtensionList.lookup(TransientViewActionFactory.class); + } + /** * Creates {@link Action}s for a view, using all registered {@link TransientViewActionFactory}s. */ - public static List createAllFor(View v) { - List result = new ArrayList<>(); - for (TransientViewActionFactory f: all()) { - result.addAll(f.createFor(v)); - } - return result; - } + public static List createAllFor(View v) { + List result = new ArrayList<>(); + for (TransientViewActionFactory f : all()) { + result.addAll(f.createFor(v)); + } + return result; + } } diff --git a/core/src/main/java/hudson/model/TreeView.java b/core/src/main/java/hudson/model/TreeView.java deleted file mode 100644 index 39740a3bb32a..000000000000 --- a/core/src/main/java/hudson/model/TreeView.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package hudson.model; - -import hudson.model.Descriptor.FormException; -import hudson.util.CaseInsensitiveComparator; -import hudson.Indenter; -import hudson.Extension; -import jenkins.util.SystemProperties; -import hudson.views.ViewsTabBar; -import jenkins.model.Jenkins; -import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; - -import javax.servlet.ServletException; -import java.io.IOException; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Set; -import java.util.TreeSet; -import java.util.concurrent.CopyOnWriteArrayList; -import org.kohsuke.stapler.interceptor.RequirePOST; -import org.kohsuke.stapler.verb.POST; - -/** - * - *

    EXPERIMENTAL

    - *

    - * The intention is to eventually merge this with the {@link ListView}. - * This class is here for experimentation. - * - *

    - * Until this class is sufficiently stable, there's no need for l10n. - * TODO: use ViewGroupMixIn - * - * @author Kohsuke Kawaguchi - */ -public class TreeView extends View implements ViewGroup { - /** - * List of job names. This is what gets serialized. - */ - private final Set jobNames - = new TreeSet<>(CaseInsensitiveComparator.INSTANCE); - - /** - * Nested views. - */ - private final CopyOnWriteArrayList views = new CopyOnWriteArrayList<>(); - - @DataBoundConstructor - public TreeView(String name) { - super(name); - } - - /** - * Returns {@link Indenter} that has the fixed indentation width. - * Used for assisting view rendering. - */ - public Indenter createFixedIndenter(String d) { - final int depth = Integer.parseInt(d); - return new Indenter() { - protected int getNestLevel(Job job) { return depth; } - }; - } - - /** - * Returns a read-only view of all {@link Job}s in this view. - * - *

    - * This method returns a separate copy each time to avoid - * concurrent modification issue. - */ - public synchronized List getItems() { - return Jenkins.get().getItems(); -// List items = new ArrayList(jobNames.size()); -// for (String name : jobNames) { -// TopLevelItem item = Hudson.getInstance().getItem(name); -// if(item!=null) -// items.add(item); -// } -// return items; - } - - public boolean contains(TopLevelItem item) { - return true; -// return jobNames.contains(item.getName()); - } - - @POST - public TopLevelItem doCreateItem(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { - ItemGroup ig = getOwner().getItemGroup(); - if (ig instanceof ModifiableItemGroup) { - TopLevelItem item = ((ModifiableItemGroup)ig).doCreateItem(req, rsp); - if(item!=null) { - jobNames.add(item.getName()); - owner.save(); - } - return item; - } - return null; - } - - // TODO listen for changes that might affect jobNames - - protected void submit(StaplerRequest req) throws IOException, ServletException, FormException { - } - - public boolean canDelete(View view) { - return true; - } - - public void deleteView(View view) throws IOException { - views.remove(view); - } - - public Collection getViews() { - return Collections.unmodifiableList(views); - } - - public View getView(String name) { - //Top level views returned first if match - for (View v : views) { - if (v.getViewName().equals(name)) { - return v; - } - } - for (View v : views) { - if (v instanceof ViewGroup) { - View nestedView = ((ViewGroup) v).getView(name); - if (nestedView != null) { - return nestedView; - } - } - } - return null; - } - - public void onViewRenamed(View view, String oldName, String newName) { - // noop - } - - @RequirePOST - public void doCreateView( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException, FormException { - checkPermission(View.CREATE); - views.add(View.create(req,rsp,this)); - save(); - } - - // this feature is not public yet - @Extension - public static ViewDescriptor register() { - if(SystemProperties.getBoolean("hudson.TreeView")) - return new DescriptorImpl(); - else - return null; - } - - public static final class DescriptorImpl extends ViewDescriptor { - @Override - public String getDisplayName() { - return "Tree View"; - } - } - - public ViewsTabBar getViewsTabBar() { - return Jenkins.get().getViewsTabBar(); - } - - @Override - public ItemGroup getItemGroup() { - return getOwner().getItemGroup(); - } - - @Override - public List getViewActions() { - return owner.getViewActions(); - } - -} diff --git a/core/src/main/java/hudson/model/UnprotectedRootAction.java b/core/src/main/java/hudson/model/UnprotectedRootAction.java index bb5a7b6b5f17..b3ebdc2c3bc4 100644 --- a/core/src/main/java/hudson/model/UnprotectedRootAction.java +++ b/core/src/main/java/hudson/model/UnprotectedRootAction.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import hudson.ExtensionPoint; diff --git a/core/src/main/java/hudson/model/UpdateCenter.java b/core/src/main/java/hudson/model/UpdateCenter.java index 26d9fba9c87d..2611f8033c21 100644 --- a/core/src/main/java/hudson/model/UpdateCenter.java +++ b/core/src/main/java/hudson/model/UpdateCenter.java @@ -21,9 +21,16 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import static hudson.init.InitMilestone.PLUGINS_STARTED; +import static java.util.logging.Level.INFO; +import static java.util.logging.Level.WARNING; + import com.google.common.annotations.VisibleForTesting; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.BulkChange; import hudson.Extension; @@ -32,22 +39,8 @@ import hudson.PluginManager; import hudson.PluginWrapper; import hudson.ProxyConfiguration; -import hudson.security.ACLContext; -import hudson.security.Permission; -import hudson.util.VersionNumber; -import java.nio.file.Files; -import java.nio.file.InvalidPathException; -import java.text.MessageFormat; -import java.util.concurrent.TimeUnit; - -import jenkins.security.stapler.StaplerDispatchable; -import jenkins.util.SystemProperties; import hudson.Util; import hudson.XmlFile; -import static hudson.init.InitMilestone.PLUGINS_STARTED; -import static java.util.logging.Level.INFO; -import static java.util.logging.Level.WARNING; - import hudson.init.Initializer; import hudson.lifecycle.Lifecycle; import hudson.lifecycle.RestartNotSupportedException; @@ -56,32 +49,15 @@ import hudson.model.listeners.SaveableListener; import hudson.remoting.AtmostOneThreadExecutor; import hudson.security.ACL; +import hudson.security.ACLContext; +import hudson.security.Permission; import hudson.util.DaemonThreadFactory; import hudson.util.FormValidation; import hudson.util.HttpResponses; import hudson.util.NamingThreadFactory; import hudson.util.PersistedList; +import hudson.util.VersionNumber; import hudson.util.XStream2; -import jenkins.MissingDependencyException; -import jenkins.RestartRequiredException; -import jenkins.install.InstallUtil; -import jenkins.model.Jenkins; -import jenkins.util.io.OnMaster; -import net.sf.json.JSONObject; - -import org.apache.commons.io.input.CountingInputStream; -import org.apache.commons.io.output.NullOutputStream; -import org.jenkinsci.Symbol; -import org.jvnet.localizer.Localizable; -import org.kohsuke.accmod.restrictions.DoNotUse; -import org.kohsuke.stapler.HttpResponse; -import org.kohsuke.stapler.StaplerProxy; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; - -import edu.umd.cs.findbugs.annotations.NonNull; -import javax.net.ssl.SSLHandshakeException; -import javax.servlet.ServletException; import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -93,9 +69,15 @@ import java.net.URL; import java.net.URLConnection; import java.net.UnknownHostException; +import java.nio.charset.StandardCharsets; +import java.nio.file.AtomicMoveNotSupportedException; +import java.nio.file.Files; +import java.nio.file.InvalidPathException; +import java.nio.file.StandardCopyOption; import java.security.DigestOutputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import java.text.MessageFormat; import java.util.ArrayList; import java.util.Base64; import java.util.Collections; @@ -113,22 +95,40 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.jar.Attributes; import java.util.jar.JarFile; import java.util.logging.Level; import java.util.logging.Logger; -import edu.umd.cs.findbugs.annotations.CheckForNull; +import javax.net.ssl.SSLHandshakeException; +import javax.servlet.ServletException; +import jenkins.MissingDependencyException; +import jenkins.RestartRequiredException; +import jenkins.install.InstallUtil; +import jenkins.model.Jenkins; +import jenkins.security.stapler.StaplerDispatchable; +import jenkins.util.SystemProperties; import jenkins.util.Timer; +import jenkins.util.io.OnMaster; +import net.sf.json.JSONObject; import org.apache.commons.io.IOUtils; +import org.apache.commons.io.input.CountingInputStream; +import org.apache.commons.io.output.NullOutputStream; +import org.jenkinsci.Symbol; +import org.jvnet.localizer.Localizable; import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.DoNotUse; import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.stapler.HttpResponse; +import org.kohsuke.stapler.StaplerProxy; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; import org.kohsuke.stapler.interceptor.RequirePOST; import org.springframework.security.core.Authentication; - /** * Controls update center capability. * @@ -143,13 +143,13 @@ *

    * Extending Update Centers. The update center in {@code Jenkins} can be replaced by defining a * System Property ({@code hudson.model.UpdateCenter.className}). See {@link #createUpdateCenter(hudson.model.UpdateCenter.UpdateCenterConfiguration)}. - * This className should be available on early startup, so it cannot come only from a library + * This className should be available on early startup, so it cannot come only from a library * (e.g. Jenkins module or Extra library dependency in the WAR file project). * Plugins cannot be used for such purpose. - * In order to be correctly instantiated, the class definition must have two constructors: + * In order to be correctly instantiated, the class definition must have two constructors: * {@link #UpdateCenter()} and {@link #UpdateCenter(hudson.model.UpdateCenter.UpdateCenterConfiguration)}. * If the class does not comply with the requirements, a fallback to the default UpdateCenter will be performed. - * + * * @author Kohsuke Kawaguchi * @since 1.220 */ @@ -162,7 +162,7 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas /** * Read timeout when downloading plugins, defaults to 1 minute */ - private static final int PLUGIN_DOWNLOAD_READ_TIMEOUT = (int)TimeUnit.SECONDS.toMillis(SystemProperties.getInteger(UpdateCenter.class.getName()+".pluginDownloadReadTimeoutSeconds", 60)); + private static final int PLUGIN_DOWNLOAD_READ_TIMEOUT = (int) TimeUnit.SECONDS.toMillis(SystemProperties.getInteger(UpdateCenter.class.getName() + ".pluginDownloadReadTimeoutSeconds", 60)); public static final String PREDEFINED_UPDATE_SITE_ID = "default"; @@ -170,7 +170,7 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas * {@linkplain UpdateSite#getId() ID} of the default update site. * @since 1.483; configurable via system property since 2.4 */ - public static final String ID_DEFAULT = SystemProperties.getString(UpdateCenter.class.getName()+".defaultUpdateSiteId", PREDEFINED_UPDATE_SITE_ID); + public static final String ID_DEFAULT = SystemProperties.getString(UpdateCenter.class.getName() + ".defaultUpdateSiteId", PREDEFINED_UPDATE_SITE_ID); @Restricted(NoExternalUse.class) public static final String ID_UPLOAD = "_upload"; @@ -217,7 +217,7 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas static { Logger logger = Logger.getLogger(UpdateCenter.class.getName()); LOGGER = logger; - String ucOverride = SystemProperties.getString(UpdateCenter.class.getName()+".updateCenterUrl"); + String ucOverride = SystemProperties.getString(UpdateCenter.class.getName() + ".updateCenterUrl"); if (ucOverride != null) { logger.log(Level.INFO, "Using a custom update center defined by the system property: {0}", ucOverride); UPDATE_CENTER_URL = ucOverride; @@ -269,7 +269,7 @@ public UpdateCenter() { UpdateCenter(@NonNull UpdateCenterConfiguration configuration) { configure(configuration); } - + /** * Creates an update center. * @param config Requested configuration. May be {@code null} if defaults should be used @@ -278,13 +278,13 @@ public UpdateCenter() { */ @NonNull public static UpdateCenter createUpdateCenter(@CheckForNull UpdateCenterConfiguration config) { - String requiredClassName = SystemProperties.getString(UpdateCenter.class.getName()+".className", null); + String requiredClassName = SystemProperties.getString(UpdateCenter.class.getName() + ".className", null); if (requiredClassName == null) { // Use the default Update Center LOGGER.log(Level.FINE, "Using the default Update Center implementation"); return createDefaultUpdateCenter(config); } - + LOGGER.log(Level.FINE, "Using the custom update center: {0}", requiredClassName); try { final Class clazz = Class.forName(requiredClassName).asSubclass(UpdateCenter.class); @@ -299,17 +299,17 @@ public static UpdateCenter createUpdateCenter(@CheckForNull UpdateCenterConfigur LOGGER.log(Level.FINE, "Using the constructor {0} Update Center configuration for {1}", new Object[] {config != null ? "with" : "without", requiredClassName}); return config != null ? configConstructor.newInstance(config) : defaultConstructor.newInstance(); - } catch(ClassCastException e) { + } catch (ClassCastException e) { // Should never happen LOGGER.log(WARNING, "UpdateCenter class {0} does not extend hudson.model.UpdateCenter. Using default.", requiredClassName); - } catch(NoSuchMethodException e) { + } catch (NoSuchMethodException e) { LOGGER.log(WARNING, String.format("UpdateCenter class %s does not define one of the required constructors. Using default", requiredClassName), e); - } catch(Exception e) { + } catch (Exception e) { LOGGER.log(WARNING, String.format("Unable to instantiate custom plugin manager [%s]. Using default.", requiredClassName), e); } return createDefaultUpdateCenter(config); } - + @NonNull private static UpdateCenter createDefaultUpdateCenter(@CheckForNull UpdateCenterConfiguration config) { return config != null ? new UpdateCenter(config) : new UpdateCenter(); @@ -328,7 +328,7 @@ public Api getApi() { * @see UpdateCenterConfiguration */ public void configure(UpdateCenterConfiguration config) { - if (config!=null) { + if (config != null) { this.config = config; } } @@ -355,7 +355,7 @@ public List getJobs() { public UpdateCenterJob getJob(int id) { synchronized (jobs) { for (UpdateCenterJob job : jobs) { - if (job.id==id) + if (job.id == id) return job; } } @@ -371,7 +371,7 @@ public InstallationJob getJob(Plugin plugin) { Collections.reverse(jobList); for (UpdateCenterJob job : jobList) if (job instanceof InstallationJob) { - InstallationJob ij = (InstallationJob)job; + InstallationJob ij = (InstallationJob) job; if (ij.plugin.name.equals(plugin.name) && ij.plugin.sourceId.equals(plugin.sourceId)) return ij; } @@ -407,7 +407,7 @@ public HttpResponse doConnectionStatus(StaplerRequest request) { if (checkJob != null) { boolean isOffline = false; for (ConnectionStatus status : checkJob.connectionStates.values()) { - if(ConnectionStatus.FAILED.equals(status)) { + if (ConnectionStatus.FAILED.equals(status)) { isOffline = true; break; } @@ -417,12 +417,12 @@ public HttpResponse doConnectionStatus(StaplerRequest request) { checkJob.run(); isOffline = false; for (ConnectionStatus status : checkJob.connectionStates.values()) { - if(ConnectionStatus.FAILED.equals(status)) { + if (ConnectionStatus.FAILED.equals(status)) { isOffline = true; break; } } - if(!isOffline) { // also need to download the metadata + if (!isOffline) { // also need to download the metadata updateAllSites(); } } @@ -442,12 +442,12 @@ public HttpResponse doConnectionStatus(StaplerRequest request) { @Restricted(DoNotUse.class) // WebOnly public HttpResponse doIncompleteInstallStatus() { try { - Map jobs = InstallUtil.getPersistedInstallStatus(); - if(jobs == null) { + Map jobs = InstallUtil.getPersistedInstallStatus(); + if (jobs == null) { jobs = Collections.emptyMap(); } return HttpResponses.okJSON(jobs); - } catch (Exception e) { + } catch (RuntimeException e) { return HttpResponses.errorJSON(String.format("ERROR: %s", e.getMessage())); } } @@ -465,13 +465,13 @@ public synchronized void persistInstallStatus() { for (UpdateCenterJob job : jobs) { if (job instanceof InstallationJob) { InstallationJob installationJob = (InstallationJob) job; - if(!installationJob.status.isSuccess()) { + if (!installationJob.status.isSuccess()) { activeInstalls = true; } } } - if(activeInstalls) { + if (activeInstalls) { InstallUtil.persistInstallStatus(jobs); // save this info } else { @@ -492,7 +492,7 @@ public synchronized void persistInstallStatus() { public HttpResponse doInstallStatus(StaplerRequest request) { try { String correlationId = request.getParameter("correlationId"); - Map response = new HashMap<>(); + Map response = new HashMap<>(); response.put("state", Jenkins.get().getInstallState().name()); List> installStates = new ArrayList<>(); response.put("jobs", installStates); @@ -517,7 +517,7 @@ public HttpResponse doInstallStatus(StaplerRequest request) { } } return HttpResponses.okJSON(JSONObject.fromObject(response)); - } catch (Exception e) { + } catch (RuntimeException e) { return HttpResponses.errorJSON(String.format("ERROR: %s", e.getMessage())); } } @@ -531,7 +531,7 @@ public HudsonUpgradeJob getHudsonJob() { Collections.reverse(jobList); for (UpdateCenterJob job : jobList) if (job instanceof HudsonUpgradeJob) - return (HudsonUpgradeJob)job; + return (HudsonUpgradeJob) job; return null; } @@ -571,7 +571,7 @@ public boolean isSiteDataReady() { /** * The same as {@link #getSites()} but for REST API. */ - @Exported(name="sites") + @Exported(name = "sites") public List getSiteList() { return sites.toList(); } @@ -593,14 +593,14 @@ public UpdateSite getSite(String id) { public String getLastUpdatedString() { long newestTs = 0; for (UpdateSite s : sites) { - if (s.getDataTimestamp()>newestTs) { + if (s.getDataTimestamp() > newestTs) { newestTs = s.getDataTimestamp(); } } if (newestTs == 0) { return Messages.UpdateCenter_n_a(); } - return Util.getTimeSpanString(System.currentTimeMillis()-newestTs); + return Util.getTimeSpanString(System.currentTimeMillis() - newestTs); } /** @@ -629,7 +629,7 @@ public UpdateSite getById(String id) { public UpdateSite getCoreSource() { for (UpdateSite s : sites) { Data data = s.getData(); - if (data!=null && data.core!=null) + if (data != null && data.core != null) return s; } return null; @@ -654,7 +654,7 @@ public String getDefaultBaseUrl() { public @CheckForNull Plugin getPlugin(String artifactId) { for (UpdateSite s : sites) { Plugin p = s.getPlugin(artifactId); - if (p!=null) return p; + if (p != null) return p; } return null; } @@ -696,16 +696,16 @@ public String getDefaultBaseUrl() { private boolean checkMinVersion(@CheckForNull Plugin p, @CheckForNull VersionNumber minVersion) { return p != null && (minVersion == null || !minVersion.isNewerThan(new VersionNumber(p.version))); - } + } - /** + /** * Schedules a Jenkins upgrade. */ @RequirePOST public void doUpgrade(StaplerResponse rsp) throws IOException, ServletException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); HudsonUpgradeJob job = new HudsonUpgradeJob(getCoreSource(), Jenkins.getAuthentication2()); - if(!Lifecycle.get().canRewriteHudsonWar()) { + if (!Lifecycle.get().canRewriteHudsonWar()) { sendError("Jenkins upgrade not supported in this running mode"); return; } @@ -810,7 +810,7 @@ public boolean isDowngradable() { @RequirePOST public void doDowngrade(StaplerResponse rsp) throws IOException, ServletException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); - if(!isDowngradable()) { + if (!isDowngradable()) { sendError("Jenkins downgrade is not possible, probably backup does not exist"); return; } @@ -848,7 +848,8 @@ public String getBackupVersion() { } } catch (IOException e) { LOGGER.log(Level.WARNING, "Failed to read backup version ", e); - return null;} + return null; + } } @@ -910,10 +911,12 @@ ConnectionCheckJob newConnectionCheckJob(UpdateSite site) { return null; } + @Override public String getDisplayName() { return Messages.UpdateCenter_DisplayName(); } + @Override public String getSearchUrl() { return "updateCenter"; } @@ -921,13 +924,14 @@ public String getSearchUrl() { /** * Saves the configuration info to the disk. */ + @Override public synchronized void save() { - if(BulkChange.contains(this)) return; + if (BulkChange.contains(this)) return; try { getConfigFile().write(sites); SaveableListener.fireOnChange(this, getConfigFile()); } catch (IOException e) { - LOGGER.log(Level.WARNING, "Failed to save "+getConfigFile(),e); + LOGGER.log(Level.WARNING, "Failed to save " + getConfigFile(), e); } } @@ -936,11 +940,11 @@ public synchronized void save() { */ public synchronized void load() throws IOException { XmlFile file = getConfigFile(); - if(file.exists()) { + if (file.exists()) { try { - sites.replaceBy(((PersistedList)file.unmarshal(sites)).toList()); + sites.replaceBy(((PersistedList) file.unmarshal(sites)).toList()); } catch (IOException e) { - LOGGER.log(Level.WARNING, "Failed to load "+file, e); + LOGGER.log(Level.WARNING, "Failed to load " + file, e); } boolean defaultSiteExists = false; for (UpdateSite site : sites) { @@ -969,15 +973,15 @@ protected UpdateSite createDefaultUpdateSite() { } private XmlFile getConfigFile() { - return new XmlFile(XSTREAM,new File(Jenkins.get().root, - UpdateCenter.class.getName()+".xml")); + return new XmlFile(XSTREAM, new File(Jenkins.get().root, + UpdateCenter.class.getName() + ".xml")); } @Exported public List getAvailables() { - Map pluginMap = new LinkedHashMap<>(); + Map pluginMap = new LinkedHashMap<>(); for (UpdateSite site : sites) { - for (Plugin plugin: site.getAvailables()) { + for (Plugin plugin : site.getAvailables()) { final Plugin existing = pluginMap.get(plugin.name); if (existing == null) { pluginMap.put(plugin.name, plugin); @@ -998,13 +1002,13 @@ public List getAvailables() { /** * Returns a list of plugins that should be shown in the "available" tab, grouped by category. * A plugin with multiple categories will appear multiple times in the list. - * @deprecated + * @deprecated use {@link #getAvailables()} */ @Deprecated public PluginEntry[] getCategorizedAvailables() { TreeSet entries = new TreeSet<>(); for (Plugin p : getAvailables()) { - if (p.categories==null || p.categories.length==0) + if (p.categories == null || p.categories.length == 0) entries.add(new PluginEntry(p, getCategoryDisplayName(null))); else for (String c : p.categories) @@ -1015,7 +1019,7 @@ public PluginEntry[] getCategorizedAvailables() { @Restricted(NoExternalUse.class) // Jelly only public static String getCategoryDisplayName(String category) { - if (category==null) + if (category == null) return Messages.UpdateCenter_PluginCategory_misc(); try { return (String) Messages.class.getMethod( @@ -1028,12 +1032,12 @@ public static String getCategoryDisplayName(String category) { } public List getUpdates() { - Map pluginMap = new LinkedHashMap<>(); + Map pluginMap = new LinkedHashMap<>(); final Map> incompatiblePluginMap = new LinkedHashMap<>(); final PluginManager.MetadataCache cache = new PluginManager.MetadataCache(); for (UpdateSite site : sites) { - for (Plugin plugin: site.getUpdates()) { + for (Plugin plugin : site.getUpdates()) { final Plugin existing = pluginMap.get(plugin.name); if (existing == null) { pluginMap.put(plugin.name, plugin); @@ -1064,7 +1068,7 @@ public List getUpdates() { @Restricted(NoExternalUse.class) public List getPluginsWithUnavailableUpdates() { - Map pluginMap = new LinkedHashMap<>(); + Map pluginMap = new LinkedHashMap<>(); for (PluginWrapper wrapper : Jenkins.get().getPluginManager().getPlugins()) { for (UpdateSite site : sites) { UpdateSite.Plugin plugin = site.getPlugin(wrapper.getShortName()); @@ -1089,13 +1093,10 @@ public List getPluginsWithUnavailableUpdates() { * browse to the instance. * * @return a list of {@link FormValidation} for each updated Update Site - * @throws ExecutionException - * @throws InterruptedException * @since 1.501 - * */ public List updateAllSites() throws InterruptedException, ExecutionException { - List > futures = new ArrayList<>(); + List> futures = new ArrayList<>(); for (UpdateSite site : getSites()) { Future future = site.updateDirectly(); if (future != null) { @@ -1128,12 +1129,12 @@ public boolean isActivated() { return false; } Data data = getData(); - return data!=null && data.hasCoreUpdates(); + return data != null && data.hasCoreUpdates(); } public Data getData() { UpdateSite cs = Jenkins.get().getUpdateCenter().getCoreSource(); - if (cs!=null) return cs.getData(); + if (cs != null) return cs.getData(); return null; } @@ -1158,7 +1159,7 @@ public Permission getRequiredPermission() { * * @since 1.266 */ - @SuppressWarnings({"UnusedDeclaration"}) + @SuppressWarnings("UnusedDeclaration") public static class UpdateCenterConfiguration implements ExtensionPoint { /** * Creates default update center configuration - uses settings for global update center. @@ -1242,6 +1243,7 @@ public void postValidate(DownloadJob job, File src) throws IOException { * @throws IOException if there were problems downloading the resource. * @see DownloadJob */ + @SuppressFBWarnings(value = "WEAK_MESSAGE_DIGEST_SHA1", justification = "SHA-1 is only used as a fallback if SHA-256/SHA-512 are not available") public File download(DownloadJob job, URL src) throws IOException { MessageDigest sha1 = null; MessageDigest sha256 = null; @@ -1257,20 +1259,27 @@ public File download(DownloadJob job, URL src) throws IOException { URLConnection con = null; try { - con = connect(job,src); + con = connect(job, src); //JENKINS-34174 - set timeout for downloads, may hang indefinitely // particularly noticeable during 2.0 install when downloading // many plugins con.setReadTimeout(PLUGIN_DOWNLOAD_READ_TIMEOUT); - - int total = con.getContentLength(); + + long total; + final long sizeFromMetadata = job.getContentLength(); + if (sizeFromMetadata == -1) { + // Update site does not advertise a file size, so fall back to download file size, if any + total = con.getContentLength(); + } else { + total = sizeFromMetadata; + } byte[] buf = new byte[8192]; int len; File dst = job.getDestination(); - File tmp = new File(dst.getPath()+".tmp"); + File tmp = new File(dst.getPath() + ".tmp"); - LOGGER.info("Downloading "+job.getName()); + LOGGER.info("Downloading " + job.getName()); Thread t = Thread.currentThread(); String oldName = t.getName(); t.setName(oldName + ": " + src); @@ -1282,20 +1291,24 @@ public File download(DownloadJob job, URL src) throws IOException { InputStream in = con.getInputStream(); CountingInputStream cin = new CountingInputStream(in)) { while ((len = cin.read(buf)) >= 0) { - out.write(buf,0,len); - job.status = job.new Installing(total == -1 ? -1 : cin.getCount() * 100 / total); + out.write(buf, 0, len); + final int count = cin.getCount(); + job.status = job.new Installing(total == -1 ? -1 : ((int) (count * 100 / total))); + if (total != -1 && total < count) { + throw new IOException("Received more data than expected. Expected " + total + " bytes but got " + count + " bytes (so far), aborting download."); + } } } catch (IOException | InvalidPathException e) { - throw new IOException("Failed to load "+src+" to "+tmp,e); + throw new IOException("Failed to load " + src + " to " + tmp, e); } finally { t.setName(oldName); } - if (total!=-1 && total!=tmp.length()) { + if (total != -1 && total != tmp.length()) { // don't know exactly how this happens, but report like // http://www.ashlux.com/wordpress/2009/08/14/hudson-and-the-sonar-plugin-fail-maveninstallation-nosuchmethoderror/ // indicates that this kind of inconsistency can happen. So let's be defensive - throw new IOException("Inconsistent file length: expected "+total+" but only got "+tmp.length()); + throw new IOException("Inconsistent file length: expected " + total + " but only got " + tmp.length()); } if (sha1 != null) { @@ -1320,7 +1333,7 @@ public File download(DownloadJob job, URL src) throws IOException { // Also, since it involved name resolution, it'd be an expensive operation. extraMessage = " (redirected to: " + con.getURL() + ")"; } - throw new IOException("Failed to download from "+src+extraMessage,e); + throw new IOException("Failed to download from " + src + extraMessage, e); } } @@ -1375,11 +1388,11 @@ public String getConnectionCheckUrl() { * Returns the URL of the server that hosts the update-center.json * file. * + * @return + * Absolute URL that ends with '/'. * @deprecated as of 1.333 * With the introduction of multiple update center capability, this information * is now moved to {@link UpdateSite}. - * @return - * Absolute URL that ends with '/'. */ @Deprecated public String getUpdateCenterUrl() { @@ -1403,9 +1416,9 @@ private void testConnection(URL url) throws IOException { try { URLConnection connection = ProxyConfiguration.open(url); - if(connection instanceof HttpURLConnection) { - int responseCode = ((HttpURLConnection)connection).getResponseCode(); - if(HttpURLConnection.HTTP_OK != responseCode) { + if (connection instanceof HttpURLConnection) { + int responseCode = ((HttpURLConnection) connection).getResponseCode(); + if (HttpURLConnection.HTTP_OK != responseCode) { throw new HttpRetryException("Invalid response code (" + responseCode + ") from URL: " + url, responseCode); } } else { @@ -1416,7 +1429,7 @@ private void testConnection(URL url) throws IOException { } catch (SSLHandshakeException e) { if (e.getMessage().contains("PKIX path building failed")) // fix up this crappy error message from JDK - throw new IOException("Failed to validate the SSL certificate of "+url,e); + throw new IOException("Failed to validate the SSL certificate of " + url, e); } } } @@ -1491,11 +1504,11 @@ public String getType() { * {@link Future} to keeps track of the status of the execution. */ public Future submit() { - LOGGER.fine("Scheduling "+this+" to installerService"); + LOGGER.fine("Scheduling " + this + " to installerService"); // TODO: seems like this access to jobs should be synchronized, no? // It might get synch'd accidentally via the addJob method, but that wouldn't be good. jobs.add(this); - return installerService.submit(this,this); + return installerService.submit(this, this); } @Exported @@ -1515,8 +1528,8 @@ public class RestartJenkinsJob extends UpdateCenterJob { /** * Immutable state of this job. */ - @Exported(inline=true) - public volatile RestartJenkinsJobStatus status = new Pending(); + @Exported(inline = true) + public volatile RestartJenkinsJobStatus status = new RestartJenkinsJob.Pending(); /** * The name of the user that started this job @@ -1527,8 +1540,8 @@ public class RestartJenkinsJob extends UpdateCenterJob { * Cancel job */ public synchronized boolean cancel() { - if (status instanceof Pending) { - status = new Canceled(); + if (status instanceof RestartJenkinsJob.Pending) { + status = new RestartJenkinsJob.Canceled(); return true; } return false; @@ -1539,11 +1552,12 @@ public RestartJenkinsJob(UpdateSite site) { this.authentication = Jenkins.getAuthentication2().getName(); } + @Override public synchronized void run() { - if (!(status instanceof Pending)) { + if (!(status instanceof RestartJenkinsJob.Pending)) { return; } - status = new Running(); + status = new RestartJenkinsJob.Running(); try { // safeRestart records the current authentication for the log, so set it to the managing user try (ACLContext acl = ACL.as(User.get(authentication, false, Collections.emptyMap()))) { @@ -1551,7 +1565,7 @@ public synchronized void run() { } } catch (RestartNotSupportedException exception) { // ignore if restart is not allowed - status = new Failure(); + status = new RestartJenkinsJob.Failure(); error = exception; } } @@ -1587,7 +1601,7 @@ public class Canceled extends RestartJenkinsJobStatus { * Tests the internet connectivity. */ public final class ConnectionCheckJob extends UpdateCenterJob { - private final Vector statuses= new Vector<>(); + private final Vector statuses = new Vector<>(); final Map connectionStates = new ConcurrentHashMap<>(); @@ -1597,6 +1611,7 @@ public ConnectionCheckJob(UpdateSite site) { connectionStates.put(ConnectionStatus.UPDATE_SITE, ConnectionStatus.PRECHECK); } + @Override public void run() { connectionStates.put(ConnectionStatus.INTERNET, ConnectionStatus.UNCHECKED); connectionStates.put(ConnectionStatus.UPDATE_SITE, ConnectionStatus.UNCHECKED); @@ -1607,7 +1622,7 @@ public void run() { Future internetCheck = null; try { final String connectionCheckUrl = site.getConnectionCheckUrl(); - if (connectionCheckUrl!=null) { + if (connectionCheckUrl != null) { connectionStates.put(ConnectionStatus.INTERNET, ConnectionStatus.CHECKING); statuses.add(Messages.UpdateCenter_Status_CheckingInternet()); // Run the internet check in parallel @@ -1617,7 +1632,7 @@ public void run() { try { config.checkConnection(ConnectionCheckJob.this, connectionCheckUrl); } catch (Exception e) { - if(e.getMessage().contains("Connection timed out")) { + if (e.getMessage().contains("Connection timed out")) { // Google can't be down, so this is probably a proxy issue connectionStates.put(ConnectionStatus.INTERNET, ConnectionStatus.FAILED); statuses.add(Messages.UpdateCenter_Status_ConnectionFailed(Functions.xmlEscape(connectionCheckUrl))); @@ -1650,8 +1665,8 @@ public void run() { addStatus(e); error = e; } - - if(internetCheck != null) { + + if (internetCheck != null) { try { // Wait for internet check to complete internetCheck.get(); @@ -1662,7 +1677,7 @@ public void run() { } private void addStatus(Throwable e) { - statuses.add("

    "+ Functions.xmlEscape(Functions.printThrowable(e))+"
    "); + statuses.add("
    " + Functions.xmlEscape(Functions.printThrowable(e)) + "
    "); } public String[] getStatuses() { @@ -1673,7 +1688,7 @@ public String[] getStatuses() { } - + /** * Enables a required plugin, provides feedback in the update center */ @@ -1681,25 +1696,25 @@ public class EnableJob extends InstallationJob { public EnableJob(UpdateSite site, Authentication auth, @NonNull Plugin plugin, boolean dynamicLoad) { super(plugin, site, auth, dynamicLoad); } - + public Plugin getPlugin() { return plugin; } - + @Override public void run() { try { PluginWrapper installed = plugin.getInstalled(); - synchronized(installed) { + synchronized (installed) { if (!installed.isEnabled()) { try { installed.enable(); } catch (IOException e) { LOGGER.log(Level.SEVERE, "Failed to enable " + plugin.getDisplayName(), e); error = e; - status = new Failure(e); + status = new DownloadJob.Failure(e); } - + if (dynamicLoad) { try { // remove the existing, disabled inactive plugin to force a new one to load @@ -1708,25 +1723,25 @@ public void run() { LOGGER.log(Level.SEVERE, "Failed to dynamically load " + plugin.getDisplayName(), e); error = e; requiresRestart = true; - status = new Failure(e); + status = new DownloadJob.Failure(e); } } else { requiresRestart = true; } } } - } catch(Throwable e) { + } catch (Throwable e) { LOGGER.log(Level.SEVERE, "An unexpected error occurred while attempting to enable " + plugin.getDisplayName(), e); error = e; requiresRestart = true; - status = new Failure(e); + status = new DownloadJob.Failure(e); } - if(status instanceof Pending) { - status = new Success(); + if (status instanceof DownloadJob.Pending) { + status = new DownloadJob.Success(); } } } - + /** * A no-op, e.g. this plugin is already installed */ @@ -1734,20 +1749,23 @@ public class NoOpJob extends EnableJob { public NoOpJob(UpdateSite site, Authentication auth, @NonNull Plugin plugin) { super(site, auth, plugin, false); } + @Override public void run() { // do nothing - status = new Success(); + status = new DownloadJob.Success(); } } @Restricted(NoExternalUse.class) /*package*/ interface WithComputedChecksums { String getComputedSHA1(); + String getComputedSHA256(); + String getComputedSHA512(); } - + /** * Base class for a job that downloads a file from the Jenkins project. */ @@ -1755,8 +1773,8 @@ public abstract class DownloadJob extends UpdateCenterJob implements WithCompute /** * Immutable object representing the current state of this job. */ - @Exported(inline=true) - public volatile InstallationStatus status = new Pending(); + @Exported(inline = true) + public volatile InstallationStatus status = new DownloadJob.Pending(); /** * Where to download the file from. @@ -1793,6 +1811,7 @@ public String getDisplayName() { * * @since 1.641 */ + @Override @CheckForNull public String getComputedSHA1() { return computedSHA1; @@ -1805,6 +1824,7 @@ public String getComputedSHA1() { * * @since 2.130 */ + @Override @CheckForNull public String getComputedSHA256() { return computedSHA256; @@ -1817,6 +1837,7 @@ public String getComputedSHA256() { * * @since 2.130 */ + @Override @CheckForNull public String getComputedSHA512() { return computedSHA512; @@ -1838,14 +1859,15 @@ protected DownloadJob(UpdateSite site, Authentication authentication) { this.authentication = authentication; } + @Override public void run() { try { - LOGGER.info("Starting the installation of "+getName()+" on behalf of "+getUser().getName()); + LOGGER.info("Starting the installation of " + getName() + " on behalf of " + getUser().getName()); _run(); - LOGGER.info("Installation successful: "+getName()); - status = new Success(); + LOGGER.info("Installation successful: " + getName()); + status = new DownloadJob.Success(); onSuccess(); } catch (InstallationStatus e) { status = e; @@ -1853,11 +1875,11 @@ public void run() { requiresRestart |= status.requiresRestart(); } catch (MissingDependencyException e) { LOGGER.log(Level.SEVERE, "Failed to install {0}: {1}", new Object[] { getName(), e.getMessage() }); - status = new Failure(e); + status = new DownloadJob.Failure(e); error = e; } catch (Throwable e) { - LOGGER.log(Level.SEVERE, "Failed to install "+getName(),e); - status = new Failure(e); + LOGGER.log(Level.SEVERE, "Failed to install " + getName(), e); + status = new DownloadJob.Failure(e); error = e; } } @@ -1878,14 +1900,21 @@ protected void _run() throws IOException, InstallationStatus { * Called when the download is completed to overwrite * the old file with the new file. */ - protected void replace(File dst, File src) throws IOException { - File bak = Util.changeExtension(dst,".bak"); - bak.delete(); - dst.renameTo(bak); - dst.delete(); // any failure up to here is no big deal - if(!src.renameTo(dst)) { - throw new IOException("Failed to rename "+src+" to "+dst); - } + protected synchronized void replace(File dst, File src) throws IOException { + File bak = Util.changeExtension(dst, ".bak"); + moveAtomically(dst, bak); + moveAtomically(src, dst); + } + + /** + * Indicate the expected size of the download as provided in update site + * metadata. + * + * @return the expected size, or -1 if unknown. + * @since 2.325 + */ + public long getContentLength() { + return -1; } /** @@ -1896,10 +1925,12 @@ protected void replace(File dst, File src) throws IOException { @ExportedBean public abstract class InstallationStatus extends Throwable { public final int id = iota.incrementAndGet(); + @Exported public boolean isSuccess() { return false; } + @Exported public final String getType() { return getClass().getSimpleName(); @@ -2002,11 +2033,11 @@ private static VerificationResult verifyChecksums(String expectedDigest, String } if (caseSensitive) { - if (MessageDigest.isEqual(expectedDigest.getBytes(), actualDigest.getBytes())) { + if (MessageDigest.isEqual(expectedDigest.getBytes(StandardCharsets.US_ASCII), actualDigest.getBytes(StandardCharsets.US_ASCII))) { return VerificationResult.PASS; } } else { - if (MessageDigest.isEqual(expectedDigest.toLowerCase().getBytes(), actualDigest.toLowerCase().getBytes())) { + if (MessageDigest.isEqual(expectedDigest.toLowerCase().getBytes(StandardCharsets.US_ASCII), actualDigest.toLowerCase().getBytes(StandardCharsets.US_ASCII))) { return VerificationResult.PASS; } } @@ -2084,6 +2115,8 @@ private static void throwVerificationFailure(String expected, String actual, Fil throw new IOException("Failed to compute SHA-1 of downloaded file, refusing installation"); case NOT_PROVIDED: throw new IOException("Unable to confirm integrity of downloaded file, refusing installation"); + default: + throw new AssertionError("Unknown verification result: " + result1); } } @@ -2111,11 +2144,11 @@ public class InstallationJob extends DownloadJob { */ @Deprecated public InstallationJob(Plugin plugin, UpdateSite site, Authentication auth) { - this(plugin,site,auth,false); + this(plugin, site, auth, false); } /** - * @deprecated use {@link InstallationJob(Plugin, UpdateSite, Authentication, boolean)} + * @deprecated use {@link #InstallationJob(UpdateSite.Plugin, UpdateSite, Authentication, boolean)} */ @Deprecated public InstallationJob(Plugin plugin, UpdateSite site, org.acegisecurity.Authentication auth, boolean dynamicLoad) { @@ -2128,10 +2161,12 @@ public InstallationJob(Plugin plugin, UpdateSite site, Authentication auth, bool this.dynamicLoad = dynamicLoad; } + @Override protected URL getURL() throws MalformedURLException { return new URL(plugin.url); } + @Override protected File getDestination() { File baseDir = pm.rootDir; return new File(baseDir, plugin.name + ".jpi"); @@ -2152,6 +2187,12 @@ public String getDisplayName() { return plugin.getDisplayName(); } + @Override + public long getContentLength() { + final Long size = plugin.getFileSize(); + return size == null ? -1 : size; + } + @Override public void _run() throws IOException, InstallationStatus { if (wasInstalled()) { @@ -2165,7 +2206,7 @@ public void _run() throws IOException, InstallationStatus { // if this is a bundled plugin, make sure it won't get overwritten PluginWrapper pw = plugin.getInstalled(); - if (pw!=null && pw.isBundled()) { + if (pw != null && pw.isBundled()) { try (ACLContext ctx = ACL.as2(ACL.SYSTEM2)) { pw.doPin(); } @@ -2175,20 +2216,20 @@ public void _run() throws IOException, InstallationStatus { try { pm.dynamicLoad(getDestination(), false, batch); } catch (RestartRequiredException e) { - throw new SuccessButRequiresRestart(e.message); + throw new DownloadJob.SuccessButRequiresRestart(e.message); } catch (Exception e) { - throw new IOException("Failed to dynamically deploy this plugin",e); + throw new IOException("Failed to dynamically deploy this plugin", e); } } else { - throw new SuccessButRequiresRestart(Messages._UpdateCenter_DownloadButNotActivated()); + throw new DownloadJob.SuccessButRequiresRestart(Messages._UpdateCenter_DownloadButNotActivated()); } } finally { - synchronized(this) { + synchronized (this) { // There may be other threads waiting on completion LOGGER.fine("Install complete for: " + plugin.getDisplayName() + "@" + plugin.version); // some status other than Installing or Downloading needs to be set here // {@link #isAlreadyInstalling()}, it will be overwritten by {@link DownloadJob#run()} - status = new Skipped(); + status = new DownloadJob.Skipped(); notifyAll(); } } @@ -2199,7 +2240,7 @@ public void _run() throws IOException, InstallationStatus { * @since 2.1 */ protected boolean wasInstalled() { - synchronized(UpdateCenter.this) { + synchronized (UpdateCenter.this) { for (UpdateCenterJob job : getJobs()) { if (job == this) { // oldest entries first, if we reach this instance, @@ -2207,11 +2248,11 @@ protected boolean wasInstalled() { return false; } if (job instanceof InstallationJob) { - InstallationJob ij = (InstallationJob)job; + InstallationJob ij = (InstallationJob) job; if (ij.plugin.equals(plugin) && ij.plugin.version.equals(plugin.version)) { // wait until other install is completed - synchronized(ij) { - if(ij.status instanceof Installing || ij.status instanceof Pending) { + synchronized (ij) { + if (ij.status instanceof DownloadJob.Installing || ij.status instanceof DownloadJob.Pending) { try { LOGGER.fine("Waiting for other plugin install of: " + plugin.getDisplayName() + "@" + plugin.version); ij.wait(); @@ -2220,7 +2261,7 @@ protected boolean wasInstalled() { } } // Must check for success, otherwise may have failed installation - if (ij.status instanceof Success) { + if (ij.status instanceof DownloadJob.Success) { return true; } } @@ -2231,13 +2272,14 @@ protected boolean wasInstalled() { } } + @Override protected void onSuccess() { pm.pluginUploaded = true; } @Override public String toString() { - return super.toString()+"[plugin="+plugin.title+"]"; + return super.toString() + "[plugin=" + plugin.title + "]"; } /** @@ -2250,23 +2292,18 @@ protected void replace(File dst, File src) throws IOException { verifyChecksums(this, plugin, src); } - File bak = Util.changeExtension(dst, ".bak"); - bak.delete(); + synchronized (this) { + File bak = Util.changeExtension(dst, ".bak"); - final File legacy = getLegacyDestination(); - if (legacy.exists()) { - if (!legacy.renameTo(bak)) { - legacy.delete(); + final File legacy = getLegacyDestination(); + if (Files.exists(Util.fileToPath(legacy))) { + moveAtomically(legacy, bak); } - } - if (dst.exists()) { - if (!dst.renameTo(bak)) { - dst.delete(); + if (Files.exists(Util.fileToPath(dst))) { + moveAtomically(dst, bak); } - } - if(!src.renameTo(dst)) { - throw new IOException("Failed to rename "+src+" to "+dst); + moveAtomically(src, dst); } } @@ -2282,7 +2319,8 @@ public final class CompleteBatchJob extends UpdateCenterJob { private final List batch; private final long start; @Exported(inline = true) - public volatile CompleteBatchJobStatus status = new Pending(); + @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD", justification = "read by Stapler") + public volatile CompleteBatchJobStatus status = new CompleteBatchJob.Pending(); public CompleteBatchJob(List batch, long start, UUID correlationId) { super(getCoreSource()); @@ -2294,12 +2332,12 @@ public CompleteBatchJob(List batch, long start, UUID correlationI @Override public void run() { LOGGER.info("Completing installing of plugin batch…"); - status = new Running(); + status = new CompleteBatchJob.Running(); try { Jenkins.get().getPluginManager().start(batch); - status = new Success(); + status = new CompleteBatchJob.Success(); } catch (Exception x) { - status = new Failure(x); + status = new CompleteBatchJob.Failure(x); LOGGER.log(Level.WARNING, "Failed to start some plugins", x); } LOGGER.log(INFO, "Completed installation of {0} plugins in {1}", new Object[] {batch.size(), Util.getTimeSpanString((System.nanoTime() - start) / 1_000_000)}); @@ -2321,6 +2359,7 @@ public class Failure extends CompleteBatchJobStatus { Failure(Throwable problemStackTrace) { this.problemStackTrace = problemStackTrace; } + public final Throwable problemStackTrace; } @@ -2338,7 +2377,7 @@ public final class PluginDowngradeJob extends DownloadJob { private final PluginManager pm = Jenkins.get().getPluginManager(); /** - * @deprecated use {@link PluginDowngradeJob(Plugin, UpdateSite, Authentication)} + * @deprecated use {@link #PluginDowngradeJob(UpdateSite.Plugin, UpdateSite, Authentication)} */ @Deprecated public PluginDowngradeJob(Plugin plugin, UpdateSite site, org.acegisecurity.Authentication auth) { @@ -2351,14 +2390,16 @@ public PluginDowngradeJob(Plugin plugin, UpdateSite site, Authentication auth) { this.plugin = plugin; } + @Override protected URL getURL() throws MalformedURLException { return new URL(plugin.url); } + @Override protected File getDestination() { File baseDir = pm.rootDir; final File legacy = new File(baseDir, plugin.name + ".hpi"); - if(legacy.exists()){ + if (legacy.exists()) { return legacy; } return new File(baseDir, plugin.name + ".jpi"); @@ -2382,16 +2423,16 @@ public String getDisplayName() { @Override public void run() { try { - LOGGER.info("Starting the downgrade of "+getName()+" on behalf of "+getUser().getName()); + LOGGER.info("Starting the downgrade of " + getName() + " on behalf of " + getUser().getName()); _run(); - LOGGER.info("Downgrade successful: "+getName()); + LOGGER.info("Downgrade successful: " + getName()); status = new Success(); onSuccess(); } catch (Throwable e) { - LOGGER.log(Level.SEVERE, "Failed to downgrade "+getName(),e); - status = new Failure(e); + LOGGER.log(Level.SEVERE, "Failed to downgrade " + getName(), e); + status = new DownloadJob.Failure(e); error = e; } } @@ -2409,20 +2450,18 @@ protected void _run() throws IOException { * current version with backup file */ @Override - protected void replace(File dst, File backup) throws IOException { - dst.delete(); // any failure up to here is no big deal - if(!backup.renameTo(dst)) { - throw new IOException("Failed to rename "+backup+" to "+dst); - } + protected synchronized void replace(File dst, File backup) throws IOException { + moveAtomically(backup, dst); } + @Override protected void onSuccess() { pm.pluginUploaded = true; } @Override public String toString() { - return super.toString()+"[plugin="+plugin.title+"]"; + return super.toString() + "[plugin=" + plugin.title + "]"; } } @@ -2432,7 +2471,7 @@ public String toString() { public final class HudsonUpgradeJob extends DownloadJob { /** - * @deprecated use {@link HudsonUpgradeJob(UpdateSite site, Authentication auth)} + * @deprecated use {@link #HudsonUpgradeJob(UpdateSite, Authentication)} */ @Deprecated public HudsonUpgradeJob(UpdateSite site, org.acegisecurity.Authentication auth) { @@ -2443,6 +2482,7 @@ public HudsonUpgradeJob(UpdateSite site, Authentication auth) { super(site, auth); } + @Override protected URL getURL() throws MalformedURLException { if (site == null) { throw new MalformedURLException("no update site defined"); @@ -2450,16 +2490,19 @@ protected URL getURL() throws MalformedURLException { return new URL(site.getData().core.url); } + @Override protected File getDestination() { return Lifecycle.get().getHudsonWar(); } + @Override public String getName() { return "jenkins.war"; } + @Override protected void onSuccess() { - status = new Success(); + status = new DownloadJob.Success(); } @Override @@ -2475,7 +2518,7 @@ protected void replace(File dst, File src) throws IOException { public final class HudsonDowngradeJob extends DownloadJob { /** - * @deprecated use {@link HudsonDowngradeJob(UpdateSite site, Authentication auth)} + * @deprecated use {@link #HudsonDowngradeJob(UpdateSite, Authentication)} */ @Deprecated public HudsonDowngradeJob(UpdateSite site, org.acegisecurity.Authentication auth) { @@ -2486,6 +2529,7 @@ public HudsonDowngradeJob(UpdateSite site, Authentication auth) { super(site, auth); } + @Override protected URL getURL() throws MalformedURLException { if (site == null) { throw new MalformedURLException("no update site defined"); @@ -2493,29 +2537,34 @@ protected URL getURL() throws MalformedURLException { return new URL(site.getData().core.url); } + @Override protected File getDestination() { return Lifecycle.get().getHudsonWar(); } + @Override public String getName() { return "jenkins.war"; } + + @Override protected void onSuccess() { - status = new Success(); + status = new DownloadJob.Success(); } + @Override public void run() { try { - LOGGER.info("Starting the downgrade of "+getName()+" on behalf of "+getUser().getName()); + LOGGER.info("Starting the downgrade of " + getName() + " on behalf of " + getUser().getName()); _run(); - LOGGER.info("Downgrading successful: "+getName()); - status = new Success(); + LOGGER.info("Downgrading successful: " + getName()); + status = new DownloadJob.Success(); onSuccess(); } catch (Throwable e) { - LOGGER.log(Level.SEVERE, "Failed to downgrade "+getName(),e); - status = new Failure(e); + LOGGER.log(Level.SEVERE, "Failed to downgrade " + getName(), e); + status = new DownloadJob.Failure(e); error = e; } } @@ -2539,15 +2588,17 @@ protected void replace(File dst, File src) throws IOException { public static final class PluginEntry implements Comparable { public Plugin plugin; public String category; + private PluginEntry(Plugin p, String c) { plugin = p; category = c; } + @Override public int compareTo(PluginEntry o) { int r = category.compareTo(o.category); - if (r==0) r = plugin.name.compareToIgnoreCase(o.plugin.name); - if (r==0) r = new VersionNumber(plugin.version).compareTo(new VersionNumber(o.plugin.version)); + if (r == 0) r = plugin.name.compareToIgnoreCase(o.plugin.name); + if (r == 0) r = new VersionNumber(plugin.version).compareTo(new VersionNumber(o.plugin.version)); return r; } @@ -2585,7 +2636,7 @@ public int hashCode() { * * This has to wait until after all plugins load, to let custom UpdateCenterConfiguration take effect first. */ - @Initializer(after=PLUGINS_STARTED, fatal=false) + @Initializer(after = PLUGINS_STARTED, fatal = false) public static void init(Jenkins h) throws IOException { h.getUpdateCenter().load(); } @@ -2633,8 +2684,8 @@ public Object getTarget() { * Escape hatch for StaplerProxy-based access control */ @Restricted(NoExternalUse.class) - @SuppressFBWarnings("MS_SHOULD_BE_FINAL") - public static /* Script Console modifiable */ boolean SKIP_PERMISSION_CHECK = Boolean.getBoolean(UpdateCenter.class.getName() + ".skipPermissionCheck"); + @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "for script console") + public static /* Script Console modifiable */ boolean SKIP_PERMISSION_CHECK = SystemProperties.getBoolean(UpdateCenter.class.getName() + ".skipPermissionCheck"); /** @@ -2647,12 +2698,26 @@ public Object getTarget() { * Use {@link UpdateSite#neverUpdate} */ @Deprecated - public static boolean neverUpdate = SystemProperties.getBoolean(UpdateCenter.class.getName()+".never"); + public static boolean neverUpdate = SystemProperties.getBoolean(UpdateCenter.class.getName() + ".never"); public static final XStream2 XSTREAM = new XStream2(); static { - XSTREAM.alias("site",UpdateSite.class); - XSTREAM.alias("sites",PersistedList.class); + XSTREAM.alias("site", UpdateSite.class); + XSTREAM.alias("sites", PersistedList.class); + } + + private static void moveAtomically(File src, File target) throws IOException { + try { + Files.move(Util.fileToPath(src), Util.fileToPath(target), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE); + } catch (AtomicMoveNotSupportedException e) { + LOGGER.log(Level.WARNING, "Atomic move not supported. Falling back to non-atomic move.", e); + try { + Files.move(Util.fileToPath(src), Util.fileToPath(target), StandardCopyOption.REPLACE_EXISTING); + } catch (IOException e2) { + e2.addSuppressed(e); + throw e2; + } + } } } diff --git a/core/src/main/java/hudson/model/UpdateSite.java b/core/src/main/java/hudson/model/UpdateSite.java index 30f292387fe3..72966f873b06 100644 --- a/core/src/main/java/hudson/model/UpdateSite.java +++ b/core/src/main/java/hudson/model/UpdateSite.java @@ -1,19 +1,19 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Yahoo! Inc., Seiji Sogabe, * Andrew Bayer - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -25,6 +25,15 @@ package hudson.model; +import static java.util.concurrent.TimeUnit.DAYS; +import static java.util.concurrent.TimeUnit.HOURS; +import static java.util.concurrent.TimeUnit.SECONDS; +import static jenkins.util.MemoryReductionUtil.getPresizedMutableMap; + +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.Nullable; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.ExtensionList; import hudson.PluginManager; import hudson.PluginWrapper; @@ -32,12 +41,10 @@ import hudson.lifecycle.Lifecycle; import hudson.model.UpdateCenter.UpdateCenterJob; import hudson.util.FormValidation; -import hudson.util.FormValidation.Kind; import hudson.util.HttpResponses; -import static jenkins.util.MemoryReductionUtil.*; import hudson.util.TextFile; -import static java.util.concurrent.TimeUnit.*; import hudson.util.VersionNumber; +import io.jenkins.lib.versionnumber.JavaSpecificationVersion; import java.io.File; import java.io.IOException; import java.net.URI; @@ -66,17 +73,12 @@ import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; import java.util.stream.Stream; - -import edu.umd.cs.findbugs.annotations.CheckForNull; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; - -import io.jenkins.lib.versionnumber.JavaSpecificationVersion; import jenkins.model.Jenkins; import jenkins.plugins.DetachedPluginsUtil; import jenkins.security.UpdateSiteWarningsConfiguration; import jenkins.security.UpdateSiteWarningsMonitor; import jenkins.util.JSONSignatureValidator; +import jenkins.util.PluginLabelUtil; import jenkins.util.SystemProperties; import jenkins.util.java.JavaUtils; import net.sf.json.JSONArray; @@ -216,7 +218,7 @@ public long getDataTimestamp() { public @NonNull FormValidation updateDirectlyNow(boolean signatureCheck) throws IOException { return updateData(DownloadService.loadJSON(new URL(getUrl() + "?id=" + URLEncoder.encode(getId(), "UTF-8") + "&version=" + URLEncoder.encode(Jenkins.VERSION, "UTF-8"))), signatureCheck); } - + private FormValidation updateData(String json, boolean signatureCheck) throws IOException { @@ -235,7 +237,7 @@ private FormValidation updateData(String json, boolean signatureCheck) if (signatureCheck) { FormValidation e = verifySignatureInternal(o); - if (e.kind!=Kind.OK) { + if (e.kind != FormValidation.Kind.OK) { LOGGER.severe(e.toString()); return e; } @@ -287,7 +289,7 @@ protected JSONSignatureValidator getJsonSignatureValidator() { /** * Let sub-classes of UpdateSite provide their own signature validator. - * @param name, the name for the JSON signature Validator object. + * @param name the name for the JSON signature Validator object. * if name is null, then the default name will be used, * which is "update site" followed by the update site id * @return the signature validator. @@ -305,17 +307,17 @@ protected JSONSignatureValidator getJsonSignatureValidator(@CheckForNull String * Returns true if it's time for us to check for new version. */ public synchronized boolean isDue() { - if(neverUpdate) return false; - if(dataTimestamp == 0) + if (neverUpdate) return false; + if (dataTimestamp == 0) dataTimestamp = getDataFile().file.lastModified(); long now = System.currentTimeMillis(); - retryWindow = Math.max(retryWindow,SECONDS.toMillis(15)); - + retryWindow = Math.max(retryWindow, SECONDS.toMillis(15)); + boolean due = now - dataTimestamp > DAY && now - lastAttempt > retryWindow; - if(due) { + if (due) { lastAttempt = now; - retryWindow = Math.min(retryWindow*2, HOURS.toMillis(1)); // exponential back off but at most 1 hour + retryWindow = Math.min(retryWindow * 2, HOURS.toMillis(1)); // exponential back off but at most 1 hour } return due; } @@ -362,15 +364,19 @@ boolean hasUnparsedData() { */ public JSONObject getJSONObject() { TextFile df = getDataFile(); - if(df.exists()) { + if (df.exists()) { long start = System.nanoTime(); try { JSONObject o = JSONObject.fromObject(df.read()); LOGGER.fine(() -> String.format("Loaded and parsed %s in %.01fs", df, (System.nanoTime() - start) / 1_000_000_000.0)); return o; } catch (JSONException | IOException e) { - LOGGER.log(Level.SEVERE,"Failed to parse "+df,e); - df.delete(); // if we keep this file, it will cause repeated failures + LOGGER.log(Level.SEVERE, "Failed to parse " + df, e); + try { + df.delete(); // if we keep this file, it will cause repeated failures + } catch (IOException e2) { + LOGGER.log(Level.SEVERE, "Failed to delete " + df, e2); + } return null; } } else { @@ -386,9 +392,9 @@ public JSONObject getJSONObject() { public List getAvailables() { List r = new ArrayList<>(); Data data = getData(); - if(data==null) return Collections.emptyList(); + if (data == null) return Collections.emptyList(); for (Plugin p : data.plugins.values()) { - if(p.getInstalled()==null) + if (p.getInstalled() == null) r.add(p); } r.sort((plugin, t1) -> { @@ -413,7 +419,7 @@ public List getAvailables() { @CheckForNull public Plugin getPlugin(String artifactId) { Data dt = getData(); - if(dt==null) return null; + if (dt == null) return null; return dt.plugins.get(artifactId); } @@ -429,7 +435,7 @@ public Api getApi() { @CheckForNull public String getConnectionCheckUrl() { Data dt = getData(); - if(dt==null) return "http://www.google.com/"; + if (dt == null) return "http://www.google.com/"; return dt.connectionCheckUrl; } @@ -438,9 +444,9 @@ public String getConnectionCheckUrl() { */ private TextFile getDataFile() { return new TextFile(new File(Jenkins.get().getRootDir(), - "updates/" + getId()+".json")); + "updates/" + getId() + ".json")); } - + /** * Returns the list of plugins that are updates to currently installed ones. * @@ -450,35 +456,35 @@ private TextFile getDataFile() { @Exported public List getUpdates() { Data data = getData(); - if(data==null) return Collections.emptyList(); // fail to determine - + if (data == null) return Collections.emptyList(); // fail to determine + List r = new ArrayList<>(); for (PluginWrapper pw : Jenkins.get().getPluginManager().getPlugins()) { Plugin p = pw.getUpdateInfo(); - if(p!=null) r.add(p); + if (p != null) r.add(p); } - + return r; } - + /** * Does any of the plugin has updates? */ @Exported public boolean hasUpdates() { Data data = getData(); - if(data==null) return false; - + if (data == null) return false; + for (PluginWrapper pw : Jenkins.get().getPluginManager().getPlugins()) { - if(!pw.isBundled() && pw.getUpdateInfo()!=null) + if (!pw.isBundled() && pw.getUpdateInfo() != null) // do not advertize updates to bundled plugins, since we generally want users to get them - // as a part of jenkins.war updates. This also avoids unnecessary pinning of plugins. + // as a part of jenkins.war updates. This also avoids unnecessary pinning of plugins. return true; } return false; } - - + + /** * Exposed to get rid of hardcoding of the URL that serves up update-center.json * in JavaScript. @@ -491,7 +497,7 @@ public String getUrl() { /** * URL which exposes the metadata location in a specific update site. - * @param downloadable, the downloadable id of a specific metatadata json (e.g. hudson.tasks.Maven.MavenInstaller.json) + * @param downloadable the downloadable id of a specific metatadata json (e.g. hudson.tasks.Maven.MavenInstaller.json) * @return the location * @since 2.20 */ @@ -552,7 +558,7 @@ public final class Data { /** * Plugins in the repository, keyed by their artifact IDs. */ - public final Map plugins = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + public final Map plugins = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); /** * List of warnings (mostly security) published with the update site. * @@ -574,9 +580,9 @@ public final class Data { public final String connectionCheckUrl; Data(JSONObject o) { - this.sourceId = Util.intern((String)o.get("id")); + this.sourceId = Util.intern((String) o.get("id")); JSONObject c = o.optJSONObject("core"); - if (c!=null) { + if (c != null) { core = new Entry(sourceId, c, url); } else { core = null; @@ -611,13 +617,13 @@ public final class Data { } } - for(Map.Entry e : (Set>)o.getJSONObject("plugins").entrySet()) { + for (Map.Entry e : (Set>) o.getJSONObject("plugins").entrySet()) { Plugin p = new Plugin(sourceId, e.getValue()); // JENKINS-33308 - include implied dependencies for older plugins that may need them List implicitDeps = DetachedPluginsUtil.getImpliedDependencies(p.name, p.requiredCore); - if(!implicitDeps.isEmpty()) { - for(PluginWrapper.Dependency dep : implicitDeps) { - if(!p.dependencies.containsKey(dep.shortName)) { + if (!implicitDeps.isEmpty()) { + for (PluginWrapper.Dependency dep : implicitDeps) { + if (!p.dependencies.containsKey(dep.shortName)) { p.dependencies.put(dep.shortName, dep.version); } } @@ -633,7 +639,7 @@ public final class Data { } } - connectionCheckUrl = (String)o.get("connectionCheckUrl"); + connectionCheckUrl = (String) o.get("connectionCheckUrl"); } /** @@ -695,6 +701,10 @@ public static class Entry { @Exported public final String url; + /** + * Size of the file in bytes, or {@code null} if unknown. + */ + private final Long size; // non-private, non-final for test @Restricted(NoExternalUse.class) @@ -721,6 +731,12 @@ public Entry(String sourceId, JSONObject o) { this.sha256 = Util.fixEmptyAndTrim(o.optString("sha256")); this.sha512 = Util.fixEmptyAndTrim(o.optString("sha512")); + Long fileSize = null; + if (o.has("size")) { + fileSize = o.getLong("size"); + } + this.size = fileSize; + String url = o.getString("url"); if (!URI.create(url).isAbsolute()) { if (baseURL == null) { @@ -781,6 +797,17 @@ public Api getApi() { return new Api(this); } + /** + * Size of the file being advertised in bytes, or {@code null} if unspecified/unknown. + * @return size of the file if known, {@code null} otherwise. + * + * @since 2.325 + */ + // @Exported -- TODO unsure + @Restricted(NoExternalUse.class) + public Long getFileSize() { + return size; + } } /** @@ -851,6 +878,7 @@ public static final class Deprecation { * Jenkins will show a link to this URL when displaying the deprecation message. */ public final String url; + public Deprecation(String url) { this.url = url; } @@ -1041,14 +1069,50 @@ public boolean isRelevantToVersion(@NonNull VersionNumber version) { } private static String get(JSONObject o, String prop) { - if(o.has(prop)) + if (o.has(prop)) return o.getString(prop); else return null; } - static final Predicate IS_DEP_PREDICATE = x -> x instanceof JSONObject && get(((JSONObject)x), "name") != null; - static final Predicate IS_NOT_OPTIONAL = x-> "false".equals(get(((JSONObject)x), "optional")); + static final Predicate IS_DEP_PREDICATE = x -> x instanceof JSONObject && get((JSONObject) x, "name") != null; + static final Predicate IS_NOT_OPTIONAL = x -> "false".equals(get((JSONObject) x, "optional")); + + /** + * Metadata for one issue tracker provided by the update site. + */ + @Restricted(NoExternalUse.class) + public static final class IssueTracker { + /** + * A string specifying the type of issue tracker. + */ + public final String type; + /** + * Issue tracker URL that can be used to view previously reported issues. + */ + public final String viewUrl; + /** + * Issue tracker URL that can be used to report a new issue. + */ + @CheckForNull + public final String reportUrl; + + public IssueTracker(@NonNull String type, @NonNull String viewUrl, @CheckForNull String reportUrl) { + this.type = type; + this.viewUrl = viewUrl; + this.reportUrl = reportUrl; + } + + private static IssueTracker createFromJSONObject(Object o) { + if (o instanceof JSONObject) { + JSONObject jsonObject = (JSONObject) o; + if (jsonObject.has("type") && jsonObject.has("viewUrl") && jsonObject.has("reportUrl")) { + return new IssueTracker(jsonObject.getString("type"), jsonObject.getString("viewUrl"), jsonObject.getString("reportUrl")); + } + } + return null; + } + } public final class Plugin extends Entry { /** @@ -1099,13 +1163,13 @@ public final class Plugin extends Entry { * Dependencies of this plugin, a name -> version mapping. */ @Exported - public final Map dependencies; - + public final Map dependencies; + /** * Optional dependencies of this plugin. */ @Exported - public final Map optionalDependencies; + public final Map optionalDependencies; /** * Set of plugins, this plugin is a incompatible dependency to. @@ -1134,22 +1198,31 @@ public final class Plugin extends Entry { @Restricted(NoExternalUse.class) public String latest; + /** + * Issue trackers associated with this plugin. + * This list is sorted by preference in descending order, meaning a UI + * supporting only one issue tracker should reference the first one + * supporting the desired behavior (like having a {@code reportUrl}). + */ + @Restricted(NoExternalUse.class) + public IssueTracker[] issueTrackers; + @DataBoundConstructor public Plugin(String sourceId, JSONObject o) { super(sourceId, o, UpdateSite.this.url); - this.wiki = get(o,"wiki"); - this.title = get(o,"title"); - this.excerpt = get(o,"excerpt"); - this.compatibleSinceVersion = Util.intern(get(o,"compatibleSinceVersion")); + this.wiki = get(o, "wiki"); + this.title = get(o, "title"); + this.excerpt = get(o, "excerpt"); + this.compatibleSinceVersion = Util.intern(get(o, "compatibleSinceVersion")); this.minimumJavaVersion = Util.intern(get(o, "minimumJavaVersion")); this.latest = get(o, "latest"); - this.requiredCore = Util.intern(get(o,"requiredCore")); + this.requiredCore = Util.intern(get(o, "requiredCore")); final String releaseTimestamp = get(o, "releaseTimestamp"); Date date = null; if (releaseTimestamp != null) { try { date = Date.from(Instant.parse(releaseTimestamp)); - } catch (Exception ex) { + } catch (RuntimeException ex) { LOGGER.log(Level.FINE, "Failed to parse releaseTimestamp for " + title + " from " + sourceId, ex); } } @@ -1164,18 +1237,20 @@ public Plugin(String sourceId, JSONObject o) { } this.popularity = popularity; this.releaseTimestamp = date; - this.categories = o.has("labels") ? internInPlace((String[])o.getJSONArray("labels").toArray(EMPTY_STRING_ARRAY)) : null; + this.categories = o.has("labels") ? PluginLabelUtil.canonicalLabels(o.getJSONArray("labels")) : null; + this.issueTrackers = o.has("issueTrackers") ? o.getJSONArray("issueTrackers").stream().map(IssueTracker::createFromJSONObject).filter(Objects::nonNull).toArray(IssueTracker[]::new) : null; + JSONArray ja = o.getJSONArray("dependencies"); - int depCount = (int)(ja.stream().filter(IS_DEP_PREDICATE.and(IS_NOT_OPTIONAL)).count()); - int optionalDepCount = (int)(ja.stream().filter(IS_DEP_PREDICATE.and(IS_NOT_OPTIONAL.negate())).count()); + int depCount = (int) ja.stream().filter(IS_DEP_PREDICATE.and(IS_NOT_OPTIONAL)).count(); + int optionalDepCount = (int) ja.stream().filter(IS_DEP_PREDICATE.and(IS_NOT_OPTIONAL.negate())).count(); dependencies = getPresizedMutableMap(depCount); optionalDependencies = getPresizedMutableMap(optionalDepCount); - for(Object jo : o.getJSONArray("dependencies")) { + for (Object jo : o.getJSONArray("dependencies")) { JSONObject depObj = (JSONObject) jo; // Make sure there's a name attribute and that the optional value isn't true. - String depName = Util.intern(get(depObj,"name")); - if (depName!=null) { + String depName = Util.intern(get(depObj, "name")); + if (depName != null) { if (get(depObj, "optional").equals("false")) { dependencies.put(depName, Util.intern(get(depObj, "version"))); } else { @@ -1198,7 +1273,7 @@ public UpdateSite.Deprecation getDeprecation() { public String getDisplayName() { String displayName; - if(title!=null) + if (title != null) displayName = title; else displayName = name; @@ -1262,7 +1337,7 @@ public boolean isCompatibleWithInstalledVersion() { public List getNeededDependencies() { List deps = new ArrayList<>(); - for(Map.Entry e : dependencies.entrySet()) { + for (Map.Entry e : dependencies.entrySet()) { VersionNumber requiredVersion = e.getValue() != null ? new VersionNumber(e.getValue()) : null; Plugin depPlugin = Jenkins.get().getUpdateCenter().getPlugin(e.getKey(), requiredVersion); if (depPlugin == null) { @@ -1273,7 +1348,7 @@ public List getNeededDependencies() { // Is the plugin installed already? If not, add it. PluginWrapper current = depPlugin.getInstalled(); - if (current ==null) { + if (current == null) { deps.add(depPlugin); } // If the dependency plugin is installed, is the version we depend on newer than @@ -1287,7 +1362,7 @@ else if (!current.isEnabled()) { } } - for(Map.Entry e : optionalDependencies.entrySet()) { + for (Map.Entry e : optionalDependencies.entrySet()) { VersionNumber requiredVersion = e.getValue() != null ? new VersionNumber(e.getValue()) : null; Plugin depPlugin = Jenkins.get().getUpdateCenter().getPlugin(e.getKey(), requiredVersion); if (depPlugin == null) { @@ -1308,7 +1383,7 @@ else if (!current.isEnabled()) { public boolean isForNewerHudson() { try { - return requiredCore!=null && new VersionNumber(requiredCore).isNewerThan( + return requiredCore != null && new VersionNumber(requiredCore).isNewerThan( new VersionNumber(Jenkins.VERSION.replaceFirst("SHOT *\\(private.*\\)", "SHOT"))); } catch (NumberFormatException nfe) { return true; // If unable to parse version @@ -1337,7 +1412,7 @@ public VersionNumber getNeededDependenciesRequiredCore() { } catch (NumberFormatException nfe) { // unable to parse version } - for (Plugin p: getNeededDependencies()) { + for (Plugin p : getNeededDependencies()) { VersionNumber v = p.getNeededDependenciesRequiredCore(); if (versionNumber == null || v.isNewerThan(versionNumber)) versionNumber = v; } @@ -1357,7 +1432,7 @@ public VersionNumber getNeededDependenciesMinimumJavaVersion() { } catch (NumberFormatException nfe) { logBadMinJavaVersion(); } - for (Plugin p: getNeededDependencies()) { + for (Plugin p : getNeededDependencies()) { VersionNumber v = p.getNeededDependenciesMinimumJavaVersion(); if (v == null) { continue; @@ -1396,7 +1471,7 @@ public boolean isNeededDependenciesForNewerJenkins(PluginManager.MetadataCache c * @since 2.158 */ public boolean isNeededDependenciesForNewerJava() { - for (Plugin p: getNeededDependencies()) { + for (Plugin p : getNeededDependencies()) { if (p.isForNewerJava() || p.isNeededDependenciesForNewerJava()) { return true; } @@ -1489,7 +1564,7 @@ public Set getWarnings() { UpdateSiteWarningsConfiguration configuration = ExtensionList.lookupSingleton(UpdateSiteWarningsConfiguration.class); Set warnings = new HashSet<>(); - for (Warning warning: configuration.getAllWarnings()) { + for (Warning warning : configuration.getAllWarnings()) { if (configuration.isIgnored(warning)) { // warning is currently being ignored continue; @@ -1594,14 +1669,14 @@ public Future deploy(boolean dynamicLoad, @CheckForNull UUID co } } PluginWrapper pw = getInstalled(); - if(pw != null) { // JENKINS-34494 - check for this plugin being disabled + if (pw != null) { // JENKINS-34494 - check for this plugin being disabled Future enableJob = null; - if(!pw.isEnabled()) { + if (!pw.isEnabled()) { UpdateCenter.EnableJob job = uc.new EnableJob(UpdateSite.this, null, this, dynamicLoad); job.setCorrelationId(correlationId); enableJob = uc.addJob(job); } - if(pw.getVersionNumber().equals(new VersionNumber(version))) { + if (pw.getVersionNumber().equals(new VersionNumber(version))) { return enableJob != null ? enableJob : uc.addJob(uc.new NoOpJob(UpdateSite.this, null, this)); } } @@ -1622,6 +1697,7 @@ public Future deployBackup() { /** * Making the installation web bound. */ + @RequirePOST public HttpResponse doInstall() throws IOException { deploy(false); @@ -1649,6 +1725,7 @@ public HttpResponse doDowngrade() throws IOException { private static final Logger LOGGER = Logger.getLogger(UpdateSite.class.getName()); // The name uses UpdateCenter for compatibility reason. - public static boolean neverUpdate = SystemProperties.getBoolean(UpdateCenter.class.getName()+".never"); + @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "for script console") + public static boolean neverUpdate = SystemProperties.getBoolean(UpdateCenter.class.getName() + ".never"); } diff --git a/core/src/main/java/hudson/model/UsageStatistics.java b/core/src/main/java/hudson/model/UsageStatistics.java index 4abc004b61fd..0a13c0983b16 100644 --- a/core/src/main/java/hudson/model/UsageStatistics.java +++ b/core/src/main/java/hudson/model/UsageStatistics.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,37 +21,27 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import static java.util.concurrent.TimeUnit.DAYS; + +import com.jcraft.jzlib.GZIPOutputStream; +import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import hudson.Extension; import hudson.PluginWrapper; import hudson.Util; -import hudson.Extension; -import hudson.node_monitors.ArchitectureMonitor.DescriptorImpl; +import hudson.node_monitors.ArchitectureMonitor; import hudson.security.Permission; import hudson.util.Secret; -import static java.util.concurrent.TimeUnit.DAYS; - -import jenkins.model.Jenkins; -import net.sf.json.JSONObject; -import org.apache.commons.io.output.ByteArrayOutputStream; -import org.kohsuke.stapler.StaplerRequest; - -import edu.umd.cs.findbugs.annotations.NonNull; -import javax.crypto.Cipher; -import javax.crypto.CipherOutputStream; -import javax.crypto.KeyGenerator; -import javax.crypto.SecretKey; -import javax.crypto.CipherInputStream; -import javax.crypto.spec.IvParameterSpec; -import javax.crypto.spec.SecretKeySpec; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.io.FilterOutputStream; -import java.io.OutputStream; +import java.io.DataInputStream; import java.io.FilterInputStream; +import java.io.FilterOutputStream; +import java.io.IOException; import java.io.InputStream; -import java.io.DataInputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; import java.nio.charset.StandardCharsets; import java.security.GeneralSecurityException; import java.security.Key; @@ -63,14 +53,28 @@ import java.util.ArrayList; import java.util.Base64; import java.util.List; -import com.jcraft.jzlib.GZIPOutputStream; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.crypto.Cipher; +import javax.crypto.CipherInputStream; +import javax.crypto.CipherOutputStream; +import javax.crypto.KeyGenerator; +import javax.crypto.SecretKey; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import jenkins.model.Jenkins; import jenkins.util.SystemProperties; +import net.sf.json.JSONObject; +import org.apache.commons.io.output.ByteArrayOutputStream; +import org.kohsuke.stapler.StaplerRequest; /** * @author Kohsuke Kawaguchi */ @Extension public class UsageStatistics extends PageDecorator implements PersistentDescriptor { + private static final Logger LOG = Logger.getLogger(UsageStatistics.class.getName()); + private final String keyImage; /** @@ -99,10 +103,10 @@ public UsageStatistics(String keyImage) { */ public boolean isDue() { // user opted out. no data collection. - if(!Jenkins.get().isUsageStatisticsCollected() || DISABLED) return false; - + if (!Jenkins.get().isUsageStatisticsCollected() || DISABLED) return false; + long now = System.currentTimeMillis(); - if(now - lastAttempt > DAY) { + if (now - lastAttempt > DAY) { lastAttempt = now; return true; } @@ -113,7 +117,7 @@ private RSAPublicKey getKey() { try { if (key == null) { KeyFactory keyFactory = KeyFactory.getInstance("RSA"); - key = (RSAPublicKey)keyFactory.generatePublic(new X509EncodedKeySpec(Util.fromHexString(keyImage))); + key = (RSAPublicKey) keyFactory.generatePublic(new X509EncodedKeySpec(Util.fromHexString(keyImage))); } return key; } catch (GeneralSecurityException e) { @@ -123,48 +127,49 @@ private RSAPublicKey getKey() { /** * Gets the encrypted usage stat data to be sent to the Hudson server. + * Used exclusively by jelly: resources/hudson/model/UsageStatistics/footer.jelly */ public String getStatData() throws IOException { Jenkins j = Jenkins.get(); JSONObject o = new JSONObject(); - o.put("stat",1); + o.put("stat", 1); o.put("install", j.getLegacyInstanceId()); o.put("servletContainer", j.servletContext.getServerInfo()); o.put("version", Jenkins.VERSION); List nodes = new ArrayList<>(); - for( Computer c : j.getComputers() ) { + for (Computer c : j.getComputers()) { JSONObject n = new JSONObject(); - if(c.getNode()==j) { - n.put("master",true); + if (c.getNode() == j) { + n.put("master", true); n.put("jvm-vendor", System.getProperty("java.vm.vendor")); n.put("jvm-name", System.getProperty("java.vm.name")); n.put("jvm-version", System.getProperty("java.version")); } - n.put("executors",c.getNumExecutors()); - DescriptorImpl descriptor = j.getDescriptorByType(DescriptorImpl.class); + n.put("executors", c.getNumExecutors()); + ArchitectureMonitor.DescriptorImpl descriptor = j.getDescriptorByType(ArchitectureMonitor.DescriptorImpl.class); n.put("os", descriptor.get(c)); nodes.add(n); } - o.put("nodes",nodes); + o.put("nodes", nodes); List plugins = new ArrayList<>(); - for( PluginWrapper pw : j.getPluginManager().getPlugins() ) { - if(!pw.isActive()) continue; // treat disabled plugins as if they are uninstalled + for (PluginWrapper pw : j.getPluginManager().getPlugins()) { + if (!pw.isActive()) continue; // treat disabled plugins as if they are uninstalled JSONObject p = new JSONObject(); - p.put("name",pw.getShortName()); - p.put("version",pw.getVersion()); + p.put("name", pw.getShortName()); + p.put("version", pw.getVersion()); plugins.add(p); } - o.put("plugins",plugins); + o.put("plugins", plugins); JSONObject jobs = new JSONObject(); // capture the descriptors as these should be small compared with the number of items // so we will walk all items only once and we can short-cut the search of descriptors TopLevelItemDescriptor[] descriptors = Items.all().toArray(new TopLevelItemDescriptor[0]); int[] counts = new int[descriptors.length]; - for (TopLevelItem item: j.allItems(TopLevelItem.class)) { + for (TopLevelItem item : j.allItems(TopLevelItem.class)) { TopLevelItemDescriptor d = item.getDescriptor(); for (int i = 0; i < descriptors.length; i++) { if (d == descriptors[i]) { @@ -177,21 +182,23 @@ public String getStatData() throws IOException { for (int i = 0; i < descriptors.length; i++) { jobs.put(descriptors[i].getJsonSafeClassName(), counts[i]); } - o.put("jobs",jobs); + o.put("jobs", jobs); try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); // json -> UTF-8 encode -> gzip -> encrypt -> base64 -> string - try (OutputStream cipheros = new CombinedCipherOutputStream(baos,getKey(),"AES"); + try (OutputStream cipheros = new CombinedCipherOutputStream(baos, getKey(), "AES"); OutputStream zipos = new GZIPOutputStream(cipheros); OutputStreamWriter w = new OutputStreamWriter(zipos, StandardCharsets.UTF_8)) { o.write(w); } - return new String(Base64.getEncoder().encode(baos.toByteArray())); - } catch (GeneralSecurityException e) { - throw new Error(e); // impossible + return Base64.getEncoder().encodeToString(baos.toByteArray()); + } catch (Throwable e) { // the exception could be GeneralSecurityException, InvalidParameterException or any other depending on the security provider you have installed + LOG.log(Level.INFO, "Usage statistics could not be sent ({0})", e.getMessage()); + LOG.log(Level.FINE, "Error sending usage statistics", e); + return null; } } @@ -208,7 +215,7 @@ public boolean configure(StaplerRequest req, JSONObject json) throws FormExcepti Jenkins.get().setNoUsageStatistics(json.has("usageStatisticsCollected") ? null : true); return true; } catch (IOException e) { - throw new FormException(e,"usageStatisticsCollected"); + throw new FormException(e, "usageStatisticsCollected"); } } @@ -231,12 +238,12 @@ public CombinedCipherOutputStream(OutputStream out, Cipher asym, String algorith // the rest of the data will be encrypted by this symmetric cipher Cipher sym = Secret.getCipher(algorithm); - sym.init(Cipher.ENCRYPT_MODE,symKey, keyAlgorithm.equals(algorithm) ? null : new IvParameterSpec(symKey.getEncoded())); - super.out = new CipherOutputStream(out,sym); + sym.init(Cipher.ENCRYPT_MODE, symKey, keyAlgorithm.equals(algorithm) ? null : new IvParameterSpec(symKey.getEncoded())); + super.out = new CipherOutputStream(out, sym); } public CombinedCipherOutputStream(OutputStream out, RSAKey key, String algorithm) throws IOException, GeneralSecurityException { - this(out,toCipher(key,Cipher.ENCRYPT_MODE),algorithm); + this(out, toCipher(key, Cipher.ENCRYPT_MODE), algorithm); } } @@ -255,39 +262,44 @@ public CombinedCipherInputStream(InputStream in, Cipher asym, String algorithm, String keyAlgorithm = getKeyAlgorithm(algorithm); // first read the symmetric key cipher - byte[] symKeyBytes = new byte[keyLength/8]; + byte[] symKeyBytes = new byte[keyLength / 8]; new DataInputStream(in).readFully(symKeyBytes); - SecretKey symKey = new SecretKeySpec(asym.doFinal(symKeyBytes),keyAlgorithm); + SecretKey symKey = new SecretKeySpec(asym.doFinal(symKeyBytes), keyAlgorithm); // the rest of the data will be decrypted by this symmetric cipher Cipher sym = Secret.getCipher(algorithm); - sym.init(Cipher.DECRYPT_MODE,symKey, keyAlgorithm.equals(algorithm) ? null : new IvParameterSpec(symKey.getEncoded())); - super.in = new CipherInputStream(in,sym); + sym.init(Cipher.DECRYPT_MODE, symKey, keyAlgorithm.equals(algorithm) ? null : new IvParameterSpec(symKey.getEncoded())); + super.in = new CipherInputStream(in, sym); } public CombinedCipherInputStream(InputStream in, RSAKey key, String algorithm) throws IOException, GeneralSecurityException { - this(in,toCipher(key,Cipher.DECRYPT_MODE),algorithm,key.getModulus().bitLength()); + this(in, toCipher(key, Cipher.DECRYPT_MODE), algorithm, key.getModulus().bitLength()); } } private static String getKeyAlgorithm(String algorithm) { int index = algorithm.indexOf('/'); - return (index>0)?algorithm.substring(0,index):algorithm; + return index > 0 ? algorithm.substring(0, index) : algorithm; } private static Cipher toCipher(RSAKey key, int mode) throws GeneralSecurityException { Cipher cipher = Cipher.getInstance("RSA"); - cipher.init(mode, (Key)key); + cipher.init(mode, (Key) key); return cipher; } /** * Public key to encrypt the usage statistics */ - private static final String DEFAULT_KEY_BYTES = "30819f300d06092a864886f70d010101050003818d0030818902818100c14970473bd90fd1f2d20e4fa6e36ea21f7d46db2f4104a3a8f2eb097d6e26278dfadf3fe9ed05bbbb00a4433f4b7151e6683a169182e6ff2f6b4f2bb6490b2cddef73148c37a2a7421fc75f99fb0fadab46f191806599a208652f4829fd6f76e13195fb81ff3f2fce15a8e9a85ebe15c07c90b34ebdb416bd119f0d74105f3b0203010001"; + private static final String DEFAULT_KEY_BYTES = + "30819f300d06092a864886f70d010101050003818d0030818902818100c14970473bd90fd1f2d20e" + + "4fa6e36ea21f7d46db2f4104a3a8f2eb097d6e26278dfadf3fe9ed05bbbb00a4433f4b7151e6683a" + + "169182e6ff2f6b4f2bb6490b2cddef73148c37a2a7421fc75f99fb0fadab46f191806599a208652f" + + "4829fd6f76e13195fb81ff3f2fce15a8e9a85ebe15c07c90b34ebdb416bd119f0d74105f3b020301" + + "0001"; private static final long DAY = DAYS.toMillis(1); - @SuppressFBWarnings("MS_SHOULD_BE_FINAL") - public static boolean DISABLED = SystemProperties.getBoolean(UsageStatistics.class.getName()+".disabled"); + @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "for script console") + public static boolean DISABLED = SystemProperties.getBoolean(UsageStatistics.class.getName() + ".disabled"); } diff --git a/core/src/main/java/hudson/model/User.java b/core/src/main/java/hudson/model/User.java index eb39b3c5ed9b..bc2a86138d1a 100644 --- a/core/src/main/java/hudson/model/User.java +++ b/core/src/main/java/hudson/model/User.java @@ -22,9 +22,9 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; -import java.util.function.Predicate; import com.infradna.tool.bridge_method_injector.WithBridgeMethods; import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.NonNull; @@ -63,6 +63,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ExecutionException; +import java.util.function.Predicate; import java.util.logging.Level; import java.util.logging.Logger; import javax.servlet.ServletException; @@ -70,6 +71,7 @@ import jenkins.model.IdStrategy; import jenkins.model.Jenkins; import jenkins.model.ModelObjectWithContextMenu; +import jenkins.scm.RunWithSCM; import jenkins.security.ImpersonatingUserDetailsService2; import jenkins.security.LastGrantedAuthoritiesProperty; import jenkins.security.UserDetailsCache; @@ -128,8 +130,8 @@ public class User extends AbstractModelObject implements AccessControlled, Descr * Escape hatch for StaplerProxy-based access control */ @Restricted(NoExternalUse.class) - @SuppressFBWarnings("MS_SHOULD_BE_FINAL") - public static /* Script Console modifiable */ boolean SKIP_PERMISSION_CHECK = Boolean.getBoolean(User.class.getName() + ".skipPermissionCheck"); + @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "for script console") + public static /* Script Console modifiable */ boolean SKIP_PERMISSION_CHECK = SystemProperties.getBoolean(User.class.getName() + ".skipPermissionCheck"); /** * Jenkins now refuses to let the user login if he/she doesn't exist in {@link SecurityRealm}, @@ -138,9 +140,9 @@ public class User extends AbstractModelObject implements AccessControlled, Descr * Unfortunately this infringed some legitimate use cases of creating Jenkins-local users for * automation purposes. This escape hatch switch can be enabled to resurrect that behaviour. *

    - * @see JENKINS-22346. + * See JENKINS-22346. */ - @SuppressFBWarnings("MS_SHOULD_BE_FINAL") + @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "for script console") public static boolean ALLOW_NON_EXISTENT_USER_TO_LOGIN = SystemProperties.getBoolean(User.class.getName() + ".allowNonExistentUserToLogin"); /** @@ -148,7 +150,7 @@ public class User extends AbstractModelObject implements AccessControlled, Descr * accesses a /user/arbitraryName URL. *

    * Unfortunately this constitutes a CSRF vulnerability, as malicious users can make admins create arbitrary numbers - * of ephemeral user records, so the behavior was changed in Jenkins 2.TODO / 2.32.2. + * of ephemeral user records, so the behavior was changed in Jenkins 2.44 / 2.32.2. *

    * As some users may be relying on the previous behavior, setting this to true restores the previous behavior. This * is not recommended. @@ -156,7 +158,7 @@ public class User extends AbstractModelObject implements AccessControlled, Descr * SECURITY-406. */ @Restricted(NoExternalUse.class) - @SuppressFBWarnings("MS_SHOULD_BE_FINAL") + @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "for script console") public static boolean ALLOW_USER_CREATION_VIA_URL = SystemProperties.getBoolean(User.class.getName() + ".allowUserCreationViaUrl"); /** @@ -220,7 +222,7 @@ private void removeNullsThatFailedToLoad() { private void loadFromUserConfigFile(String userId) { XmlFile config = getConfigFile(); try { - if ( config != null && config.exists()) { + if (config != null && config.exists()) { config.unmarshal(this); this.id = userId; } @@ -255,6 +257,7 @@ public static IdStrategy idStrategy() { return realm.getUserIdStrategy(); } + @Override public int compareTo(@NonNull User that) { return idStrategy().compare(this.id, that.id); } @@ -268,6 +271,7 @@ public String getId() { return "user/" + Util.rawEncode(idStrategy().keyFor(id)); } + @Override public @NonNull String getSearchUrl() { return "/user/" + Util.rawEncode(idStrategy().keyFor(id)); } @@ -675,15 +679,16 @@ public static void rekey() { /** * Returns the user name. */ + @Override public @NonNull String getDisplayName() { return getFullName(); } /** - * true if {@link AbstractBuild#hasParticipant} or {@link hudson.model.Cause.UserIdCause} + * true if {@link RunWithSCM#hasParticipant} or {@link hudson.model.Cause.UserIdCause} */ - private boolean relatedTo(@NonNull AbstractBuild b) { - if (b.hasParticipant(this)) { + private boolean relatedTo(@NonNull Run b) { + if (b instanceof RunWithSCM && ((RunWithSCM) b).hasParticipant(this)) { return true; } for (Cause cause : b.getCauses()) { @@ -698,14 +703,13 @@ private boolean relatedTo(@NonNull AbstractBuild b) { } /** - * Gets the list of {@link Build}s that include changes by this user, - * by the timestamp order. + * Searches for builds which include changes by this user or which were triggered by this user. */ @SuppressWarnings("unchecked") @WithBridgeMethods(List.class) public @NonNull RunList getBuilds() { return RunList.fromJobs((Iterable) Jenkins.get(). - allItems(Job.class)).filter((Predicate>) r -> r instanceof AbstractBuild && relatedTo((AbstractBuild) r)); + allItems(Job.class)).filter((Predicate>) this::relatedTo); } /** @@ -728,6 +732,7 @@ public String toString() { /** * Called by tests in the JTH. Otherwise this shouldn't be called. * Even in the tests this usage is questionable. + * @deprecated removed without replacement */ @Deprecated public static void clear() { @@ -741,19 +746,20 @@ public static void clear() { private static File getConfigFileFor(String id) { return new File(getUserFolderFor(id), "config.xml"); } - - private static File getUserFolderFor(String id){ + + private static File getUserFolderFor(String id) { return new File(getRootDir(), idStrategy().filenameOf(id)); } /** * Returns the folder that store all the user information. * Useful for plugins to save a user-specific file aside the config.xml. * Exposes implementation details that may be subject to change. - * + * * @return The folder containing the user configuration files or {@code null} if the user was not yet saved. * * @since 2.129 */ + public @CheckForNull File getUserFolder() { return getExistingUserFolder(); } @@ -797,6 +803,7 @@ public static boolean isIdOrFullnameAllowed(@CheckForNull String id) { /** * Save the user configuration. */ + @Override public synchronized void save() throws IOException { if (!isIdOrFullnameAllowed(id)) { throw FormValidation.error(Messages.User_IllegalUsername(id)); @@ -864,7 +871,7 @@ public void doConfigSubmit(StaplerRequest req, StaplerResponse rsp) throws IOExc for (UserPropertyDescriptor d : UserProperty.all()) { UserProperty p = getProperty(d.clazz); - JSONObject o = json.optJSONObject("userProperty" + (i++)); + JSONObject o = json.optJSONObject("userProperty" + i++); if (o != null) { if (p != null) { p = p.reconfigure(req, o); @@ -914,8 +921,8 @@ public void doRssFailed(StaplerRequest req, StaplerResponse rsp) throws IOExcept public void doRssLatest(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { final List lastBuilds = new ArrayList<>(); - for (AbstractProject p : Jenkins.get().allItems(AbstractProject.class)) { - for (AbstractBuild b = p.getLastBuild(); b != null; b = b.getPreviousBuild()) { + for (Job p : Jenkins.get().allItems(Job.class)) { + for (Run b = p.getLastBuild(); b != null; b = b.getPreviousBuild()) { if (relatedTo(b)) { lastBuilds.add(b); break; @@ -1019,6 +1026,7 @@ public List getTransientActions() { return Collections.unmodifiableList(actions); } + @Override public ContextMenu doContextMenu(StaplerRequest request, StaplerResponse response) throws Exception { return new ContextMenu().from(this, request, response); } diff --git a/core/src/main/java/hudson/model/UserIdMapper.java b/core/src/main/java/hudson/model/UserIdMapper.java index 4858fdb8dfab..93e6a03fd0f5 100644 --- a/core/src/main/java/hudson/model/UserIdMapper.java +++ b/core/src/main/java/hudson/model/UserIdMapper.java @@ -21,8 +21,10 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import edu.umd.cs.findbugs.annotations.CheckForNull; import hudson.Extension; import hudson.ExtensionList; import hudson.Util; @@ -30,11 +32,6 @@ import hudson.init.InitMilestone; import hudson.init.Initializer; import hudson.util.XStream2; -import jenkins.model.IdStrategy; -import org.kohsuke.accmod.Restricted; -import org.kohsuke.accmod.restrictions.NoExternalUse; - -import edu.umd.cs.findbugs.annotations.CheckForNull; import java.io.File; import java.io.IOException; import java.nio.file.Files; @@ -47,6 +44,9 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; +import jenkins.model.IdStrategy; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; @Restricted(NoExternalUse.class) @Extension diff --git a/core/src/main/java/hudson/model/UserIdMigrator.java b/core/src/main/java/hudson/model/UserIdMigrator.java index d16a034ecc57..4af152b6acb4 100644 --- a/core/src/main/java/hudson/model/UserIdMigrator.java +++ b/core/src/main/java/hudson/model/UserIdMigrator.java @@ -21,11 +21,8 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package hudson.model; -import jenkins.model.IdStrategy; -import org.kohsuke.accmod.Restricted; -import org.kohsuke.accmod.restrictions.NoExternalUse; +package hudson.model; import java.io.File; import java.io.IOException; @@ -35,6 +32,9 @@ import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; +import jenkins.model.IdStrategy; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; @Restricted(NoExternalUse.class) class UserIdMigrator { diff --git a/core/src/main/java/hudson/model/UserProperties.java b/core/src/main/java/hudson/model/UserProperties.java index 3b02a7c7114c..cb840e40752d 100644 --- a/core/src/main/java/hudson/model/UserProperties.java +++ b/core/src/main/java/hudson/model/UserProperties.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,11 +21,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import hudson.Extension; import hudson.util.DescriptorList; - import java.util.List; /** diff --git a/core/src/main/java/hudson/model/UserProperty.java b/core/src/main/java/hudson/model/UserProperty.java index 7cbe57a486a0..a9b9dbae7acd 100644 --- a/core/src/main/java/hudson/model/UserProperty.java +++ b/core/src/main/java/hudson/model/UserProperty.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,14 +21,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; -import hudson.ExtensionPoint; import hudson.DescriptorExtensionList; +import hudson.ExtensionPoint; import hudson.model.Descriptor.FormException; import jenkins.model.Jenkins; import net.sf.json.JSONObject; - import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.export.ExportedBean; @@ -63,6 +63,7 @@ protected void setUser(User u) { } // descriptor must be of the UserPropertyDescriptor type + @Override public UserPropertyDescriptor getDescriptor() { return (UserPropertyDescriptor) Jenkins.get().getDescriptorOrDie(getClass()); } @@ -70,11 +71,12 @@ public UserPropertyDescriptor getDescriptor() { /** * Returns all the registered {@link UserPropertyDescriptor}s. */ - public static DescriptorExtensionList all() { + public static DescriptorExtensionList all() { return Jenkins.get().getDescriptorList(UserProperty.class); } + @Override public UserProperty reconfigure(StaplerRequest req, JSONObject form) throws FormException { - return form==null ? null : getDescriptor().newInstance(req, form); + return form == null ? null : getDescriptor().newInstance(req, form); } } diff --git a/core/src/main/java/hudson/model/UserPropertyDescriptor.java b/core/src/main/java/hudson/model/UserPropertyDescriptor.java index 5367c7c01451..22e05ea59aff 100644 --- a/core/src/main/java/hudson/model/UserPropertyDescriptor.java +++ b/core/src/main/java/hudson/model/UserPropertyDescriptor.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Daniel Dyer - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,11 +21,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; /** * {@link Descriptor} for {@link UserProperty}. - * + * * @author Kohsuke Kawaguchi */ public abstract class UserPropertyDescriptor extends Descriptor { @@ -67,7 +68,7 @@ protected UserPropertyDescriptor() { * *

    * This mechanism is useful if the availability of the property is - * contingent of some other settings. + * contingent of some other settings. */ public boolean isEnabled() { return true; diff --git a/core/src/main/java/hudson/model/View.java b/core/src/main/java/hudson/model/View.java index b7a277584712..37fe1a64a854 100644 --- a/core/src/main/java/hudson/model/View.java +++ b/core/src/main/java/hudson/model/View.java @@ -1,19 +1,19 @@ /* * The MIT License - * + * * Copyright (c) 2004-2011, Sun Microsystems, Inc., Kohsuke Kawaguchi, Tom Huybrechts, * Yahoo!, Inc. - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -22,20 +22,26 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST; + import com.thoughtworks.xstream.converters.ConversionException; import com.thoughtworks.xstream.io.StreamException; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.DescriptorExtensionList; import hudson.Extension; import hudson.ExtensionPoint; import hudson.Functions; import hudson.Indenter; import hudson.Util; +import hudson.init.InitMilestone; +import hudson.init.Initializer; import hudson.model.Descriptor.FormException; import hudson.model.listeners.ItemListener; import hudson.scm.ChangeLogSet; -import hudson.scm.ChangeLogSet.Entry; import hudson.search.CollectionSearchIndex; import hudson.search.SearchIndexBuilder; import hudson.security.ACL; @@ -54,45 +60,6 @@ import hudson.util.XStream2; import hudson.views.ListViewColumn; import hudson.widgets.Widget; -import edu.umd.cs.findbugs.annotations.NonNull; -import jenkins.model.Jenkins; -import jenkins.model.ModelObjectWithChildren; -import jenkins.model.ModelObjectWithContextMenu; -import jenkins.model.item_category.Categories; -import jenkins.model.item_category.Category; -import jenkins.model.item_category.ItemCategory; -import jenkins.scm.RunWithSCM; -import jenkins.security.stapler.StaplerAccessibleType; -import jenkins.util.ProgressiveRendering; -import jenkins.util.xml.XMLUtils; - -import net.sf.json.JSON; -import net.sf.json.JSONArray; -import net.sf.json.JSONObject; -import org.apache.commons.jelly.JellyContext; -import org.apache.commons.lang.StringUtils; -import org.apache.tools.ant.filters.StringInputStream; -import org.jenkins.ui.icon.Icon; -import org.jenkins.ui.icon.IconSet; -import org.kohsuke.accmod.restrictions.DoNotUse; -import org.kohsuke.stapler.DataBoundSetter; -import org.kohsuke.stapler.HttpResponse; -import org.kohsuke.stapler.HttpResponses; -import org.kohsuke.stapler.Stapler; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; -import org.kohsuke.stapler.WebMethod; -import org.kohsuke.stapler.export.Exported; -import org.kohsuke.stapler.export.ExportedBean; -import org.kohsuke.stapler.interceptor.RequirePOST; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletResponse; -import javax.xml.transform.Source; -import javax.xml.transform.TransformerException; -import javax.xml.transform.sax.SAXSource; -import javax.xml.transform.stream.StreamResult; -import javax.xml.transform.stream.StreamSource; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -100,6 +67,7 @@ import java.io.OutputStream; import java.io.Serializable; import java.io.StringWriter; +import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; @@ -113,16 +81,48 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; - -import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST; - +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletResponse; +import javax.xml.transform.Source; +import javax.xml.transform.TransformerException; +import javax.xml.transform.sax.SAXSource; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; +import jenkins.model.Jenkins; +import jenkins.model.ModelObjectWithChildren; +import jenkins.model.ModelObjectWithContextMenu; +import jenkins.model.item_category.Categories; +import jenkins.model.item_category.Category; +import jenkins.model.item_category.ItemCategory; +import jenkins.scm.RunWithSCM; +import jenkins.security.stapler.StaplerAccessibleType; +import jenkins.util.ProgressiveRendering; +import jenkins.util.xml.XMLUtils; +import net.sf.json.JSON; +import net.sf.json.JSONArray; +import net.sf.json.JSONObject; +import org.apache.commons.lang.StringUtils; +import org.jenkins.ui.icon.Icon; +import org.jenkins.ui.icon.IconSet; import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.DoNotUse; import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.stapler.DataBoundSetter; +import org.kohsuke.stapler.HttpResponse; +import org.kohsuke.stapler.HttpResponses; import org.kohsuke.stapler.QueryParameter; +import org.kohsuke.stapler.Stapler; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.WebMethod; +import org.kohsuke.stapler.export.Exported; +import org.kohsuke.stapler.export.ExportedBean; +import org.kohsuke.stapler.interceptor.RequirePOST; import org.kohsuke.stapler.verb.POST; import org.xml.sax.SAXException; @@ -139,7 +139,7 @@ *

  • * {@link View} subtypes need the {@code newViewDetail.jelly} page, * which is included in the "new view" page. This page should have some - * description of what the view is about. + * description of what the view is about. * * * @author Kohsuke Kawaguchi @@ -147,7 +147,7 @@ * @see ViewGroup */ @ExportedBean -public abstract class View extends AbstractModelObject implements AccessControlled, Describable, ExtensionPoint, Saveable, ModelObjectWithChildren { +public abstract class View extends AbstractModelObject implements AccessControlled, Describable, ExtensionPoint, Saveable, ModelObjectWithChildren, DescriptorByNameOwner { /** * Container of this view. Set right after the construction @@ -164,7 +164,7 @@ public abstract class View extends AbstractModelObject implements AccessControll * Message displayed in the view page. */ protected String description; - + /** * If true, only show relevant executors */ @@ -174,12 +174,12 @@ public abstract class View extends AbstractModelObject implements AccessControll * If true, only show relevant queue items */ protected boolean filterQueue; - + /** * List of {@link ViewProperty}s configured for this view. * @since 1.406 */ - private volatile DescribableList properties = new PropertyList(this); + private volatile DescribableList properties = new PropertyList(this); protected View(String name) { this.name = name; @@ -194,7 +194,7 @@ protected View(String name, ViewGroup owner) { * Gets all the items in this collection in a read-only view. */ @NonNull - @Exported(name="jobs") + @Exported(name = "jobs") public abstract Collection getItems(); /** @@ -210,7 +210,7 @@ public Collection getAllItems() { if (this instanceof ViewGroup) { final Collection items = new LinkedHashSet<>(getItems()); - for(View view: ((ViewGroup) this).getViews()) { + for (View view : ((ViewGroup) this).getViews()) { items.addAll(view.getAllItems()); } return Collections.unmodifiableCollection(items); @@ -243,7 +243,7 @@ public final TopLevelItem getJob(String name) { * * @see #rename(String) */ - @Exported(visibility=2,name="name") + @Exported(visibility = 2, name = "name") @NonNull public String getViewName() { return name; @@ -253,13 +253,13 @@ public String getViewName() { * Renames this view. */ public void rename(String newName) throws Failure, FormException { - if(name.equals(newName)) return; // noop + if (name.equals(newName)) return; // noop Jenkins.checkGoodName(newName); - if(owner.getView(newName)!=null) - throw new FormException(Messages.Hudson_ViewAlreadyExists(newName),"name"); + if (owner.getView(newName) != null) + throw new FormException(Messages.Hudson_ViewAlreadyExists(newName), "name"); String oldName = name; name = newName; - owner.onViewRenamed(this,oldName,newName); + owner.onViewRenamed(this, oldName, newName); } /** @@ -291,12 +291,12 @@ public List getOwnerViewActions() { * Message displayed in the top page. Can be null. Includes HTML. */ @Exported - public String getDescription() { + public synchronized String getDescription() { return description; } @DataBoundSetter - public void setDescription(String description) { + public synchronized void setDescription(String description) { this.description = description; } @@ -304,7 +304,7 @@ public void setDescription(String description) { * Gets the view properties configured for this view. * @since 1.406 */ - public DescribableList getProperties() { + public DescribableList getProperties() { // readResolve was the best place to do this, but for compatibility reasons, // this class can no longer have readResolve() (the mechanism itself isn't suitable for class hierarchy) // see JENKINS-9431 @@ -343,6 +343,7 @@ public List getVisiblePropertyDescriptors() { return DescriptorVisibilityFilter.apply(this, getApplicablePropertyDescriptors()); } + @Override public void save() throws IOException { // persistence is a part of the owner // due to initialization timing issue, it can be null when this method is called @@ -355,15 +356,17 @@ public void save() throws IOException { * List of all {@link ViewProperty}s exposed primarily for the remoting API. * @since 1.406 */ - @Exported(name="property",inline=true) + @Exported(name = "property", inline = true) public List getAllProperties() { return getProperties().toList(); } + @Override public ViewDescriptor getDescriptor() { return (ViewDescriptor) Jenkins.get().getDescriptorOrDie(getClass()); } + @Override public String getDisplayName() { return getViewName(); } @@ -382,7 +385,7 @@ public String getNewPronoun() { public boolean isEditable() { return true; } - + /** * Used to enable or disable automatic refreshes of the view. * @@ -394,14 +397,14 @@ public boolean isEditable() { public boolean isAutomaticRefreshEnabled() { return false; } - + /** * If true, only show relevant executors */ public boolean isFilterExecutors() { return filterExecutors; } - + /** * If true, only show relevant queue items */ @@ -438,9 +441,9 @@ public Indenter getIndenter() { * If true, this is a view that renders the top page of Hudson. */ public boolean isDefault() { - return getOwner().getPrimaryView()==this; + return getOwner().getPrimaryView() == this; } - + public List getComputers() { Computer[] computers = Jenkins.get().getComputers(); @@ -512,7 +515,7 @@ private boolean filterQueueItemTest(Queue.Item item, Collection vi } // Check root project for sub-job projects (e.g. matrix jobs). if (item.task instanceof AbstractProject) { - AbstractProject project = (AbstractProject) item.task; + AbstractProject project = (AbstractProject) item.task; if (viewItems.contains(project.getRootProject())) { return true; } @@ -525,8 +528,8 @@ public List getQueueItems() { } /** - * @deprecated Use {@link #getQueueItems()}. As of 1.607 the approximation is no longer needed. * @return The items in the queue. + * @deprecated Use {@link #getQueueItems()}. As of 1.607 the approximation is no longer needed. */ @Deprecated public List getApproximateQueueItemsQuickly() { @@ -540,7 +543,7 @@ public List getApproximateQueueItemsQuickly() { * empty string when this is the default view). */ public String getUrl() { - return isDefault() ? (owner!=null ? owner.getUrl() : "") : getViewUrl(); + return isDefault() ? (owner != null ? owner.getUrl() : "") : getViewUrl(); } /** @@ -548,13 +551,14 @@ public String getUrl() { * even for the default view. */ public String getViewUrl() { - return (owner!=null ? owner.getUrl() : "") + "view/" + Util.rawEncode(getViewName()) + '/'; + return (owner != null ? owner.getUrl() : "") + "view/" + Util.rawEncode(getViewName()) + '/'; } @Override public String toString() { return super.toString() + "[" + getViewUrl() + "]"; } + @Override public String getSearchUrl() { return getUrl(); } @@ -586,7 +590,7 @@ public void updateTransientActions() {} public Object getDynamic(String token) { for (Action a : getActions()) { String url = a.getUrlName(); - if (url==null) continue; + if (url == null) continue; if (url.equals(token)) return a; } @@ -596,9 +600,9 @@ public Object getDynamic(String token) { /** * Gets the absolute URL of this view. */ - @Exported(visibility=2,name="url") + @Exported(visibility = 2, name = "url") public String getAbsoluteUrl() { - return Jenkins.get().getRootUrl()+getUrl(); + return Jenkins.get().getRootUrl() + getUrl(); } public Api getApi() { @@ -618,6 +622,7 @@ public String getPostConstructLandingPage() { /** * Returns the {@link ACL} for this object. */ + @Override public ACL getACL() { return Jenkins.get().getAuthorizationStrategy().getACL(this); } @@ -626,7 +631,7 @@ public ACL getACL() { @Deprecated public void onJobRenamed(Item item, String oldName, String newName) {} - @ExportedBean(defaultVisibility=2) + @ExportedBean(defaultVisibility = 2) public static final class UserInfo implements Comparable { private final User user; /** @@ -636,12 +641,12 @@ public static final class UserInfo implements Comparable { /** * Which project did this user commit? Can be null. */ - private Job project; + private Job project; /** @see UserAvatarResolver */ String avatar; - UserInfo(User user, Job p, Calendar lastChange) { + UserInfo(User user, Job p, Calendar lastChange) { this.user = user; this.project = p; this.lastChange = lastChange; @@ -659,11 +664,11 @@ public Calendar getLastChange() { @Deprecated public AbstractProject getProject() { - return project instanceof AbstractProject ? (AbstractProject)project : null; + return project instanceof AbstractProject ? (AbstractProject) project : null; } - @Exported(name="project") - public Job getJob() { + @Exported(name = "project") + public Job getJob() { return project; } @@ -671,16 +676,17 @@ public Job getJob() { * Returns a human-readable string representation of when this user was last active. */ public String getLastChangeTimeString() { - if(lastChange==null) return "N/A"; - long duration = new GregorianCalendar().getTimeInMillis()- ordinal(); + if (lastChange == null) return "N/A"; + long duration = new GregorianCalendar().getTimeInMillis() - ordinal(); return Util.getTimeSpanString(duration); } public String getTimeSortKey() { - if(lastChange==null) return "-"; + if (lastChange == null) return "-"; return Util.XS_DATETIME_FORMATTER.format(lastChange.getTime()); } + @Override public int compareTo(UserInfo that) { long rhs = that.ordinal(); long lhs = this.ordinal(); @@ -688,7 +694,7 @@ public int compareTo(UserInfo that) { } private long ordinal() { - if(lastChange==null) return 0; + if (lastChange == null) return 0; return lastChange.getTimeInMillis(); } } @@ -727,12 +733,12 @@ public static final class People { public People(Jenkins parent) { this.parent = parent; // for Hudson, really load all users - Map users = getUserInfo(parent.getItems()); + Map users = getUserInfo(parent.getItems()); User unknown = User.getUnknown(); for (User u : User.getAll()) { - if(u==unknown) continue; // skip the special 'unknown' user - if(!users.containsKey(u)) - users.put(u,new UserInfo(u,null,null)); + if (u == unknown) continue; // skip the special 'unknown' user + if (!users.containsKey(u)) + users.put(u, new UserInfo(u, null, null)); } this.users = toList(users); } @@ -742,17 +748,17 @@ public People(View parent) { this.users = toList(getUserInfo(parent.getItems())); } - private Map getUserInfo(Collection items) { - Map users = new HashMap<>(); + private Map getUserInfo(Collection items) { + Map users = new HashMap<>(); for (Item item : items) { for (Job job : item.getAllJobs()) { RunList> runs = job.getBuilds(); for (Run r : runs) { if (r instanceof RunWithSCM) { - RunWithSCM runWithSCM = (RunWithSCM) r; + RunWithSCM runWithSCM = (RunWithSCM) r; - for (ChangeLogSet c : runWithSCM.getChangeSets()) { - for (Entry entry : c) { + for (ChangeLogSet c : runWithSCM.getChangeSets()) { + for (ChangeLogSet.Entry entry : c) { User user = entry.getAuthor(); UserInfo info = users.get(user); @@ -771,7 +777,7 @@ else if (info.getLastChange().before(r.getTimestamp())) { return users; } - private List toList(Map users) { + private List toList(Map users) { ArrayList list = new ArrayList<>(users.values()); Collections.sort(list); return Collections.unmodifiableList(list); @@ -790,11 +796,11 @@ public static boolean isApplicable(Collection items) { for (Job job : item.getAllJobs()) { RunList> runs = job.getBuilds(); - for (Run r : runs) { + for (Run r : runs) { if (r instanceof RunWithSCM) { - RunWithSCM runWithSCM = (RunWithSCM) r; - for (ChangeLogSet c : runWithSCM.getChangeSets()) { - for (Entry entry : c) { + RunWithSCM runWithSCM = (RunWithSCM) r; + for (ChangeLogSet c : runWithSCM.getChangeSets()) { + for (ChangeLogSet.Entry entry : c) { User user = entry.getAuthor(); if (user != null) return true; @@ -816,7 +822,7 @@ public static final class AsynchPeople extends ProgressiveRendering { // JENKINS private final Collection items; private final User unknown; - private final Map users = new HashMap<>(); + private final Map users = new HashMap<>(); private final Set modified = new HashSet<>(); private final String iconSize; public final ModelObject parent; @@ -843,7 +849,7 @@ public AsynchPeople(View parent) { @Override protected void compute() throws Exception { int itemCount = 0; for (Item item : items) { - for (Job job : item.getAllJobs()) { + for (Job job : item.getAllJobs()) { RunList> builds = job.getBuilds(); int buildCount = 0; for (Run r : builds) { @@ -915,11 +921,11 @@ public AsynchPeople(View parent) { JSONObject entry = new JSONObject(). accumulate("id", u.getId()). accumulate("fullName", u.getFullName()). - accumulate("url", u.getUrl()). - accumulate("avatar", i.avatar != null ? i.avatar : Stapler.getCurrentRequest().getContextPath() + Functions.getResourcePath() + "/images/" + iconSize + "/user.png"). + accumulate("url", u.getUrl() + "/"). + accumulate("avatar", i.avatar != null ? i.avatar : Stapler.getCurrentRequest().getContextPath() + Functions.getResourcePath() + "/images/svgs/person.svg"). accumulate("timeSortKey", i.getTimeSortKey()). accumulate("lastChangeTimeString", i.getLastChangeTimeString()); - Job p = i.getJob(); + Job p = i.getJob(); if (p != null) { entry.accumulate("projectUrl", p.getUrl()).accumulate("projectFullDisplayName", p.getFullDisplayName()); } @@ -951,14 +957,14 @@ public final class People { } void addDisplayNamesToSearchIndex(SearchIndexBuilder sib, Collection items) { - for(TopLevelItem item : items) { - - if(LOGGER.isLoggable(Level.FINE)) { - LOGGER.fine((String.format("Adding url=%s,displayName=%s", - item.getSearchUrl(), item.getDisplayName()))); + for (TopLevelItem item : items) { + + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.fine(String.format("Adding url=%s,displayName=%s", + item.getSearchUrl(), item.getDisplayName())); } sib.add(item.getSearchUrl(), item.getDisplayName()); - } + } } /** @@ -968,9 +974,13 @@ void addDisplayNamesToSearchIndex(SearchIndexBuilder sib, Collection() {// for jobs in the view + sib.add(new CollectionSearchIndex() { // for jobs in the view + @Override protected TopLevelItem get(String key) { return getItem(key); } + + @Override protected Collection all() { return getItems(); } + @Override protected String getName(TopLevelItem o) { // return the name instead of the display for suggestion searching @@ -983,7 +993,7 @@ protected String getName(TopLevelItem o) { public SearchIndexBuilder makeSearchIndex() { SearchIndexBuilder sib = super.makeSearchIndex(); makeSearchIndex(sib); - + // add the display name for each item in the search index addDisplayNamesToSearchIndex(sib, getItems()); @@ -994,7 +1004,7 @@ public SearchIndexBuilder makeSearchIndex() { * Accepts the new description. */ @RequirePOST - public synchronized void doSubmitDescription( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException { + public synchronized void doSubmitDescription(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { checkPermission(CONFIGURE); description = req.getParameter("description"); @@ -1008,7 +1018,7 @@ public synchronized void doSubmitDescription( StaplerRequest req, StaplerRespons * Subtypes should override the {@link #submit(StaplerRequest)} method. */ @POST - public final synchronized void doConfigSubmit( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException, FormException { + public final synchronized void doConfigSubmit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, FormException { checkPermission(CONFIGURE); submit(req); @@ -1023,7 +1033,7 @@ public final synchronized void doConfigSubmit( StaplerRequest req, StaplerRespon save(); - FormApply.success("../" + Util.rawEncode(name)).generateResponse(req,rsp,this); + FormApply.success("../" + Util.rawEncode(name)).generateResponse(req, rsp, this); } /** @@ -1042,7 +1052,7 @@ public synchronized void doDoDelete(StaplerRequest req, StaplerResponse rsp) thr owner.deleteView(this); - rsp.sendRedirect2(req.getContextPath()+"/" + owner.getUrl()); + rsp.sendRedirect2(req.getContextPath() + "/" + owner.getUrl()); } @@ -1052,11 +1062,11 @@ public synchronized void doDoDelete(StaplerRequest req, StaplerResponse rsp) thr *

    * This method should call {@link ModifiableItemGroup#doCreateItem(StaplerRequest, StaplerResponse)} * and then add the newly created item to this view. - * + * * @return * null if fails. */ - public abstract Item doCreateItem( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException; + public abstract Item doCreateItem(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException; /** * Makes sure that the given name is good as a job name. @@ -1102,13 +1112,12 @@ public Categories doItemCategories(StaplerRequest req, StaplerResponse rsp, @Que rsp.addHeader("Expires", "0"); Categories categories = new Categories(); int order = 0; - JellyContext ctx; + String resUrl; if (StringUtils.isNotBlank(iconStyle)) { - ctx = new JellyContext(); - ctx.setVariable("resURL", req.getContextPath() + Jenkins.RESOURCE_PATH); + resUrl = req.getContextPath() + Jenkins.RESOURCE_PATH; } else { - ctx = null; + resUrl = null; } for (TopLevelItemDescriptor descriptor : DescriptorVisibilityFilter.apply(getOwner().getItemGroup(), Items.all2(Jenkins.getAuthentication2(), getOwner().getItemGroup()))) { ItemCategory ic = ItemCategory.getCategory(descriptor); @@ -1123,11 +1132,11 @@ public Categories doItemCategories(StaplerRequest req, StaplerResponse rsp, @Que String iconClassName = descriptor.getIconClassName(); if (StringUtils.isNotBlank(iconClassName)) { metadata.put("iconClassName", iconClassName); - if (ctx != null) { + if (resUrl != null) { Icon icon = IconSet.icons - .getIconByClassSpec(StringUtils.join(new String[]{iconClassName, iconStyle}, " ")); + .getIconByClassSpec(String.join(" ", iconClassName, iconStyle)); if (icon != null) { - metadata.put("iconQualifiedUrl", icon.getQualifiedUrl(ctx)); + metadata.put("iconQualifiedUrl", icon.getQualifiedUrl(resUrl)); } } } @@ -1145,29 +1154,29 @@ public Categories doItemCategories(StaplerRequest req, StaplerResponse rsp, @Que return categories; } - public void doRssAll( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException { + public void doRssAll(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { RSS.rss(req, rsp, "Jenkins:" + getDisplayName() + " (all builds)", getUrl(), getBuilds().newBuilds()); } - public void doRssFailed( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException { + public void doRssFailed(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { RSS.rss(req, rsp, "Jenkins:" + getDisplayName() + " (failed builds)", getUrl(), getBuilds().failureOnly().newBuilds()); } - + public RunList getBuilds() { return new RunList(this); } - + public BuildTimelineWidget getTimeline() { return new BuildTimelineWidget(getBuilds()); } - public void doRssLatest( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException { + public void doRssLatest(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { List lastBuilds = new ArrayList<>(); for (TopLevelItem item : getItems()) { if (item instanceof Job) { Job job = (Job) item; Run lb = job.getLastBuild(); - if(lb!=null) lastBuilds.add(lb); + if (lb != null) lastBuilds.add(lb); } } RSS.rss(req, rsp, "Jenkins:" + getDisplayName() + " (latest builds)", getUrl(), RunList.fromRuns(lastBuilds), Run.FEED_ADAPTER_LATEST); @@ -1182,6 +1191,7 @@ public HttpResponse doConfigDotXml(StaplerRequest req) throws IOException { // read checkPermission(READ); return new HttpResponse() { + @Override public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { rsp.setContentType("application/xml"); View.this.writeXml(rsp.getOutputStream()); @@ -1223,12 +1233,12 @@ public void updateByXml(Source source) throws IOException { // data XMLUtils.safeTransform(source, new StreamResult(out)); out.close(); - } catch (TransformerException|SAXException e) { + } catch (TransformerException | SAXException e) { throw new IOException("Failed to persist configuration.xml", e); } // try to reflect the changes by reloading - try (InputStream in = new BufferedInputStream(new ByteArrayInputStream(out.toString().getBytes(StandardCharsets.UTF_8)))){ + try (InputStream in = new BufferedInputStream(new ByteArrayInputStream(out.toString().getBytes(StandardCharsets.UTF_8)))) { // Do not allow overwriting view name as it might collide with another // view in same ViewGroup and might not satisfy Jenkins.checkGoodName. String oldname = name; @@ -1237,22 +1247,23 @@ public void updateByXml(Source source) throws IOException { if (!o.getClass().equals(getClass())) { // ensure that we've got the same view type. extending this code to support updating // to different view type requires destroying & creating a new view type - throw new IOException("Expecting view type: "+this.getClass()+" but got: "+o.getClass()+" instead." + + throw new IOException("Expecting view type: " + this.getClass() + " but got: " + o.getClass() + " instead." + "\nShould you needed to change to a new view type, you must first delete and then re-create " + "the view with the new view type."); } name = oldname; owner = oldOwner; - } catch (StreamException | ConversionException | Error e) {// mostly reflection errors - throw new IOException("Unable to read",e); + } catch (StreamException | ConversionException | Error e) { // mostly reflection errors + throw new IOException("Unable to read", e); } save(); } + @Override public ModelObjectWithContextMenu.ContextMenu doChildrenContextMenu(StaplerRequest request, StaplerResponse response) throws Exception { ModelObjectWithContextMenu.ContextMenu m = new ModelObjectWithContextMenu.ContextMenu(); for (TopLevelItem i : getItems()) - m.add(i.getShortUrl(),i.getDisplayName()); + m.add(i.getShortUrl(), i.getDisplayName()); return m; } @@ -1267,7 +1278,7 @@ public ModelObjectWithContextMenu.ContextMenu doChildrenContextMenu(StaplerReque /** * Returns all the registered {@link ViewDescriptor}s. */ - public static DescriptorExtensionList all() { + public static DescriptorExtensionList all() { return Jenkins.get().getDescriptorList(View.class); } @@ -1298,26 +1309,35 @@ public static List allInstantiable() { return r; } - public static final Comparator SORTER = new Comparator() { - public int compare(View lhs, View rhs) { - return lhs.getViewName().compareTo(rhs.getViewName()); - } - }; + public static final Comparator SORTER = Comparator.comparing(View::getViewName); - public static final PermissionGroup PERMISSIONS = new PermissionGroup(View.class,Messages._View_Permissions_Title()); + public static final PermissionGroup PERMISSIONS = new PermissionGroup(View.class, Messages._View_Permissions_Title()); /** * Permission to create new views. */ - public static final Permission CREATE = new Permission(PERMISSIONS,"Create", Messages._View_CreatePermission_Description(), Permission.CREATE, PermissionScope.ITEM_GROUP); - public static final Permission DELETE = new Permission(PERMISSIONS,"Delete", Messages._View_DeletePermission_Description(), Permission.DELETE, PermissionScope.ITEM_GROUP); - public static final Permission CONFIGURE = new Permission(PERMISSIONS,"Configure", Messages._View_ConfigurePermission_Description(), Permission.CONFIGURE, PermissionScope.ITEM_GROUP); - public static final Permission READ = new Permission(PERMISSIONS,"Read", Messages._View_ReadPermission_Description(), Permission.READ, PermissionScope.ITEM_GROUP); + public static final Permission CREATE = new Permission(PERMISSIONS, "Create", Messages._View_CreatePermission_Description(), Permission.CREATE, PermissionScope.ITEM_GROUP); + public static final Permission DELETE = new Permission(PERMISSIONS, "Delete", Messages._View_DeletePermission_Description(), Permission.DELETE, PermissionScope.ITEM_GROUP); + public static final Permission CONFIGURE = new Permission(PERMISSIONS, "Configure", Messages._View_ConfigurePermission_Description(), Permission.CONFIGURE, PermissionScope.ITEM_GROUP); + public static final Permission READ = new Permission(PERMISSIONS, "Read", Messages._View_ReadPermission_Description(), Permission.READ, PermissionScope.ITEM_GROUP); + + @SuppressFBWarnings(value = "RV_RETURN_VALUE_IGNORED_NO_SIDE_EFFECT", justification = "to guard against potential future compiler optimizations") + @Initializer(before = InitMilestone.SYSTEM_CONFIG_LOADED) + @Restricted(DoNotUse.class) + public static void registerPermissions() { + // Pending JENKINS-17200, ensure that the above permissions have been registered prior to + // allowing plugins to adapt the system configuration, which may depend on these permissions + // having been registered. Since this method is static and since it follows the above + // construction of static permission objects (and therefore their calls to + // PermissionGroup#register), there is nothing further to do in this method. We call + // Objects.hash() to guard against potential future compiler optimizations. + Objects.hash(PERMISSIONS, CREATE, DELETE, CONFIGURE, READ); + } // to simplify access from Jelly public static Permission getItemCreatePermission() { return Item.CREATE; } - + public static View create(StaplerRequest req, StaplerResponse rsp, ViewGroup owner) throws FormException, IOException, ServletException { String mode = req.getParameter("mode"); @@ -1333,11 +1353,11 @@ public static View create(StaplerRequest req, StaplerResponse rsp, ViewGroup own String name = req.getParameter("name"); Jenkins.checkGoodName(name); - if(owner.getView(name)!=null) + if (owner.getView(name) != null) throw new Failure(Messages.Hudson_ViewAlreadyExists(name)); - if (mode==null || mode.length()==0) { - if(isXmlSubmission) { + if (mode == null || mode.length() == 0) { + if (isXmlSubmission) { View v = createViewFromXML(name, req.getInputStream()); owner.getACL().checkCreatePermission(owner, v.getDescriptor()); v.owner = owner; @@ -1365,7 +1385,7 @@ public static View create(StaplerRequest req, StaplerResponse rsp, ViewGroup own v.owner = owner; // redirect to the config screen - rsp.sendRedirect2(req.getContextPath()+'/'+v.getUrl()+v.getPostConstructLandingPage()); + rsp.sendRedirect2(req.getContextPath() + '/' + v.getUrl() + v.getPostConstructLandingPage()); return v; } @@ -1375,14 +1395,14 @@ private static View copy(StaplerRequest req, ViewGroup owner, String name) throw String from = req.getParameter("from"); View src = owner.getView(from); - if(src==null) { - if(Util.fixEmpty(from)==null) + if (src == null) { + if (Util.fixEmpty(from) == null) throw new Failure("Specify which view to copy"); else - throw new Failure("No such view: "+from); + throw new Failure("No such view: " + from); } String xml = Jenkins.XSTREAM.toXML(src); - v = createViewFromXML(name, new StringInputStream(xml)); + v = createViewFromXML(name, new ByteArrayInputStream(xml.getBytes(Charset.defaultCharset()))); return v; } @@ -1398,12 +1418,12 @@ public static View createViewFromXML(String name, InputStream xml) throws IOExce if (name != null) v.name = name; Jenkins.checkGoodName(v.name); return v; - } catch(StreamException|ConversionException|Error e) {// mostly reflection errors - throw new IOException("Unable to read",e); + } catch (StreamException | ConversionException | Error e) { // mostly reflection errors + throw new IOException("Unable to read", e); } } - public static class PropertyList extends DescribableList { + public static class PropertyList extends DescribableList { private PropertyList(View owner) { super(owner); } @@ -1412,7 +1432,7 @@ public PropertyList() {// needed for XStream deserialization } public View getOwner() { - return (View)owner; + return (View) owner; } @Override diff --git a/core/src/main/java/hudson/model/ViewDescriptor.java b/core/src/main/java/hudson/model/ViewDescriptor.java index 35481d30ff76..7d4417e024c3 100644 --- a/core/src/main/java/hudson/model/ViewDescriptor.java +++ b/core/src/main/java/hudson/model/ViewDescriptor.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,17 +21,18 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.util.FormValidation; import hudson.views.ListViewColumn; import hudson.views.ListViewColumnDescriptor; import hudson.views.ViewJobFilter; - import java.util.Iterator; import java.util.List; -import edu.umd.cs.findbugs.annotations.CheckForNull; -import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Objects; import jenkins.model.DirectlyModifiableTopLevelItemGroup; import jenkins.model.Jenkins; import org.apache.commons.lang.StringUtils; @@ -71,7 +72,7 @@ public boolean isInstantiable() { * Jelly fragment included in the "new view" page. */ public final String getNewViewDetailPage() { - return '/'+clazz.getName().replace('.','/').replace('$','/')+"/newViewDetail.jelly"; + return '/' + clazz.getName().replace('.', '/').replace('$', '/') + "/newViewDetail.jelly"; } protected ViewDescriptor(Class clazz) { @@ -143,11 +144,11 @@ protected FormValidation checkDisplayName(@NonNull View view, @CheckForNull Stri // no custom name, no need to check return FormValidation.ok(); } - for (View v: view.owner.getViews()) { + for (View v : view.owner.getViews()) { if (v.getViewName().equals(view.getViewName())) { continue; } - if (StringUtils.equals(v.getDisplayName(), value)) { + if (Objects.equals(v.getDisplayName(), value)) { return FormValidation.warning(Messages.View_DisplayNameNotUniqueWarning(value)); } } diff --git a/core/src/main/java/hudson/model/ViewGroup.java b/core/src/main/java/hudson/model/ViewGroup.java index b91ca202c998..1072f394322b 100644 --- a/core/src/main/java/hudson/model/ViewGroup.java +++ b/core/src/main/java/hudson/model/ViewGroup.java @@ -1,19 +1,19 @@ /* * The MIT License - * + * * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, * Tom Huybrechts, Alan Harder - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -22,19 +22,18 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.security.AccessControlled; import hudson.views.ViewsTabBar; - import java.io.IOException; import java.util.Collection; import java.util.LinkedHashSet; import java.util.List; import jenkins.model.Jenkins; -import edu.umd.cs.findbugs.annotations.NonNull; - /** * Container of {@link View}s. * @@ -159,5 +158,5 @@ default ItemGroup getItemGroup() { default List getViewActions() { return Jenkins.get().getActions(); } - + } diff --git a/core/src/main/java/hudson/model/ViewGroupMixIn.java b/core/src/main/java/hudson/model/ViewGroupMixIn.java index 6f661d10c18c..049475807152 100644 --- a/core/src/main/java/hudson/model/ViewGroupMixIn.java +++ b/core/src/main/java/hudson/model/ViewGroupMixIn.java @@ -21,17 +21,17 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package hudson.model; -import java.util.Locale; -import org.kohsuke.stapler.export.Exported; +package hudson.model; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.List; -import edu.umd.cs.findbugs.annotations.CheckForNull; -import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Locale; +import org.kohsuke.stapler.export.Exported; /** * Implements {@link ViewGroup} to be used as a "mix-in". @@ -133,7 +133,7 @@ public View getView(@CheckForNull String name) { // Fallback to subview of primary view if it is a ViewGroup View pv = getPrimaryView(); if (pv instanceof ViewGroup) - return ((ViewGroup)pv).getView(name); + return ((ViewGroup) pv).getView(name); if (pv instanceof AllView && AllView.DEFAULT_VIEW_NAME.equals(pv.name)) { // JENKINS-38606: primary view is the default AllView, is somebody using an old link to localized form? for (Locale l : Locale.getAvailableLocales()) { @@ -170,7 +170,7 @@ public Collection getViews() { @CheckForNull public View getPrimaryView() { View v = getView(primaryView()); - if(v==null && !views().isEmpty()) // fallback + if (v == null && !views().isEmpty()) // fallback v = views().get(0); return v; } diff --git a/core/src/main/java/hudson/model/ViewJob.java b/core/src/main/java/hudson/model/ViewJob.java index 765843d58189..5e8227450bde 100644 --- a/core/src/main/java/hudson/model/ViewJob.java +++ b/core/src/main/java/hudson/model/ViewJob.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,9 +21,10 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; -import jenkins.util.SystemProperties; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.model.Descriptor.FormException; import java.io.IOException; import java.util.LinkedHashSet; @@ -34,6 +35,7 @@ import java.util.logging.Logger; import javax.servlet.ServletException; import jenkins.model.Jenkins; +import jenkins.util.SystemProperties; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; @@ -46,8 +48,8 @@ * * @author Kohsuke Kawaguchi */ -public abstract class ViewJob, RunT extends Run> - extends Job { +public abstract class ViewJob, RunT extends Run> + extends Job { private static final Logger LOGGER = Logger.getLogger(ViewJob.class.getName()); @@ -83,13 +85,14 @@ static synchronized void interruptReloadThread() { */ @Deprecated protected ViewJob(Jenkins parent, String name) { - super(parent,name); + super(parent, name); } protected ViewJob(ItemGroup parent, String name) { - super(parent,name); + super(parent, name); } + @Override public boolean isBuildable() { return false; } @@ -100,20 +103,21 @@ public void onLoad(ItemGroup parent, String name) throws IOExcep notLoaded = true; } - protected SortedMap _getRuns() { - if(notLoaded || runs==null) { + @Override + protected SortedMap _getRuns() { + if (notLoaded || runs == null) { // if none is loaded yet, do so immediately. - synchronized(this) { - if(runs==null) + synchronized (this) { + if (runs == null) runs = new RunMap<>(); - if(notLoaded) { + if (notLoaded) { notLoaded = false; - _reload(); + _reload(); } } } - if(nextUpdate _getRuns() { } reloadQueue = reloadThread.reloadQueue; } - synchronized(reloadQueue) { + synchronized (reloadQueue) { reloadQueue.add(this); reloadQueue.notify(); } @@ -135,6 +139,7 @@ protected SortedMap _getRuns() { return runs; } + @Override public void removeRun(RunT run) { if (runs != null && !runs.remove(run)) { LOGGER.log(Level.WARNING, "{0} did not contain {1} to begin with", new Object[] {this, run}); @@ -146,7 +151,7 @@ private void _reload() { reload(); } finally { reloadingInProgress = false; - nextUpdate = reloadPeriodically ? System.currentTimeMillis()+TimeUnit.MINUTES.toMillis(1) : Long.MAX_VALUE; + nextUpdate = reloadPeriodically ? System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(1) : Long.MAX_VALUE; } } @@ -159,8 +164,8 @@ private void _reload() { protected abstract void reload(); @Override - protected void submit( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException, FormException { - super.submit(req,rsp); + protected void submit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, FormException { + super.submit(req, rsp); // make sure to reload to reflect this config change. nextUpdate = 0; } @@ -184,12 +189,12 @@ private ReloadThread() { } private ViewJob getNext() throws InterruptedException { - synchronized(reloadQueue) { + synchronized (reloadQueue) { // reload operations might eat InterruptException, // so check the status every so often - while(reloadQueue.isEmpty() && !terminating()) + while (reloadQueue.isEmpty() && !terminating()) reloadQueue.wait(TimeUnit.MINUTES.toMillis(1)); - if(terminating()) + if (terminating()) throw new InterruptedException(); // terminate now ViewJob job = reloadQueue.iterator().next(); reloadQueue.remove(job); @@ -226,7 +231,8 @@ public void run() { *

    * We then switched to submission via HTTP, so this reloading is no longer necessary, so only do this * when explicitly requested. - * + * */ - public static boolean reloadPeriodically = SystemProperties.getBoolean(ViewJob.class.getName()+".reloadPeriodically"); + @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "for script console") + public static boolean reloadPeriodically = SystemProperties.getBoolean(ViewJob.class.getName() + ".reloadPeriodically"); } diff --git a/core/src/main/java/hudson/model/ViewProperty.java b/core/src/main/java/hudson/model/ViewProperty.java index 2ace3390f937..31ad3078d449 100644 --- a/core/src/main/java/hudson/model/ViewProperty.java +++ b/core/src/main/java/hudson/model/ViewProperty.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; import hudson.DescriptorExtensionList; @@ -58,15 +59,17 @@ public class ViewProperty implements ReconfigurableDescribable, Ex this.view = view; } + @Override public ViewPropertyDescriptor getDescriptor() { return (ViewPropertyDescriptor) Jenkins.get().getDescriptorOrDie(getClass()); } - public static DescriptorExtensionList all() { + public static DescriptorExtensionList all() { return Jenkins.get().getDescriptorList(ViewProperty.class); } + @Override public ViewProperty reconfigure(StaplerRequest req, JSONObject form) throws Descriptor.FormException { - return form==null ? null : getDescriptor().newInstance(req, form); + return form == null ? null : getDescriptor().newInstance(req, form); } } diff --git a/core/src/main/java/hudson/model/ViewPropertyDescriptor.java b/core/src/main/java/hudson/model/ViewPropertyDescriptor.java index da0e0bbb516c..a8d9b40082a0 100644 --- a/core/src/main/java/hudson/model/ViewPropertyDescriptor.java +++ b/core/src/main/java/hudson/model/ViewPropertyDescriptor.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; /** diff --git a/core/src/main/java/hudson/model/WorkspaceBrowser.java b/core/src/main/java/hudson/model/WorkspaceBrowser.java index d0c0dac088bd..7275e276d63f 100644 --- a/core/src/main/java/hudson/model/WorkspaceBrowser.java +++ b/core/src/main/java/hudson/model/WorkspaceBrowser.java @@ -24,17 +24,16 @@ package hudson.model; +import edu.umd.cs.findbugs.annotations.CheckForNull; import hudson.ExtensionPoint; import hudson.FilePath; import hudson.slaves.WorkspaceList; -import edu.umd.cs.findbugs.annotations.CheckForNull; - /** * Allows to access a workspace as an alternative to online build node. *

    * Primary use case is {@link hudson.slaves.Cloud} implementations that don't keep the agent - * online to browse workspace, but maintain a copy of node workspace on master. + * online to browse workspace, but maintain a copy of node workspace on the controller. * * @author Nicolas De Loof * @since 1.502 @@ -45,7 +44,6 @@ public abstract class WorkspaceBrowser implements ExtensionPoint { /** * Provide access to job's workspace - * @param job * @return {@code null} if this WorkspaceBrowser don't have a workspace for this job */ public abstract @CheckForNull FilePath getWorkspace(Job job); diff --git a/core/src/main/java/hudson/model/WorkspaceCleanupThread.java b/core/src/main/java/hudson/model/WorkspaceCleanupThread.java index 3f017caee29d..00ef65c4a92e 100644 --- a/core/src/main/java/hudson/model/WorkspaceCleanupThread.java +++ b/core/src/main/java/hudson/model/WorkspaceCleanupThread.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,13 +21,15 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.Extension; import hudson.ExtensionList; import hudson.FilePath; import hudson.Functions; -import jenkins.util.SystemProperties; import hudson.Util; import java.io.IOException; import java.util.ArrayList; @@ -35,9 +37,9 @@ import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; -import edu.umd.cs.findbugs.annotations.NonNull; import jenkins.model.Jenkins; import jenkins.model.ModifiableTopLevelItemGroup; +import jenkins.util.SystemProperties; import org.jenkinsci.Symbol; /** @@ -102,40 +104,40 @@ private boolean shouldBeDeleted(@NonNull TopLevelItem item, FilePath dir, @NonNu // TODO: the use of remoting is not optimal. // One remoting can execute "exists", "lastModified", and "delete" all at once. // (Could even invert master loop so that one FileCallable takes care of all known items.) - if(!dir.exists()) { + if (!dir.exists()) { LOGGER.log(Level.FINE, "Directory {0} does not exist", dir); return false; } // if younger than a month, keep it long now = new Date().getTime(); - if(dir.lastModified() + retainForDays * DAY > now) { - LOGGER.log(Level.FINE, "Directory {0} is only {1} old, so not deleting", new Object[] {dir, Util.getTimeSpanString(now-dir.lastModified())}); + if (dir.lastModified() + retainForDays * DAY > now) { + LOGGER.log(Level.FINE, "Directory {0} is only {1} old, so not deleting", new Object[] {dir, Util.getTimeSpanString(now - dir.lastModified())}); return false; } // TODO could also be good to add checkbox that lets users configure a workspace to never be auto-cleaned. // TODO check instead for SCMTriggerItem: - if (item instanceof AbstractProject) { - AbstractProject p = (AbstractProject) item; + if (item instanceof AbstractProject) { + AbstractProject p = (AbstractProject) item; Node lb = p.getLastBuiltOn(); LOGGER.log(Level.FINER, "Directory {0} is last built on {1}", new Object[] {dir, lb}); - if(lb!=null && lb.equals(n)) { + if (lb != null && lb.equals(n)) { // this is the active workspace. keep it. LOGGER.log(Level.FINE, "Directory {0} is the last workspace for {1}", new Object[] {dir, p}); return false; } - - if(!p.getScm().processWorkspaceBeforeDeletion((Job) p,dir,n)) { + + if (!p.getScm().processWorkspaceBeforeDeletion((Job) p, dir, n)) { LOGGER.log(Level.FINE, "Directory deletion of {0} is vetoed by SCM", dir); return false; } } // TODO this may only check the last build in fact: - if (item instanceof Job) { - Job j = (Job) item; + if (item instanceof Job) { + Job j = (Job) item; if (j.isBuilding()) { LOGGER.log(Level.FINE, "Job {0} is building, so not deleting", item.getFullDisplayName()); return false; @@ -151,15 +153,17 @@ private boolean shouldBeDeleted(@NonNull TopLevelItem item, FilePath dir, @NonNu /** * Can be used to disable workspace clean up. */ - public static boolean disabled = SystemProperties.getBoolean(WorkspaceCleanupThread.class.getName()+".disabled"); + @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "Accessible via System Groovy Scripts") + public static boolean disabled = SystemProperties.getBoolean(WorkspaceCleanupThread.class.getName() + ".disabled"); /** * How often the clean up should run. This is final as Jenkins will not reflect changes anyway. */ - public static final int recurrencePeriodHours = SystemProperties.getInteger(WorkspaceCleanupThread.class.getName()+".recurrencePeriodHours", 24); + public static final int recurrencePeriodHours = SystemProperties.getInteger(WorkspaceCleanupThread.class.getName() + ".recurrencePeriodHours", 24); /** * Number of days workspaces should be retained. */ - public static int retainForDays = SystemProperties.getInteger(WorkspaceCleanupThread.class.getName()+".retainForDays", 30); + @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "Accessible via System Groovy Scripts") + public static int retainForDays = SystemProperties.getInteger(WorkspaceCleanupThread.class.getName() + ".retainForDays", 30); } diff --git a/core/src/main/java/hudson/model/WorkspaceListener.java b/core/src/main/java/hudson/model/WorkspaceListener.java index 94d37d414418..4a6089164a16 100644 --- a/core/src/main/java/hudson/model/WorkspaceListener.java +++ b/core/src/main/java/hudson/model/WorkspaceListener.java @@ -5,25 +5,21 @@ import hudson.FilePath; public abstract class WorkspaceListener implements ExtensionPoint { - + /** * Called after a workspace is deleted successfully. - * @param project */ public void afterDelete(AbstractProject project) { - + } /** * Called before a build uses a workspace. IE, before any SCM checkout. - * @param b - * @param workspace - * @param listener */ public void beforeUse(AbstractBuild b, FilePath workspace, BuildListener listener) { - + } - + /** * All registered {@link WorkspaceListener}s. */ diff --git a/core/src/main/java/hudson/model/labels/LabelAssignmentAction.java b/core/src/main/java/hudson/model/labels/LabelAssignmentAction.java index ef65176e23b6..350b825d5fc0 100644 --- a/core/src/main/java/hudson/model/labels/LabelAssignmentAction.java +++ b/core/src/main/java/hudson/model/labels/LabelAssignmentAction.java @@ -1,5 +1,6 @@ package hudson.model.labels; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.model.Action; import hudson.model.Label; import hudson.model.LoadBalancer; @@ -7,7 +8,6 @@ import hudson.model.Queue.QueueDecisionHandler; import hudson.model.Queue.Task; import hudson.model.queue.SubTask; -import edu.umd.cs.findbugs.annotations.NonNull; /** * {@link Action} that can be submitted to {@link Queue} that controls where diff --git a/core/src/main/java/hudson/model/labels/LabelAtom.java b/core/src/main/java/hudson/model/labels/LabelAtom.java index 2598e77e2290..52779eb6fce1 100644 --- a/core/src/main/java/hudson/model/labels/LabelAtom.java +++ b/core/src/main/java/hudson/model/labels/LabelAtom.java @@ -21,33 +21,31 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model.labels; import com.thoughtworks.xstream.converters.MarshallingContext; import com.thoughtworks.xstream.converters.UnmarshallingContext; import com.thoughtworks.xstream.io.HierarchicalStreamReader; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.Nullable; import hudson.BulkChange; import hudson.CopyOnWrite; import hudson.XmlFile; import hudson.model.Action; import hudson.model.Descriptor.FormException; import hudson.model.Failure; -import hudson.util.*; -import jenkins.model.Jenkins; import hudson.model.Label; import hudson.model.Saveable; import hudson.model.listeners.SaveableListener; -import jenkins.util.SystemProperties; -import org.kohsuke.accmod.Restricted; -import org.kohsuke.accmod.restrictions.DoNotUse; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; -import org.kohsuke.stapler.export.Exported; -import org.kohsuke.stapler.interceptor.RequirePOST; -import org.kohsuke.stapler.verb.POST; - -import javax.servlet.ServletException; +import hudson.util.DescribableList; +import hudson.util.EditDistance; +import hudson.util.FormApply; +import hudson.util.QuotedStringTokenizer; +import hudson.util.VariableResolver; +import hudson.util.XStream2; import java.io.File; import java.io.IOException; import java.util.ArrayList; @@ -58,13 +56,20 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; - -import edu.umd.cs.findbugs.annotations.CheckForNull; -import edu.umd.cs.findbugs.annotations.Nullable; +import javax.servlet.ServletException; +import jenkins.model.Jenkins; +import jenkins.util.SystemProperties; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.DoNotUse; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.export.Exported; +import org.kohsuke.stapler.interceptor.RequirePOST; +import org.kohsuke.stapler.verb.POST; /** * Atomic single token label, like "foo" or "bar". - * + * * @author Kohsuke Kawaguchi * @since 1.372 */ @@ -75,7 +80,7 @@ public class LabelAtom extends Label implements Saveable { private static /* Script Console modifiable */ boolean ALLOW_FOLDER_TRAVERSAL = SystemProperties.getBoolean(LabelAtom.class.getName() + ".allowFolderTraversal"); - private DescribableList properties = + private DescribableList properties = new DescribableList<>(this); @CopyOnWrite @@ -83,7 +88,7 @@ public class LabelAtom extends Label implements Saveable { private String description; - public LabelAtom(String name) { + public LabelAtom(@NonNull String name) { super(name); } @@ -107,6 +112,7 @@ public String getExpression() { * should do so by implementing {@link LabelAtomProperty#getActions(LabelAtom)}. */ @SuppressWarnings("deprecation") + @NonNull @Override public List getActions() { // add all the transient actions, too @@ -159,7 +165,7 @@ public boolean matches(VariableResolver resolver) { @Override public V accept(LabelVisitor visitor, P param) { - return visitor.onAtom(this,param); + return visitor.onAtom(this, param); } @Override @@ -173,29 +179,30 @@ public LabelOperatorPrecedence precedence() { } /*package*/ XmlFile getConfigFile() { - return new XmlFile(XSTREAM, new File(Jenkins.get().root, "labels/"+name+".xml")); + return new XmlFile(XSTREAM, new File(Jenkins.get().root, "labels/" + name + ".xml")); } + @Override public void save() throws IOException { if (isInvalidName()) { throw new IOException("Invalid label"); } - if(BulkChange.contains(this)) return; + if (BulkChange.contains(this)) return; try { getConfigFile().write(this); SaveableListener.fireOnChange(this, getConfigFile()); } catch (IOException e) { - LOGGER.log(Level.WARNING, "Failed to save "+getConfigFile(),e); + LOGGER.log(Level.WARNING, "Failed to save " + getConfigFile(), e); } } public void load() { XmlFile file = getConfigFile(); - if(file.exists()) { + if (file.exists()) { try { file.unmarshal(this); } catch (IOException e) { - LOGGER.log(Level.WARNING, "Failed to load "+file, e); + LOGGER.log(Level.WARNING, "Failed to load " + file, e); } } properties.setOwner(this); @@ -214,7 +221,7 @@ public List getApplicablePropertyDescriptors() { * Accepts the update to the node configuration. */ @POST - public void doConfigSubmit( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException, FormException { + public void doConfigSubmit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, FormException { final Jenkins app = Jenkins.get(); app.checkPermission(Jenkins.ADMINISTER); @@ -242,7 +249,7 @@ private boolean isInvalidName() { */ @RequirePOST @Restricted(DoNotUse.class) - public synchronized void doSubmitDescription( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException { + public synchronized void doSubmitDescription(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); setDescription(req.getParameter("description")); @@ -269,9 +276,9 @@ public static boolean needsEscape(String name) { try { Jenkins.checkGoodName(name); // additional restricted chars - for( int i=0; i getActions(LabelAtom atom) { /** * Lists up all the registered {@link LabelAtomPropertyDescriptor}s in the system. */ - public static DescriptorExtensionList all() { + public static DescriptorExtensionList all() { return Jenkins.get().getDescriptorList(LabelAtomProperty.class); } } diff --git a/core/src/main/java/hudson/model/labels/LabelAtomPropertyDescriptor.java b/core/src/main/java/hudson/model/labels/LabelAtomPropertyDescriptor.java index b9b9312939f1..3c45b2e0a76e 100644 --- a/core/src/main/java/hudson/model/labels/LabelAtomPropertyDescriptor.java +++ b/core/src/main/java/hudson/model/labels/LabelAtomPropertyDescriptor.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model.labels; import hudson.Extension; @@ -31,7 +32,7 @@ * *

    * Put {@link Extension} on your descriptor implementation to have it auto-registered. - * + * *

    * When extending this class, override {@link Descriptor#getDisplayName()}. In the * context of LabelAtomPropertyDescriptor, this function is used to determine the label of diff --git a/core/src/main/java/hudson/model/labels/LabelExpression.java b/core/src/main/java/hudson/model/labels/LabelExpression.java index 688167fa4b24..40a7fc6f80db 100644 --- a/core/src/main/java/hudson/model/labels/LabelExpression.java +++ b/core/src/main/java/hudson/model/labels/LabelExpression.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model.labels; import antlr.ANTLRException; @@ -36,6 +37,7 @@ import hudson.util.FormValidation; import hudson.util.VariableResolver; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Set; import jenkins.model.Jenkins; @@ -44,7 +46,7 @@ /** * Boolean expression of labels. - * + * * @author Kohsuke Kawaguchi * @since 1.372 */ @@ -62,7 +64,7 @@ public static class Not extends LabelExpression { public final Label base; public Not(Label base) { - super('!'+paren(LabelOperatorPrecedence.NOT,base)); + super('!' + paren(LabelOperatorPrecedence.NOT, base)); this.base = base; } @@ -89,7 +91,7 @@ public static class Paren extends LabelExpression { public final Label base; public Paren(Label base) { - super('('+base.getExpression()+')'); + super('(' + base.getExpression() + ')'); this.base = base; } @@ -113,22 +115,22 @@ public LabelOperatorPrecedence precedence() { * Puts the label name into a parenthesis if the given operator will have a higher precedence. */ static String paren(LabelOperatorPrecedence op, Label l) { - if (op.compareTo(l.precedence())<0) - return '('+l.getExpression()+')'; + if (op.compareTo(l.precedence()) < 0) + return '(' + l.getExpression() + ')'; return l.getExpression(); } public abstract static class Binary extends LabelExpression { - public final Label lhs,rhs; + public final Label lhs, rhs; - public Binary(Label lhs, Label rhs, LabelOperatorPrecedence op) { + protected Binary(Label lhs, Label rhs, LabelOperatorPrecedence op) { super(combine(lhs, rhs, op)); this.lhs = lhs; this.rhs = rhs; } private static String combine(Label lhs, Label rhs, LabelOperatorPrecedence op) { - return paren(op,lhs)+op.str+paren(op,rhs); + return paren(op, lhs) + op.str + paren(op, rhs); } /** @@ -137,7 +139,7 @@ private static String combine(Label lhs, Label rhs, LabelOperatorPrecedence op) */ @Override public boolean matches(VariableResolver resolver) { - return op(lhs.matches(resolver),rhs.matches(resolver)); + return op(lhs.matches(resolver), rhs.matches(resolver)); } protected abstract boolean op(boolean a, boolean b); @@ -285,8 +287,15 @@ public static FormValidation validate(@Nullable String expression, @CheckForNull } final Jenkins j = Jenkins.get(); Label l = j.getLabel(expression); - if (l.isEmpty()) { - for (LabelAtom a : l.listAtoms()) { + if (l == null || l.isEmpty()) { + final LabelAtom masterLabel = LabelAtom.get("master"); + final Set labelAtoms = (l == null ? Collections.emptySet() : l.listAtoms()); + if (!masterLabel.equals(Jenkins.get().getSelfLabel()) && labelAtoms.contains(masterLabel) && masterLabel.isEmpty()) { + // Show a warning if this expression's lack of nodes and clouds is likely caused by the built-in node name migration. + // This can probably be done better (e.g. also when `!l.isEmpty()`), but it's a start. + return FormValidation.warningWithMarkup(Messages.LabelExpression_ObsoleteMasterLabel()); + } + for (LabelAtom a : labelAtoms) { if (a.isEmpty()) { LabelAtom nearest = LabelAtom.findNearest(a.getName()); return FormValidation.warning(Messages.LabelExpression_NoMatch_DidYouMean(a.getName(), nearest.getDisplayName())); diff --git a/core/src/main/java/hudson/model/labels/LabelOperatorPrecedence.java b/core/src/main/java/hudson/model/labels/LabelOperatorPrecedence.java index a917d97b0563..b70f0036af76 100644 --- a/core/src/main/java/hudson/model/labels/LabelOperatorPrecedence.java +++ b/core/src/main/java/hudson/model/labels/LabelOperatorPrecedence.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model.labels; /** diff --git a/core/src/main/java/hudson/model/labels/LabelVisitor.java b/core/src/main/java/hudson/model/labels/LabelVisitor.java index fcb2f9b58eab..0fb8114f32c0 100644 --- a/core/src/main/java/hudson/model/labels/LabelVisitor.java +++ b/core/src/main/java/hudson/model/labels/LabelVisitor.java @@ -7,7 +7,7 @@ * @see LabelExpression#accept(LabelVisitor, Object) * @since 1.420 */ -public abstract class LabelVisitor { +public abstract class LabelVisitor { public abstract V onAtom(LabelAtom a, P param); public abstract V onParen(LabelExpression.Paren p, P param); diff --git a/core/src/main/java/hudson/model/listeners/ItemListener.java b/core/src/main/java/hudson/model/listeners/ItemListener.java index ef2905938c73..aef431c3207b 100644 --- a/core/src/main/java/hudson/model/listeners/ItemListener.java +++ b/core/src/main/java/hudson/model/listeners/ItemListener.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,19 +21,20 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model.listeners; -import hudson.ExtensionPoint; -import hudson.ExtensionList; import hudson.Extension; +import hudson.ExtensionList; +import hudson.ExtensionPoint; import hudson.model.Failure; import hudson.model.Item; import hudson.model.ItemGroup; import hudson.model.Items; import hudson.security.ACL; -import java.util.function.Consumer; import java.util.logging.Level; import java.util.logging.Logger; +import jenkins.util.Listeners; /** * Receives notifications about CRUD operations of {@link Item}. @@ -171,23 +172,8 @@ public static ExtensionList all() { return ExtensionList.lookup(ItemListener.class); } - // TODO JENKINS-21224 generalize this to a method perhaps in ExtensionList and use consistently from all listeners - private static void forAll(final Consumer consumer) { - for (ItemListener l : all()) { - try { - consumer.accept(l); - } catch (RuntimeException x) { - LOGGER.log(Level.WARNING, "failed to send event to listener of " + l.getClass(), x); - } - } - } - public static void fireOnCopied(final Item src, final Item result) { - forAll(l -> { - if (l != null) { - l.onCopied(src, result); - } - }); + Listeners.notify(ItemListener.class, false, l -> l.onCopied(src, result)); } /** @@ -212,28 +198,16 @@ public static void checkBeforeCopy(final Item src, final ItemGroup parent) throw } public static void fireOnCreated(final Item item) { - forAll(l -> { - if (l != null) { - l.onCreated(item); - } - }); + Listeners.notify(ItemListener.class, false, l -> l.onCreated(item)); } public static void fireOnUpdated(final Item item) { - forAll(l -> { - if (l != null) { - l.onUpdated(item); - } - }); + Listeners.notify(ItemListener.class, false, l -> l.onUpdated(item)); } /** @since 1.548 */ public static void fireOnDeleted(final Item item) { - forAll(l -> { - if (l != null) { - l.onDeleted(item); - } - }); + Listeners.notify(ItemListener.class, false, l -> l.onDeleted(item)); } /** @@ -254,28 +228,16 @@ public static void fireLocationChange(final Item rootItem, final String oldFullN final String oldName = oldFullName.substring(prefixS); final String newName = rootItem.getName(); assert newName.equals(newFullName.substring(prefixS)); - forAll(l -> { - if (l != null) { - l.onRenamed(rootItem, oldName, newName); - } - }); + Listeners.notify(ItemListener.class, false, l -> l.onRenamed(rootItem, oldName, newName)); } - forAll(l -> { - if (l!= null) { - l.onLocationChanged(rootItem, oldFullName, newFullName); - } - }); + Listeners.notify(ItemListener.class, false, l -> l.onLocationChanged(rootItem, oldFullName, newFullName)); if (rootItem instanceof ItemGroup) { - for (final Item child : Items.allItems2(ACL.SYSTEM2, (ItemGroup)rootItem, Item.class)) { + for (final Item child : Items.allItems2(ACL.SYSTEM2, (ItemGroup) rootItem, Item.class)) { final String childNew = child.getFullName(); assert childNew.startsWith(newFullName); assert childNew.charAt(newFullName.length()) == '/'; final String childOld = oldFullName + childNew.substring(newFullName.length()); - forAll(l -> { - if (l != null) { - l.onLocationChanged(child, childOld, childNew); - } - }); + Listeners.notify(ItemListener.class, false, l -> l.onLocationChanged(child, childOld, childNew)); } } } diff --git a/core/src/main/java/hudson/model/listeners/RunListener.java b/core/src/main/java/hudson/model/listeners/RunListener.java index fce83e8e844f..0ecbf725c792 100644 --- a/core/src/main/java/hudson/model/listeners/RunListener.java +++ b/core/src/main/java/hudson/model/listeners/RunListener.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Tom Huybrechts - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,12 +21,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model.listeners; -import hudson.ExtensionPoint; -import hudson.ExtensionListView; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.Extension; import hudson.ExtensionList; +import hudson.ExtensionListView; +import hudson.ExtensionPoint; import hudson.FilePath; import hudson.Functions; import hudson.Launcher; @@ -40,15 +42,12 @@ import hudson.scm.SCM; import hudson.tasks.BuildWrapper; import hudson.util.CopyOnWriteList; -import org.jvnet.tiger_types.Types; - import java.io.File; import java.io.IOException; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; -import java.util.logging.Level; -import java.util.logging.Logger; -import edu.umd.cs.findbugs.annotations.NonNull; +import jenkins.util.Listeners; +import org.jvnet.tiger_types.Types; /** * Receives notifications about builds. @@ -59,7 +58,7 @@ * *

    * This is an abstract class so that methods added in the future won't break existing listeners. - * + * * @author Kohsuke Kawaguchi * @since 1.145 */ @@ -73,9 +72,9 @@ protected RunListener(Class targetType) { protected RunListener() { Type type = Types.getBaseClass(getClass(), RunListener.class); if (type instanceof ParameterizedType) - targetType = Types.erasure(Types.getTypeArgument(type,0)); + targetType = Types.erasure(Types.getTypeArgument(type, 0)); else - throw new IllegalStateException(getClass()+" uses the raw type for extending RunListener"); + throw new IllegalStateException(getClass() + " uses the raw type for extending RunListener"); } /** @@ -158,8 +157,8 @@ public void onStarted(R r, TaskListener listener) {} * to suppress a stack trace by the receiver. * @since 1.410 */ - public Environment setUpEnvironment( AbstractBuild build, Launcher launcher, BuildListener listener ) throws IOException, InterruptedException, RunnerAbortedException { - return new Environment() {}; + public Environment setUpEnvironment(AbstractBuild build, Launcher launcher, BuildListener listener) throws IOException, InterruptedException, RunnerAbortedException { + return new Environment() {}; } /** @@ -203,28 +202,22 @@ public void unregister() { * Fires the {@link #onCompleted(Run, TaskListener)} event. */ public static void fireCompleted(Run r, @NonNull TaskListener listener) { - for (RunListener l : all()) { - if(l.targetType.isInstance(r)) - try { - l.onCompleted(r,listener); - } catch (Throwable e) { - report(e); - } - } + Listeners.notify(RunListener.class, true, l -> { + if (l.targetType.isInstance(r)) { + l.onCompleted(r, listener); + } + }); } /** * Fires the {@link #onInitialize(Run)} event. */ public static void fireInitialize(Run r) { - for (RunListener l : all()) { - if(l.targetType.isInstance(r)) - try { - l.onInitialize(r); - } catch (Throwable e) { - report(e); - } - } + Listeners.notify(RunListener.class, true, l -> { + if (l.targetType.isInstance(r)) { + l.onInitialize(r); + } + }); } @@ -232,14 +225,11 @@ public static void fireInitialize(Run r) { * Fires the {@link #onStarted(Run, TaskListener)} event. */ public static void fireStarted(Run r, TaskListener listener) { - for (RunListener l : all()) { - if(l.targetType.isInstance(r)) - try { - l.onStarted(r,listener); - } catch (Throwable e) { - report(e); - } - } + Listeners.notify(RunListener.class, true, l -> { + if (l.targetType.isInstance(r)) { + l.onStarted(r, listener); + } + }); } /** @@ -249,28 +239,22 @@ public static void fireFinalized(Run r) { if (!Functions.isExtensionsAvailable()) { return; } - for (RunListener l : all()) { - if(l.targetType.isInstance(r)) - try { - l.onFinalized(r); - } catch (Throwable e) { - report(e); - } - } + Listeners.notify(RunListener.class, true, l -> { + if (l.targetType.isInstance(r)) { + l.onFinalized(r); + } + }); } /** * Fires the {@link #onDeleted} event. */ public static void fireDeleted(Run r) { - for (RunListener l : all()) { - if(l.targetType.isInstance(r)) - try { - l.onDeleted(r); - } catch (Throwable e) { - report(e); - } - } + Listeners.notify(RunListener.class, true, l -> { + if (l.targetType.isInstance(r)) { + l.onDeleted(r); + } + }); } /** @@ -279,11 +263,4 @@ public static void fireDeleted(Run r) { public static ExtensionList all() { return ExtensionList.lookup(RunListener.class); } - - private static void report(Throwable e) { - LOGGER.log(Level.WARNING, "RunListener failed",e); - } - - private static final Logger LOGGER = Logger.getLogger(RunListener.class.getName()); - } diff --git a/core/src/main/java/hudson/model/listeners/SCMListener.java b/core/src/main/java/hudson/model/listeners/SCMListener.java index c3412df090f0..afb93bf2c7ab 100644 --- a/core/src/main/java/hudson/model/listeners/SCMListener.java +++ b/core/src/main/java/hudson/model/listeners/SCMListener.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,8 +21,10 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model.listeners; +import edu.umd.cs.findbugs.annotations.CheckForNull; import hudson.Extension; import hudson.ExtensionPoint; import hudson.FilePath; @@ -41,7 +43,6 @@ import java.util.Collection; import java.util.Collections; import java.util.List; -import edu.umd.cs.findbugs.annotations.CheckForNull; import jenkins.model.Jenkins; /** @@ -51,7 +52,7 @@ * This is an abstract class so that methods added in the future won't break existing listeners. * *

    - * Once instantiated, use the {@link #register()} method to start receiving events. + * Once instantiated, use the {@link #register()} method to start receiving events. * * @author Kohsuke Kawaguchi * @see jenkins.model.Jenkins#getSCMListeners() @@ -65,7 +66,7 @@ public abstract class SCMListener implements ExtensionPoint { * @throws Exception if the checkout should be considered failed * @since 1.568 */ - public void onCheckout(Run build, SCM scm, FilePath workspace, TaskListener listener, @CheckForNull File changelogFile, @CheckForNull SCMRevisionState pollingBaseline) throws Exception {} + public void onCheckout(Run build, SCM scm, FilePath workspace, TaskListener listener, @CheckForNull File changelogFile, @CheckForNull SCMRevisionState pollingBaseline) throws Exception {} /** * Called once the changelog is determined. @@ -79,7 +80,7 @@ public void onCheckout(Run build, SCM scm, FilePath workspace, TaskListener *

    * If a build failed before we successfully determine changelog, this method * will not be invoked (for example, if "cvs update" failed.) OTOH, this method - * is invoked before the actual build (like ant invocation) happens. + * is invoked before the actual build (like ant invocation) happens. * *

    * This is an opportunity for SCM-related plugins to act on changelog. @@ -105,17 +106,17 @@ public void onCheckout(Run build, SCM scm, FilePath workspace, TaskListener * * @throws Exception * If any exception is thrown from this method, it will be recorded - * and causes the build to fail. + * and causes the build to fail. * @since 1.568 */ - public void onChangeLogParsed(Run build, SCM scm, TaskListener listener, ChangeLogSet changelog) throws Exception { + public void onChangeLogParsed(Run build, SCM scm, TaskListener listener, ChangeLogSet changelog) throws Exception { if (build instanceof AbstractBuild && listener instanceof BuildListener && Util.isOverridden(SCMListener.class, getClass(), "onChangeLogParsed", AbstractBuild.class, BuildListener.class, ChangeLogSet.class)) { onChangeLogParsed((AbstractBuild) build, (BuildListener) listener, changelog); } } @Deprecated - public void onChangeLogParsed(AbstractBuild build, BuildListener listener, ChangeLogSet changelog) throws Exception { + public void onChangeLogParsed(AbstractBuild build, BuildListener listener, ChangeLogSet changelog) throws Exception { if (Util.isOverridden(SCMListener.class, getClass(), "onChangeLogParsed", Run.class, SCM.class, TaskListener.class, ChangeLogSet.class)) { onChangeLogParsed(build, build.getProject().getScm(), listener, changelog); } diff --git a/core/src/main/java/hudson/model/listeners/SCMPollListener.java b/core/src/main/java/hudson/model/listeners/SCMPollListener.java index 55dd8d558930..341f91ac79b8 100644 --- a/core/src/main/java/hudson/model/listeners/SCMPollListener.java +++ b/core/src/main/java/hudson/model/listeners/SCMPollListener.java @@ -21,15 +21,16 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model.listeners; import hudson.ExtensionList; import hudson.ExtensionPoint; -import hudson.scm.PollingResult; import hudson.model.AbstractProject; import hudson.model.TaskListener; - +import hudson.scm.PollingResult; import java.io.IOException; +import jenkins.util.Listeners; /** * A hook for listening to polling activities in Jenkins. @@ -48,7 +49,7 @@ public abstract class SCMPollListener implements ExtensionPoint { * Connected to the polling log. */ // TODO switch to Job - public void onBeforePolling( AbstractProject project, TaskListener listener ) {} + public void onBeforePolling(AbstractProject project, TaskListener listener) {} /** * Called when the polling successfully concluded. @@ -56,7 +57,7 @@ public void onBeforePolling( AbstractProject project, TaskListener listene * @param result * The result of the polling. */ - public void onPollingSuccess( AbstractProject project, TaskListener listener, PollingResult result) {} + public void onPollingSuccess(AbstractProject project, TaskListener listener, PollingResult result) {} /** * Called when the polling concluded with an error. @@ -65,42 +66,24 @@ public void onPollingSuccess( AbstractProject project, TaskListener listen * The problem reported. This can include {@link InterruptedException} (that corresponds to the user cancelling it), * some anticipated problems like {@link IOException}, or bug in the code ({@link RuntimeException}) */ - public void onPollingFailed( AbstractProject project, TaskListener listener, Throwable exception) {} + public void onPollingFailed(AbstractProject project, TaskListener listener, Throwable exception) {} - public static void fireBeforePolling( AbstractProject project, TaskListener listener ) { - for (SCMPollListener l : all()) { - try { - l.onBeforePolling(project, listener); - } catch (Exception e) { - /* Make sure, that the listeners do not have any impact on the actual poll */ - } - } + public static void fireBeforePolling(AbstractProject project, TaskListener listener) { + Listeners.notify(SCMPollListener.class, true, l -> l.onBeforePolling(project, listener)); } - public static void firePollingSuccess( AbstractProject project, TaskListener listener, PollingResult result ) { - for( SCMPollListener l : all() ) { - try { - l.onPollingSuccess(project, listener, result); - } catch (Exception e) { - /* Make sure, that the listeners do not have any impact on the actual poll */ - } - } - } + public static void firePollingSuccess(AbstractProject project, TaskListener listener, PollingResult result) { + Listeners.notify(SCMPollListener.class, true, l -> l.onPollingSuccess(project, listener, result)); + } - public static void firePollingFailed( AbstractProject project, TaskListener listener, Throwable exception ) { - for( SCMPollListener l : all() ) { - try { - l.onPollingFailed(project, listener, exception); - } catch (Exception e) { - /* Make sure, that the listeners do not have any impact on the actual poll */ - } - } - } + public static void firePollingFailed(AbstractProject project, TaskListener listener, Throwable exception) { + Listeners.notify(SCMPollListener.class, true, l -> l.onPollingFailed(project, listener, exception)); + } - /** - * Returns all the registered {@link SCMPollListener}s. - */ - public static ExtensionList all() { - return ExtensionList.lookup( SCMPollListener.class ); - } + /** + * Returns all the registered {@link SCMPollListener}s. + */ + public static ExtensionList all() { + return ExtensionList.lookup(SCMPollListener.class); + } } diff --git a/core/src/main/java/hudson/model/listeners/SaveableListener.java b/core/src/main/java/hudson/model/listeners/SaveableListener.java index 37fed04f69f1..51cac4861a57 100644 --- a/core/src/main/java/hudson/model/listeners/SaveableListener.java +++ b/core/src/main/java/hudson/model/listeners/SaveableListener.java @@ -1,19 +1,19 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Tom Huybrechts, * Andrew Bayer - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -22,11 +22,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model.listeners; -import hudson.ExtensionPoint; import hudson.Extension; import hudson.ExtensionList; +import hudson.ExtensionPoint; import hudson.XmlFile; import hudson.model.Saveable; import java.util.logging.Level; @@ -78,7 +79,7 @@ public void unregister() { public static void fireOnChange(Saveable o, XmlFile file) { for (SaveableListener l : all()) { try { - l.onChange(o,file); + l.onChange(o, file); } catch (ThreadDeath t) { throw t; } catch (Throwable t) { diff --git a/core/src/main/java/hudson/model/queue/AbstractQueueSorterImpl.java b/core/src/main/java/hudson/model/queue/AbstractQueueSorterImpl.java index b81b099a0f65..99ac92828bb5 100644 --- a/core/src/main/java/hudson/model/queue/AbstractQueueSorterImpl.java +++ b/core/src/main/java/hudson/model/queue/AbstractQueueSorterImpl.java @@ -2,11 +2,10 @@ import hudson.RestrictedSince; import hudson.model.Queue.BuildableItem; -import org.kohsuke.accmod.Restricted; -import org.kohsuke.accmod.restrictions.NoExternalUse; - import java.util.Comparator; import java.util.List; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; /** * Partial implementation of {@link QueueSorter} in terms of {@link Comparator}. @@ -30,8 +29,9 @@ public void sortBuildableItems(List buildables) { *

    * The default implementation does FIFO. */ + @Override public int compare(BuildableItem lhs, BuildableItem rhs) { - return Long.compare(lhs.buildableStartMilliseconds,rhs.buildableStartMilliseconds); + return Long.compare(lhs.buildableStartMilliseconds, rhs.buildableStartMilliseconds); } /** diff --git a/core/src/main/java/hudson/model/queue/AbstractSubTask.java b/core/src/main/java/hudson/model/queue/AbstractSubTask.java index b8de10e02ce1..8888eaab72c9 100644 --- a/core/src/main/java/hudson/model/queue/AbstractSubTask.java +++ b/core/src/main/java/hudson/model/queue/AbstractSubTask.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model.queue; /** diff --git a/core/src/main/java/hudson/model/queue/BackFiller.java b/core/src/main/java/hudson/model/queue/BackFiller.java deleted file mode 100644 index e2bea6772610..000000000000 --- a/core/src/main/java/hudson/model/queue/BackFiller.java +++ /dev/null @@ -1,212 +0,0 @@ -package hudson.model.queue; - -import com.google.common.collect.Iterables; -import hudson.Extension; -import jenkins.util.SystemProperties; -import hudson.model.Computer; -import hudson.model.Executor; -import jenkins.model.Jenkins; -import hudson.model.InvisibleAction; -import hudson.model.Queue.BuildableItem; -import hudson.model.queue.MappingWorksheet.ExecutorChunk; -import hudson.model.queue.MappingWorksheet.ExecutorSlot; -import hudson.model.queue.MappingWorksheet.Mapping; -import hudson.model.queue.MappingWorksheet.WorkChunk; -import java.util.concurrent.TimeUnit; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -/** - * Experimental. - * - * @author Kohsuke Kawaguchi - */ -public class BackFiller extends LoadPredictor { - private boolean recursion = false; - - @Override - public Iterable predict(MappingWorksheet plan, Computer computer, long start, long end) { - TimeRange timeRange = new TimeRange(start, end - start); - List loads = new ArrayList<>(); - - for (BuildableItem bi : Jenkins.get().getQueue().getBuildableItems()) { - TentativePlan tp = bi.getAction(TentativePlan.class); - if (tp==null) {// do this even for bi==plan.item ensures that we have FIFO semantics in tentative plans. - tp = makeTentativePlan(bi); - if (tp==null) continue; // no viable plan. - } - - if (tp.isStale()) { - // if the tentative plan is stale, just keep on pushing it to the current time - // (if we recreate the plan, it'll be put at the end of the queue, whereas this job - // should actually get priority over others) - tp.range.shiftTo(System.currentTimeMillis()); - } - - // don't let its own tentative plan count when considering a scheduling for a job - if (plan.item==bi) continue; - - - // no overlap in the time span, meaning this plan is for a distant future - if (!timeRange.overlapsWith(tp.range)) continue; - - // if this tentative plan has no baring on this computer, that's ignorable - Integer i = tp.footprint.get(computer); - if (i==null) continue; - - return Collections.singleton(tp.range.toFutureLoad(i)); - } - - return loads; - } - - private static final class PseudoExecutorSlot extends ExecutorSlot { - private Executor executor; - - private PseudoExecutorSlot(Executor executor) { - this.executor = executor; - } - - @Override - public Executor getExecutor() { - return executor; - } - - @Override - public boolean isAvailable() { - return true; - } - - // this slot isn't executable - @Override - protected void set(WorkUnit p) { - throw new UnsupportedOperationException(); - } - } - - private TentativePlan makeTentativePlan(BuildableItem bi) { - if (recursion) return null; - recursion = true; - try { - // pretend for now that all executors are available and decide some assignment that's executable. - List slots = new ArrayList<>(); - for (Computer c : Jenkins.get().getComputers()) { - if (c.isOffline()) continue; - for (Executor e : c.getExecutors()) { - slots.add(new PseudoExecutorSlot(e)); - } - } - - // also ignore all load predictions as we just want to figure out some executable assignment - // and we are not trying to figure out if this task is executable right now. - MappingWorksheet worksheet = new MappingWorksheet(bi, slots, Collections.emptyList()); - Mapping m = Jenkins.get().getQueue().getLoadBalancer().map(bi.task, worksheet); - if (m==null) return null; - - // figure out how many executors we need on each computer? - Map footprint = new HashMap<>(); - for (Entry e : m.toMap().entrySet()) { - Computer c = e.getValue().computer; - Integer v = footprint.get(c); - if (v==null) v = 0; - v += e.getKey().size(); - footprint.put(c,v); - } - - // the point of a tentative plan is to displace other jobs to create a point in time - // where this task can start executing. An incorrectly estimated duration is not - // a problem in this regard, as we just need enough idle executors in the right moment. - // The downside of guessing the duration wrong is that we can end up creating tentative plans - // afterward that may be incorrect, but those plans will be rebuilt. - long d = bi.task.getEstimatedDuration(); - if (d<=0) d = TimeUnit.MINUTES.toMillis(5); - - TimeRange slot = new TimeRange(System.currentTimeMillis(), d); - - // now, based on the real predicted loads, figure out the approximation of when we can - // start executing this guy. - for (Entry e : footprint.entrySet()) { - Computer computer = e.getKey(); - Timeline timeline = new Timeline(); - for (LoadPredictor lp : LoadPredictor.all()) { - for (FutureLoad fl : Iterables.limit(lp.predict(worksheet, computer, slot.start, slot.end),100)) { - timeline.insert(fl.startTime, fl.startTime+fl.duration, fl.numExecutors); - } - } - - Long x = timeline.fit(slot.start, slot.duration, computer.countExecutors()-e.getValue()); - // if no suitable range was found in [slot.start,slot.end), slot.end would be a good approximation - if (x==null) x = slot.end; - slot = slot.shiftTo(x); - } - - TentativePlan tp = new TentativePlan(footprint, slot); - bi.addAction(tp); - return tp; - } finally { - recursion = false; - } - } - - /** - * Represents a duration in time. - */ - private static final class TimeRange { - public final long start; - public final long duration; - public final long end; - - private TimeRange(long start, long duration) { - this.start = start; - this.duration = duration; - this.end = start+duration; - } - - public boolean overlapsWith(TimeRange that) { - return (this.start <= that.start && that.start <=this.end) - || (that.start <= this.start && this.start <=that.end); - } - - public FutureLoad toFutureLoad(int size) { - return new FutureLoad(start,duration,size); - } - - public TimeRange shiftTo(long newStart) { - if (newStart==start) return this; - return new TimeRange(newStart,duration); - } - } - - public static final class TentativePlan extends InvisibleAction { - private final Map footprint; - public final TimeRange range; - - public TentativePlan(Map footprint, TimeRange range) { - this.footprint = footprint; - this.range = range; - } - - public Object writeReplace() {// don't persist - return null; - } - - public boolean isStale() { - return range.end < System.currentTimeMillis(); - } - } - - /** - * Once this feature stabilizes, move it to the heavyjob plugin - */ - @Extension - public static BackFiller newInstance() { - if (SystemProperties.getBoolean(BackFiller.class.getName())) - return new BackFiller(); - return null; - } -} diff --git a/core/src/main/java/hudson/model/queue/CauseOfBlockage.java b/core/src/main/java/hudson/model/queue/CauseOfBlockage.java index c75d9ed72cc7..a99194883085 100644 --- a/core/src/main/java/hudson/model/queue/CauseOfBlockage.java +++ b/core/src/main/java/hudson/model/queue/CauseOfBlockage.java @@ -1,14 +1,15 @@ package hudson.model.queue; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.console.ModelHyperlinkNote; import hudson.model.Computer; -import hudson.model.Queue.Task; -import hudson.model.Node; -import hudson.model.Messages; import hudson.model.Label; +import hudson.model.Messages; +import hudson.model.Node; +import hudson.model.Queue.Task; import hudson.model.TaskListener; import hudson.slaves.Cloud; -import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Objects; import org.jvnet.localizer.Localizable; /** @@ -45,7 +46,7 @@ public void print(TaskListener listener) { * Obtains a simple implementation backed by {@link Localizable}. */ public static CauseOfBlockage fromMessage(@NonNull final Localizable l) { - l.getKey(); // null check + Objects.requireNonNull(l); return new CauseOfBlockage() { @Override public String getShortDescription() { @@ -80,6 +81,7 @@ private NeedsMoreExecutorImpl(Localizable l) { this.l = l; } + @Override public String getShortDescription() { return l.toString(); } @@ -95,11 +97,12 @@ public BecauseNodeIsOffline(Node node) { this.node = node; } + @Override public String getShortDescription() { - String name = (node.toComputer() != null) ? node.toComputer().getDisplayName() : node.getDisplayName(); + String name = node.toComputer() != null ? node.toComputer().getDisplayName() : node.getDisplayName(); return Messages.Queue_NodeOffline(name); } - + @Override public void print(TaskListener listener) { listener.getLogger().println( @@ -144,6 +147,7 @@ public BecauseLabelIsOffline(Label l) { this.label = l; } + @Override public String getShortDescription() { if (label.isEmpty()) { return Messages.Queue_LabelHasNoNodes(label.getName()); @@ -173,11 +177,12 @@ public BecauseNodeIsBusy(Node node) { this.node = node; } + @Override public String getShortDescription() { - String name = (node.toComputer() != null) ? node.toComputer().getDisplayName() : node.getDisplayName(); + String name = node.toComputer() != null ? node.toComputer().getDisplayName() : node.getDisplayName(); return Messages.Queue_WaitingForNextAvailableExecutorOn(name); } - + @Override public void print(TaskListener listener) { listener.getLogger().println(Messages.Queue_WaitingForNextAvailableExecutorOn(ModelHyperlinkNote.encodeTo(node))); @@ -194,6 +199,7 @@ public BecauseLabelIsBusy(Label label) { this.label = label; } + @Override public String getShortDescription() { return Messages.Queue_WaitingForNextAvailableExecutorOn(label.getName()); } diff --git a/core/src/main/java/hudson/model/queue/Executables.java b/core/src/main/java/hudson/model/queue/Executables.java index 43530ed3a8ad..396133fe4d33 100644 --- a/core/src/main/java/hudson/model/queue/Executables.java +++ b/core/src/main/java/hudson/model/queue/Executables.java @@ -21,14 +21,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model.queue; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.model.Queue.Executable; - import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import edu.umd.cs.findbugs.annotations.CheckForNull; -import edu.umd.cs.findbugs.annotations.NonNull; /** * Convenience methods around {@link Executable}. @@ -36,13 +36,13 @@ * @author Kohsuke Kawaguchi */ public class Executables { - + /** * Due to the return type change in {@link Executable} in 1.377, the caller needs a special precaution now. * @param e Executable * @return Discovered subtask */ - public static @NonNull SubTask getParentOf(@NonNull Executable e) + public static @NonNull SubTask getParentOf(@NonNull Executable e) throws Error, RuntimeException { try { return e.getParent(); @@ -52,13 +52,13 @@ public class Executables { m.setAccessible(true); return (SubTask) m.invoke(e); } catch (IllegalAccessException x) { - throw (Error)new IllegalAccessError().initCause(x); + throw (Error) new IllegalAccessError().initCause(x); } catch (NoSuchMethodException x) { - throw (Error)new NoSuchMethodError().initCause(x); + throw (Error) new NoSuchMethodError().initCause(x); } catch (InvocationTargetException x) { Throwable y = x.getTargetException(); - if (y instanceof Error) throw (Error)y; - if (y instanceof RuntimeException) throw (RuntimeException)y; + if (y instanceof Error) throw (Error) y; + if (y instanceof RuntimeException) throw (RuntimeException) y; throw new Error(x); } } diff --git a/core/src/main/java/hudson/model/queue/FoldableAction.java b/core/src/main/java/hudson/model/queue/FoldableAction.java index acd23d2f17ff..4b368a2b9d15 100644 --- a/core/src/main/java/hudson/model/queue/FoldableAction.java +++ b/core/src/main/java/hudson/model/queue/FoldableAction.java @@ -21,12 +21,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model.queue; -import hudson.model.Queue.Task; import hudson.model.Action; import hudson.model.Queue; - +import hudson.model.Queue.Task; import java.util.List; /** diff --git a/core/src/main/java/hudson/model/queue/FutureImpl.java b/core/src/main/java/hudson/model/queue/FutureImpl.java index 171dccd03d37..f6bba013f2cc 100644 --- a/core/src/main/java/hudson/model/queue/FutureImpl.java +++ b/core/src/main/java/hudson/model/queue/FutureImpl.java @@ -21,20 +21,20 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model.queue; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.model.Executor; -import jenkins.model.Jenkins; import hudson.model.Queue; import hudson.model.Queue.Executable; import hudson.model.Queue.Task; import hudson.remoting.AsyncFutureImpl; - import java.util.HashSet; import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; -import edu.umd.cs.findbugs.annotations.NonNull; +import jenkins.model.Jenkins; /** * Created when {@link hudson.model.Queue.Item} is created so that the caller can track the progress of the task. @@ -60,10 +60,12 @@ public FutureImpl(Task task) { this.task = task; } + @Override public Future getStartCondition() { return start; } + @Override public Executable waitForStart() throws InterruptedException, ExecutionException { return getStartCondition().get(); } @@ -72,8 +74,8 @@ public Executable waitForStart() throws InterruptedException, ExecutionException public boolean cancel(boolean mayInterruptIfRunning) { Queue q = Jenkins.get().getQueue(); synchronized (this) { - if(!executors.isEmpty()) { - if(mayInterruptIfRunning) + if (!executors.isEmpty()) { + if (mayInterruptIfRunning) for (Executor e : executors) e.interrupt(); return mayInterruptIfRunning; diff --git a/core/src/main/java/hudson/model/queue/FutureLoad.java b/core/src/main/java/hudson/model/queue/FutureLoad.java index 90f8d237534b..1d3046d09288 100644 --- a/core/src/main/java/hudson/model/queue/FutureLoad.java +++ b/core/src/main/java/hudson/model/queue/FutureLoad.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model.queue; /** @@ -49,7 +50,8 @@ public FutureLoad(long startTime, long duration, int numExecutors) { this.duration = duration; } + @Override public String toString() { - return "startTime="+startTime+",#executors="+numExecutors+",duration="+duration; + return "startTime=" + startTime + ",#executors=" + numExecutors + ",duration=" + duration; } } diff --git a/core/src/main/java/hudson/model/queue/Latch.java b/core/src/main/java/hudson/model/queue/Latch.java index d6fe39a4a933..3479c0599c38 100644 --- a/core/src/main/java/hudson/model/queue/Latch.java +++ b/core/src/main/java/hudson/model/queue/Latch.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model.queue; import hudson.AbortException; @@ -36,7 +37,7 @@ */ class Latch { private final int n; - private int i=0; + private int i = 0; /** * If the synchronization on the latch is aborted/interrupted, * point to the stack trace where that happened. If null, @@ -55,7 +56,7 @@ class Latch { public synchronized void abort(Throwable cause) { interrupted = new AbortException(); - if (cause!=null) + if (cause != null) interrupted.initCause(cause); notifyAll(); } @@ -64,8 +65,7 @@ public synchronized void abort(Throwable cause) { * Waits for N threads to enter the {@link #synchronize()} method, then * returns. * - * @return - * returns normally if N threads successfully synchronized. + * returns normally if N threads successfully synchronized. * @throws InterruptedException * if any of the threads that were synchronizing get interrupted, * or if the {@link #abort(Throwable)} is called. @@ -80,15 +80,15 @@ public synchronized void synchronize() throws InterruptedException { throw e; } - check(n*2); + check(n * 2); } private void check(int threshold) throws InterruptedException { i++; - if (i==threshold) { + if (i == threshold) { notifyAll(); } else { - while (i predict(MappingWorksheet plan, Computer computer, long start, long end) { // maintain backward compatibility by calling the old signature. - return predict(computer,start,end); + return predict(computer, start, end); } /** @@ -97,9 +97,9 @@ public Iterable predict(MappingWorksheet plan, final Computer comput if (e.isIdle()) continue; long eta = e.getEstimatedRemainingTimeMillis(); - long end = eta<0 ? eternity : now + eta; // when does this task end? + long end = eta < 0 ? eternity : now + eta; // when does this task end? if (end < start) continue; // should be over by the 'start' time. - fl.add(new FutureLoad(start, end-start, 1)); + fl.add(new FutureLoad(start, end - start, 1)); } return fl; } diff --git a/core/src/main/java/hudson/model/queue/MappingWorksheet.java b/core/src/main/java/hudson/model/queue/MappingWorksheet.java index 1a1d9032414c..54829ec0dac2 100644 --- a/core/src/main/java/hudson/model/queue/MappingWorksheet.java +++ b/core/src/main/java/hudson/model/queue/MappingWorksheet.java @@ -21,9 +21,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model.queue; -import com.google.common.collect.ImmutableList; +import static java.lang.Math.max; + import com.google.common.collect.Iterables; import hudson.model.Computer; import hudson.model.Executor; @@ -37,17 +39,14 @@ import hudson.model.Queue.Task; import hudson.model.labels.LabelAssignmentAction; import hudson.security.ACL; - import java.util.AbstractList; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.Map.Entry; - -import static java.lang.Math.*; /** * Defines a mapping problem for answering "where do we execute this task?" @@ -100,10 +99,12 @@ private static class ReadOnlyList extends AbstractList { this.base = base; } + @Override public E get(int index) { return base.get(index); } + @Override public int size() { return base.size(); } @@ -128,10 +129,10 @@ private ExecutorChunk(List base, int index) { * Is this executor chunk and the given work chunk compatible? Can the latter be run on the former? */ public boolean canAccept(WorkChunk c) { - if (this.size() { public final int index; - // the main should be always at position 0 -// /** -// * This chunk includes {@linkplain WorkUnit#isMainWork() the main work unit}. -// */ -// public final boolean isMain; - /** * If this task needs to be run on a node with a particular label, * return that {@link Label}. Otherwise null, indicating @@ -201,7 +196,7 @@ private WorkChunk(List base, int index) { Node lbo = base.get(0).getLastBuiltOn(); for (ExecutorChunk ec : executors) { - if (ec.node==lbo) { + if (ec.node == lbo) { lastBuiltOn = ec; return; } @@ -212,7 +207,7 @@ private WorkChunk(List base, int index) { private Label getAssignedLabel(SubTask task) { for (LabelAssignmentAction laa : item.getActions(LabelAssignmentAction.class)) { Label l = laa.getAssignedLabel(task); - if (l!=null) return l; + if (l != null) return l; } return task.getAssignedLabel(); } @@ -269,10 +264,10 @@ public int size() { /** * Returns the assignment as a map. */ - public Map toMap() { - Map r = new HashMap<>(); - for (int i=0; i toMap() { + Map r = new HashMap<>(); + for (int i = 0; i < size(); i++) + r.put(get(i), assigned(i)); return r; } @@ -281,9 +276,9 @@ public Map toMap() { */ public boolean isPartiallyValid() { int[] used = new int[executors.size()]; - for (int i=0; i ec.capacity()) @@ -297,7 +292,7 @@ public boolean isPartiallyValid() { */ public boolean isCompletelyValid() { for (ExecutorChunk ec : mapping) - if (ec==null) return false; // unassigned + if (ec == null) return false; // unassigned return isPartiallyValid(); } @@ -309,31 +304,31 @@ public void execute(WorkUnitContext wuc) { if (!isCompletelyValid()) throw new IllegalStateException(); - for (int i=0; i offers) { - this(item,offers,LoadPredictor.all()); + this(item, offers, LoadPredictor.all()); } public MappingWorksheet(BuildableItem item, List offers, Collection loadPredictors) { this.item = item; - + // group executors by their computers - Map> j = new HashMap<>(); + Map> j = new HashMap<>(); for (ExecutorSlot o : offers) { Computer c = o.getExecutor().getOwner(); List l = j.computeIfAbsent(c, k -> new ArrayList<>()); l.add(o); } - {// take load prediction into account and reduce the available executor pool size accordingly + { // take load prediction into account and reduce the available executor pool size accordingly long duration = item.task.getEstimatedDuration(); if (duration > 0) { long now = System.currentTimeMillis(); - for (Entry> e : j.entrySet()) { + for (Map.Entry> e : j.entrySet()) { final List list = e.getValue(); final int max = e.getKey().countExecutors(); @@ -342,20 +337,20 @@ public MappingWorksheet(BuildableItem item, List offers, int peak = 0; OUTER: for (LoadPredictor lp : loadPredictors) { - for (FutureLoad fl : Iterables.limit(lp.predict(this,e.getKey(), now, now + duration),100)) { - peak = max(peak,timeline.insert(fl.startTime, fl.startTime+fl.duration, fl.numExecutors)); - if (peak>=max) break OUTER; + for (FutureLoad fl : Iterables.limit(lp.predict(this, e.getKey(), now, now + duration), 100)) { + peak = max(peak, timeline.insert(fl.startTime, fl.startTime + fl.duration, fl.numExecutors)); + if (peak >= max) break OUTER; } } - int minIdle = max-peak; // minimum number of idle nodes during this time period + int minIdle = max - peak; // minimum number of idle nodes during this time period // total predicted load could exceed available executors [JENKINS-8882] - if (minIdle<0) { + if (minIdle < 0) { // Should we toss a warning/info message? minIdle = 0; } - if (minIdle offers, for (List group : j.values()) { if (group.isEmpty()) continue; // evict empty group ExecutorChunk ec = new ExecutorChunk(group, executors.size()); - if (ec.node==null) continue; // evict out of sync node + if (ec.node == null) continue; // evict out of sync node executors.add(ec); } - this.executors = ImmutableList.copyOf(executors); + this.executors = Collections.unmodifiableList(executors); // group execution units into chunks. use of LinkedHashMap ensures that the main work comes at the top - Map> m = new LinkedHashMap<>(); + Map> m = new LinkedHashMap<>(); for (SubTask meu : item.task.getSubTasks()) { Object c = meu.getSameNodeConstraint(); - if (c==null) c = new Object(); + if (c == null) c = new Object(); List l = m.computeIfAbsent(c, k -> new ArrayList<>()); l.add(meu); @@ -383,9 +378,9 @@ public MappingWorksheet(BuildableItem item, List offers, // build into the final shape List works = new ArrayList<>(); for (List group : m.values()) { - works.add(new WorkChunk(group,works.size())); + works.add(new WorkChunk(group, works.size())); } - this.works = ImmutableList.copyOf(works); + this.works = Collections.unmodifiableList(works); } public WorkChunk works(int index) { diff --git a/core/src/main/java/hudson/model/queue/QueueListener.java b/core/src/main/java/hudson/model/queue/QueueListener.java index 4bd57da2e463..761f41de5b3f 100644 --- a/core/src/main/java/hudson/model/queue/QueueListener.java +++ b/core/src/main/java/hudson/model/queue/QueueListener.java @@ -9,7 +9,6 @@ import hudson.model.Queue.Item; import hudson.model.Queue.LeftItem; import hudson.model.Queue.WaitingItem; - import java.util.concurrent.Executor; /** diff --git a/core/src/main/java/hudson/model/queue/QueueSorter.java b/core/src/main/java/hudson/model/queue/QueueSorter.java index 6c9d86524079..939d1c6fdff5 100644 --- a/core/src/main/java/hudson/model/queue/QueueSorter.java +++ b/core/src/main/java/hudson/model/queue/QueueSorter.java @@ -1,18 +1,17 @@ package hudson.model.queue; +import static hudson.init.InitMilestone.JOB_CONFIG_ADAPTED; + import hudson.ExtensionList; import hudson.ExtensionPoint; import hudson.init.Initializer; -import jenkins.model.Jenkins; import hudson.model.LoadBalancer; import hudson.model.Queue; import hudson.model.Queue.BuildableItem; - import java.util.Comparator; import java.util.List; import java.util.logging.Logger; - -import static hudson.init.InitMilestone.JOB_CONFIG_ADAPTED; +import jenkins.model.Jenkins; /** * Singleton extension point for sorting buildable items @@ -27,12 +26,7 @@ public abstract class QueueSorter implements ExtensionPoint { * * @since 1.618 */ - public static final Comparator DEFAULT_BLOCKED_ITEM_COMPARATOR = new Comparator() { - @Override - public int compare(Queue.BlockedItem o1, Queue.BlockedItem o2) { - return Long.compare(o1.getInQueueSince(), o2.getInQueueSince()); - } - }; + public static final Comparator DEFAULT_BLOCKED_ITEM_COMPARATOR = Comparator.comparingLong(Queue.Item::getInQueueSince); /** * Sorts the buildable items list. The items at the beginning will be executed @@ -68,17 +62,17 @@ public static ExtensionList all() { * * {@link Queue#Queue(LoadBalancer)} is too early to do this */ - @Initializer(after=JOB_CONFIG_ADAPTED) + @Initializer(after = JOB_CONFIG_ADAPTED) public static void installDefaultQueueSorter() { ExtensionList all = all(); if (all.isEmpty()) return; Queue q = Jenkins.get().getQueue(); - if (q.getSorter()!=null) return; // someone has already installed something. leave that alone. + if (q.getSorter() != null) return; // someone has already installed something. leave that alone. q.setSorter(all.get(0)); - if (all.size()>1) - LOGGER.warning("Multiple QueueSorters are registered. Only the first one is used and the rest are ignored: "+all); + if (all.size() > 1) + LOGGER.warning("Multiple QueueSorters are registered. Only the first one is used and the rest are ignored: " + all); } private static final Logger LOGGER = Logger.getLogger(QueueSorter.class.getName()); diff --git a/core/src/main/java/hudson/model/queue/QueueTaskDispatcher.java b/core/src/main/java/hudson/model/queue/QueueTaskDispatcher.java index dc1fd3d2eabf..9b51bedb36a8 100644 --- a/core/src/main/java/hudson/model/queue/QueueTaskDispatcher.java +++ b/core/src/main/java/hudson/model/queue/QueueTaskDispatcher.java @@ -24,16 +24,15 @@ package hudson.model.queue; +import edu.umd.cs.findbugs.annotations.CheckForNull; import hudson.Extension; import hudson.ExtensionList; import hudson.ExtensionPoint; -import hudson.slaves.Cloud; import hudson.model.Node; import hudson.model.Queue; import hudson.model.Queue.BuildableItem; import hudson.model.Queue.Task; - -import edu.umd.cs.findbugs.annotations.CheckForNull; +import hudson.slaves.Cloud; /** * Vetos the execution of a task on a node @@ -99,7 +98,7 @@ public abstract class QueueTaskDispatcher implements ExtensionPoint { * @since 1.413 */ public @CheckForNull CauseOfBlockage canTake(Node node, BuildableItem item) { - return canTake(node,item.task); // backward compatible behaviour + return canTake(node, item.task); // backward compatible behaviour } /** diff --git a/core/src/main/java/hudson/model/queue/QueueTaskFilter.java b/core/src/main/java/hudson/model/queue/QueueTaskFilter.java index 84751032edaf..e2a113dfaa59 100644 --- a/core/src/main/java/hudson/model/queue/QueueTaskFilter.java +++ b/core/src/main/java/hudson/model/queue/QueueTaskFilter.java @@ -24,16 +24,15 @@ package hudson.model.queue; +import edu.umd.cs.findbugs.annotations.CheckForNull; import hudson.model.Label; import hudson.model.Node; import hudson.model.Queue; import hudson.model.Queue.Executable; import hudson.model.Queue.Task; import hudson.model.ResourceList; - import java.io.IOException; import java.util.Collection; -import edu.umd.cs.findbugs.annotations.CheckForNull; /** * Base class for defining filter {@link hudson.model.Queue.Task}. @@ -75,10 +74,12 @@ public CauseOfBlockage getCauseOfBlockage() { return base.getCauseOfBlockage(); } + @Override public String getName() { return base.getName(); } + @Override public String getFullDisplayName() { return base.getFullDisplayName(); } @@ -88,18 +89,22 @@ public long getEstimatedDuration() { return base.getEstimatedDuration(); } + @Override public @CheckForNull Executable createExecutable() throws IOException { return base.createExecutable(); } + @Override public void checkAbortPermission() { base.checkAbortPermission(); } + @Override public boolean hasAbortPermission() { return base.hasAbortPermission(); } + @Override public String getUrl() { return base.getUrl(); } @@ -109,6 +114,7 @@ public boolean isConcurrentBuild() { return base.isConcurrentBuild(); } + @Override public String getDisplayName() { return base.getDisplayName(); } diff --git a/core/src/main/java/hudson/model/queue/QueueTaskFuture.java b/core/src/main/java/hudson/model/queue/QueueTaskFuture.java index 7a00967ce34c..5e81eb4c0f5a 100644 --- a/core/src/main/java/hudson/model/queue/QueueTaskFuture.java +++ b/core/src/main/java/hudson/model/queue/QueueTaskFuture.java @@ -1,7 +1,6 @@ package hudson.model.queue; import hudson.model.Queue.Executable; - import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; diff --git a/core/src/main/java/hudson/model/queue/ScheduleResult.java b/core/src/main/java/hudson/model/queue/ScheduleResult.java index 82b6e6df2a89..ed43b651917e 100644 --- a/core/src/main/java/hudson/model/queue/ScheduleResult.java +++ b/core/src/main/java/hudson/model/queue/ScheduleResult.java @@ -1,11 +1,11 @@ package hudson.model.queue; +import edu.umd.cs.findbugs.annotations.CheckForNull; import hudson.model.Action; import hudson.model.Queue; import hudson.model.Queue.Item; import hudson.model.Queue.Task; import hudson.model.Queue.WaitingItem; -import edu.umd.cs.findbugs.annotations.CheckForNull; /** * Result of {@link Queue#schedule2} @@ -58,6 +58,7 @@ public final boolean isAccepted() { public static final class Created extends ScheduleResult { private final WaitingItem item; + private Created(WaitingItem item) { this.item = item; } diff --git a/core/src/main/java/hudson/model/queue/SubTask.java b/core/src/main/java/hudson/model/queue/SubTask.java index f16931759f75..98c9e0bacbaf 100644 --- a/core/src/main/java/hudson/model/queue/SubTask.java +++ b/core/src/main/java/hudson/model/queue/SubTask.java @@ -21,8 +21,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model.queue; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.model.AbstractProject; import hudson.model.Executor; import hudson.model.Label; @@ -30,10 +33,7 @@ import hudson.model.Queue.Executable; import hudson.model.Queue.Task; import hudson.model.ResourceActivity; - -import edu.umd.cs.findbugs.annotations.NonNull; import java.io.IOException; -import edu.umd.cs.findbugs.annotations.CheckForNull; /** * A component of {@link Task} that represents a computation carried out by a single {@link Executor}. diff --git a/core/src/main/java/hudson/model/queue/SubTaskContributor.java b/core/src/main/java/hudson/model/queue/SubTaskContributor.java index 313b863601c4..72bfb80a397a 100644 --- a/core/src/main/java/hudson/model/queue/SubTaskContributor.java +++ b/core/src/main/java/hudson/model/queue/SubTaskContributor.java @@ -21,13 +21,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model.queue; import hudson.Extension; import hudson.ExtensionList; import hudson.ExtensionPoint; import hudson.model.AbstractProject; - import java.util.Collection; import java.util.Collections; @@ -41,7 +41,7 @@ * @since 1.377 */ public abstract class SubTaskContributor implements ExtensionPoint { - public Collection forProject(AbstractProject p) { + public Collection forProject(AbstractProject p) { return Collections.emptyList(); } diff --git a/core/src/main/java/hudson/model/queue/Tasks.java b/core/src/main/java/hudson/model/queue/Tasks.java index af26411c29ce..fe007200f1b4 100644 --- a/core/src/main/java/hudson/model/queue/Tasks.java +++ b/core/src/main/java/hudson/model/queue/Tasks.java @@ -21,14 +21,15 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model.queue; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.model.Queue; import hudson.model.Queue.Item; import hudson.model.Queue.Task; -import edu.umd.cs.findbugs.annotations.CheckForNull; import java.util.Collection; -import edu.umd.cs.findbugs.annotations.NonNull; import jenkins.security.QueueItemAuthenticator; import jenkins.security.QueueItemAuthenticatorProvider; import org.springframework.security.core.Authentication; @@ -53,7 +54,7 @@ public static Object getSameNodeConstraintOf(SubTask t) { return t.getSameNodeConstraint(); } - /** deprecated call {@link SubTask#getOwnerTask} directly */ + /** @deprecated call {@link SubTask#getOwnerTask} directly */ @Deprecated public static @NonNull Task getOwnerTaskOf(@NonNull SubTask t) { return t.getOwnerTask(); @@ -76,7 +77,7 @@ public static hudson.model.Item getItemOf(@NonNull SubTask t) { } p = o; } - return p instanceof hudson.model.Item ? (hudson.model.Item)p : null; + return p instanceof hudson.model.Item ? (hudson.model.Item) p : null; } /** @deprecated call {@link Queue.Task#getDefaultAuthentication()} directly */ diff --git a/core/src/main/java/hudson/model/queue/Timeline.java b/core/src/main/java/hudson/model/queue/Timeline.java index 43da59fc68ee..ee7c4d54deef 100644 --- a/core/src/main/java/hudson/model/queue/Timeline.java +++ b/core/src/main/java/hudson/model/queue/Timeline.java @@ -21,14 +21,15 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model.queue; +import static java.lang.Math.max; + import java.util.Map; import java.util.SortedMap; import java.util.TreeMap; -import static java.lang.Math.*; - /** * Represents a mutable q(t), a discrete value that changes over the time. * @@ -44,7 +45,7 @@ final class Timeline { * Obtains q(t) for the given t. */ private int at(long t) { - SortedMap head = data.subMap(t,Long.MAX_VALUE); + SortedMap head = data.subMap(t, Long.MAX_VALUE); if (head.isEmpty()) return 0; return data.get(head.firstKey())[0]; } @@ -104,16 +105,16 @@ Long fit(long start, long duration, int n) { while (true) { long t = start; // check if 'start' satisfies the two conditions by moving t across [start,start+duration) - while ((t-start)n) { + while (t - start < duration) { + if (at(t) > n) { // value too big. what's the next t that's worth trying? Long nxt = next(t); - if (nxt==null) return null; + if (nxt == null) return null; start = nxt; continue OUTER; } else { Long nxt = next(t); - if (nxt==null) t = Long.MAX_VALUE; + if (nxt == null) t = Long.MAX_VALUE; else t = nxt; } } diff --git a/core/src/main/java/hudson/model/queue/WorkUnit.java b/core/src/main/java/hudson/model/queue/WorkUnit.java index 541485b8adbf..8c2924b49ba5 100644 --- a/core/src/main/java/hudson/model/queue/WorkUnit.java +++ b/core/src/main/java/hudson/model/queue/WorkUnit.java @@ -21,13 +21,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model.queue; +import edu.umd.cs.findbugs.annotations.CheckForNull; import hudson.model.Executor; import hudson.model.Queue; import hudson.model.Queue.Executable; import hudson.model.Queue.Task; -import edu.umd.cs.findbugs.annotations.CheckForNull; import hudson.model.Run; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; @@ -98,14 +99,14 @@ public void setExecutable(Executable executable) { * represented by {@link Task} itself. */ public boolean isMainWork() { - return context.task==work; + return context.task == work; } @Override public String toString() { - if (work==context.task) - return super.toString()+"[work="+context.task.getFullDisplayName()+"]"; + if (work == context.task) + return super.toString() + "[work=" + context.task.getFullDisplayName() + "]"; else - return super.toString()+"[work="+work+",context.task="+context.task.getFullDisplayName()+"]"; + return super.toString() + "[work=" + work + ",context.task=" + context.task.getFullDisplayName() + "]"; } } diff --git a/core/src/main/java/hudson/model/queue/WorkUnitContext.java b/core/src/main/java/hudson/model/queue/WorkUnitContext.java index 1196c32ec04d..31829ba7dd1f 100644 --- a/core/src/main/java/hudson/model/queue/WorkUnitContext.java +++ b/core/src/main/java/hudson/model/queue/WorkUnitContext.java @@ -21,19 +21,24 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.model.queue; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import hudson.ExtensionList; import hudson.model.Action; import hudson.model.Executor; +import hudson.model.ExecutorListener; import hudson.model.Queue; import hudson.model.Queue.BuildableItem; import hudson.model.Queue.Task; -import org.kohsuke.accmod.Restricted; -import org.kohsuke.accmod.restrictions.NoExternalUse; - import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; /** * Holds the information shared between {@link WorkUnit}s created from the same {@link Task}. @@ -42,6 +47,8 @@ */ public final class WorkUnitContext { + private static final Logger LOGGER = Logger.getLogger(WorkUnitContext.class.getName()); + public final BuildableItem item; public final Task task; @@ -68,12 +75,13 @@ public final class WorkUnitContext { public WorkUnitContext(BuildableItem item) { this.item = item; this.task = item.task; - this.future = (FutureImpl)item.getFuture(); + this.future = (FutureImpl) item.getFuture(); // JENKINS-51584 do not use item.getAllActions() here. this.actions = new ArrayList<>(item.getActions()); // +1 for the main task int workUnitSize = task.getSubTasks().size(); startLatch = new Latch(workUnitSize) { + @SuppressFBWarnings(value = "NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE", justification = "TODO needs triage") @Override protected void onCriteriaMet() { // on behalf of the member Executors, @@ -81,7 +89,14 @@ protected void onCriteriaMet() { // Unclear if this will work with AsynchronousExecution; it *seems* this is only called from synchronize which is only called from synchronizeStart which is only called from an executor thread. Executor e = Executor.currentExecutor(); if (e.getCurrentWorkUnit().isMainWork()) { - e.getOwner().taskAccepted(e,task); + e.getOwner().taskAccepted(e, task); + for (ExecutorListener listener : ExtensionList.lookup(ExecutorListener.class)) { + try { + listener.taskAccepted(e, task); + } catch (RuntimeException x) { + LOGGER.log(Level.WARNING, null, x); + } + } } } }; @@ -121,6 +136,13 @@ public void synchronizeStart() throws InterruptedException { WorkUnit wu = e.getCurrentWorkUnit(); if (wu.isMainWork()) { future.start.set(e.getCurrentExecutable()); + for (ExecutorListener listener : ExtensionList.lookup(ExecutorListener.class)) { + try { + listener.taskStarted(e, task); + } catch (RuntimeException x) { + LOGGER.log(Level.WARNING, null, x); + } + } } } } @@ -139,7 +161,7 @@ public void synchronizeEnd(Queue.Executable executable, Throwable problems, long */ @Restricted(NoExternalUse.class) public void synchronizeEnd(Executor e, Queue.Executable executable, Throwable problems, long duration) throws InterruptedException { - // Let code waiting for the build to finish (future.get()) finishes when there is a faulty SubTask by setting + // Let code waiting for the build to finish (future.get()) finishes when there is a faulty SubTask by setting // the future always. try { endLatch.synchronize(); @@ -150,9 +172,23 @@ public void synchronizeEnd(Executor e, Queue.Executable executable, Throwable pr if (problems == null) { future.set(executable); e.getOwner().taskCompleted(e, task, duration); + for (ExecutorListener listener : ExtensionList.lookup(ExecutorListener.class)) { + try { + listener.taskCompleted(e, task, duration); + } catch (RuntimeException x) { + LOGGER.log(Level.WARNING, null, x); + } + } } else { future.set(problems); e.getOwner().taskCompletedWithProblems(e, task, duration, problems); + for (ExecutorListener listener : ExtensionList.lookup(ExecutorListener.class)) { + try { + listener.taskCompletedWithProblems(e, task, duration, problems); + } catch (RuntimeException x) { + LOGGER.log(Level.WARNING, null, x); + } + } } } } @@ -162,8 +198,8 @@ public void synchronizeEnd(Executor e, Queue.Executable executable, Throwable pr * When one of the work unit is aborted, call this method to abort all the other work units. */ public synchronized void abort(Throwable cause) { - if (cause==null) throw new IllegalArgumentException(); - if (aborted!=null) return; // already aborted + if (cause == null) throw new IllegalArgumentException(); + if (aborted != null) return; // already aborted aborted = cause; startLatch.abort(cause); endLatch.abort(cause); @@ -171,7 +207,7 @@ public synchronized void abort(Throwable cause) { Thread c = Thread.currentThread(); for (WorkUnit wu : workUnits) { Executor e = wu.getExecutor(); - if (e!=null && e!=c) + if (e != null && e != c) e.interrupt(); } } diff --git a/core/src/main/java/hudson/node_monitors/AbstractAsyncNodeMonitorDescriptor.java b/core/src/main/java/hudson/node_monitors/AbstractAsyncNodeMonitorDescriptor.java index b7f2ab15ff0c..8e46a3705718 100644 --- a/core/src/main/java/hudson/node_monitors/AbstractAsyncNodeMonitorDescriptor.java +++ b/core/src/main/java/hudson/node_monitors/AbstractAsyncNodeMonitorDescriptor.java @@ -1,14 +1,15 @@ package hudson.node_monitors; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.logging.Level.WARNING; + +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.Functions; import hudson.model.Computer; import hudson.remoting.Callable; import hudson.remoting.VirtualChannel; import hudson.slaves.SlaveComputer; -import jenkins.model.Jenkins; - -import edu.umd.cs.findbugs.annotations.CheckForNull; -import edu.umd.cs.findbugs.annotations.NonNull; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; @@ -16,15 +17,12 @@ import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Map.Entry; import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeoutException; import java.util.logging.Logger; - -import static java.util.concurrent.TimeUnit.MILLISECONDS; -import static java.util.logging.Level.WARNING; +import jenkins.model.Jenkins; /** * Sophisticated version of {@link AbstractNodeMonitorDescriptor} that @@ -53,14 +51,14 @@ protected AbstractAsyncNodeMonitorDescriptor(Class clazz, /** * Creates a {@link Callable} that performs the monitoring when executed. */ - protected abstract @CheckForNull Callable createCallable(Computer c); + protected abstract @CheckForNull Callable createCallable(Computer c); @Override protected T monitor(Computer c) throws IOException, InterruptedException { VirtualChannel ch = c.getChannel(); if (ch != null) { - Callable cc = createCallable(c); - if (cc!=null) + Callable cc = createCallable(c); + if (cc != null) return ch.call(cc); } return null; @@ -82,17 +80,17 @@ protected Map monitor() throws InterruptedException { * Perform monitoring with detailed reporting. */ protected final @NonNull Result monitorDetailed() throws InterruptedException { - Map> futures = new HashMap<>(); + Map> futures = new HashMap<>(); Set skipped = new HashSet<>(); for (Computer c : Jenkins.get().getComputers()) { try { VirtualChannel ch = c.getChannel(); - futures.put(c,null); // sentinel value - if (ch!=null) { + futures.put(c, null); // sentinel value + if (ch != null) { Callable cc = createCallable(c); - if (cc!=null) - futures.put(c,ch.callAsync(cc)); + if (cc != null) + futures.put(c, ch.callAsync(cc)); } } catch (RuntimeException | IOException e) { error(c, e); @@ -102,16 +100,16 @@ protected Map monitor() throws InterruptedException { final long now = System.currentTimeMillis(); final long end = now + getMonitoringTimeOut(); - final Map data = new HashMap<>(); + final Map data = new HashMap<>(); - for (Entry> e : futures.entrySet()) { + for (Map.Entry> e : futures.entrySet()) { Computer c = e.getKey(); Future f = futures.get(c); data.put(c, null); // sentinel value - if (f!=null) { + if (f != null) { try { - data.put(c,f.get(Math.max(0,end-System.currentTimeMillis()), MILLISECONDS)); + data.put(c, f.get(Math.max(0, end - System.currentTimeMillis()), MILLISECONDS)); } catch (RuntimeException | TimeoutException | ExecutionException x) { error(c, x); } diff --git a/core/src/main/java/hudson/node_monitors/AbstractDiskSpaceMonitor.java b/core/src/main/java/hudson/node_monitors/AbstractDiskSpaceMonitor.java index 58a59312efcf..38230dd80f91 100644 --- a/core/src/main/java/hudson/node_monitors/AbstractDiskSpaceMonitor.java +++ b/core/src/main/java/hudson/node_monitors/AbstractDiskSpaceMonitor.java @@ -2,12 +2,10 @@ import hudson.model.Computer; import hudson.node_monitors.DiskSpaceMonitorDescriptor.DiskSpace; - -import org.kohsuke.accmod.Restricted; -import org.kohsuke.accmod.restrictions.NoExternalUse; - import java.text.ParseException; import java.util.logging.Logger; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; /** * @author Kohsuke Kawaguchi @@ -20,17 +18,17 @@ public abstract class AbstractDiskSpaceMonitor extends NodeMonitor { */ public final String freeSpaceThreshold; - public AbstractDiskSpaceMonitor(String threshold) throws ParseException { + protected AbstractDiskSpaceMonitor(String threshold) throws ParseException { this.freeSpaceThreshold = threshold; DiskSpace.parse(threshold); // make sure it parses } - public AbstractDiskSpaceMonitor() { + protected AbstractDiskSpaceMonitor() { this.freeSpaceThreshold = "1GB"; } public long getThresholdBytes() { - if (freeSpaceThreshold==null) + if (freeSpaceThreshold == null) return DEFAULT_THRESHOLD; // backward compatibility with the data format that didn't have 'freeSpaceThreshold' try { return DiskSpace.parse(freeSpaceThreshold).size; @@ -41,12 +39,12 @@ public long getThresholdBytes() { @Override public Object data(Computer c) { - DiskSpace size = markNodeOfflineIfDiskspaceIsTooLow(c); - - // mark online (again), if free space is over threshold - if(size!=null && size.size > getThresholdBytes() && c.isOffline() && c.getOfflineCause() instanceof DiskSpace) - if(this.getClass().equals(((DiskSpace)c.getOfflineCause()).getTrigger())) - if(getDescriptor().markOnline(c)) { + DiskSpace size = markNodeOfflineIfDiskspaceIsTooLow(c); + + // mark online (again), if free space is over threshold + if (size != null && size.size > getThresholdBytes() && c.isOffline() && c.getOfflineCause() instanceof DiskSpace) + if (this.getClass().equals(((DiskSpace) c.getOfflineCause()).getTrigger())) + if (getDescriptor().markOnline(c)) { LOGGER.info(Messages.DiskSpaceMonitor_MarkedOnline(c.getDisplayName())); } return size; @@ -61,15 +59,15 @@ public Object data(Computer c) { @Restricted(NoExternalUse.class) public DiskSpace markNodeOfflineIfDiskspaceIsTooLow(Computer c) { DiskSpace size = (DiskSpace) super.data(c); - if(size!=null && size.size < getThresholdBytes()) { - size.setTriggered(this.getClass(), true); - if(getDescriptor().markOffline(c,size)) { - LOGGER.warning(Messages.DiskSpaceMonitor_MarkedOffline(c.getDisplayName())); - } + if (size != null && size.size < getThresholdBytes()) { + size.setTriggered(this.getClass(), true); + if (getDescriptor().markOffline(c, size)) { + LOGGER.warning(Messages.DiskSpaceMonitor_MarkedOffline(c.getDisplayName())); + } } return size; } private static final Logger LOGGER = Logger.getLogger(AbstractDiskSpaceMonitor.class.getName()); - private static final long DEFAULT_THRESHOLD = 1024L*1024*1024; + private static final long DEFAULT_THRESHOLD = 1024L * 1024 * 1024; } diff --git a/core/src/main/java/hudson/node_monitors/AbstractNodeMonitorDescriptor.java b/core/src/main/java/hudson/node_monitors/AbstractNodeMonitorDescriptor.java index 7410251f4250..4a2386c2a1b1 100644 --- a/core/src/main/java/hudson/node_monitors/AbstractNodeMonitorDescriptor.java +++ b/core/src/main/java/hudson/node_monitors/AbstractNodeMonitorDescriptor.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,20 +21,16 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.node_monitors; import hudson.Util; +import hudson.model.AdministrativeMonitor; import hudson.model.Computer; -import hudson.model.Descriptor; -import jenkins.model.Jenkins; import hudson.model.ComputerSet; -import hudson.model.AdministrativeMonitor; -import hudson.triggers.SafeTimerTask; +import hudson.model.Descriptor; import hudson.slaves.OfflineCause; -import jenkins.util.SystemProperties; -import jenkins.util.Timer; - -import net.jcip.annotations.GuardedBy; +import hudson.triggers.SafeTimerTask; import java.io.IOException; import java.util.Collections; import java.util.Date; @@ -43,6 +39,10 @@ import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; +import jenkins.model.Jenkins; +import jenkins.util.SystemProperties; +import jenkins.util.Timer; +import net.jcip.annotations.GuardedBy; /** * Convenient base class for common {@link NodeMonitor} implementation @@ -97,6 +97,7 @@ protected AbstractNodeMonitorDescriptor(Class clazz, long private void schedule(long interval) { Timer.get() .scheduleAtFixedRate(new SafeTimerTask() { + @Override public void doRun() { triggerUpdate(); } @@ -134,7 +135,7 @@ public void doRun() { * whereas {@link IOException} is useful for indicating a hard error that needs to be * corrected. */ - protected abstract T monitor(Computer c) throws IOException,InterruptedException; + protected abstract T monitor(Computer c) throws IOException, InterruptedException; /** * Performs monitoring across the board. @@ -142,20 +143,20 @@ public void doRun() { * @return * For all the computers, report the monitored values. */ - protected Map monitor() throws InterruptedException { - Map data = new HashMap<>(); - for( Computer c : Jenkins.get().getComputers() ) { + protected Map monitor() throws InterruptedException { + Map data = new HashMap<>(); + for (Computer c : Jenkins.get().getComputers()) { try { - Thread.currentThread().setName("Monitoring "+c.getDisplayName()+" for "+getDisplayName()); + Thread.currentThread().setName("Monitoring " + c.getDisplayName() + " for " + getDisplayName()); - if(c.getChannel()==null) - data.put(c,null); + if (c.getChannel() == null) + data.put(c, null); else - data.put(c,monitor(c)); + data.put(c, monitor(c)); } catch (RuntimeException | IOException e) { - LOGGER.log(Level.WARNING, "Failed to monitor "+c.getDisplayName()+" for "+getDisplayName(), e); + LOGGER.log(Level.WARNING, "Failed to monitor " + c.getDisplayName() + " for " + getDisplayName(), e); } catch (InterruptedException e) { - throw (InterruptedException)new InterruptedException("Node monitoring "+c.getDisplayName()+" for "+getDisplayName()+" aborted.").initCause(e); + throw (InterruptedException) new InterruptedException("Node monitoring " + c.getDisplayName() + " for " + getDisplayName() + " aborted.").initCause(e); } } return data; @@ -168,7 +169,7 @@ protected Map monitor() throws InterruptedException { * If no data is available, a background task to collect data will be started. */ public T get(Computer c) { - if(record==null || !record.data.containsKey(c)) { + if (record == null || !record.data.containsKey(c)) { // if we don't have the data, schedule the check now triggerUpdate(); return null; @@ -180,22 +181,20 @@ public T get(Computer c) { * Is the monitoring activity currently in progress? */ private synchronized boolean isInProgress() { - return inProgress !=null && inProgress.isAlive(); + return inProgress != null && inProgress.isAlive(); } /** * The timestamp that indicates when the last round of the monitoring has completed. */ public long getTimestamp() { - return record==null ? 0L : record.timestamp; + return record == null ? 0L : record.timestamp; } public String getTimestampString() { - if (record==null) + if (record == null) return Messages.AbstractNodeMonitorDescriptor_NoDataYet(); -// return Messages.AbstractNodeMonitorDescriptor_DataObtainedSometimeAgo( -// Util.getTimeSpanString(System.currentTimeMillis()-record.timestamp)); - return Util.getTimeSpanString(System.currentTimeMillis()-record.timestamp); + return Util.getTimeSpanString(System.currentTimeMillis() - record.timestamp); } /** @@ -203,22 +202,22 @@ public String getTimestampString() { */ public boolean isIgnored() { NodeMonitor m = ComputerSet.getMonitors().get(this); - return m==null || m.isIgnored(); + return m == null || m.isIgnored(); } /** * Utility method to mark the computer online for derived classes. - * - * @return true + * + * @return true * if the node was actually taken online by this act (as opposed to us deciding not to do it, * or the computer was already online.) */ protected boolean markOnline(Computer c) { - if(isIgnored() || c.isOnline()) return false; // noop - c.setTemporarilyOffline(false,null); + if (isIgnored() || c.isOnline()) return false; // noop + c.setTemporarilyOffline(false, null); return true; } - + /** * Utility method to mark the computer offline for derived classes. * @@ -227,13 +226,13 @@ protected boolean markOnline(Computer c) { * or the computer already marked offline.) */ protected boolean markOffline(Computer c, OfflineCause oc) { - if(isIgnored() || c.isTemporarilyOffline()) return false; // noop + if (isIgnored() || c.isTemporarilyOffline()) return false; // noop c.setTemporarilyOffline(true, oc); // notify the admin MonitorMarkedNodeOffline no = AdministrativeMonitor.all().get(MonitorMarkedNodeOffline.class); - if(no!=null) + if (no != null) no.active = true; return true; } @@ -244,7 +243,7 @@ protected boolean markOffline(Computer c, OfflineCause oc) { */ @Deprecated protected boolean markOffline(Computer c) { - return markOffline(c,null); + return markOffline(c, null); } /** @@ -290,12 +289,12 @@ private final class Record extends Thread { /** * Last computed monitoring result. */ - private /*final*/ Map data = Collections.emptyMap(); + private /*final*/ Map data = Collections.emptyMap(); private long timestamp; Record() { - super("Monitoring thread for "+getDisplayName()+" started on "+new Date()); + super("Monitoring thread for " + getDisplayName() + " started on " + new Date()); } @Override @@ -303,20 +302,20 @@ public void run() { try { long startTime = System.currentTimeMillis(); String oldName = getName(); - data=monitor(); + data = monitor(); setName(oldName); timestamp = System.currentTimeMillis(); record = this; - LOGGER.log(Level.FINE, "Node monitoring {0} completed in {1}ms", new Object[] {getDisplayName(), System.currentTimeMillis()-startTime}); + LOGGER.log(Level.FINE, "Node monitoring {0} completed in {1}ms", new Object[] {getDisplayName(), System.currentTimeMillis() - startTime}); } catch (InterruptedException x) { // interrupted by new one, fine } catch (Throwable t) { - LOGGER.log(Level.WARNING, "Unexpected node monitoring termination: "+getDisplayName(),t); + LOGGER.log(Level.WARNING, "Unexpected node monitoring termination: " + getDisplayName(), t); } finally { - synchronized(AbstractNodeMonitorDescriptor.this) { - if (inProgress==this) + synchronized (AbstractNodeMonitorDescriptor.this) { + if (inProgress == this) inProgress = null; } } diff --git a/core/src/main/java/hudson/node_monitors/ArchitectureMonitor.java b/core/src/main/java/hudson/node_monitors/ArchitectureMonitor.java index b2329f02db6a..b7e88d8e0eef 100644 --- a/core/src/main/java/hudson/node_monitors/ArchitectureMonitor.java +++ b/core/src/main/java/hudson/node_monitors/ArchitectureMonitor.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,18 +21,18 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.node_monitors; +import hudson.Extension; import hudson.model.Computer; import hudson.remoting.Callable; -import hudson.Extension; +import java.io.IOException; import jenkins.security.MasterToSlaveCallable; import net.sf.json.JSONObject; import org.jenkinsci.Symbol; import org.kohsuke.stapler.StaplerRequest; -import java.io.IOException; - /** * Discovers the architecture of the system to display in the agent list page. * @@ -60,11 +60,12 @@ public NodeMonitor newInstance(StaplerRequest req, JSONObject formData) throws F /** * Obtains the string that represents the architecture. */ - private static class GetArchTask extends MasterToSlaveCallable { + private static class GetArchTask extends MasterToSlaveCallable { + @Override public String call() { String os = System.getProperty("os.name"); String arch = System.getProperty("os.arch"); - return os+" ("+arch+')'; + return os + " (" + arch + ')'; } private static final long serialVersionUID = 1L; diff --git a/core/src/main/java/hudson/node_monitors/ClockMonitor.java b/core/src/main/java/hudson/node_monitors/ClockMonitor.java index 3050f2f2c315..6c7dc54f343d 100644 --- a/core/src/main/java/hudson/node_monitors/ClockMonitor.java +++ b/core/src/main/java/hudson/node_monitors/ClockMonitor.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Thomas J. Black - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,22 +21,22 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.node_monitors; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import hudson.Extension; import hudson.model.Computer; import hudson.model.Node; import hudson.remoting.Callable; import hudson.util.ClockDifference; -import hudson.Extension; +import java.io.IOException; +import net.sf.json.JSONObject; import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.StaplerRequest; -import java.io.IOException; - -import net.sf.json.JSONObject; - /** * {@link NodeMonitor} that checks clock of {@link Node} to * detect out of sync clocks. @@ -55,18 +55,20 @@ public ClockDifference getDifferenceFor(Computer c) { */ @Deprecated @Restricted(NoExternalUse.class) + @SuppressFBWarnings(value = "MS_PKGPROTECT", justification = "for backward compatibility") public static /*almost final*/ AbstractNodeMonitorDescriptor DESCRIPTOR; @Extension @Symbol("clock") public static class DescriptorImpl extends AbstractAsyncNodeMonitorDescriptor { + @SuppressFBWarnings(value = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD", justification = "for backward compatibility") public DescriptorImpl() { DESCRIPTOR = this; } @Override - protected Callable createCallable(Computer c) { + protected Callable createCallable(Computer c) { Node n = c.getNode(); - if(n==null) return null; + if (n == null) return null; return n.getClockDifferenceCallable(); } diff --git a/core/src/main/java/hudson/node_monitors/DiskSpaceMonitor.java b/core/src/main/java/hudson/node_monitors/DiskSpaceMonitor.java index baba07dcd39b..bcf96ba02704 100644 --- a/core/src/main/java/hudson/node_monitors/DiskSpaceMonitor.java +++ b/core/src/main/java/hudson/node_monitors/DiskSpaceMonitor.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,19 +21,19 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.node_monitors; import hudson.Extension; import hudson.FilePath; import hudson.model.Computer; import hudson.model.Node; -import hudson.remoting.Callable; -import jenkins.model.Jenkins; import hudson.node_monitors.DiskSpaceMonitorDescriptor.DiskSpace; -import org.kohsuke.stapler.DataBoundConstructor; - +import hudson.remoting.Callable; import java.io.IOException; import java.text.ParseException; +import jenkins.model.Jenkins; +import org.kohsuke.stapler.DataBoundConstructor; /** * Checks available disk space of the remote FS root. @@ -44,12 +44,12 @@ */ public class DiskSpaceMonitor extends AbstractDiskSpaceMonitor { @DataBoundConstructor - public DiskSpaceMonitor(String freeSpaceThreshold) throws ParseException { + public DiskSpaceMonitor(String freeSpaceThreshold) throws ParseException { super(freeSpaceThreshold); - } + } public DiskSpaceMonitor() {} - + public DiskSpace getFreeSpace(Computer c) { return DESCRIPTOR.get(c); } @@ -70,9 +70,9 @@ public String getDisplayName() { protected Callable createCallable(Computer c) { Node node = c.getNode(); if (node == null) return null; - + FilePath p = node.getRootPath(); - if(p==null) return null; + if (p == null) return null; return p.asCallableWith(new GetUsableSpace()); } diff --git a/core/src/main/java/hudson/node_monitors/DiskSpaceMonitorDescriptor.java b/core/src/main/java/hudson/node_monitors/DiskSpaceMonitorDescriptor.java index 13bd79093a69..076c2b281c7f 100644 --- a/core/src/main/java/hudson/node_monitors/DiskSpaceMonitorDescriptor.java +++ b/core/src/main/java/hudson/node_monitors/DiskSpaceMonitorDescriptor.java @@ -21,25 +21,24 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.node_monitors; import hudson.Functions; -import jenkins.MasterToSlaveFileCallable; -import hudson.remoting.VirtualChannel; import hudson.Util; import hudson.node_monitors.DiskSpaceMonitorDescriptor.DiskSpace; - +import hudson.remoting.VirtualChannel; import java.io.File; import java.io.IOException; import java.io.Serializable; import java.math.BigDecimal; import java.text.ParseException; import java.util.Locale; - +import jenkins.MasterToSlaveFileCallable; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.DoNotUse; -import org.kohsuke.stapler.export.ExportedBean; import org.kohsuke.stapler.export.Exported; +import org.kohsuke.stapler.export.ExportedBean; /** * {@link AbstractNodeMonitorDescriptor} for {@link NodeMonitor} that checks a free disk space of some directory. @@ -56,7 +55,7 @@ public static final class DiskSpace extends MonitorOfflineCause implements Seria private final String path; @Exported public final long size; - + private boolean triggered; private Class trigger; @@ -71,12 +70,12 @@ public DiskSpace(String path, long size) { @Override public String toString() { - if(triggered) { + if (triggered) { return Messages.DiskSpaceMonitorDescriptor_DiskSpace_FreeSpaceTooLow(getGbLeft(), path); } return Messages.DiskSpaceMonitorDescriptor_DiskSpace_FreeSpace(getGbLeft(), path); } - + /** * The path that was checked */ @@ -98,8 +97,8 @@ public long getFreeSize() { */ public String getGbLeft() { long space = size; - space/=1024L; // convert to KB - space/=1024L; // convert to MB + space /= 1024L; // convert to KB + space /= 1024L; // convert to MB return new BigDecimal(space).scaleByPowerOfTen(-3).toPlainString(); } @@ -109,33 +108,33 @@ public String getGbLeft() { */ public String toHtml() { String humanReadableSpace = Functions.humanReadableByteSize(size); - if(triggered) { + if (triggered) { return Util.wrapToErrorSpan(humanReadableSpace); } return humanReadableSpace; } - + /** * Sets whether this disk space amount should be treated as outside * the acceptable conditions or not. */ protected void setTriggered(boolean triggered) { - this.triggered = triggered; + this.triggered = triggered; } - /** + /** * Same as {@link DiskSpace#setTriggered(boolean)}, also sets the trigger class which made the decision */ protected void setTriggered(Class trigger, boolean triggered) { this.trigger = trigger; this.triggered = triggered; } - + @Override public Class getTrigger() { return trigger; } - + /** * Parses a human readable size description like "1GB", "0.5m", etc. into {@link DiskSpace} * @@ -145,23 +144,23 @@ public Class getTrigger() { public static DiskSpace parse(String size) throws ParseException { size = size.toUpperCase(Locale.ENGLISH).trim(); if (size.endsWith("B")) // cut off 'B' from KB, MB, etc. - size = size.substring(0,size.length()-1); + size = size.substring(0, size.length() - 1); - long multiplier=1; + long multiplier = 1; // look for the size suffix. The goal here isn't to detect all invalid size suffix, // so we ignore double suffix like "10gkb" or anything like that. String suffix = "KMGT"; - for (int i=0; i { public GetUsableSpace() {} + + @Override public DiskSpace invoke(File f, VirtualChannel channel) throws IOException { long s = f.getUsableSpace(); - if(s<=0) return null; + if (s <= 0) return null; return new DiskSpace(f.getCanonicalPath(), s); } + private static final long serialVersionUID = 1L; } } diff --git a/core/src/main/java/hudson/node_monitors/MonitorMarkedNodeOffline.java b/core/src/main/java/hudson/node_monitors/MonitorMarkedNodeOffline.java index 6a75d5c14b71..220774a458ed 100644 --- a/core/src/main/java/hudson/node_monitors/MonitorMarkedNodeOffline.java +++ b/core/src/main/java/hudson/node_monitors/MonitorMarkedNodeOffline.java @@ -21,10 +21,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.node_monitors; -import hudson.model.AdministrativeMonitor; import hudson.Extension; +import hudson.model.AdministrativeMonitor; /** * If {@link NodeMonitor} marks the node as offline, we'll show this to the admin to get their attention. @@ -44,6 +45,7 @@ public String getDisplayName() { public boolean active = false; + @Override public boolean isActivated() { return active; } diff --git a/core/src/main/java/hudson/node_monitors/MonitorOfflineCause.java b/core/src/main/java/hudson/node_monitors/MonitorOfflineCause.java index 77c3285cd70e..7bb30048d872 100644 --- a/core/src/main/java/hudson/node_monitors/MonitorOfflineCause.java +++ b/core/src/main/java/hudson/node_monitors/MonitorOfflineCause.java @@ -21,10 +21,10 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.node_monitors; import edu.umd.cs.findbugs.annotations.NonNull; - import hudson.slaves.OfflineCause; /** diff --git a/core/src/main/java/hudson/node_monitors/NodeMonitor.java b/core/src/main/java/hudson/node_monitors/NodeMonitor.java index bc04c75569d2..eb5a9459c33d 100644 --- a/core/src/main/java/hudson/node_monitors/NodeMonitor.java +++ b/core/src/main/java/hudson/node_monitors/NodeMonitor.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Thomas J. Black - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,23 +21,22 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.node_monitors; -import hudson.ExtensionPoint; +import edu.umd.cs.findbugs.annotations.CheckForNull; import hudson.DescriptorExtensionList; import hudson.Extension; -import hudson.tasks.Publisher; +import hudson.ExtensionPoint; import hudson.model.Computer; import hudson.model.ComputerSet; import hudson.model.Describable; -import hudson.model.Node; -import jenkins.model.Jenkins; import hudson.model.Descriptor; +import hudson.model.Node; +import hudson.tasks.Publisher; import hudson.util.DescriptorList; - import java.util.List; -import edu.umd.cs.findbugs.annotations.CheckForNull; - +import jenkins.model.Jenkins; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; @@ -55,7 +54,7 @@ *

    config.jelly (optional)
    *
    * Configuration fragment to be displayed in {@code http://server/hudson/computer/configure}. - * Used for configuring the threshold for taking nodes offline. + * Used for configuring the threshold for taking nodes offline. * * *

    Persistence

    @@ -80,6 +79,7 @@ public abstract class NodeMonitor implements ExtensionPoint, Describable getDescriptor() { return (AbstractNodeMonitorDescriptor) Jenkins.get().getDescriptorOrDie(getClass()); } @@ -145,7 +145,7 @@ public void setIgnored(boolean ignored) { /** * Returns all the registered {@link NodeMonitor} descriptors. */ - public static DescriptorExtensionList> all() { + public static DescriptorExtensionList> all() { return Jenkins.get().getDescriptorList(NodeMonitor.class); } } diff --git a/core/src/main/java/hudson/node_monitors/NodeMonitorUpdater.java b/core/src/main/java/hudson/node_monitors/NodeMonitorUpdater.java index 73ef319c3fcb..10238deb3352 100644 --- a/core/src/main/java/hudson/node_monitors/NodeMonitorUpdater.java +++ b/core/src/main/java/hudson/node_monitors/NodeMonitorUpdater.java @@ -6,11 +6,9 @@ import hudson.model.TaskListener; import hudson.slaves.ComputerListener; import hudson.util.Futures; - import java.io.IOException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; - import jenkins.util.Timer; /** @@ -38,7 +36,7 @@ public void run() { */ @Override public void onOnline(Computer c, TaskListener listener) throws IOException, InterruptedException { - synchronized(this) { + synchronized (this) { future.cancel(false); future = Timer.get().schedule(MONITOR_UPDATER, 5, TimeUnit.SECONDS); } diff --git a/core/src/main/java/hudson/node_monitors/ResponseTimeMonitor.java b/core/src/main/java/hudson/node_monitors/ResponseTimeMonitor.java index 3dfc517241d7..8932941432c1 100644 --- a/core/src/main/java/hudson/node_monitors/ResponseTimeMonitor.java +++ b/core/src/main/java/hudson/node_monitors/ResponseTimeMonitor.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Red Hat, Inc. - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,20 +21,19 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.node_monitors; import hudson.Extension; import hudson.model.Computer; import hudson.remoting.Callable; -import jenkins.security.MasterToSlaveCallable; -import net.sf.json.JSONObject; -import org.kohsuke.stapler.StaplerRequest; - import java.io.IOException; import java.io.Serializable; import java.util.Map; -import java.util.Map.Entry; import java.util.logging.Logger; +import jenkins.security.MasterToSlaveCallable; +import net.sf.json.JSONObject; +import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; @@ -48,7 +47,7 @@ public class ResponseTimeMonitor extends NodeMonitor { public static final AbstractNodeMonitorDescriptor DESCRIPTOR = new AbstractAsyncNodeMonitorDescriptor() { @Override - protected Callable createCallable(Computer c) { + protected Callable createCallable(Computer c) { return new Step1(get(c)); } @@ -56,7 +55,7 @@ protected Callable createCallable(Computer c) { protected Map monitor() throws InterruptedException { Result base = monitorDetailed(); Map monitoringData = base.getMonitoringData(); - for (Entry e : monitoringData.entrySet()) { + for (Map.Entry e : monitoringData.entrySet()) { Computer c = e.getKey(); Data d = e.getValue(); if (base.getSkipped().contains(c)) { @@ -64,12 +63,12 @@ protected Map monitor() throws InterruptedException { continue; } - if (d ==null) { + if (d == null) { // if we failed to monitor, put in the special value that indicates a failure - e.setValue(d=new Data(get(c),-1L)); + e.setValue(d = new Data(get(c), -1L)); } - if(d.hasTooManyTimeouts() && !isIgnored()) { + if (d.hasTooManyTimeouts() && !isIgnored()) { // unlike other monitors whose failure still allow us to communicate with the agent, // the failure in this monitor indicates that we are just unable to make any requests // to this agent. So we should severe the connection, as opposed to marking it temporarily @@ -92,16 +91,17 @@ public NodeMonitor newInstance(StaplerRequest req, JSONObject formData) throws F } }; - private static final class Step1 extends MasterToSlaveCallable { + private static final class Step1 extends MasterToSlaveCallable { private Data cur; private Step1(Data cur) { this.cur = cur; } + @Override public Data call() { // this method must be being invoked locally, which means the roundtrip time is zero and zero forever - return new Data(cur,0); + return new Data(cur, 0); } private Object writeReplace() { @@ -111,7 +111,7 @@ private Object writeReplace() { private static final long serialVersionUID = 1L; } - private static final class Step2 extends MasterToSlaveCallable { + private static final class Step2 extends MasterToSlaveCallable { private final Data cur; private final long start = System.currentTimeMillis(); @@ -119,9 +119,10 @@ private static final class Step2 extends MasterToSlaveCallable=0 && past5[i]<0; i--, cnt++) + for (int i = past5.length - 1; i >= 0 && past5[i] < 0; i--, cnt++) ; return cnt; } @@ -182,16 +183,16 @@ private int failureCount() { */ @Exported public long getAverage() { - long total=0; + long total = 0; for (long l : past5) { - if(l<0) total += TIMEOUT; + if (l < 0) total += TIMEOUT; else total += l; } - return total/past5.length; + return total / past5.length; } public boolean hasTooManyTimeouts() { - return failureCount()>=5; + return failureCount() >= 5; } /** @@ -199,16 +200,10 @@ public boolean hasTooManyTimeouts() { */ @Override public String toString() { -// StringBuilder buf = new StringBuilder(); -// for (long l : past5) { -// if(buf.length()>0) buf.append(','); -// buf.append(l); -// } -// return buf.toString(); int fc = failureCount(); - if(fc>0) + if (fc > 0) return Messages.ResponseTimeMonitor_TimeOut(fc); - return getAverage()+"ms"; + return getAverage() + "ms"; } @Override diff --git a/core/src/main/java/hudson/node_monitors/SwapSpaceMonitor.java b/core/src/main/java/hudson/node_monitors/SwapSpaceMonitor.java index c9195c800279..286274b42fe5 100644 --- a/core/src/main/java/hudson/node_monitors/SwapSpaceMonitor.java +++ b/core/src/main/java/hudson/node_monitors/SwapSpaceMonitor.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Seiji Sogabe - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,12 +21,15 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.node_monitors; -import hudson.Util; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.Extension; import hudson.Functions; +import hudson.Util; import hudson.model.Computer; +import java.io.IOException; import jenkins.model.Jenkins; import jenkins.security.MasterToSlaveCallable; import net.sf.json.JSONObject; @@ -34,10 +37,8 @@ import org.jvnet.hudson.MemoryMonitor; import org.jvnet.hudson.MemoryUsage; import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.export.ExportedBean; import org.kohsuke.stapler.export.Exported; - -import java.io.IOException; +import org.kohsuke.stapler.export.ExportedBean; /** * Checks the swap space availability. @@ -50,15 +51,15 @@ public class SwapSpaceMonitor extends NodeMonitor { * Returns the HTML representation of the space. */ public String toHtml(MemoryUsage usage) { - if(usage.availableSwapSpace==-1) + if (usage.availableSwapSpace == -1) return "N/A"; String humanReadableSpace = Functions.humanReadableByteSize(usage.availableSwapSpace); - + long free = usage.availableSwapSpace; - free/=1024L; // convert to KB - free/=1024L; // convert to MB - if(free>256 || usage.totalSwapSpace 256 || usage.totalSwapSpace < usage.availableSwapSpace * 5) return humanReadableSpace; // if we have more than 256MB free or less than 80% filled up, it's OK // Otherwise considered dangerously low. @@ -66,12 +67,12 @@ public String toHtml(MemoryUsage usage) { } public long toMB(MemoryUsage usage) { - if(usage.availableSwapSpace==-1) + if (usage.availableSwapSpace == -1) return -1; long free = usage.availableSwapSpace; - free/=1024L; // convert to KB - free/=1024L; // convert to MB + free /= 1024L; // convert to KB + free /= 1024L; // convert to MB return free; } @@ -90,6 +91,7 @@ public String getColumnCaption() { @Extension @Symbol("swapSpace") public static class DescriptorImpl extends AbstractAsyncNodeMonitorDescriptor { + @SuppressFBWarnings(value = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD", justification = "for backward compatibility") public DescriptorImpl() { DESCRIPTOR = this; } @@ -113,7 +115,8 @@ public NodeMonitor newInstance(StaplerRequest req, JSONObject formData) throws F /** * Obtains the string that represents the architecture. */ - private static class MonitorTask extends MasterToSlaveCallable { + private static class MonitorTask extends MasterToSlaveCallable { + @Override public MemoryUsage call() throws IOException { MemoryMonitor mm; try { diff --git a/core/src/main/java/hudson/node_monitors/TemporarySpaceMonitor.java b/core/src/main/java/hudson/node_monitors/TemporarySpaceMonitor.java index 022d72590674..d6b8a4f23359 100644 --- a/core/src/main/java/hudson/node_monitors/TemporarySpaceMonitor.java +++ b/core/src/main/java/hudson/node_monitors/TemporarySpaceMonitor.java @@ -21,23 +21,24 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.node_monitors; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.Extension; import hudson.FilePath; -import jenkins.MasterToSlaveFileCallable; import hudson.model.Computer; import hudson.model.Node; -import hudson.remoting.Callable; -import jenkins.model.Jenkins; import hudson.node_monitors.DiskSpaceMonitorDescriptor.DiskSpace; +import hudson.remoting.Callable; import hudson.remoting.VirtualChannel; -import org.jenkinsci.Symbol; -import org.kohsuke.stapler.DataBoundConstructor; - import java.io.File; import java.io.IOException; import java.text.ParseException; +import jenkins.MasterToSlaveFileCallable; +import jenkins.model.Jenkins; +import org.jenkinsci.Symbol; +import org.kohsuke.stapler.DataBoundConstructor; /** * Monitors the disk space of "/tmp". @@ -46,9 +47,9 @@ */ public class TemporarySpaceMonitor extends AbstractDiskSpaceMonitor { @DataBoundConstructor - public TemporarySpaceMonitor(String freeSpaceThreshold) throws ParseException { + public TemporarySpaceMonitor(String freeSpaceThreshold) throws ParseException { super(freeSpaceThreshold); - } + } public TemporarySpaceMonitor() {} @@ -67,10 +68,12 @@ public String getColumnCaption() { * Use injection */ @Deprecated + @SuppressFBWarnings(value = "MS_PKGPROTECT", justification = "for backward compatibility") public static /*almost final*/ DiskSpaceMonitorDescriptor DESCRIPTOR; @Extension @Symbol("tmpSpace") public static class DescriptorImpl extends DiskSpaceMonitorDescriptor { + @SuppressFBWarnings(value = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD", justification = "for backward compatibility") public DescriptorImpl() { DESCRIPTOR = this; } @@ -81,12 +84,12 @@ public String getDisplayName() { } @Override - protected Callable createCallable(Computer c) { + protected Callable createCallable(Computer c) { Node node = c.getNode(); if (node == null) return null; - + FilePath p = node.getRootPath(); - if(p==null) return null; + if (p == null) return null; return p.asCallableWith(new GetTempSpace()); } @@ -99,16 +102,18 @@ protected Callable createCallable(Computer c) { public static DiskSpaceMonitorDescriptor install() { return DESCRIPTOR; } - + protected static final class GetTempSpace extends MasterToSlaveFileCallable { + @Override public DiskSpace invoke(File f, VirtualChannel channel) throws IOException { // if the disk is really filled up we can't even create a single file, // so calling File.createTempFile and figuring out the directory won't reliably work. f = new File(System.getProperty("java.io.tmpdir")); long s = f.getUsableSpace(); - if(s<=0) return null; + if (s <= 0) return null; return new DiskSpace(f.getCanonicalPath(), s); } + private static final long serialVersionUID = 1L; } } diff --git a/core/src/main/java/hudson/org/apache/tools/tar/TarInputStream.java b/core/src/main/java/hudson/org/apache/tools/tar/TarInputStream.java deleted file mode 100644 index 14383fd7ea65..000000000000 --- a/core/src/main/java/hudson/org/apache/tools/tar/TarInputStream.java +++ /dev/null @@ -1,411 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -/* - * This package is based on the work done by Timothy Gerard Endres - * (time@ice.com) to whom the Ant project is very grateful for his great code. - */ - -package hudson.org.apache.tools.tar; - -import hudson.RestrictedSince; -import org.apache.tools.tar.TarBuffer; -import org.apache.tools.tar.TarEntry; -import org.kohsuke.accmod.Restricted; -import org.kohsuke.accmod.restrictions.NoExternalUse; - -import java.io.FilterInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.ByteArrayOutputStream; - -/** - * The TarInputStream reads a UNIX tar archive as an InputStream. - * methods are provided to position at each successive entry in - * the archive, and the read each entry as a normal input stream - * using read(). - * @deprecated Use {@link org.apache.commons.compress.archivers.tar.TarArchiveInputStream} instead - */ -@Deprecated -@Restricted(NoExternalUse.class) -@RestrictedSince("2.200") -public class TarInputStream extends FilterInputStream { - - // CheckStyle:VisibilityModifier OFF - bc - protected boolean debug; - protected boolean hasHitEOF; - protected long entrySize; - protected long entryOffset; - protected byte[] readBuf; - protected TarBuffer buffer; - protected TarEntry currEntry; - - /** - * This contents of this array is not used at all in this class, - * it is only here to avoid repeated object creation during calls - * to the no-arg read method. - */ - protected byte[] oneBuf; - - // CheckStyle:VisibilityModifier ON - - /** - * Constructor for TarInputStream. - * @param is the input stream to use - */ - public TarInputStream(InputStream is) { - this(is, TarBuffer.DEFAULT_BLKSIZE, TarBuffer.DEFAULT_RCDSIZE); - } - - /** - * Constructor for TarInputStream. - * @param is the input stream to use - * @param blockSize the block size to use - */ - public TarInputStream(InputStream is, int blockSize) { - this(is, blockSize, TarBuffer.DEFAULT_RCDSIZE); - } - - /** - * Constructor for TarInputStream. - * @param is the input stream to use - * @param blockSize the block size to use - * @param recordSize the record size to use - */ - public TarInputStream(InputStream is, int blockSize, int recordSize) { - super(is); - - this.buffer = new TarBuffer(is, blockSize, recordSize); - this.readBuf = null; - this.oneBuf = new byte[1]; - this.debug = false; - this.hasHitEOF = false; - } - - /** - * Sets the debugging flag. - * - * @param debug True to turn on debugging. - */ - public void setDebug(boolean debug) { - this.debug = debug; - this.buffer.setDebug(debug); - } - - /** - * Closes this stream. Calls the TarBuffer's close() method. - * @throws IOException on error - */ - @Override - public void close() throws IOException { - this.buffer.close(); - } - - /** - * Get the record size being used by this stream's TarBuffer. - * - * @return The TarBuffer record size. - */ - public int getRecordSize() { - return this.buffer.getRecordSize(); - } - - /** - * Get the available data that can be read from the current - * entry in the archive. This does not indicate how much data - * is left in the entire archive, only in the current entry. - * This value is determined from the entry's size header field - * and the amount of data already read from the current entry. - * Integer.MAX_VALUE is returned in case more than Integer.MAX_VALUE - * bytes are left in the current entry in the archive. - * - * @return The number of available bytes for the current entry. - * @throws IOException for signature - */ - @Override - public int available() throws IOException { - if (this.entrySize - this.entryOffset > Integer.MAX_VALUE) { - return Integer.MAX_VALUE; - } - return (int) (this.entrySize - this.entryOffset); - } - - /** - * Skip bytes in the input buffer. This skips bytes in the - * current entry's data, not the entire archive, and will - * stop at the end of the current entry's data if the number - * to skip extends beyond that point. - * - * @param numToSkip The number of bytes to skip. - * @return the number actually skipped - * @throws IOException on error - */ - @Override - public long skip(long numToSkip) throws IOException { - // REVIEW - // This is horribly inefficient, but it ensures that we - // properly skip over bytes via the TarBuffer... - // - byte[] skipBuf = new byte[8 * 1024]; - long skip = numToSkip; - while (skip > 0) { - int realSkip = (int) (skip > skipBuf.length ? skipBuf.length : skip); - int numRead = this.read(skipBuf, 0, realSkip); - if (numRead == -1) { - break; - } - skip -= numRead; - } - return (numToSkip - skip); - } - - /** - * Since we do not support marking just yet, we return false. - * - * @return False. - */ - @Override - public boolean markSupported() { - return false; - } - - /** - * Since we do not support marking just yet, we do nothing. - * - * @param markLimit The limit to mark. - */ - @Override - public void mark(int markLimit) { - } - - /** - * Since we do not support marking just yet, we do nothing. - */ - @Override - public void reset() { - } - - /** - * Get the next entry in this tar archive. This will skip - * over any remaining data in the current entry, if there - * is one, and place the input stream at the header of the - * next entry, and read the header and instantiate a new - * TarEntry from the header bytes and return that entry. - * If there are no more entries in the archive, null will - * be returned to indicate that the end of the archive has - * been reached. - * - * @return The next TarEntry in the archive, or null. - * @throws IOException on error - */ - public TarEntry getNextEntry() throws IOException { - if (this.hasHitEOF) { - return null; - } - - if (this.currEntry != null) { - long numToSkip = this.entrySize - this.entryOffset; - - if (this.debug) { - System.err.println("TarInputStream: SKIP currENTRY '" - + this.currEntry.getName() + "' SZ " - + this.entrySize + " OFF " - + this.entryOffset + " skipping " - + numToSkip + " bytes"); - } - - if (numToSkip > 0) { - this.skip(numToSkip); - } - - this.readBuf = null; - } - - byte[] headerBuf = this.buffer.readRecord(); - - if (headerBuf == null) { - if (this.debug) { - System.err.println("READ NULL RECORD"); - } - this.hasHitEOF = true; - } else if (this.buffer.isEOFRecord(headerBuf)) { - if (this.debug) { - System.err.println("READ EOF RECORD"); - } - this.hasHitEOF = true; - } - - if (this.hasHitEOF) { - this.currEntry = null; - } else { - this.currEntry = new TarEntry(headerBuf); - - if (this.debug) { - System.err.println("TarInputStream: SET currENTRY '" - + this.currEntry.getName() - + "' size = " - + this.currEntry.getSize()); - } - - this.entryOffset = 0; - - this.entrySize = this.currEntry.getSize(); - } - - if (this.currEntry != null && this.currEntry.isGNULongNameEntry()) { - // read in the name - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - byte[] buf = new byte[256]; - int length; - while ((length = read(buf)) >= 0) { - baos.write(buf,0,length); - } - getNextEntry(); - if (this.currEntry == null) { - // Bugzilla: 40334 - // Malformed tar file - long entry name not followed by entry - return null; - } - String longName = baos.toString("UTF-8"); - // remove trailing null terminator - if (longName.length() > 0 - && longName.charAt(longName.length() - 1) == 0) { - longName = longName.substring(0,longName.length()-1); - } - this.currEntry.setName(longName); - } - - return this.currEntry; - } - - /** - * Reads a byte from the current tar archive entry. - * - * This method simply calls read( byte[], int, int ). - * - * @return The byte read, or -1 at EOF. - * @throws IOException on error - */ - @Override - public int read() throws IOException { - int num = this.read(this.oneBuf, 0, 1); - return num == -1 ? -1 : ((int) this.oneBuf[0]) & 0xFF; - } - - /** - * Reads bytes from the current tar archive entry. - * - * This method is aware of the boundaries of the current - * entry in the archive and will deal with them as if they - * were this stream's start and EOF. - * - * @param buf The buffer into which to place bytes read. - * @param offset The offset at which to place bytes read. - * @param numToRead The number of bytes to read. - * @return The number of bytes read, or -1 at EOF. - * @throws IOException on error - */ - @Override - public int read(byte[] buf, int offset, int numToRead) throws IOException { - int totalRead = 0; - - if (this.entryOffset >= this.entrySize) { - return -1; - } - - if ((numToRead + this.entryOffset) > this.entrySize) { - numToRead = (int) (this.entrySize - this.entryOffset); - } - - if (this.readBuf != null) { - int sz = Math.min(numToRead, this.readBuf.length); - - System.arraycopy(this.readBuf, 0, buf, offset, sz); - - if (sz >= this.readBuf.length) { - this.readBuf = null; - } else { - int newLen = this.readBuf.length - sz; - byte[] newBuf = new byte[newLen]; - - System.arraycopy(this.readBuf, sz, newBuf, 0, newLen); - - this.readBuf = newBuf; - } - - totalRead += sz; - numToRead -= sz; - offset += sz; - } - - while (numToRead > 0) { - byte[] rec = this.buffer.readRecord(); - - if (rec == null) { - // Unexpected EOF! - throw new IOException("unexpected EOF with " + numToRead - + " bytes unread"); - } - - int sz = numToRead; - int recLen = rec.length; - - if (recLen > sz) { - System.arraycopy(rec, 0, buf, offset, sz); - - this.readBuf = new byte[recLen - sz]; - - System.arraycopy(rec, sz, this.readBuf, 0, recLen - sz); - } else { - sz = recLen; - - System.arraycopy(rec, 0, buf, offset, recLen); - } - - totalRead += sz; - numToRead -= sz; - offset += sz; - } - - this.entryOffset += totalRead; - - return totalRead; - } - - /** - * Copies the contents of the current tar archive entry directly into - * an output stream. - * - * @param out The OutputStream into which to write the entry's data. - * @throws IOException on error - */ - public void copyEntryContents(OutputStream out) throws IOException { - byte[] buf = new byte[32 * 1024]; - - while (true) { - int numRead = this.read(buf, 0, buf.length); - - if (numRead == -1) { - break; - } - - out.write(buf, 0, numRead); - } - } -} diff --git a/core/src/main/java/hudson/org/apache/tools/tar/TarOutputStream.java b/core/src/main/java/hudson/org/apache/tools/tar/TarOutputStream.java deleted file mode 100644 index 032cc7ef92b4..000000000000 --- a/core/src/main/java/hudson/org/apache/tools/tar/TarOutputStream.java +++ /dev/null @@ -1,372 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -/* - * This package is based on the work done by Timothy Gerard Endres - * (time@ice.com) to whom the Ant project is very grateful for his great code. - */ - -package hudson.org.apache.tools.tar; - -import hudson.RestrictedSince; -import org.apache.tools.tar.TarBuffer; -import org.apache.tools.tar.TarConstants; -import org.apache.tools.tar.TarEntry; -import org.kohsuke.accmod.Restricted; -import org.kohsuke.accmod.restrictions.NoExternalUse; - -import java.io.FilterOutputStream; -import java.io.OutputStream; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.Arrays; - -/** - * The TarOutputStream writes a UNIX tar archive as an OutputStream. - * Methods are provided to put entries, and then write their contents - * by writing to this stream using write(). - * - * @deprecated Use {@link org.apache.commons.compress.archivers.tar.TarArchiveOutputStream} instead - * - */ -@Deprecated -@Restricted(NoExternalUse.class) -@RestrictedSince("2.200") -public class TarOutputStream extends FilterOutputStream { - /** Fail if a long file name is required in the archive. */ - public static final int LONGFILE_ERROR = 0; - - /** Long paths will be truncated in the archive. */ - public static final int LONGFILE_TRUNCATE = 1; - - /** GNU tar extensions are used to store long file names in the archive. */ - public static final int LONGFILE_GNU = 2; - - // CheckStyle:VisibilityModifier OFF - bc - protected boolean debug; - protected long currSize; - protected String currName; - protected long currBytes; - protected byte[] oneBuf; - protected byte[] recordBuf; - protected int assemLen; - protected byte[] assemBuf; - protected TarBuffer buffer; - protected int longFileMode = LONGFILE_ERROR; - // CheckStyle:VisibilityModifier ON - - private boolean closed = false; - - /** - * Constructor for TarInputStream. - * @param os the output stream to use - */ - public TarOutputStream(OutputStream os) { - this(os, TarBuffer.DEFAULT_BLKSIZE, TarBuffer.DEFAULT_RCDSIZE); - } - - /** - * Constructor for TarInputStream. - * @param os the output stream to use - * @param blockSize the block size to use - */ - public TarOutputStream(OutputStream os, int blockSize) { - this(os, blockSize, TarBuffer.DEFAULT_RCDSIZE); - } - - /** - * Constructor for TarInputStream. - * @param os the output stream to use - * @param blockSize the block size to use - * @param recordSize the record size to use - */ - public TarOutputStream(OutputStream os, int blockSize, int recordSize) { - super(os); - - this.buffer = new TarBuffer(os, blockSize, recordSize); - this.debug = false; - this.assemLen = 0; - this.assemBuf = new byte[recordSize]; - this.recordBuf = new byte[recordSize]; - this.oneBuf = new byte[1]; - } - - /** - * Set the long file mode. - * This can be LONGFILE_ERROR(0), LONGFILE_TRUNCATE(1) or LONGFILE_GNU(2). - * This specifies the treatment of long file names (names ≥ TarConstants.NAMELEN). - * Default is LONGFILE_ERROR. - * @param longFileMode the mode to use - */ - public void setLongFileMode(int longFileMode) { - this.longFileMode = longFileMode; - } - - - /** - * Sets the debugging flag. - * - * @param debugF True to turn on debugging. - */ - public void setDebug(boolean debugF) { - this.debug = debugF; - } - - /** - * Sets the debugging flag in this stream's TarBuffer. - * - * @param debug True to turn on debugging. - */ - public void setBufferDebug(boolean debug) { - this.buffer.setDebug(debug); - } - - /** - * Ends the TAR archive without closing the underlying OutputStream. - * The result is that the two EOF records of nulls are written. - * @throws IOException on error - */ - public void finish() throws IOException { - // See Bugzilla 28776 for a discussion on this - // http://issues.apache.org/bugzilla/show_bug.cgi?id=28776 - this.writeEOFRecord(); - this.writeEOFRecord(); - } - - /** - * Ends the TAR archive and closes the underlying OutputStream. - * This means that finish() is called followed by calling the - * TarBuffer's close(). - * @throws IOException on error - */ - @Override - public void close() throws IOException { - if (!closed) { - this.finish(); - this.buffer.close(); - out.close(); - closed = true; - } - } - - /** - * Get the record size being used by this stream's TarBuffer. - * - * @return The TarBuffer record size. - */ - public int getRecordSize() { - return this.buffer.getRecordSize(); - } - - /** - * Put an entry on the output stream. This writes the entry's - * header record and positions the output stream for writing - * the contents of the entry. Once this method is called, the - * stream is ready for calls to write() to write the entry's - * contents. Once the contents are written, closeEntry() - * MUST be called to ensure that all buffered data - * is completely written to the output stream. - * - * @param entry The TarEntry to be written to the archive. - * @throws IOException on error - */ - public void putNextEntry(TarEntry entry) throws IOException { - if (entry.getName().length() >= TarConstants.NAMELEN) { - - if (longFileMode == LONGFILE_GNU) { - // create a TarEntry for the LongLink, the contents - // of which are the entry's name - TarEntry longLinkEntry = new TarEntry(TarConstants.GNU_LONGLINK, - TarConstants.LF_GNUTYPE_LONGNAME); - - byte[] name = entry.getName().getBytes(StandardCharsets.UTF_8); - longLinkEntry.setSize(name.length + 1); - putNextEntry(longLinkEntry); - write(name); - write(0); - closeEntry(); - } else if (longFileMode != LONGFILE_TRUNCATE) { - throw new RuntimeException("file name '" + entry.getName() - + "' is too long ( > " - + TarConstants.NAMELEN + " bytes)"); - } - } - - entry.writeEntryHeader(this.recordBuf); - this.buffer.writeRecord(this.recordBuf); - - this.currBytes = 0; - - if (entry.isDirectory()) { - this.currSize = 0; - } else { - this.currSize = entry.getSize(); - } - currName = entry.getName(); - } - - /** - * Close an entry. This method MUST be called for all file - * entries that contain data. The reason is that we must - * buffer data written to the stream in order to satisfy - * the buffer's record based writes. Thus, there may be - * data fragments still being assembled that must be written - * to the output stream before this entry is closed and the - * next entry written. - * @throws IOException on error - */ - public void closeEntry() throws IOException { - if (this.assemLen > 0) { - for (int i = this.assemLen; i < this.assemBuf.length; ++i) { - this.assemBuf[i] = 0; - } - - this.buffer.writeRecord(this.assemBuf); - - this.currBytes += this.assemLen; - this.assemLen = 0; - } - - if (this.currBytes < this.currSize) { - throw new IOException("entry '" + currName + "' closed at '" - + this.currBytes - + "' before the '" + this.currSize - + "' bytes specified in the header were written"); - } - } - - /** - * Writes a byte to the current tar archive entry. - * - * This method simply calls read( byte[], int, int ). - * - * @param b The byte written. - * @throws IOException on error - */ - @Override - public void write(int b) throws IOException { - this.oneBuf[0] = (byte) b; - - this.write(this.oneBuf, 0, 1); - } - - /** - * Writes bytes to the current tar archive entry. - * - * This method simply calls write( byte[], int, int ). - * - * @param wBuf The buffer to write to the archive. - * @throws IOException on error - */ - @Override - public void write(byte[] wBuf) throws IOException { - this.write(wBuf, 0, wBuf.length); - } - - /** - * Writes bytes to the current tar archive entry. This method - * is aware of the current entry and will throw an exception if - * you attempt to write bytes past the length specified for the - * current entry. The method is also (painfully) aware of the - * record buffering required by TarBuffer, and manages buffers - * that are not a multiple of recordsize in length, including - * assembling records from small buffers. - * - * @param wBuf The buffer to write to the archive. - * @param wOffset The offset in the buffer from which to get bytes. - * @param numToWrite The number of bytes to write. - * @throws IOException on error - */ - @Override - public void write(byte[] wBuf, int wOffset, int numToWrite) throws IOException { - if ((this.currBytes + numToWrite) > this.currSize) { - throw new IOException("request to write '" + numToWrite - + "' bytes exceeds size in header of '" - + this.currSize + "' bytes for entry '" - + currName + "'"); - - // - // We have to deal with assembly!!! - // The programmer can be writing little 32 byte chunks for all - // we know, and we must assemble complete records for writing. - // REVIEW Maybe this should be in TarBuffer? Could that help to - // eliminate some of the buffer copying. - // - } - - if (this.assemLen > 0) { - if ((this.assemLen + numToWrite) >= this.recordBuf.length) { - int aLen = this.recordBuf.length - this.assemLen; - - System.arraycopy(this.assemBuf, 0, this.recordBuf, 0, - this.assemLen); - System.arraycopy(wBuf, wOffset, this.recordBuf, - this.assemLen, aLen); - this.buffer.writeRecord(this.recordBuf); - - this.currBytes += this.recordBuf.length; - wOffset += aLen; - numToWrite -= aLen; - this.assemLen = 0; - } else { - System.arraycopy(wBuf, wOffset, this.assemBuf, this.assemLen, - numToWrite); - - wOffset += numToWrite; - this.assemLen += numToWrite; - numToWrite = 0; - } - } - - // - // When we get here we have EITHER: - // o An empty "assemble" buffer. - // o No bytes to write (numToWrite == 0) - // - while (numToWrite > 0) { - if (numToWrite < this.recordBuf.length) { - System.arraycopy(wBuf, wOffset, this.assemBuf, this.assemLen, - numToWrite); - - this.assemLen += numToWrite; - - break; - } - - this.buffer.writeRecord(wBuf, wOffset); - - int num = this.recordBuf.length; - - this.currBytes += num; - numToWrite -= num; - wOffset += num; - } - } - - /** - * Write an EOF (end of archive) record to the tar archive. - * An EOF record consists of a record of all zeros. - */ - private void writeEOFRecord() throws IOException { - Arrays.fill(this.recordBuf, (byte) 0); - - this.buffer.writeRecord(this.recordBuf); - } -} - - diff --git a/core/src/main/java/hudson/os/PosixAPI.java b/core/src/main/java/hudson/os/PosixAPI.java deleted file mode 100644 index f54f29331e8a..000000000000 --- a/core/src/main/java/hudson/os/PosixAPI.java +++ /dev/null @@ -1,125 +0,0 @@ -package hudson.os; - -import java.io.File; -import java.io.InputStream; -import java.io.PrintStream; -import java.util.Map; -import java.util.logging.Logger; -import jnr.constants.platform.Errno; -import jnr.posix.POSIX; -import jnr.posix.POSIXFactory; -import jnr.posix.util.DefaultPOSIXHandler; - -/** - * POSIX API wrapper. - * Formerly used the jna-posix library, but this has been superseded by jnr-posix. - * @author Kohsuke Kawaguchi - */ -public class PosixAPI { - - private static POSIX posix; - - /** - * Load the JNR implementation of the POSIX APIs for the current platform. - * Runtime exceptions will be of type {@link PosixException}. - * {@link IllegalStateException} will be thrown for methods not implemented on this platform. - * @return some implementation (even on Windows or unsupported Unix) - * @since 1.518 - */ - public static synchronized POSIX jnr() { - if (posix == null) { - posix = POSIXFactory.getPOSIX(new DefaultPOSIXHandler() { - @Override public void error(Errno error, String extraData) { - throw new PosixException("native error " + error.description() + " " + extraData, convert(error)); - } - @Override public void error(Errno error, String methodName, String extraData) { - throw new PosixException("native error calling " + methodName + ": " + error.description() + " " + extraData, convert(error)); - } - private org.jruby.ext.posix.POSIX.ERRORS convert(Errno error) { - try { - return org.jruby.ext.posix.POSIX.ERRORS.valueOf(error.name()); - } catch (IllegalArgumentException x) { - return org.jruby.ext.posix.POSIX.ERRORS.EIO; // PosixException.message has real error anyway - } - } - }, true); - } - return posix; - } - - /** - * @deprecated use {@link #jnr} and {@link POSIX#isNative} - */ - @Deprecated - public boolean isNative() { - return supportsNative(); - } - - /** - * @deprecated use {@link #jnr} and {@link POSIX#isNative} - */ - @Deprecated - public static boolean supportsNative() { - return !(jnaPosix instanceof org.jruby.ext.posix.JavaPOSIX); - } - - private static org.jruby.ext.posix.POSIX jnaPosix; - /** @deprecated Use {@link #jnr} instead. */ - @Deprecated - public static synchronized org.jruby.ext.posix.POSIX get() { - if (jnaPosix == null) { - jnaPosix = org.jruby.ext.posix.POSIXFactory.getPOSIX(new org.jruby.ext.posix.POSIXHandler() { - public void error(org.jruby.ext.posix.POSIX.ERRORS errors, String s) { - throw new PosixException(s,errors); - } - - public void unimplementedError(String s) { - throw new UnsupportedOperationException(s); - } - - public void warn(WARNING_ID warning_id, String s, Object... objects) { - LOGGER.fine(s); - } - - public boolean isVerbose() { - return true; - } - - public File getCurrentWorkingDirectory() { - return new File(".").getAbsoluteFile(); - } - - public String[] getEnv() { - Map envs = System.getenv(); - String[] envp = new String[envs.size()]; - - int i = 0; - for (Map.Entry e : envs.entrySet()) { - envp[i++] = e.getKey()+'+'+e.getValue(); - } - return envp; - } - - public InputStream getInputStream() { - return System.in; - } - - public PrintStream getOutputStream() { - return System.out; - } - - public int getPID() { - // TODO - return 0; - } - - public PrintStream getErrorStream() { - return System.err; - } - }, true); - } - return jnaPosix; - } - - private static final Logger LOGGER = Logger.getLogger(PosixAPI.class.getName()); -} diff --git a/core/src/main/java/hudson/os/PosixException.java b/core/src/main/java/hudson/os/PosixException.java index 03cdd50e38b8..b741e94246a6 100644 --- a/core/src/main/java/hudson/os/PosixException.java +++ b/core/src/main/java/hudson/os/PosixException.java @@ -1,28 +1,20 @@ package hudson.os; -import org.jruby.ext.posix.POSIX.ERRORS; +import java.io.IOException; /** * Indicates an error during POSIX API call. - * @see PosixAPI * @author Kohsuke Kawaguchi + * @deprecated use {@link IOException} */ +@Deprecated public class PosixException extends RuntimeException { - private final ERRORS errors; - public PosixException(String message, ERRORS errors) { + public PosixException(String message) { super(message); - this.errors = errors; } - /** @deprecated Leaks reference to deprecated jna-posix API. */ - @Deprecated - public ERRORS getErrorCode() { - return errors; - } - - @Override - public String toString() { - return super.toString()+" "+errors; + public PosixException(String message, Throwable cause) { + super(message, cause); } } diff --git a/core/src/main/java/hudson/os/SU.java b/core/src/main/java/hudson/os/SU.java index 954a1144db0a..185110d83781 100644 --- a/core/src/main/java/hudson/os/SU.java +++ b/core/src/main/java/hudson/os/SU.java @@ -21,9 +21,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.os; +import static hudson.util.jna.GNUCLibrary.LIBC; + import com.sun.solaris.EmbeddedSu; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.FilePath; import hudson.Launcher.LocalLauncher; import hudson.Util; @@ -36,14 +40,12 @@ import hudson.remoting.Which; import hudson.slaves.Channels; import hudson.util.ArgumentListBuilder; - import java.io.File; import java.io.IOException; import java.io.PrintStream; +import java.nio.charset.Charset; import java.util.Collections; -import static hudson.util.jna.GNUCLibrary.*; - /** * Executes {@link Callable} as the super user, by forking a new process and executing the closure in there * if necessary. @@ -71,37 +73,44 @@ private SU() { // not meant to be instantiated * Close this channel and the SU environment will be shut down. */ public static VirtualChannel start(final TaskListener listener, final String rootUsername, final String rootPassword) throws IOException, InterruptedException { - if(File.pathSeparatorChar==';') // on Windows + if (File.pathSeparatorChar == ';') // on Windows return newLocalChannel(); // TODO: perhaps use RunAs to run as an Administrator? String os = Util.fixNull(System.getProperty("os.name")); - if(os.equals("Linux")) + if (os.equals("Linux")) return new UnixSu() { + @Override protected String sudoExe() { return "sudo"; } + @SuppressFBWarnings(value = "COMMAND_INJECTION", justification = "TODO needs triage") + @Override protected Process sudoWithPass(ArgumentListBuilder args) throws IOException { - args.prepend(sudoExe(),"-S"); - listener.getLogger().println("$ "+Util.join(args.toList()," ")); + args.prepend(sudoExe(), "-S"); + listener.getLogger().println("$ " + String.join(" ", args.toList())); ProcessBuilder pb = new ProcessBuilder(args.toCommandArray()); Process p = pb.start(); // TODO: use -p to detect prompt // TODO: detect if the password didn't work - PrintStream ps = new PrintStream(p.getOutputStream()); - ps.println(rootPassword); - ps.println(rootPassword); - ps.println(rootPassword); + try (PrintStream ps = new PrintStream(p.getOutputStream(), false, Charset.defaultCharset().name())) { + ps.println(rootPassword); + ps.println(rootPassword); + ps.println(rootPassword); + } return p; } - }.start(listener,rootPassword); + }.start(listener, rootPassword); - if(os.equals("SunOS")) + if (os.equals("SunOS")) return new UnixSu() { + @Override protected String sudoExe() { return "/usr/bin/pfexec"; } + @SuppressFBWarnings(value = "COMMAND_INJECTION", justification = "TODO needs triage") + @Override protected Process sudoWithPass(ArgumentListBuilder args) throws IOException { listener.getLogger().println("Running with embedded_su"); ProcessBuilder pb = new ProcessBuilder(args.prepend(sudoExe()).toCommandArray()); @@ -109,7 +118,7 @@ protected Process sudoWithPass(ArgumentListBuilder args) throws IOException { } // in solaris, pfexec never asks for a password, so username==null means // we won't be using password. this helps disambiguate empty password - }.start(listener,rootUsername==null?null:rootPassword); + }.start(listener, rootUsername == null ? null : rootPassword); // TODO: Mac? @@ -124,7 +133,7 @@ private static LocalChannel newLocalChannel() { /** * Starts a new privilege-escalated environment, execute a closure, and shut it down. */ - public static V execute(TaskListener listener, String rootUsername, String rootPassword, final Callable closure) throws T, IOException, InterruptedException { + public static V execute(TaskListener listener, String rootUsername, String rootPassword, final Callable closure) throws T, IOException, InterruptedException { VirtualChannel ch = start(listener, rootUsername, rootPassword); try { return ch.call(closure); @@ -143,16 +152,16 @@ private abstract static class UnixSu { VirtualChannel start(TaskListener listener, String rootPassword) throws IOException, InterruptedException { final int uid = LIBC.geteuid(); - if(uid==0) // already running as root + if (uid == 0) // already running as root return newLocalChannel(); String javaExe = System.getProperty("java.home") + "/bin/java"; File agentJar = Which.jarFile(Launcher.class); ArgumentListBuilder args = new ArgumentListBuilder().add(javaExe); - if(agentJar.isFile()) + if (agentJar.isFile()) args.add("-jar").add(agentJar); - else // in production code this never happens, but during debugging this is convenient + else // in production code this never happens, but during debugging this is convenient args.add("-cp").add(agentJar).add(hudson.remoting.Launcher.class.getName()); if (Util.fixEmptyAndTrim(rootPassword) == null) { @@ -164,7 +173,7 @@ VirtualChannel start(TaskListener listener, String rootPassword) throws IOExcept // try sudo with the given password. Also run in pfexec so that we can elevate the privileges Process proc = sudoWithPass(args); return Channels.forProcess(args.toStringWithQuote(), Computer.threadPoolForRemoting, proc, - listener.getLogger() ); + listener.getLogger()); } } } diff --git a/core/src/main/java/hudson/os/WindowsUtil.java b/core/src/main/java/hudson/os/WindowsUtil.java index 116820fac26d..7ec4637e59e1 100644 --- a/core/src/main/java/hudson/os/WindowsUtil.java +++ b/core/src/main/java/hudson/os/WindowsUtil.java @@ -24,15 +24,14 @@ package hudson.os; -import hudson.Functions; -import org.apache.commons.io.IOUtils; - import edu.umd.cs.findbugs.annotations.NonNull; +import hudson.Functions; import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.regex.Pattern; import java.util.stream.Collectors; +import org.apache.commons.io.IOUtils; /** * Utilities for the Windows Platform. diff --git a/core/src/main/java/hudson/scheduler/BaseParser.java b/core/src/main/java/hudson/scheduler/BaseParser.java index e846636d6fed..36a713101177 100644 --- a/core/src/main/java/hudson/scheduler/BaseParser.java +++ b/core/src/main/java/hudson/scheduler/BaseParser.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.scheduler; import antlr.ANTLRException; @@ -38,14 +39,14 @@ */ abstract class BaseParser extends LLkParser { // lower/upper bounds of fields (inclusive) - static final int[] LOWER_BOUNDS = new int[] {0,0,1,1,0}; - static final int[] UPPER_BOUNDS = new int[] {59,23,31,12,7}; + static final int[] LOWER_BOUNDS = new int[] {0, 0, 1, 1, 0}; + static final int[] UPPER_BOUNDS = new int[] {59, 23, 31, 12, 7}; /** * Used to pick a value from within the range */ protected Hash hash = Hash.zero(); - + protected BaseParser(int i) { super(i); } @@ -63,7 +64,7 @@ protected BaseParser(TokenStream tokenStream, int i) { } public void setHash(Hash hash) { - if (hash==null) hash = Hash.zero(); + if (hash == null) hash = Hash.zero(); this.hash = hash; } @@ -72,8 +73,8 @@ protected long doRange(int start, int end, int step, int field) throws ANTLRExce rangeCheck(end, field); if (step <= 0) error(Messages.BaseParser_MustBePositive(step)); - if (start>end) - error(Messages.BaseParser_StartEndReversed(end,start)); + if (start > end) + error(Messages.BaseParser_StartEndReversed(end, start)); long bits = 0; for (int i = start; i <= end; i += step) { @@ -82,8 +83,8 @@ protected long doRange(int start, int end, int step, int field) throws ANTLRExce return bits; } - protected long doRange( int step, int field ) throws ANTLRException { - return doRange( LOWER_BOUNDS[field], UPPER_BOUNDS[field], step, field ); + protected long doRange(int step, int field) throws ANTLRException { + return doRange(LOWER_BOUNDS[field], UPPER_BOUNDS[field], step, field); } /** @@ -95,8 +96,8 @@ protected long doRange( int step, int field ) throws ANTLRException { */ protected long doHash(int step, int field) throws ANTLRException { int u = UPPER_BOUNDS[field]; - if (field==2) u = 28; // day of month can vary depending on month, so to make life simpler, just use [1,28] that's always safe - if (field==4) u = 6; // Both 0 and 7 of day of week are Sunday. For better distribution, limit upper bound to 6 + if (field == 2) u = 28; // day of month can vary depending on month, so to make life simpler, just use [1,28] that's always safe + if (field == 4) u = 6; // Both 0 and 7 of day of week are Sunday. For better distribution, limit upper bound to 6 return doHash(LOWER_BOUNDS[field], u, step, field); } @@ -113,19 +114,19 @@ protected long doHash(int s, int e, int step, int field) throws ANTLRException { } assert bits != 0; return bits; - } else if (step <=0) { + } else if (step <= 0) { error(Messages.BaseParser_MustBePositive(step)); throw new AssertionError(); } else { - assert step==NO_STEP; + assert step == NO_STEP; // step=1 (i.e. omitted) in the case of hash is actually special; means pick one value, not step by 1 - return 1L << (s+hash.next(e+1-s)); + return 1L << (s + hash.next(e + 1 - s)); } } - + protected void rangeCheck(int value, int field) throws ANTLRException { - if( value60) return -1; + while ((bits | (1L << n)) != bits) { + if (n > 60) return -1; n++; } return n; @@ -231,20 +234,20 @@ private int ceil(CronTab c, int n) { * Given a bit mask, finds the first bit that's on, and return its index. */ private int first(CronTab c) { - return ceil(c,0); + return ceil(c, 0); } private int floor(CronTab c, int n) { long bits = bits(c); - while ((bits|(1L<= firstDayOfWeek) { // in crontab, the first DoW is always Sunday, but in Java, it can be Monday or in theory arbitrary other days. // When first DoW is 1/2 Monday, calendar points to 1/2 Monday, setting the DoW to Sunday makes // the calendar moves forward to 1/8 Sunday, instead of 1/1 Sunday. So we need to compensate that effect here. - addTo(c,-7); + addTo(c, -7); } else if (was < firstDayOfWeek && firstDayOfWeek <= v) { // If we wrap the other way around, we need to adjust in the opposite direction of above. addTo(c, 7); @@ -298,7 +316,11 @@ void setTo(Calendar c, int i) { }; private static final CalendarField[] ADJUST_ORDER = { - MONTH, DAY_OF_MONTH, DAY_OF_WEEK, HOUR, MINUTE + MONTH, + DAY_OF_MONTH, + DAY_OF_WEEK, + HOUR, + MINUTE, }; } @@ -341,26 +363,26 @@ public Calendar ceil(Calendar cal) { } for (CalendarField f : CalendarField.ADJUST_ORDER) { int cur = f.valueOf(cal); - int next = f.ceil(this,cur); - if (cur==next) continue; // this field is already in a good shape. move on to next + int next = f.ceil(this, cur); + if (cur == next) continue; // this field is already in a good shape. move on to next // we are modifying this field, so clear all the lower level fields - for (CalendarField l=f.lowerField; l!=null; l=l.lowerField) + for (CalendarField l = f.lowerField; l != null; l = l.lowerField) l.clear(cal); - if (next<0) { + if (next < 0) { // we need to roll over to the next field. f.rollUp(cal, 1); - f.setTo(cal,f.first(this)); + f.setTo(cal, f.first(this)); // since higher order field is affected by this, we need to restart from all over continue OUTER; } else { - f.setTo(cal,next); + f.setTo(cal, next); //check if value was actually set if (f.valueOf(cal) != next) { // we need to roll over to the next field. f.rollUp(cal, 1); - f.setTo(cal,f.first(this)); + f.setTo(cal, f.first(this)); // since higher order field is affected by this, we need to restart from all over continue OUTER; } @@ -411,30 +433,30 @@ public Calendar floor(Calendar cal) { } for (CalendarField f : CalendarField.ADJUST_ORDER) { int cur = f.valueOf(cal); - int next = f.floor(this,cur); - if (cur==next) continue; // this field is already in a good shape. move on to next + int next = f.floor(this, cur); + if (cur == next) continue; // this field is already in a good shape. move on to next // we are modifying this field, so clear all the lower level fields - for (CalendarField l=f.lowerField; l!=null; l=l.lowerField) + for (CalendarField l = f.lowerField; l != null; l = l.lowerField) l.clear(cal); - if (next<0) { + if (next < 0) { // we need to borrow from the next field. - f.rollUp(cal,-1); + f.rollUp(cal, -1); // the problem here, in contrast with the ceil method, is that // the maximum value of the field is not always a fixed value (that is, day of month) // so we zero-clear all the lower fields, set the desired value +1, - f.setTo(cal,f.last(this)); - f.addTo(cal,1); + f.setTo(cal, f.last(this)); + f.addTo(cal, 1); // then subtract a minute to achieve maximum values on all the lower fields, // with the desired value in 'f' - CalendarField.MINUTE.addTo(cal,-1); + CalendarField.MINUTE.addTo(cal, -1); // since higher order field is affected by this, we need to restart from all over continue OUTER; } else { - f.setTo(cal,next); - f.addTo(cal,1); - CalendarField.MINUTE.addTo(cal,-1); + f.setTo(cal, next); + f.addTo(cal, 1); + CalendarField.MINUTE.addTo(cal, -1); if (f.redoAdjustmentIfModified) continue OUTER; // when we modify DAY_OF_MONTH and DAY_OF_WEEK, do it all over from the top } @@ -444,27 +466,28 @@ public Calendar floor(Calendar cal) { } void set(String format, Hash hash) throws ANTLRException { - set(format,1,hash); + set(format, 1, hash); } /** * Returns true if n-th bit is on. */ private boolean checkBits(long bitMask, int n) { - return (bitMask|(1L<0) + if (i > 0) return Messages.CronTab_do_you_really_mean_every_minute_when_you(spec, "H " + spec.substring(spec.indexOf(' ') + 1)); // once we find a sparse rank, upper ranks don't matter break OUTER; @@ -519,9 +542,9 @@ private String toString(String key, long bit) { if (spec.contains("H")) { // if someone is already using H, presumably he knows what it is, so a warning is likely false positive return null; - } else if (spec.startsWith("*/")) {// "*/15 ...." (every N minutes) to hash + } else if (spec.startsWith("*/")) { // "*/15 ...." (every N minutes) to hash return "H" + spec.substring(1); - } else if (spec.matches("\\d+ .+")) {// "0 ..." (certain minute) to hash + } else if (spec.matches("\\d+ .+")) { // "0 ..." (certain minute) to hash return "H " + spec.substring(spec.indexOf(' ') + 1); } else { Matcher m = Pattern.compile("0(,(\\d+)(,\\d+)*)( .+)").matcher(spec); diff --git a/core/src/main/java/hudson/scheduler/CronTabList.java b/core/src/main/java/hudson/scheduler/CronTabList.java index 97dd53dd7676..7a1b4760ff75 100644 --- a/core/src/main/java/hudson/scheduler/CronTabList.java +++ b/core/src/main/java/hudson/scheduler/CronTabList.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,21 +21,20 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.scheduler; import antlr.ANTLRException; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; import java.util.Calendar; -import java.util.TimeZone; import java.util.Collection; +import java.util.TimeZone; import java.util.Vector; -import edu.umd.cs.findbugs.annotations.CheckForNull; -import edu.umd.cs.findbugs.annotations.NonNull; - -import org.kohsuke.accmod.Restricted; -import org.kohsuke.accmod.restrictions.NoExternalUse; - import java.util.logging.Level; import java.util.logging.Logger; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; /** * {@link CronTab} list (logically OR-ed). @@ -54,7 +53,7 @@ public CronTabList(Collection tabs) { */ public synchronized boolean check(Calendar cal) { for (CronTab tab : tabs) { - if(tab.check(cal)) + if (tab.check(cal)) return true; } return false; @@ -72,7 +71,7 @@ public synchronized boolean check(Calendar cal) { public String checkSanity() { for (CronTab tab : tabs) { String s = tab.checkSanity(); - if(s!=null) return s; + if (s != null) return s; } return null; } @@ -93,7 +92,7 @@ public String checkSanity() { } public static CronTabList create(@NonNull String format) throws ANTLRException { - return create(format,null); + return create(format, null); } public static CronTabList create(@NonNull String format, Hash hash) throws ANTLRException { @@ -104,11 +103,11 @@ public static CronTabList create(@NonNull String format, Hash hash) throws ANTLR for (String line : format.split("\\r?\\n")) { lineNumber++; line = line.trim(); - - if(lineNumber == 1 && line.startsWith("TZ=")) { + + if (lineNumber == 1 && line.startsWith("TZ=")) { final String timezoneString = line.replace("TZ=", ""); timezone = getValidTimezone(timezoneString); - if(timezone != null) { + if (timezone != null) { LOGGER.log(Level.CONFIG, "CRON with timezone {0}", timezone); } else { throw new ANTLRException("Invalid or unsupported timezone '" + timezoneString + "'"); @@ -116,15 +115,15 @@ public static CronTabList create(@NonNull String format, Hash hash) throws ANTLR continue; } - if(line.length()==0 || line.startsWith("#")) + if (line.length() == 0 || line.startsWith("#")) continue; // ignorable line try { - r.add(new CronTab(line,lineNumber,hash,timezone)); + r.add(new CronTab(line, lineNumber, hash, timezone)); } catch (ANTLRException e) { - throw new ANTLRException(Messages.CronTabList_InvalidInput(line,e.toString()),e); + throw new ANTLRException(Messages.CronTabList_InvalidInput(line, e.toString()), e); } } - + return new CronTabList(r); } @@ -151,6 +150,6 @@ public static CronTabList create(@NonNull String format, Hash hash) throws ANTLR } return nearest; } - + private static final Logger LOGGER = Logger.getLogger(CronTabList.class.getName()); } diff --git a/core/src/main/java/hudson/scheduler/Hash.java b/core/src/main/java/hudson/scheduler/Hash.java index 833ee87e1c19..86520ed87faa 100644 --- a/core/src/main/java/hudson/scheduler/Hash.java +++ b/core/src/main/java/hudson/scheduler/Hash.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2012, CloudBees, Inc. - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,10 +21,10 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.scheduler; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; - import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -33,16 +33,12 @@ /** * Generates a pseudo-random sequence of integers in the specified range. * - *

    - * {@link CronTab} supports tokens like '@daily', which means "do it once a day". + *

    {@link CronTab} supports tokens like '@daily', which means "do it once a day". * Exactly which time of the day this gets scheduled is randomized --- randomized * in the sense that it's spread out when many jobs choose @daily, but it's at * the same time stable so that every job sticks to a specific time of the day * even after the configuration is updated. * - *

    - * - * * @author Kohsuke Kawaguchi * @since 1.448 */ @@ -54,18 +50,19 @@ public abstract class Hash { */ public abstract int next(int n); + @SuppressFBWarnings(value = "PREDICTABLE_RANDOM", justification = "The random is just used for load distribution.") public static Hash from(String seed) { try { MessageDigest md5 = getMd5(); md5.update(seed.getBytes(StandardCharsets.UTF_8)); byte[] digest = md5.digest(); - for (int i=8; i run; + private transient /*final*/ Run run; @Deprecated protected transient /*final*/ AbstractBuild build; /** * @since 1.568 */ - protected AbstractScmTagAction(Run run) { + protected AbstractScmTagAction(Run run) { this.run = run; this.build = run instanceof AbstractBuild ? (AbstractBuild) run : null; } @@ -65,6 +65,7 @@ protected AbstractScmTagAction(AbstractBuild build) { this((Run) build); } + @Override public final String getUrlName() { // to make this consistent with CVSSCM, even though the name is bit off return "tagBuild"; @@ -73,6 +74,7 @@ public final String getUrlName() { /** * Defaults to {@link SCM#TAG}. */ + @Override protected Permission getPermission() { return SCM.TAG; } @@ -80,7 +82,7 @@ protected Permission getPermission() { /** * @since 1.568 */ - public Run getRun() { + public Run getRun() { return run; } @@ -101,16 +103,17 @@ public String getTooltip() { */ public abstract boolean isTagged(); + @Override protected ACL getACL() { return run.getACL(); } public void doIndex(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { - req.getView(this,chooseAction()).forward(req,rsp); + req.getView(this, chooseAction()).forward(req, rsp); } protected synchronized String chooseAction() { - if(workerThread!=null) + if (workerThread != null) return "inProgress.jelly"; return "tagForm.jelly"; } diff --git a/core/src/main/java/hudson/scm/AutoBrowserHolder.java b/core/src/main/java/hudson/scm/AutoBrowserHolder.java index cd14a15c2808..f851704ba25d 100644 --- a/core/src/main/java/hudson/scm/AutoBrowserHolder.java +++ b/core/src/main/java/hudson/scm/AutoBrowserHolder.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.scm; import hudson.model.AbstractProject; @@ -61,7 +62,7 @@ public RepositoryBrowser get() { return cache; } int g = d.getGeneration(); - if(g!=cacheGeneration) { + if (g != cacheGeneration) { cacheGeneration = g; cache = infer(); } @@ -76,10 +77,10 @@ public RepositoryBrowser get() { * null if no applicable configuration was found. */ private RepositoryBrowser infer() { - for( AbstractProject p : Jenkins.get().allItems(AbstractProject.class) ) { + for (AbstractProject p : Jenkins.get().allItems(AbstractProject.class)) { SCM scm = p.getScm(); - if (scm!=null && scm.getClass()==owner.getClass() && scm.getBrowser()!=null && - ((SCMDescriptor)scm.getDescriptor()).isBrowserReusable(scm,owner)) { + if (scm != null && scm.getClass() == owner.getClass() && scm.getBrowser() != null && + ((SCMDescriptor) scm.getDescriptor()).isBrowserReusable(scm, owner)) { return scm.getBrowser(); } } diff --git a/core/src/main/java/hudson/scm/ChangeLogAnnotator.java b/core/src/main/java/hudson/scm/ChangeLogAnnotator.java index c9544b69a2ff..c76b3f4d0d15 100644 --- a/core/src/main/java/hudson/scm/ChangeLogAnnotator.java +++ b/core/src/main/java/hudson/scm/ChangeLogAnnotator.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.scm; import hudson.Extension; @@ -31,7 +32,6 @@ import hudson.Util; import hudson.model.AbstractBuild; import hudson.model.Run; -import hudson.scm.ChangeLogSet.Entry; import hudson.util.CopyOnWriteList; import java.util.logging.Level; import java.util.logging.Logger; @@ -75,11 +75,11 @@ public abstract class ChangeLogAnnotator implements ExtensionPoint { * add additional annotations into this object. If other annotators * are registered, the object may already contain some markups when this * method is invoked. Never null. {@link MarkupText#getText()} on this instance - * will return the same string as {@link Entry#getMsgEscaped()}. + * will return the same string as {@link ChangeLogSet.Entry#getMsgEscaped()}. * @since 1.568 */ - public void annotate(Run build, Entry change, MarkupText text) { - if (build instanceof AbstractBuild && Util.isOverridden(ChangeLogAnnotator.class, getClass(), "annotate", AbstractBuild.class, Entry.class, MarkupText.class)) { + public void annotate(Run build, ChangeLogSet.Entry change, MarkupText text) { + if (build instanceof AbstractBuild && Util.isOverridden(ChangeLogAnnotator.class, getClass(), "annotate", AbstractBuild.class, ChangeLogSet.Entry.class, MarkupText.class)) { annotate((AbstractBuild) build, change, text); } else { Logger.getLogger(ChangeLogAnnotator.class.getName()).log(Level.WARNING, "You must override the newer overload of annotate from {0}", getClass().getName()); @@ -87,7 +87,7 @@ public void annotate(Run build, Entry change, MarkupText text) { } @Deprecated - public void annotate(AbstractBuild build, Entry change, MarkupText text) { + public void annotate(AbstractBuild build, ChangeLogSet.Entry change, MarkupText text) { annotate((Run) build, change, text); } diff --git a/core/src/main/java/hudson/scm/ChangeLogParser.java b/core/src/main/java/hudson/scm/ChangeLogParser.java index 1c2ac303a93b..f38f83660715 100644 --- a/core/src/main/java/hudson/scm/ChangeLogParser.java +++ b/core/src/main/java/hudson/scm/ChangeLogParser.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,12 +21,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.scm; import hudson.Util; import hudson.model.AbstractBuild; import hudson.model.Run; -import hudson.scm.ChangeLogSet.Entry; import java.io.File; import java.io.IOException; import org.xml.sax.SAXException; @@ -44,7 +44,7 @@ public abstract class ChangeLogParser { /** * @since 1.568 */ - public ChangeLogSet parse(Run build, RepositoryBrowser browser, File changelogFile) throws IOException, SAXException { + public ChangeLogSet parse(Run build, RepositoryBrowser browser, File changelogFile) throws IOException, SAXException { if (build instanceof AbstractBuild && Util.isOverridden(ChangeLogParser.class, getClass(), "parse", AbstractBuild.class, File.class)) { return parse((AbstractBuild) build, changelogFile); } else { @@ -53,7 +53,7 @@ public ChangeLogSet parse(Run build, RepositoryBrowser brows } @Deprecated - public ChangeLogSet parse(AbstractBuild build, File changelogFile) throws IOException, SAXException { + public ChangeLogSet parse(AbstractBuild build, File changelogFile) throws IOException, SAXException { return parse(build, build.getProject().getScm().getEffectiveBrowser(), changelogFile); } } diff --git a/core/src/main/java/hudson/scm/ChangeLogSet.java b/core/src/main/java/hudson/scm/ChangeLogSet.java index 135869989bb2..a0c4a4c9cd79 100644 --- a/core/src/main/java/hudson/scm/ChangeLogSet.java +++ b/core/src/main/java/hudson/scm/ChangeLogSet.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.scm; import hudson.MarkupText; @@ -28,15 +29,14 @@ import hudson.model.AbstractBuild; import hudson.model.Run; import hudson.model.User; -import org.kohsuke.stapler.export.Exported; -import org.kohsuke.stapler.export.ExportedBean; - import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.logging.Logger; +import org.kohsuke.stapler.export.Exported; +import org.kohsuke.stapler.export.ExportedBean; /** * Represents SCM change list. @@ -51,21 +51,21 @@ * * @author Kohsuke Kawaguchi */ -@ExportedBean(defaultVisibility=999) +@ExportedBean(defaultVisibility = 999) public abstract class ChangeLogSet implements Iterable { /** * Build whose change log this object represents. */ - private final Run run; + private final Run run; @Deprecated - public final AbstractBuild build; + public final AbstractBuild build; private final RepositoryBrowser browser; /** * @since 1.568 */ - protected ChangeLogSet(Run run, RepositoryBrowser browser) { + protected ChangeLogSet(Run run, RepositoryBrowser browser) { this.run = run; build = run instanceof AbstractBuild ? (AbstractBuild) run : null; this.browser = browser; @@ -75,7 +75,8 @@ protected ChangeLogSet(Run run, RepositoryBrowser browser) { protected ChangeLogSet(AbstractBuild build) { this(build, browserFromBuild(build)); } - private static RepositoryBrowser browserFromBuild(AbstractBuild build) { + + private static RepositoryBrowser browserFromBuild(AbstractBuild build) { if (build == null) { // not generally allowed, but sometimes done in unit tests return null; } @@ -85,7 +86,7 @@ private static RepositoryBrowser browserFromBuild(AbstractBuild build) { /** * @since 1.568 */ - public Run getRun() { + public Run getRun() { return run; } @@ -102,7 +103,7 @@ public RepositoryBrowser getBrowser() { public abstract boolean isEmptySet(); /** - * All changes in this change set. + * All changes in this change set. */ // method for the remote API. @Exported @@ -136,7 +137,7 @@ public static ChangeLogSet createEmpty(AbstractBui return createEmpty((Run) build); } - @ExportedBean(defaultVisibility=999) + @ExportedBean(defaultVisibility = 999) public abstract static class Entry { private ChangeLogSet parent; @@ -217,29 +218,29 @@ public long getTimestamp() { */ @Exported public abstract Collection getAffectedPaths(); - + /** * Returns a set of paths in the workspace that was * affected by this change. *

    - * Noted: since this is a new interface, some of the SCMs may not have - * implemented this interface. The default implementation for this + * Noted: since this is a new interface, some of the SCMs may not have + * implemented this interface. The default implementation for this * interface is throw UnsupportedOperationException *

    - * It doesn't throw NoSuchMethodException because I rather to throw a + * It doesn't throw NoSuchMethodException because I rather to throw a * runtime exception * * @return AffectedFile never null. * @since 1.309 */ public Collection getAffectedFiles() { - String scm = "this SCM"; - ChangeLogSet parent = getParent(); - if ( null != parent ) { - String kind = parent.getKind(); - if ( null != kind && kind.trim().length() > 0 ) scm = kind; - } - throw new UnsupportedOperationException("getAffectedFiles() is not implemented by " + scm); + String scm = "this SCM"; + ChangeLogSet parent = getParent(); + if (null != parent) { + String kind = parent.getKind(); + if (null != kind && kind.trim().length() > 0) scm = kind; + } + throw new UnsupportedOperationException("getAffectedFiles() is not implemented by " + scm); } /** @@ -250,10 +251,10 @@ public String getMsgAnnotated() { for (ChangeLogAnnotator a : ChangeLogAnnotator.all()) try { a.annotate(parent.run, this, markup); - } catch(Exception e) { + } catch (RuntimeException e) { LOGGER.info("ChangeLogAnnotator " + a.toString() + " failed to annotate message '" + getMsg() + "'; " + e.getMessage()); - } catch(Error e) { - LOGGER.severe("ChangeLogAnnotator " + a.toString() + " failed to annotate message '" + getMsg() + "'; " + e.getMessage()); + } catch (Error e) { + LOGGER.severe("ChangeLogAnnotator " + a + " failed to annotate message '" + getMsg() + "'; " + e.getMessage()); } return markup.toString(false); @@ -265,13 +266,13 @@ public String getMsgAnnotated() { public String getMsgEscaped() { return Util.escape(getMsg()); } - + static final Logger LOGGER = Logger.getLogger(ChangeLogSet.Entry.class.getName()); } - + /** * Represents a file change. Contains filename, edit type, etc. - * + * * I checked the API names against some some major SCMs and most SCMs * can adapt to this interface with very little changes * @@ -287,8 +288,8 @@ public interface AffectedFile { * @return never null. */ String getPath(); - - + + /** * Return whether the file is new/modified/deleted */ diff --git a/core/src/main/java/hudson/scm/EditType.java b/core/src/main/java/hudson/scm/EditType.java index d604fe45f09a..7672b09db2e4 100644 --- a/core/src/main/java/hudson/scm/EditType.java +++ b/core/src/main/java/hudson/scm/EditType.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,13 +21,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package hudson.scm; -import org.kohsuke.stapler.export.CustomExportedBean; +package hudson.scm; -import java.util.List; -import java.util.Collections; import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import org.kohsuke.stapler.export.CustomExportedBean; /** * Designates the SCM operation. @@ -51,13 +51,14 @@ public String getDescription() { return description; } + @Override public String toExportedObject() { return name; } - public static final EditType ADD = new EditType("add","The file was added"); - public static final EditType EDIT = new EditType("edit","The file was modified"); - public static final EditType DELETE = new EditType("delete","The file was removed"); + public static final EditType ADD = new EditType("add", "The file was added"); + public static final EditType EDIT = new EditType("edit", "The file was modified"); + public static final EditType DELETE = new EditType("delete", "The file was removed"); - public static final List ALL = Collections.unmodifiableList(Arrays.asList(ADD,EDIT,DELETE)); + public static final List ALL = Collections.unmodifiableList(Arrays.asList(ADD, EDIT, DELETE)); } diff --git a/core/src/main/java/hudson/scm/EmptyChangeLogSet.java b/core/src/main/java/hudson/scm/EmptyChangeLogSet.java index 1a933b2fd651..2f5ffdcbff8b 100644 --- a/core/src/main/java/hudson/scm/EmptyChangeLogSet.java +++ b/core/src/main/java/hudson/scm/EmptyChangeLogSet.java @@ -3,7 +3,6 @@ import hudson.model.Run; import java.io.IOException; import java.net.URL; - import java.util.Collections; import java.util.Iterator; @@ -26,6 +25,7 @@ public boolean isEmptySet() { return true; } + @Override public Iterator iterator() { return Collections.emptyIterator(); } diff --git a/core/src/main/java/hudson/scm/NullChangeLogParser.java b/core/src/main/java/hudson/scm/NullChangeLogParser.java index d78a03cce3e6..2832ede7c4b0 100644 --- a/core/src/main/java/hudson/scm/NullChangeLogParser.java +++ b/core/src/main/java/hudson/scm/NullChangeLogParser.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,26 +21,26 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.scm; import hudson.model.Run; -import org.xml.sax.SAXException; - import java.io.File; import java.io.IOException; +import org.xml.sax.SAXException; /** * {@link ChangeLogParser} for no SCM. * @author Kohsuke Kawaguchi */ public class NullChangeLogParser extends ChangeLogParser { - + public static final NullChangeLogParser INSTANCE = new NullChangeLogParser(); - + @Override public ChangeLogSet parse(Run build, RepositoryBrowser browser, File changelogFile) throws IOException, SAXException { return ChangeLogSet.createEmpty(build); } - + protected Object readResolve() { return INSTANCE; } diff --git a/core/src/main/java/hudson/scm/NullSCM.java b/core/src/main/java/hudson/scm/NullSCM.java index 777db3759e47..8d7781688655 100644 --- a/core/src/main/java/hudson/scm/NullSCM.java +++ b/core/src/main/java/hudson/scm/NullSCM.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.scm; import hudson.Extension; @@ -48,11 +49,11 @@ public NullSCM() {} return null; } - @Override public PollingResult compareRemoteRevisionWith(Job project, Launcher launcher, FilePath workspace, TaskListener listener, SCMRevisionState baseline) throws IOException, InterruptedException { + @Override public PollingResult compareRemoteRevisionWith(Job project, Launcher launcher, FilePath workspace, TaskListener listener, SCMRevisionState baseline) throws IOException, InterruptedException { return PollingResult.NO_CHANGES; } - @Override public void checkout(Run build, Launcher launcher, FilePath workspace, TaskListener listener, File changelogFile, SCMRevisionState baseline) throws IOException, InterruptedException { + @Override public void checkout(Run build, Launcher launcher, FilePath workspace, TaskListener listener, File changelogFile, SCMRevisionState baseline) throws IOException, InterruptedException { if (changelogFile != null) { createEmptyChangeLog(changelogFile, listener, "log"); } diff --git a/core/src/main/java/hudson/scm/PollingResult.java b/core/src/main/java/hudson/scm/PollingResult.java index 718b98cfc2e7..bfcb135a63b9 100644 --- a/core/src/main/java/hudson/scm/PollingResult.java +++ b/core/src/main/java/hudson/scm/PollingResult.java @@ -1,13 +1,12 @@ package hudson.scm; -import hudson.model.AbstractProject; -import hudson.model.TaskListener; -import hudson.Launcher; -import hudson.FilePath; - import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.NonNull; -import java.io.Serializable; +import hudson.FilePath; +import hudson.Launcher; +import hudson.model.AbstractProject; +import hudson.model.TaskListener; +import org.jenkinsci.remoting.SerializableOnlyOverRemoting; /** * Immutable object that represents the result of {@linkplain SCM#poll(AbstractProject, Launcher, FilePath, TaskListener, SCMRevisionState) SCM polling}. @@ -19,7 +18,7 @@ * @author Kohsuke Kawaguchi * @since 1.345 */ -public final class PollingResult implements Serializable { +public final class PollingResult implements SerializableOnlyOverRemoting { /** * Baseline of the comparison. * (This comes from either the workspace, or from the remote repository as of the last polling. @@ -80,14 +79,14 @@ public enum Change { } public PollingResult(@CheckForNull SCMRevisionState baseline, @CheckForNull SCMRevisionState remote, @NonNull Change change) { - if (change==null) throw new IllegalArgumentException(); + if (change == null) throw new IllegalArgumentException(); this.baseline = baseline; this.remote = remote; this.change = change; } public PollingResult(@NonNull Change change) { - this(null,null,change); + this(null, null, change); } public boolean hasChanges() { diff --git a/core/src/main/java/hudson/scm/RepositoryBrowser.java b/core/src/main/java/hudson/scm/RepositoryBrowser.java index d890d9970ce9..05b095b02bce 100644 --- a/core/src/main/java/hudson/scm/RepositoryBrowser.java +++ b/core/src/main/java/hudson/scm/RepositoryBrowser.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,25 +21,24 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.scm; -import hudson.ExtensionPoint; import hudson.DescriptorExtensionList; import hudson.Extension; +import hudson.ExtensionPoint; import hudson.model.AbstractDescribableImpl; import hudson.model.Descriptor; -import jenkins.model.Jenkins; - import java.io.IOException; import java.io.Serializable; -import java.net.URL; import java.net.MalformedURLException; - +import java.net.URL; +import jenkins.model.Jenkins; import org.kohsuke.stapler.export.ExportedBean; /** * Connects Hudson to repository browsers like ViewCVS or FishEye, - * so that Hudson can generate links to them. + * so that Hudson can generate links to them. * *

    * {@link RepositoryBrowser} instance is normally created as @@ -72,24 +71,24 @@ public abstract class RepositoryBrowser extends Ab * If the given string starts with '/', return a string that removes it. */ protected static String trimHeadSlash(String s) { - if(s.startsWith("/")) return s.substring(1); + if (s.startsWith("/")) return s.substring(1); return s; } /** * Normalize the URL so that it ends with '/'. *

    - * An attention is paid to preserve the query parameters in URL if any. + * An attention is paid to preserve the query parameters in URL if any. */ protected static URL normalizeToEndWithSlash(URL url) { - if(url.getPath().endsWith("/")) + if (url.getPath().endsWith("/")) return url; // normalize String q = url.getQuery(); - q = q!=null?('?'+q):""; + q = q != null ? '?' + q : ""; try { - return new URL(url,url.getPath()+'/'+q); + return new URL(url, url.getPath() + '/' + q); } catch (MalformedURLException e) { // impossible throw new Error(e); @@ -99,7 +98,7 @@ protected static URL normalizeToEndWithSlash(URL url) { /** * Returns all the registered {@link RepositoryBrowser} descriptors. */ - public static DescriptorExtensionList,Descriptor>> all() { + public static DescriptorExtensionList, Descriptor>> all() { return (DescriptorExtensionList) Jenkins.get().getDescriptorList(RepositoryBrowser.class); } diff --git a/core/src/main/java/hudson/scm/RepositoryBrowsers.java b/core/src/main/java/hudson/scm/RepositoryBrowsers.java index 11b034f119bd..0a1e28d1a152 100644 --- a/core/src/main/java/hudson/scm/RepositoryBrowsers.java +++ b/core/src/main/java/hudson/scm/RepositoryBrowsers.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Daniel Dyer, Stephen Connolly - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,18 +21,17 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.scm; +import hudson.Extension; import hudson.model.Descriptor; import hudson.model.Descriptor.FormException; import hudson.util.DescriptorList; -import hudson.Extension; -import org.kohsuke.stapler.StaplerRequest; - import java.util.ArrayList; import java.util.List; - import net.sf.json.JSONObject; +import org.kohsuke.stapler.StaplerRequest; /** * List of all installed {@link RepositoryBrowsers}. @@ -47,7 +46,7 @@ public class RepositoryBrowsers { * Use {@link RepositoryBrowser#all()} for read access and {@link Extension} for registration. */ @Deprecated - public static final List>> LIST = new DescriptorList>((Class)RepositoryBrowser.class); + public static final List>> LIST = new DescriptorList>((Class) RepositoryBrowser.class); /** * Only returns those {@link RepositoryBrowser} descriptors that extend from the given type. @@ -55,7 +54,7 @@ public class RepositoryBrowsers { public static List>> filter(Class t) { List>> r = new ArrayList<>(); for (Descriptor> d : RepositoryBrowser.all()) - if(d.isSubTypeOf(t)) + if (d.isSubTypeOf(t)) r.add(d); return r; } @@ -71,7 +70,7 @@ public static List>> filter(Class type, StaplerRequest req, String fieldName) throws FormException { List>> list = filter(type); String value = req.getParameter(fieldName); - if(value==null || value.equals("auto")) + if (value == null || value.equals("auto")) return null; // TODO: There was a TODO in the original code, which presumes passing something meaningful to the newInstance() JSON param @@ -87,9 +86,9 @@ T createInstance(Class type, StaplerRequest req, String fieldName) throws For */ public static T createInstance(Class type, StaplerRequest req, JSONObject parent, String fieldName) throws FormException { - JSONObject o = (JSONObject)parent.get(fieldName); - if(o==null) return null; + JSONObject o = (JSONObject) parent.get(fieldName); + if (o == null) return null; - return req.bindJSON(type,o); + return req.bindJSON(type, o); } } diff --git a/core/src/main/java/hudson/scm/SCM.java b/core/src/main/java/hudson/scm/SCM.java index 45ff31bd6015..c00bcea16229 100644 --- a/core/src/main/java/hudson/scm/SCM.java +++ b/core/src/main/java/hudson/scm/SCM.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Stephen Connolly, InfraDNA, Inc. - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,8 +21,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.scm; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.Nullable; import hudson.AbortException; import hudson.DescriptorExtensionList; import hudson.Extension; @@ -49,16 +53,15 @@ import hudson.security.PermissionScope; import hudson.tasks.Builder; import java.io.File; -import java.io.FileWriter; import java.io.IOException; +import java.io.Writer; +import java.nio.charset.Charset; +import java.nio.file.Files; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; -import edu.umd.cs.findbugs.annotations.CheckForNull; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; import jenkins.model.Jenkins; import jenkins.util.SystemProperties; import org.kohsuke.stapler.export.Exported; @@ -80,7 +83,7 @@ * *

    * If you are interested in writing a subclass in a plugin, - * also take a look at + * also take a look at * "Writing an SCM plugin" wiki article. * * @author Kohsuke Kawaguchi @@ -137,10 +140,10 @@ public String getType() { * @see #guessBrowser */ @SuppressWarnings("deprecation") - @Exported(name="browser") + @Exported(name = "browser") public final @CheckForNull RepositoryBrowser getEffectiveBrowser() { RepositoryBrowser b = getBrowser(); - if(b!=null) + if (b != null) return b; if (useAutoBrowserHolder) { if (autoBrowserHolder == null) { @@ -166,14 +169,14 @@ public String getType() { public boolean supportsPolling() { return true; } - + /** * Returns true if this SCM requires a checked out workspace for doing polling. * *

    * This flag affects the behavior of Hudson when a job lost its workspace - * (typically due to a agent outage.) If this method returns false and - * polling is configured, then that would immediately trigger a new build. + * (typically due to a agent outage.) If this method returns true and + * polling is configured, then that would usually trigger a new build. * *

    * This flag also affects the mutual exclusion control between builds and polling. @@ -185,12 +188,12 @@ public boolean supportsPolling() { * The default implementation returns true. * *

    - * See issue #1348 for more discussion of this feature. + * See issue JENKINS-1348 for more discussion of this feature. * * @since 1.196 */ public boolean requiresWorkspaceForPolling() { - return true; + return true; } /** @@ -229,10 +232,10 @@ public boolean requiresWorkspaceForPolling() { * @return * true if {@link SCM} is OK to let Hudson proceed with deleting the workspace. * False to veto the workspace deletion. - * + * * @since 1.568 */ - public boolean processWorkspaceBeforeDeletion(@NonNull Job project, @NonNull FilePath workspace, @NonNull Node node) throws IOException, InterruptedException { + public boolean processWorkspaceBeforeDeletion(@NonNull Job project, @NonNull FilePath workspace, @NonNull Node node) throws IOException, InterruptedException { if (project instanceof AbstractProject) { return processWorkspaceBeforeDeletion((AbstractProject) project, workspace, node); } else { @@ -241,7 +244,7 @@ public boolean processWorkspaceBeforeDeletion(@NonNull Job project, @NonNul } @Deprecated - public boolean processWorkspaceBeforeDeletion(AbstractProject project, FilePath workspace, Node node) throws IOException, InterruptedException { + public boolean processWorkspaceBeforeDeletion(AbstractProject project, FilePath workspace, Node node) throws IOException, InterruptedException { if (Util.isOverridden(SCM.class, getClass(), "processWorkspaceBeforeDeletion", Job.class, FilePath.class, Node.class)) { return processWorkspaceBeforeDeletion((Job) project, workspace, node); } else { @@ -289,7 +292,7 @@ public boolean processWorkspaceBeforeDeletion(AbstractProject project, File * Call {@link #poll(AbstractProject, Launcher, FilePath, TaskListener, SCMRevisionState)} for use instead. */ @Deprecated - public boolean pollChanges(AbstractProject project, Launcher launcher, FilePath workspace, TaskListener listener) throws IOException, InterruptedException { + public boolean pollChanges(AbstractProject project, Launcher launcher, FilePath workspace, TaskListener listener) throws IOException, InterruptedException { // up until 1.336, this method was abstract, so everyone should have overridden this method // without calling super.pollChanges. So the compatibility implementation is purely for // new implementations that doesn't override this method. @@ -311,7 +314,7 @@ public boolean pollChanges(AbstractProject project, Launcher launcher, File *

    * The obtained object is added to the build as an {@link Action} for later retrieval. As an optimization, * {@link SCM} implementation can choose to compute {@link SCMRevisionState} and add it as an action - * during check out, in which case this method will not called. + * during check out, in which case this method will not called. * * @param build * The calculated {@link SCMRevisionState} is for the files checked out in this build. @@ -326,10 +329,10 @@ public boolean pollChanges(AbstractProject project, Launcher launcher, File * * @throws InterruptedException * interruption is usually caused by the user aborting the computation. - * this exception should be simply propagated all the way up. + * this exception should be simply propagated all the way up. * @since 1.568 */ - public @CheckForNull SCMRevisionState calcRevisionsFromBuild(@NonNull Run build, @Nullable FilePath workspace, @Nullable Launcher launcher, @NonNull TaskListener listener) throws IOException, InterruptedException { + public @CheckForNull SCMRevisionState calcRevisionsFromBuild(@NonNull Run build, @Nullable FilePath workspace, @Nullable Launcher launcher, @NonNull TaskListener listener) throws IOException, InterruptedException { if (build instanceof AbstractBuild && Util.isOverridden(SCM.class, getClass(), "calcRevisionsFromBuild", AbstractBuild.class, Launcher.class, TaskListener.class)) { return calcRevisionsFromBuild((AbstractBuild) build, launcher, listener); } else { @@ -338,7 +341,7 @@ public boolean pollChanges(AbstractProject project, Launcher launcher, File } @Deprecated - public SCMRevisionState calcRevisionsFromBuild(AbstractBuild build, Launcher launcher, TaskListener listener) throws IOException, InterruptedException { + public SCMRevisionState calcRevisionsFromBuild(AbstractBuild build, Launcher launcher, TaskListener listener) throws IOException, InterruptedException { return calcRevisionsFromBuild(build, launcher != null ? build.getWorkspace() : null, launcher, listener); } @@ -346,7 +349,7 @@ public SCMRevisionState calcRevisionsFromBuild(AbstractBuild build, Launche public SCMRevisionState _calcRevisionsFromBuild(AbstractBuild build, Launcher launcher, TaskListener listener) throws IOException, InterruptedException { return calcRevisionsFromBuild(build, launcher, listener); } - + /** * Compares the current state of the remote repository against the given baseline {@link SCMRevisionState}. * @@ -355,7 +358,7 @@ public SCMRevisionState _calcRevisionsFromBuild(AbstractBuild build, Launc * if there's any difference. In practice, however, comparing two arbitrary repository states is an expensive * operation, so in this abstraction, we chose to mix (1) the act of building up a repository state and * (2) the act of comparing it with the earlier state, so that SCM implementations can implement this - * more easily. + * more easily. * *

    * Multiple invocations of this method may happen over time to make sure that the remote repository @@ -388,8 +391,23 @@ public SCMRevisionState _calcRevisionsFromBuild(AbstractBuild build, Launc * this exception should be simply propagated all the way up. * @since 1.568 */ - public PollingResult compareRemoteRevisionWith(@NonNull Job project, @Nullable Launcher launcher, @Nullable FilePath workspace, @NonNull TaskListener listener, @NonNull SCMRevisionState baseline) throws IOException, InterruptedException { - if (project instanceof AbstractProject && Util.isOverridden(SCM.class, getClass(), "compareRemoteRevisionWith", AbstractProject.class, Launcher.class, FilePath.class, TaskListener.class, SCMRevisionState.class)) { + public PollingResult compareRemoteRevisionWith( + @NonNull Job project, + @Nullable Launcher launcher, + @Nullable FilePath workspace, + @NonNull TaskListener listener, + @NonNull SCMRevisionState baseline) + throws IOException, InterruptedException { + if (project instanceof AbstractProject + && Util.isOverridden( + SCM.class, + getClass(), + "compareRemoteRevisionWith", + AbstractProject.class, + Launcher.class, + FilePath.class, + TaskListener.class, + SCMRevisionState.class)) { return compareRemoteRevisionWith((AbstractProject) project, launcher, workspace, listener, baseline); } else { throw new AbstractMethodError("you must override the new overload of compareRemoteRevisionWith"); @@ -397,19 +415,19 @@ public PollingResult compareRemoteRevisionWith(@NonNull Job project, @Nulla } @Deprecated - protected PollingResult compareRemoteRevisionWith(AbstractProject project, Launcher launcher, FilePath workspace, TaskListener listener, SCMRevisionState baseline) throws IOException, InterruptedException { + protected PollingResult compareRemoteRevisionWith(AbstractProject project, Launcher launcher, FilePath workspace, TaskListener listener, SCMRevisionState baseline) throws IOException, InterruptedException { return compareRemoteRevisionWith((Job) project, launcher, workspace, listener, baseline); } /** * Convenience method for the caller to handle the backward compatibility between pre 1.345 SCMs. */ - public final PollingResult poll(AbstractProject project, Launcher launcher, FilePath workspace, TaskListener listener, SCMRevisionState baseline) throws IOException, InterruptedException { + public final PollingResult poll(AbstractProject project, Launcher launcher, FilePath workspace, TaskListener listener, SCMRevisionState baseline) throws IOException, InterruptedException { if (is1_346OrLater()) { - // This is to work around HUDSON-5827 in a general way. + // This is to work around JENKINS-5827 in a general way. // don't let the SCM.compareRemoteRevisionWith(...) see SCMRevisionState that it didn't produce. SCMRevisionState baseline2; - if (baseline!=SCMRevisionState.NONE) { + if (baseline != SCMRevisionState.NONE) { baseline2 = baseline; } else { baseline2 = calcRevisionsFromBuild(project.getLastBuild(), launcher, listener); @@ -417,7 +435,7 @@ public final PollingResult poll(AbstractProject project, Launcher launcher, return compareRemoteRevisionWith(project, launcher, workspace, listener, baseline2); } else { - return pollChanges(project,launcher,workspace,listener) ? PollingResult.SIGNIFICANT : PollingResult.NO_CHANGES; + return pollChanges(project, launcher, workspace, listener) ? PollingResult.SIGNIFICANT : PollingResult.NO_CHANGES; } } @@ -430,7 +448,7 @@ private boolean is1_346OrLater() { try { c.getDeclaredMethod("compareRemoteRevisionWith", Job.class, Launcher.class, FilePath.class, TaskListener.class, SCMRevisionState.class); return true; - } catch (NoSuchMethodException e2) {} + } catch (NoSuchMethodException e2) { } } } return false; @@ -478,8 +496,25 @@ private boolean is1_346OrLater() { * @throws AbortException in case of a routine failure * @since 1.568 */ - public void checkout(@NonNull Run build, @NonNull Launcher launcher, @NonNull FilePath workspace, @NonNull TaskListener listener, @CheckForNull File changelogFile, @CheckForNull SCMRevisionState baseline) throws IOException, InterruptedException { - if (build instanceof AbstractBuild && listener instanceof BuildListener && Util.isOverridden(SCM.class, getClass(), "checkout", AbstractBuild.class, Launcher.class, FilePath.class, BuildListener.class, File.class)) { + public void checkout( + @NonNull Run build, + @NonNull Launcher launcher, + @NonNull FilePath workspace, + @NonNull TaskListener listener, + @CheckForNull File changelogFile, + @CheckForNull SCMRevisionState baseline) + throws IOException, InterruptedException { + if (build instanceof AbstractBuild + && listener instanceof BuildListener + && Util.isOverridden( + SCM.class, + getClass(), + "checkout", + AbstractBuild.class, + Launcher.class, + FilePath.class, + BuildListener.class, + File.class)) { if (changelogFile == null) { changelogFile = File.createTempFile("changelog", ".xml"); try { @@ -500,8 +535,8 @@ public void checkout(@NonNull Run build, @NonNull Launcher launcher, @NonNu } @Deprecated - public boolean checkout(AbstractBuild build, Launcher launcher, FilePath workspace, BuildListener listener, @NonNull File changelogFile) throws IOException, InterruptedException { - AbstractBuild prev = build.getPreviousBuild(); + public boolean checkout(AbstractBuild build, Launcher launcher, FilePath workspace, BuildListener listener, @NonNull File changelogFile) throws IOException, InterruptedException { + AbstractBuild prev = build.getPreviousBuild(); checkout((Run) build, launcher, workspace, listener, changelogFile, prev != null ? prev.getAction(SCMRevisionState.class) : null); return true; } @@ -510,14 +545,14 @@ public boolean checkout(AbstractBuild build, Launcher launcher, FilePath wo * Get a chance to do operations after the workspace i checked out and the changelog is written. * @since 1.568 */ - public void postCheckout(@NonNull Run build, @NonNull Launcher launcher, @NonNull FilePath workspace, @NonNull TaskListener listener) throws IOException, InterruptedException { + public void postCheckout(@NonNull Run build, @NonNull Launcher launcher, @NonNull FilePath workspace, @NonNull TaskListener listener) throws IOException, InterruptedException { if (build instanceof AbstractBuild && listener instanceof BuildListener) { postCheckout((AbstractBuild) build, launcher, workspace, (BuildListener) listener); } } @Deprecated - public void postCheckout(AbstractBuild build, Launcher launcher, FilePath workspace, BuildListener listener) throws IOException, InterruptedException { + public void postCheckout(AbstractBuild build, Launcher launcher, FilePath workspace, BuildListener listener) throws IOException, InterruptedException { if (Util.isOverridden(SCM.class, getClass(), "postCheckout", Run.class, Launcher.class, FilePath.class, TaskListener.class)) { postCheckout((Run) build, launcher, workspace, listener); } @@ -539,9 +574,9 @@ public void postCheckout(AbstractBuild build, Launcher launcher, FilePath w * * @since 2.60 */ - public void buildEnvironment(@NonNull Run build, @NonNull Map env) { + public void buildEnvironment(@NonNull Run build, @NonNull Map env) { if (build instanceof AbstractBuild) { - buildEnvVars((AbstractBuild)build, env); + buildEnvVars((AbstractBuild) build, env); } } @@ -549,7 +584,7 @@ public void buildEnvironment(@NonNull Run build, @NonNull Map build, Map env) { + public void buildEnvVars(AbstractBuild build, Map env) { if (Util.isOverridden(SCM.class, getClass(), "buildEnvironment", Run.class, Map.class)) { buildEnvironment(build, env); } @@ -608,16 +643,16 @@ public FilePath getModuleRoot(FilePath workspace, AbstractBuild build) { // For backwards compatibility, call the one argument version of the method. return getModuleRoot(workspace); } - + /** * @deprecated since 1.382 * Use/override {@link #getModuleRoot(FilePath, AbstractBuild)} instead. */ @Deprecated public FilePath getModuleRoot(FilePath workspace) { - if (Util.isOverridden(SCM.class,getClass(),"getModuleRoot", FilePath.class,AbstractBuild.class)) + if (Util.isOverridden(SCM.class, getClass(), "getModuleRoot", FilePath.class, AbstractBuild.class)) // if the subtype already implements newer getModuleRoot(FilePath,AbstractBuild), call that. - return getModuleRoot(workspace,null); + return getModuleRoot(workspace, null); return workspace; } @@ -656,23 +691,23 @@ public FilePath getModuleRoot(FilePath workspace) { * @since 1.382 */ public FilePath[] getModuleRoots(FilePath workspace, AbstractBuild build) { - if (Util.isOverridden(SCM.class,getClass(),"getModuleRoots", FilePath.class)) + if (Util.isOverridden(SCM.class, getClass(), "getModuleRoots", FilePath.class)) // if the subtype derives legacy getModuleRoots(FilePath), delegate to it return getModuleRoots(workspace); // otherwise the default implementation - return new FilePath[]{getModuleRoot(workspace,build)}; + return new FilePath[]{getModuleRoot(workspace, build)}; } - + /** * @deprecated as of 1.382. * Use/derive from {@link #getModuleRoots(FilePath, AbstractBuild)} instead. */ @Deprecated public FilePath[] getModuleRoots(FilePath workspace) { - if (Util.isOverridden(SCM.class,getClass(),"getModuleRoots", FilePath.class, AbstractBuild.class)) + if (Util.isOverridden(SCM.class, getClass(), "getModuleRoots", FilePath.class, AbstractBuild.class)) // if the subtype already derives newer getModuleRoots(FilePath,AbstractBuild), delegate to it - return getModuleRoots(workspace,null); + return getModuleRoots(workspace, null); // otherwise the default implementation return new FilePath[] { getModuleRoot(workspace), }; @@ -683,6 +718,7 @@ public FilePath[] getModuleRoots(FilePath workspace) { */ public abstract ChangeLogParser createChangeLogParser(); + @Override public SCMDescriptor getDescriptor() { return (SCMDescriptor) Jenkins.get().getDescriptorOrDie(getClass()); } @@ -706,14 +742,14 @@ protected final boolean createEmptyChangeLog(File changelogFile, BuildListener l * @since 1.568 */ protected final void createEmptyChangeLog(@NonNull File changelogFile, @NonNull TaskListener listener, @NonNull String rootTag) throws IOException { - try (FileWriter w = new FileWriter(changelogFile)) { - w.write("<"+rootTag +"/>"); + try (Writer w = Files.newBufferedWriter(Util.fileToPath(changelogFile), Charset.defaultCharset())) { + w.write("<" + rootTag + "/>"); } } protected final String nullify(String s) { - if(s==null) return null; - if(s.trim().length()==0) return null; + if (s == null) return null; + if (s.trim().length() == 0) return null; return s; } @@ -722,12 +758,12 @@ protected final String nullify(String s) { * Permission to create new tags. * @since 1.171 */ - public static final Permission TAG = new Permission(PERMISSIONS,"Tag",Messages._SCM_TagPermission_Description(),Permission.CREATE, PermissionScope.ITEM); + public static final Permission TAG = new Permission(PERMISSIONS, "Tag", Messages._SCM_TagPermission_Description(), Permission.CREATE, PermissionScope.ITEM); /** * Returns all the registered {@link SCMDescriptor}s. */ - public static DescriptorExtensionList> all() { + public static DescriptorExtensionList> all() { return Jenkins.get().getDescriptorList(SCM.class); } @@ -739,16 +775,16 @@ public static DescriptorExtensionList> all() { * @since 1.568 */ public static List> _for(@CheckForNull final Job project) { - if(project==null) return all(); - + if (project == null) return all(); + final Descriptor pd = Jenkins.get().getDescriptor((Class) project.getClass()); List> r = new ArrayList<>(); for (SCMDescriptor scmDescriptor : all()) { - if(!scmDescriptor.isApplicable(project)) continue; + if (!scmDescriptor.isApplicable(project)) continue; if (pd instanceof TopLevelItemDescriptor) { TopLevelItemDescriptor apd = (TopLevelItemDescriptor) pd; - if(!apd.isApplicable(scmDescriptor)) continue; + if (!apd.isApplicable(scmDescriptor)) continue; } r.add(scmDescriptor); diff --git a/core/src/main/java/hudson/scm/SCMDescriptor.java b/core/src/main/java/hudson/scm/SCMDescriptor.java index d6ace3af5395..b9a600a9a324 100644 --- a/core/src/main/java/hudson/scm/SCMDescriptor.java +++ b/core/src/main/java/hudson/scm/SCMDescriptor.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,23 +21,23 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.scm; +import static java.util.logging.Level.WARNING; + import hudson.RestrictedSince; import hudson.Util; import hudson.model.AbstractProject; import hudson.model.Descriptor; import hudson.model.Job; -import org.kohsuke.accmod.Restricted; -import org.kohsuke.accmod.restrictions.NoExternalUse; - import java.lang.reflect.Field; import java.util.Collections; import java.util.List; -import static java.util.logging.Level.WARNING; - import java.util.concurrent.atomic.AtomicInteger; import java.util.logging.Logger; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; /** * {@link Descriptor} for {@link SCM}. @@ -53,7 +53,7 @@ public abstract class SCMDescriptor extends Descriptor { * that type. Otherwise this SCM will not have any repository browser. */ public final transient Class repositoryBrowser; - + private final transient AtomicInteger atomicGeneration = new AtomicInteger(1); protected SCMDescriptor(Class clazz, Class repositoryBrowser) { @@ -95,20 +95,20 @@ public void incrementGeneration() { atomicGeneration.incrementAndGet(); } - // work around HUDSON-4514. The repositoryBrowser field was marked as non-transient until 1.325, + // work around JENKINS-4514. The repositoryBrowser field was marked as non-transient until 1.325, // causing the field to be persisted and overwritten on the load method. - @SuppressWarnings({"ConstantConditions"}) + @SuppressWarnings("ConstantConditions") @Override public void load() { Class rb = repositoryBrowser; super.load(); - if (repositoryBrowser!=rb) { // XStream may overwrite even the final field. + if (repositoryBrowser != rb) { // XStream may overwrite even the final field. try { Field f = SCMDescriptor.class.getDeclaredField("repositoryBrowser"); f.setAccessible(true); - f.set(this,rb); + f.set(this, rb); } catch (NoSuchFieldException | IllegalAccessException e) { - LOGGER.log(WARNING, "Failed to overwrite the repositoryBrowser field",e); + LOGGER.log(WARNING, "Failed to overwrite the repositoryBrowser field", e); } } } @@ -164,7 +164,7 @@ public boolean isApplicable(AbstractProject project) { * can be empty but never null. */ public List>> getBrowserDescriptors() { - if(repositoryBrowser==null) return Collections.emptyList(); + if (repositoryBrowser == null) return Collections.emptyList(); return RepositoryBrowsers.filter(repositoryBrowser); } diff --git a/core/src/main/java/hudson/scm/SCMRevisionState.java b/core/src/main/java/hudson/scm/SCMRevisionState.java index cd6ddeb93bd6..771060d39681 100644 --- a/core/src/main/java/hudson/scm/SCMRevisionState.java +++ b/core/src/main/java/hudson/scm/SCMRevisionState.java @@ -16,7 +16,7 @@ *

    * This object is used so that the successive polling can compare the tip of the repository now vs * what it was when it was last polled. (Before 1.345, Hudson was only able to compare the tip - * of the repository vs the state of the workspace, which resulted in a problem like HUDSON-2180. + * of the repository vs the state of the workspace, which resulted in a problem like JENKINS-2180. * *

    * {@link SCMRevisionState} is persisted as an action to {@link AbstractBuild}. @@ -25,14 +25,17 @@ * @since 1.345 */ public abstract class SCMRevisionState implements Action { + @Override public String getIconFileName() { return null; } + @Override public String getDisplayName() { return null; } + @Override public String getUrlName() { return null; } @@ -45,7 +48,7 @@ public String getUrlName() { So instead, here we opt to a design where we tell SCM upfront about what we are comparing against (baseline), and have it give us the new state and degree of change in PollingResult. */ - @SuppressFBWarnings("MS_SHOULD_BE_FINAL") + @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "used in several plugins") public static SCMRevisionState NONE = new None(); private static final class None extends SCMRevisionState {} diff --git a/core/src/main/java/hudson/scm/SCMS.java b/core/src/main/java/hudson/scm/SCMS.java index 975d41259b3f..a8fd4ddc4dc1 100644 --- a/core/src/main/java/hudson/scm/SCMS.java +++ b/core/src/main/java/hudson/scm/SCMS.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,22 +21,20 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.scm; +import hudson.Extension; import hudson.model.AbstractProject; import hudson.model.Descriptor.FormException; import hudson.util.DescriptorList; -import hudson.Extension; - import java.util.List; - -import org.kohsuke.stapler.StaplerRequest; - import javax.servlet.ServletException; +import org.kohsuke.stapler.StaplerRequest; /** * List of all installed SCMs. - * + * * @author Kohsuke Kawaguchi */ public class SCMS { @@ -70,7 +68,7 @@ public static SCM parseSCM(StaplerRequest req, AbstractProject target) throws Fo */ @Deprecated public static SCM parseSCM(StaplerRequest req) throws FormException, ServletException { - return parseSCM(req,null); + return parseSCM(req, null); } } diff --git a/core/src/main/java/hudson/scm/browsers/QueryBuilder.java b/core/src/main/java/hudson/scm/browsers/QueryBuilder.java index f80ca8a8068e..06d933aa7ef3 100644 --- a/core/src/main/java/hudson/scm/browsers/QueryBuilder.java +++ b/core/src/main/java/hudson/scm/browsers/QueryBuilder.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.scm.browsers; /** @@ -36,8 +37,8 @@ public QueryBuilder(String s) { } public QueryBuilder add(String s) { - if(s==null) return this; // nothing to add - if(buf.length()==0) buf.append('?'); + if (s == null) return this; // nothing to add + if (buf.length() == 0) buf.append('?'); else buf.append('&'); buf.append(s); return this; diff --git a/core/src/main/java/hudson/search/CollectionSearchIndex.java b/core/src/main/java/hudson/search/CollectionSearchIndex.java index 3f60912381d2..b6bb423d40f4 100644 --- a/core/src/main/java/hudson/search/CollectionSearchIndex.java +++ b/core/src/main/java/hudson/search/CollectionSearchIndex.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,17 +21,18 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.search; +import edu.umd.cs.findbugs.annotations.NonNull; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; -import edu.umd.cs.findbugs.annotations.NonNull; /** * {@link SearchIndex} built on a {@link Map}. - * + * * @author Kohsuke Kawaguchi */ public abstract class CollectionSearchIndex implements SearchIndex { @@ -52,22 +53,24 @@ protected Iterable allAsIterable() { return all == null ? Collections.emptySet() : all; } + @Override public void find(String token, List result) { SearchItem p = get(token); - if(p!=null) + if (p != null) result.add(p); } + @Override public void suggest(String token, List result) { boolean isCaseSensitive = UserSearchProperty.isCaseInsensitive(); - if(isCaseSensitive){ + if (isCaseSensitive) { token = token.toLowerCase(); } for (SMT o : allAsIterable()) { String name = getName(o); - if(isCaseSensitive) - name=name.toLowerCase(); - if(o!=null && name.contains(token)) + if (isCaseSensitive) + name = name.toLowerCase(); + if (o != null && name.contains(token)) result.add(o); } } diff --git a/core/src/main/java/hudson/search/FixedSet.java b/core/src/main/java/hudson/search/FixedSet.java index eca310184329..dfe413fbf737 100644 --- a/core/src/main/java/hudson/search/FixedSet.java +++ b/core/src/main/java/hudson/search/FixedSet.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,12 +21,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.search; import java.util.Arrays; import java.util.Collection; import java.util.List; - import org.apache.commons.lang.StringUtils; /** @@ -46,6 +46,7 @@ public FixedSet(SearchItem... items) { this(Arrays.asList(items)); } + @Override public void find(String token, List result) { boolean caseInsensitive = UserSearchProperty.isCaseInsensitive(); for (SearchItem i : items) { @@ -56,6 +57,7 @@ public void find(String token, List result) { } } + @Override public void suggest(String token, List result) { boolean caseInsensitive = UserSearchProperty.isCaseInsensitive(); for (SearchItem i : items) { diff --git a/core/src/main/java/hudson/search/ParsedQuickSilver.java b/core/src/main/java/hudson/search/ParsedQuickSilver.java index f99f4b150506..dc214892ac00 100644 --- a/core/src/main/java/hudson/search/ParsedQuickSilver.java +++ b/core/src/main/java/hudson/search/ParsedQuickSilver.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,16 +21,17 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.search; +import java.beans.Introspector; import java.lang.reflect.Field; -import java.lang.reflect.Method; import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.HashMap; -import java.beans.Introspector; /** * Parsed {@link QuickSilver}s so that {@link SearchIndex} can be easily created. @@ -39,12 +40,12 @@ * @author Kohsuke Kawaguchi */ final class ParsedQuickSilver { - private static final Map TABLE = new HashMap<>(); + private static final Map TABLE = new HashMap<>(); static synchronized ParsedQuickSilver get(Class clazz) { ParsedQuickSilver pqs = TABLE.get(clazz); - if(pqs==null) - TABLE.put(clazz,pqs = new ParsedQuickSilver(clazz)); + if (pqs == null) + TABLE.put(clazz, pqs = new ParsedQuickSilver(clazz)); return pqs; } @@ -55,24 +56,24 @@ private ParsedQuickSilver(Class clazz) { for (Method m : clazz.getMethods()) { qs = m.getAnnotation(QuickSilver.class); - if(qs!=null) { + if (qs != null) { String url = stripGetPrefix(m); - if(qs.value().length==0) - getters.add(new MethodGetter(url,splitName(url),m)); + if (qs.value().length == 0) + getters.add(new MethodGetter(url, splitName(url), m)); else { for (String name : qs.value()) - getters.add(new MethodGetter(url,name,m)); + getters.add(new MethodGetter(url, name, m)); } } } for (Field f : clazz.getFields()) { qs = f.getAnnotation(QuickSilver.class); - if(qs!=null) { - if(qs.value().length==0) - getters.add(new FieldGetter(f.getName(),splitName(f.getName()),f)); + if (qs != null) { + if (qs.value().length == 0) + getters.add(new FieldGetter(f.getName(), splitName(f.getName()), f)); else { for (String name : qs.value()) - getters.add(new FieldGetter(f.getName(),name,f)); + getters.add(new FieldGetter(f.getName(), name, f)); } } } @@ -82,9 +83,9 @@ private ParsedQuickSilver(Class clazz) { * Convert names like "abcDefGhi" to "abc def ghi". */ private String splitName(String url) { - StringBuilder buf = new StringBuilder(url.length()+5); - for(String token : url.split("(?<=[a-z])(?=[A-Z])")) { - if(buf.length()>0) buf.append(' '); + StringBuilder buf = new StringBuilder(url.length() + 5); + for (String token : url.split("(?<=[a-z])(?=[A-Z])")) { + if (buf.length() > 0) buf.append(' '); buf.append(Introspector.decapitalize(token)); } return buf.toString(); @@ -92,7 +93,7 @@ private String splitName(String url) { private String stripGetPrefix(Method m) { String n = m.getName(); - if(n.startsWith("get")) + if (n.startsWith("get")) n = Introspector.decapitalize(n.substring(3)); return n; } @@ -118,6 +119,7 @@ static final class MethodGetter extends Getter { this.method = method; } + @Override Object get(Object obj) { try { return method.invoke(obj); @@ -142,6 +144,7 @@ static final class FieldGetter extends Getter { this.field = field; } + @Override Object get(Object obj) { try { return field.get(obj); @@ -160,17 +163,20 @@ private static IllegalAccessError toError(IllegalAccessException e) { public void addTo(SearchIndexBuilder builder, final Object instance) { for (final Getter getter : getters) builder.add(new SearchItem() { + @Override public String getSearchName() { return getter.searchName; } + @Override public String getSearchUrl() { return getter.url; } + @Override public SearchIndex getSearchIndex() { Object child = getter.get(instance); - if(child==null) return SearchIndex.EMPTY; + if (child == null) return SearchIndex.EMPTY; return ((SearchableModelObject) child).getSearchIndex(); } }); diff --git a/core/src/main/java/hudson/search/QuickSilver.java b/core/src/main/java/hudson/search/QuickSilver.java index 1a7c65856ceb..ad214694f5ef 100644 --- a/core/src/main/java/hudson/search/QuickSilver.java +++ b/core/src/main/java/hudson/search/QuickSilver.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,12 +21,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.search; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; -import java.lang.annotation.Retention; import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; import java.lang.annotation.Target; /** @@ -42,7 +44,7 @@ *

    * Such getter/field indicates an edge in the search graph, and will be added * automatically by {@link SearchIndexBuilder#addAllAnnotations(SearchableModelObject)} - * to a search index. + * to a search index. * * @author Kohsuke Kawaguchi */ diff --git a/core/src/main/java/hudson/search/Search.java b/core/src/main/java/hudson/search/Search.java index a50b5bebac8f..9c9aac5e72d6 100644 --- a/core/src/main/java/hudson/search/Search.java +++ b/core/src/main/java/hudson/search/Search.java @@ -1,19 +1,19 @@ /* * The MIT License - * + * * Copyright (c) 2004-2011, Sun Microsystems, Inc., Kohsuke Kawaguchi, * Yahoo!, Inc. - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -22,14 +22,15 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.search; import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND; +import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.Util; import hudson.util.EditDistance; - import java.io.IOException; import java.util.AbstractList; import java.util.ArrayList; @@ -39,12 +40,10 @@ import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; - -import edu.umd.cs.findbugs.annotations.CheckForNull; import javax.servlet.ServletException; - -import jenkins.util.MemoryReductionUtil; import jenkins.model.Jenkins; +import jenkins.util.MemoryReductionUtil; +import jenkins.util.SystemProperties; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.Ancestor; @@ -71,21 +70,21 @@ public class Search implements StaplerProxy { public void doIndex(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { List l = req.getAncestors(); - for( int i=l.size()-1; i>=0; i-- ) { + for (int i = l.size() - 1; i >= 0; i--) { Ancestor a = l.get(i); if (a.getObject() instanceof SearchableModelObject) { SearchableModelObject smo = (SearchableModelObject) a.getObject(); - if(LOGGER.isLoggable(Level.FINE)){ - LOGGER.fine(String.format("smo.displayName=%s, searchName=%s",smo.getDisplayName(), smo.getSearchName())); + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.fine(String.format("smo.displayName=%s, searchName=%s", smo.getDisplayName(), smo.getSearchName())); } SearchIndex index = smo.getSearchIndex(); String query = req.getParameter("q"); - if(query!=null) { + if (query != null) { SuggestedItem target = find(index, query, smo); - if(target!=null) { + if (target != null) { // found - rsp.sendRedirect2(req.getContextPath()+target.getUrl()); + rsp.sendRedirect2(req.getContextPath() + target.getUrl()); return; } } @@ -94,7 +93,7 @@ public void doIndex(StaplerRequest req, StaplerResponse rsp) throws IOException, // no exact match. show the suggestions rsp.setStatus(SC_NOT_FOUND); - req.getView(this,"search-failed.jelly").forward(req,rsp); + req.getView(this, "search-failed.jelly").forward(req, rsp); } /** @@ -127,7 +126,7 @@ public void doSuggest(StaplerRequest req, StaplerResponse rsp, @QueryParameter S for (SuggestedItem item : getSuggestions(req, query)) r.suggestions.add(new Item(item.getPath())); - rsp.serveExposedBean(req,r,Flavor.JSON); + rsp.serveExposedBean(req, r, Flavor.JSON); } /** @@ -135,7 +134,7 @@ public void doSuggest(StaplerRequest req, StaplerResponse rsp, @QueryParameter S * * @return * can be empty but never null. The size of the list is always smaller than - * a certain threshold to avoid showing too many options. + * a certain threshold to avoid showing too many options. */ public SearchResult getSuggestions(StaplerRequest req, String query) { Set paths = new HashSet<>(); // paths already added, to control duplicates @@ -143,11 +142,11 @@ public SearchResult getSuggestions(StaplerRequest req, String query) { int max = req.hasParameter("max") ? Integer.parseInt(req.getParameter("max")) : 100; SearchableModelObject smo = findClosestSearchableModelObject(req); for (SuggestedItem i : suggest(makeSuggestIndex(req), query, smo)) { - if(r.size()>=max) { + if (r.size() >= max) { r.hasMoreResults = true; break; } - if(paths.add(i.getPath())) + if (paths.add(i.getPath())) r.add(i); } return r; @@ -155,10 +154,10 @@ public SearchResult getSuggestions(StaplerRequest req, String query) { private @CheckForNull SearchableModelObject findClosestSearchableModelObject(StaplerRequest req) { List l = req.getAncestors(); - for( int i=l.size()-1; i>=0; i-- ) { + for (int i = l.size() - 1; i >= 0; i--) { Ancestor a = l.get(i); if (a.getObject() instanceof SearchableModelObject) { - return (SearchableModelObject)a.getObject(); + return (SearchableModelObject) a.getObject(); } } return null; @@ -182,6 +181,7 @@ private static class SearchResultImpl extends ArrayList implement private boolean hasMoreResults = false; + @Override public boolean hasMoreResults() { return hasMoreResults; } @@ -193,9 +193,10 @@ public static class Result { public List suggestions = new ArrayList<>(); } - @ExportedBean(defaultVisibility=999) + @ExportedBean(defaultVisibility = 999) public static class Item { @Exported + @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD", justification = "read by Stapler") public String name; public Item(String name) { @@ -205,11 +206,13 @@ public Item(String name) { private enum Mode { FIND { + @Override void find(SearchIndex index, String token, List result) { index.find(token, result); } }, SUGGEST { + @Override void find(SearchIndex index, String token, List result) { index.suggest(token, result); } @@ -223,7 +226,7 @@ void find(SearchIndex index, String token, List result) { * When there are multiple suggested items, this method can narrow down the resultset * to the SuggestedItem that has a url that contains the query. This is useful is one * job has a display name that matches another job's project name. - * @param r A list of Suggested items. It is assumed that there is at least one + * @param r A list of Suggested items. It is assumed that there is at least one * SuggestedItem in r. * @param query A query string * @return Returns the SuggestedItem which has a search url that contains the query. @@ -231,20 +234,20 @@ void find(SearchIndex index, String token, List result) { * SuggestedItem in the List is returned. */ static SuggestedItem findClosestSuggestedItem(List r, String query) { - for(SuggestedItem curItem : r) { - if(LOGGER.isLoggable(Level.FINE)) { + for (SuggestedItem curItem : r) { + if (LOGGER.isLoggable(Level.FINE)) { LOGGER.fine(String.format("item's searchUrl:%s;query=%s", curItem.item.getSearchUrl(), query)); } - if(curItem.item.getSearchUrl().contains(Util.rawEncode(query))) { + if (curItem.item.getSearchUrl().contains(Util.rawEncode(query))) { return curItem; } } - + // couldn't find an item with the query in the url so just // return the first one - return r.get(0); + return r.get(0); } - + /** * @deprecated Use {@link Search#find(SearchIndex, String, SearchableModelObject)} instead. */ @@ -252,7 +255,7 @@ static SuggestedItem findClosestSuggestedItem(List r, String quer public static SuggestedItem find(SearchIndex index, String query) { return find(index, query, null); } - + /** * Performs a search and returns the match, or null if no match was found * or more than one match was found. @@ -260,10 +263,10 @@ public static SuggestedItem find(SearchIndex index, String query) { */ public static SuggestedItem find(SearchIndex index, String query, SearchableModelObject searchContext) { List r = find(Mode.FIND, index, query, searchContext); - if(r.isEmpty()){ + if (r.isEmpty()) { return null; } - else if(1==r.size()){ + else if (1 == r.size()) { return r.get(0); } else { @@ -271,11 +274,11 @@ else if(1==r.size()){ // contains the query as this is probably the job's name return findClosestSuggestedItem(r, query); } - + } /** - * @deprecated use {@link Search#suggest(SearchIndex, String, SearchableModelObject)} instead. + * @deprecated use {@link Search#suggest(SearchIndex, String, SearchableModelObject)} instead. */ @Deprecated public static List suggest(SearchIndex index, final String tokenList) { @@ -287,7 +290,7 @@ public static List suggest(SearchIndex index, final String tokenL */ public static List suggest(SearchIndex index, final String tokenList, SearchableModelObject searchContext) { - class Tag implements Comparable{ + class Tag implements Comparable { final SuggestedItem item; final int distance; /** If the path to this suggestion starts with the token list, 1. Otherwise 0. */ @@ -295,14 +298,15 @@ class Tag implements Comparable{ Tag(SuggestedItem i) { item = i; - distance = EditDistance.editDistance(i.getPath(),tokenList); - prefixMatch = i.getPath().startsWith(tokenList)?1:0; + distance = EditDistance.editDistance(i.getPath(), tokenList); + prefixMatch = i.getPath().startsWith(tokenList) ? 1 : 0; } + @Override public int compareTo(Tag that) { - int r = this.prefixMatch -that.prefixMatch; - if(r!=0) return -r; // ones with head match should show up earlier - return this.distance-that.distance; + int r = this.prefixMatch - that.prefixMatch; + if (r != 0) return -r; // ones with head match should show up earlier + return this.distance - that.distance; } } @@ -310,7 +314,7 @@ public int compareTo(Tag that) { List items = find(Mode.SUGGEST, index, tokenList, searchContext); // sort them - for( SuggestedItem i : items) + for (SuggestedItem i : items) buf.add(new Tag(i)); Collections.sort(buf); items.clear(); @@ -324,7 +328,7 @@ static final class TokenList { private final String[] tokens; TokenList(String tokenList) { - tokens = tokenList!=null ? tokenList.split("(?<=\\s)(?=\\S)") : MemoryReductionUtil.EMPTY_STRING_ARRAY; + tokens = tokenList != null ? tokenList.split("(?<=\\s)(?=\\S)") : MemoryReductionUtil.EMPTY_STRING_ARRAY; } public int length() { return tokens.length; } @@ -336,67 +340,70 @@ static final class TokenList { */ public List subSequence(final int start) { return new AbstractList() { + @Override public String get(int index) { StringBuilder buf = new StringBuilder(); - for(int i=start; i<=start+index; i++ ) + for (int i = start; i <= start + index; i++) buf.append(tokens[i]); return buf.toString().trim(); } + @Override public int size() { - return tokens.length-start; + return tokens.length - start; } }; } - - + + + @Override public String toString() { StringBuilder s = new StringBuilder("TokenList{"); - for(String token : tokens) { + for (String token : tokens) { s.append(token); s.append(","); } s.append('}'); - + return s.toString(); } } private static List find(Mode m, SearchIndex index, String tokenList, SearchableModelObject searchContext) { TokenList tokens = new TokenList(tokenList); - if(tokens.length()==0) return Collections.emptyList(); // no tokens given + if (tokens.length() == 0) return Collections.emptyList(); // no tokens given - List[] paths = new List[tokens.length()+1]; // we won't use [0]. - for(int i=1;i<=tokens.length();i++) + List[] paths = new List[tokens.length() + 1]; // we won't use [0]. + for (int i = 1; i <= tokens.length(); i++) paths[i] = new ArrayList<>(); List items = new ArrayList<>(); // items found in 1 step LOGGER.log(Level.FINE, "tokens={0}", tokens); - + // first token - int w=1; // width of token + int w = 1; // width of token for (String token : tokens.subSequence(0)) { items.clear(); - m.find(index,token,items); + m.find(index, token, items); for (SearchItem si : items) { - paths[w].add(SuggestedItem.build(searchContext ,si)); + paths[w].add(SuggestedItem.build(searchContext, si)); LOGGER.log(Level.FINE, "found search item: {0}", si.getSearchName()); } w++; } // successive tokens - for (int j=1; j result) { // no item to contribute } + + @Override public void suggest(String token, List result) { // nothing to suggest } diff --git a/core/src/main/java/hudson/search/SearchIndexBuilder.java b/core/src/main/java/hudson/search/SearchIndexBuilder.java index 0c62e2ad5feb..4cf082598b10 100644 --- a/core/src/main/java/hudson/search/SearchIndexBuilder.java +++ b/core/src/main/java/hudson/search/SearchIndexBuilder.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,10 +21,10 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.search; import hudson.model.AbstractModelObject; - import java.util.ArrayList; import java.util.List; @@ -46,7 +46,7 @@ public final class SearchIndexBuilder { * Adds all {@link QuickSilver}-annotated properties to the search index. */ public SearchIndexBuilder addAllAnnotations(SearchableModelObject o) { - ParsedQuickSilver.get(o.getClass()).addTo(this,o); + ParsedQuickSilver.get(o.getClass()).addTo(this, o); return this; } @@ -54,23 +54,23 @@ public SearchIndexBuilder addAllAnnotations(SearchableModelObject o) { * Short for {@code add(urlAsWellAsName,urlAsWellAsName)} */ public SearchIndexBuilder add(String urlAsWellAsName) { - return add(urlAsWellAsName,urlAsWellAsName); + return add(urlAsWellAsName, urlAsWellAsName); } /** * Adds a search index under the keyword 'name' to the given URL. * * @param url - * Relative URL from the source of the search index. + * Relative URL from the source of the search index. */ public SearchIndexBuilder add(String url, String name) { - items.add(SearchItems.create(name,url)); + items.add(SearchItems.create(name, url)); return this; } public SearchIndexBuilder add(String url, String... names) { for (String name : names) - add(url,name); + add(url, name); return this; } @@ -80,13 +80,13 @@ public SearchIndexBuilder add(SearchItem item) { } public SearchIndexBuilder add(String url, SearchableModelObject searchable, String name) { - items.add(SearchItems.create(name,url,searchable)); + items.add(SearchItems.create(name, url, searchable)); return this; } public SearchIndexBuilder add(String url, SearchableModelObject searchable, String... names) { for (String name : names) - add(url,searchable,name); + add(url, searchable, name); return this; } @@ -102,7 +102,7 @@ public SearchIndexBuilder add(SearchIndexBuilder index) { public SearchIndex make() { SearchIndex r = new FixedSet(items); for (SearchIndex index : indices) - r = new UnionSearchIndex(r,index); + r = new UnionSearchIndex(r, index); return r; } } diff --git a/core/src/main/java/hudson/search/SearchItem.java b/core/src/main/java/hudson/search/SearchItem.java index 3da63411ed06..02b2921b9741 100644 --- a/core/src/main/java/hudson/search/SearchItem.java +++ b/core/src/main/java/hudson/search/SearchItem.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.search; import hudson.model.Build; @@ -50,6 +51,7 @@ public interface SearchItem { * The path that starts with '/' will be interpreted as the absolute path * (within the context path of Jenkins.) */ + String getSearchUrl(); /** diff --git a/core/src/main/java/hudson/search/SearchItems.java b/core/src/main/java/hudson/search/SearchItems.java index b4c5ca724087..3afb24fc46fe 100644 --- a/core/src/main/java/hudson/search/SearchItems.java +++ b/core/src/main/java/hudson/search/SearchItems.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.search; /** @@ -28,19 +29,22 @@ */ public class SearchItems { public static SearchItem create(String searchName, String url) { - return create(searchName,url, SearchIndex.EMPTY); + return create(searchName, url, SearchIndex.EMPTY); } public static SearchItem create(final String searchName, final String url, final SearchIndex children) { return new SearchItem() { + @Override public String getSearchName() { return searchName; } + @Override public String getSearchUrl() { return url; } + @Override public SearchIndex getSearchIndex() { return children; } @@ -49,14 +53,17 @@ public SearchIndex getSearchIndex() { public static SearchItem create(final String searchName, final String url, final SearchableModelObject searchable) { return new SearchItem() { + @Override public String getSearchName() { return searchName; } + @Override public String getSearchUrl() { return url; } + @Override public SearchIndex getSearchIndex() { return searchable.getSearchIndex(); } diff --git a/core/src/main/java/hudson/search/SearchableModelObject.java b/core/src/main/java/hudson/search/SearchableModelObject.java index ebc16348d980..52bdcc47a587 100644 --- a/core/src/main/java/hudson/search/SearchableModelObject.java +++ b/core/src/main/java/hudson/search/SearchableModelObject.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.search; import hudson.model.ModelObject; diff --git a/core/src/main/java/hudson/search/SuggestedItem.java b/core/src/main/java/hudson/search/SuggestedItem.java index 31e5956ce4ed..86dbc36b5fe3 100644 --- a/core/src/main/java/hudson/search/SuggestedItem.java +++ b/core/src/main/java/hudson/search/SuggestedItem.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.search; import hudson.model.Item; @@ -37,7 +38,7 @@ public class SuggestedItem { private String path; public SuggestedItem(SearchItem top) { - this(null,top); + this(null, top); } public SuggestedItem(SuggestedItem parent, SearchItem item) { @@ -46,18 +47,18 @@ public SuggestedItem(SuggestedItem parent, SearchItem item) { } public String getPath() { - if(path!=null) return path; - if(parent==null) - return path=item.getSearchName(); + if (path != null) return path; + if (parent == null) + return path = item.getSearchName(); else { StringBuilder buf = new StringBuilder(); getPath(buf); - return path=buf.toString(); + return path = buf.toString(); } } private void getPath(StringBuilder buf) { - if(parent==null) + if (parent == null) buf.append(item.getSearchName()); else { parent.getPath(buf); @@ -71,23 +72,23 @@ private void getPath(StringBuilder buf) { * URL that starts with '/' but doesn't end with '/'. * The path is the combined path from the {@link SearchIndex} where the search started * to the final item found. Thus to convert to the actual URL, the caller would need - * to prepend the URL of the object where the search started. + * to prepend the URL of the object where the search started. */ public String getUrl() { StringBuilder buf = new StringBuilder(); getUrl(buf); return buf.toString(); } - + private static SuggestedItem build(SearchableModelObject searchContext, Item top) { ItemGroup parent = top.getParent(); if (parent instanceof Item) { - Item parentItem = (Item)parent; + Item parentItem = (Item) parent; return new SuggestedItem(build(searchContext, parentItem), top); } return new SuggestedItem(top); } - + /** * Given a SearchItem, builds a SuggestedItem hierarchy by looking up parent items (if applicable). * This allows search results for items not contained within the same {@link ItemGroup} to be distinguished. @@ -96,21 +97,21 @@ private static SuggestedItem build(SearchableModelObject searchContext, Item top */ public static SuggestedItem build(SearchableModelObject searchContext, SearchItem si) { if (si instanceof Item) { - return build(searchContext, (Item)si); + return build(searchContext, (Item) si); } return new SuggestedItem(si); } private void getUrl(StringBuilder buf) { - if(parent!=null) { + if (parent != null) { parent.getUrl(buf); } String f = item.getSearchUrl(); - if(f.startsWith("/")) { + if (f.startsWith("/")) { buf.setLength(0); buf.append(f); } else { - if(buf.length()==0 || buf.charAt(buf.length()-1)!='/') + if (buf.length() == 0 || buf.charAt(buf.length() - 1) != '/') buf.append('/'); buf.append(f); } diff --git a/core/src/main/java/hudson/search/UnionSearchIndex.java b/core/src/main/java/hudson/search/UnionSearchIndex.java index cde13860b95f..d32deb5edfe6 100644 --- a/core/src/main/java/hudson/search/UnionSearchIndex.java +++ b/core/src/main/java/hudson/search/UnionSearchIndex.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.search; import java.util.List; @@ -32,7 +33,7 @@ */ public class UnionSearchIndex implements SearchIndex { public static SearchIndex combine(SearchIndex... sets) { - SearchIndex p=EMPTY; + SearchIndex p = EMPTY; for (SearchIndex q : sets) { // allow some of the inputs to be null, // and also recognize EMPTY @@ -40,26 +41,28 @@ public static SearchIndex combine(SearchIndex... sets) { if (p == EMPTY) p = q; else - p = new UnionSearchIndex(p,q); + p = new UnionSearchIndex(p, q); } } return p; } - private final SearchIndex lhs,rhs; + private final SearchIndex lhs, rhs; public UnionSearchIndex(SearchIndex lhs, SearchIndex rhs) { this.lhs = lhs; this.rhs = rhs; } + @Override public void find(String token, List result) { - lhs.find(token,result); - rhs.find(token,result); + lhs.find(token, result); + rhs.find(token, result); } + @Override public void suggest(String token, List result) { - lhs.suggest(token,result); - rhs.suggest(token,result); + lhs.suggest(token, result); + rhs.suggest(token, result); } } diff --git a/core/src/main/java/hudson/search/UserSearchProperty.java b/core/src/main/java/hudson/search/UserSearchProperty.java index e93a7e35ea1f..50813ce3c79b 100644 --- a/core/src/main/java/hudson/search/UserSearchProperty.java +++ b/core/src/main/java/hudson/search/UserSearchProperty.java @@ -5,7 +5,6 @@ import hudson.model.UserProperty; import hudson.model.UserPropertyDescriptor; import net.sf.json.JSONObject; - import org.jenkinsci.Symbol; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.export.Exported; @@ -24,8 +23,8 @@ public UserSearchProperty(boolean insensitiveSearch) { public boolean getInsensitiveSearch() { return insensitiveSearch; } - - public static boolean isCaseInsensitive(){ + + public static boolean isCaseInsensitive() { User user = User.current(); if (user == null) { @@ -34,7 +33,7 @@ public static boolean isCaseInsensitive(){ return user.getProperty(UserSearchProperty.class).getInsensitiveSearch(); } - + @Extension @Symbol("search") public static final class DescriptorImpl extends UserPropertyDescriptor { @@ -43,6 +42,7 @@ public String getDisplayName() { return Messages.UserSearchProperty_DisplayName(); } + @Override public UserProperty newInstance(User user) { return new UserSearchProperty(DEFAULT_SEARCH_CASE_INSENSITIVE_MODE); } diff --git a/core/src/main/java/hudson/security/ACL.java b/core/src/main/java/hudson/security/ACL.java index cf4260035c0a..039820ef22f3 100644 --- a/core/src/main/java/hudson/security/ACL.java +++ b/core/src/main/java/hudson/security/ACL.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.security; import edu.umd.cs.findbugs.annotations.CheckForNull; @@ -69,14 +70,14 @@ public abstract class ACL { */ public final void checkPermission(@NonNull Permission p) { Authentication a = Jenkins.getAuthentication2(); - if (a.equals(SYSTEM2)) { + if (a.equals(SYSTEM2)) { // perhaps redundant given check in AccessControlled return; } - if (!hasPermission2(a,p)) { + if (!hasPermission2(a, p)) { while (!p.enabled && p.impliedBy != null) { p = p.impliedBy; } - throw new AccessDeniedException3(a,p); + throw new AccessDeniedException3(a, p); } } @@ -131,7 +132,7 @@ public final void checkAnyPermission(@NonNull Permission... permissions) { */ public final boolean hasPermission(@NonNull Permission p) { Authentication a = Jenkins.getAuthentication2(); - if (a.equals(SYSTEM2)) { + if (a.equals(SYSTEM2)) { // perhaps redundant given check in AccessControlled return true; } return hasPermission2(a, p); @@ -236,7 +237,7 @@ public final void checkCreatePermission(@NonNull ItemGroup c, } if (!hasCreatePermission2(a, c, d)) { throw new AccessDeniedException(Messages.AccessDeniedException2_MissingPermission(a.getName(), - Item.CREATE.group.title+"/"+Item.CREATE.name + Item.CREATE + "/" + d.getDisplayName())); + Item.CREATE.group.title + "/" + Item.CREATE.name + Item.CREATE + "/" + d.getDisplayName())); } } /** @@ -251,6 +252,7 @@ public final void checkCreatePermission(@NonNull ItemGroup c, * if the user doesn't have the permission. * @since 2.266 */ + public boolean hasCreatePermission2(@NonNull Authentication a, @NonNull ItemGroup c, @NonNull TopLevelItemDescriptor d) { if (Util.isOverridden(ACL.class, getClass(), "hasCreatePermission", org.acegisecurity.Authentication.class, ItemGroup.class, TopLevelItemDescriptor.class)) { @@ -355,7 +357,7 @@ public String toString() { */ public static final Sid ANONYMOUS = new PrincipalSid(ANONYMOUS_USERNAME); - protected static final Sid[] AUTOMATIC_SIDS = new Sid[]{EVERYONE,ANONYMOUS}; + static final Sid[] AUTOMATIC_SIDS = new Sid[]{EVERYONE, ANONYMOUS}; /** * The username for the system user @@ -370,7 +372,7 @@ public String toString() { * of acting on behalf of an user, such as doing builds. * @since 2.266 */ - public static final Authentication SYSTEM2 = new UsernamePasswordAuthenticationToken(SYSTEM_USERNAME,"SYSTEM"); + public static final Authentication SYSTEM2 = new UsernamePasswordAuthenticationToken(SYSTEM_USERNAME, "SYSTEM"); /** * @deprecated use {@link #SYSTEM2} @@ -381,12 +383,12 @@ public String toString() { /** * Changes the {@link Authentication} associated with the current thread * to the specified one, and returns the previous security context. - * + * *

    * When the impersonation is over, be sure to restore the previous authentication * via {@code SecurityContextHolder.setContext(returnValueFromThisMethod)}; * or just use {@link #impersonate2(Authentication, Runnable)}. - * + * *

    * We need to create a new {@link SecurityContext} instead of {@link SecurityContext#setAuthentication(Authentication)} * because the same {@link SecurityContext} object is reused for all the concurrent requests from the same session. @@ -443,7 +445,7 @@ public static void impersonate(@NonNull org.acegisecurity.Authentication auth, @ * @deprecated use try with resources and {@link #as2(Authentication)} */ @Deprecated - public static V impersonate2(Authentication auth, Callable body) throws T { + public static V impersonate2(Authentication auth, Callable body) throws T { SecurityContext old = impersonate2(auth); try { return body.call(); @@ -457,7 +459,7 @@ public static V impersonate2(Authentication auth, Callab * @since 1.587 */ @Deprecated - public static V impersonate(org.acegisecurity.Authentication auth, Callable body) throws T { + public static V impersonate(org.acegisecurity.Authentication auth, Callable body) throws T { return impersonate2(auth.toSpring(), body); } diff --git a/core/src/main/java/hudson/security/ACLContext.java b/core/src/main/java/hudson/security/ACLContext.java index e5b49ff324be..9873e65f3762 100644 --- a/core/src/main/java/hudson/security/ACLContext.java +++ b/core/src/main/java/hudson/security/ACLContext.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.security; import edu.umd.cs.findbugs.annotations.NonNull; diff --git a/core/src/main/java/hudson/security/AbstractPasswordBasedSecurityRealm.java b/core/src/main/java/hudson/security/AbstractPasswordBasedSecurityRealm.java index 2bac2a4e00ea..055c7151a94a 100644 --- a/core/src/main/java/hudson/security/AbstractPasswordBasedSecurityRealm.java +++ b/core/src/main/java/hudson/security/AbstractPasswordBasedSecurityRealm.java @@ -173,12 +173,14 @@ public GroupDetails loadGroupByGroupname(String groupname) throws org.acegisecur } class Authenticator extends AbstractUserDetailsAuthenticationProvider { + @Override protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException { // authentication is assumed to be done already in the retrieveUser method } + @Override protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException { - return doAuthenticate(username,authentication.getCredentials().toString()); + return doAuthenticate(username, authentication.getCredentials().toString()); } } diff --git a/core/src/main/java/hudson/security/AccessControlled.java b/core/src/main/java/hudson/security/AccessControlled.java index 2de2ae904bc5..b0cb2c2a9b82 100644 --- a/core/src/main/java/hudson/security/AccessControlled.java +++ b/core/src/main/java/hudson/security/AccessControlled.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Tom Huybrechts - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,9 +21,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.security; import edu.umd.cs.findbugs.annotations.NonNull; +import jenkins.model.Jenkins; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.core.Authentication; @@ -44,6 +46,9 @@ public interface AccessControlled { * Convenient short-cut for {@code getACL().checkPermission(permission)} */ default void checkPermission(@NonNull Permission permission) throws AccessDeniedException { + if (Jenkins.getAuthentication2().equals(ACL.SYSTEM2)) { + return; + } getACL().checkPermission(permission); } @@ -61,6 +66,9 @@ default void checkAnyPermission(@NonNull Permission... permission) throws Access * Convenient short-cut for {@code getACL().hasPermission(permission)} */ default boolean hasPermission(@NonNull Permission permission) { + if (Jenkins.getAuthentication2().equals(ACL.SYSTEM2)) { + return true; + } return getACL().hasPermission(permission); } diff --git a/core/src/main/java/hudson/security/AccessDeniedException2.java b/core/src/main/java/hudson/security/AccessDeniedException2.java index ed6e5f49769e..00daee721251 100644 --- a/core/src/main/java/hudson/security/AccessDeniedException2.java +++ b/core/src/main/java/hudson/security/AccessDeniedException2.java @@ -1,11 +1,10 @@ package hudson.security; -import org.acegisecurity.AccessDeniedException; -import org.acegisecurity.Authentication; - -import javax.servlet.http.HttpServletResponse; import java.io.PrintWriter; +import javax.servlet.http.HttpServletResponse; import jenkins.util.SystemProperties; +import org.acegisecurity.AccessDeniedException; +import org.acegisecurity.Authentication; /** * {@link AccessDeniedException} with more information. @@ -29,12 +28,12 @@ public class AccessDeniedException2 extends AccessDeniedException { public final Permission permission; public AccessDeniedException2(Authentication authentication, Permission permission) { - this(null,authentication,permission); + this(null, authentication, permission); } public AccessDeniedException2(Throwable t, Authentication authentication, Permission permission) { super(Messages.AccessDeniedException2_MissingPermission(authentication.getName(), - permission.group.title+"/"+permission.name), t); + permission.group.title + "/" + permission.name), t); this.authentication = authentication; this.permission = permission; } diff --git a/core/src/main/java/hudson/security/AccessDeniedException3.java b/core/src/main/java/hudson/security/AccessDeniedException3.java index a10f0f235513..82f5d50428ce 100644 --- a/core/src/main/java/hudson/security/AccessDeniedException3.java +++ b/core/src/main/java/hudson/security/AccessDeniedException3.java @@ -1,7 +1,7 @@ package hudson.security; -import javax.servlet.http.HttpServletResponse; import java.io.PrintWriter; +import javax.servlet.http.HttpServletResponse; import jenkins.util.SystemProperties; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.core.Authentication; @@ -29,12 +29,12 @@ public class AccessDeniedException3 extends AccessDeniedException { public final Permission permission; public AccessDeniedException3(Authentication authentication, Permission permission) { - this(null,authentication,permission); + this(null, authentication, permission); } public AccessDeniedException3(Throwable t, Authentication authentication, Permission permission) { super(Messages.AccessDeniedException2_MissingPermission(authentication.getName(), - permission.group.title+"/"+permission.name), t); + permission.group.title + "/" + permission.name), t); this.authentication = authentication; this.permission = permission; } @@ -43,16 +43,16 @@ public AccessDeniedException3(Throwable t, Authentication authentication, Permis * Reports the details of the access failure in HTTP headers to assist diagnosis. */ public void reportAsHeaders(HttpServletResponse rsp) { - rsp.addHeader("X-You-Are-Authenticated-As",authentication.getName()); + rsp.addHeader("X-You-Are-Authenticated-As", authentication.getName()); if (REPORT_GROUP_HEADERS) { for (GrantedAuthority auth : authentication.getAuthorities()) { - rsp.addHeader("X-You-Are-In-Group",auth.getAuthority()); + rsp.addHeader("X-You-Are-In-Group", auth.getAuthority()); } } else { rsp.addHeader("X-You-Are-In-Group-Disabled", "JENKINS-39402: use -Dhudson.security.AccessDeniedException2.REPORT_GROUP_HEADERS=true or use /whoAmI to diagnose"); } rsp.addHeader("X-Required-Permission", permission.getId()); - for (Permission p=permission.impliedBy; p!=null; p=p.impliedBy) { + for (Permission p = permission.impliedBy; p != null; p = p.impliedBy) { rsp.addHeader("X-Permission-Implied-By", p.getId()); } } @@ -63,15 +63,15 @@ public void reportAsHeaders(HttpServletResponse rsp) { * but instead of using HTTP headers, this version is meant to go inside the payload. */ public void report(PrintWriter w) { - w.println("You are authenticated as: "+authentication.getName()); + w.println("You are authenticated as: " + authentication.getName()); w.println("Groups that you are in:"); for (GrantedAuthority auth : authentication.getAuthorities()) { - w.println(" "+auth.getAuthority()); + w.println(" " + auth.getAuthority()); } - w.println("Permission you need to have (but didn't): "+permission.getId()); - for (Permission p=permission.impliedBy; p!=null; p=p.impliedBy) { - w.println(" ... which is implied by: "+p.getId()); + w.println("Permission you need to have (but didn't): " + permission.getId()); + for (Permission p = permission.impliedBy; p != null; p = p.impliedBy) { + w.println(" ... which is implied by: " + p.getId()); } } } diff --git a/core/src/main/java/hudson/security/AccessDeniedHandlerImpl.java b/core/src/main/java/hudson/security/AccessDeniedHandlerImpl.java index 92c45b0f9fe9..68843cfddd16 100644 --- a/core/src/main/java/hudson/security/AccessDeniedHandlerImpl.java +++ b/core/src/main/java/hudson/security/AccessDeniedHandlerImpl.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.security; import java.io.IOException; @@ -46,13 +47,13 @@ public class AccessDeniedHandlerImpl implements AccessDeniedHandler { @Override public void handle(HttpServletRequest req, HttpServletResponse rsp, AccessDeniedException cause) throws IOException, ServletException { rsp.setStatus(HttpServletResponse.SC_FORBIDDEN); - req.setAttribute("exception",cause); + req.setAttribute("exception", cause); if (cause instanceof AccessDeniedException3) { - ((AccessDeniedException3)cause).reportAsHeaders(rsp); + ((AccessDeniedException3) cause).reportAsHeaders(rsp); } WebApp.get(Jenkins.get().servletContext).getSomeStapler() - .invoke(req,rsp, Jenkins.get(), "/accessDenied"); + .invoke(req, rsp, Jenkins.get(), "/accessDenied"); } } diff --git a/core/src/main/java/hudson/security/AuthenticationManagerProxy.java b/core/src/main/java/hudson/security/AuthenticationManagerProxy.java index 2b5b4de7c83d..7de8cb39ab5e 100644 --- a/core/src/main/java/hudson/security/AuthenticationManagerProxy.java +++ b/core/src/main/java/hudson/security/AuthenticationManagerProxy.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.security; import org.kohsuke.accmod.Restricted; @@ -44,10 +45,11 @@ public class AuthenticationManagerProxy implements AuthenticationManager { private volatile AuthenticationManager delegate; + @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { AuthenticationManager m = delegate; // fix the reference we are working with - if(m ==null) + if (m == null) throw new DisabledException("Authentication service is still not ready yet"); else return m.authenticate(authentication); diff --git a/core/src/main/java/hudson/security/AuthenticationProcessingFilter2.java b/core/src/main/java/hudson/security/AuthenticationProcessingFilter2.java index 71be533d7750..2714ec8eba63 100644 --- a/core/src/main/java/hudson/security/AuthenticationProcessingFilter2.java +++ b/core/src/main/java/hudson/security/AuthenticationProcessingFilter2.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Matthew R. Harrah - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,8 +21,10 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.security; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.model.User; import java.io.IOException; import java.util.logging.Level; @@ -34,6 +36,7 @@ import javax.servlet.http.HttpSession; import jenkins.security.SecurityListener; import jenkins.security.seed.UserSeedProperty; +import jenkins.util.SystemProperties; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.springframework.security.core.Authentication; @@ -45,12 +48,13 @@ * Login filter with a change for Jenkins so that * we can pick up the hidden "from" form field defined in {@code login.jelly} * to send the user back to where he came from, after a successful authentication. - * + * * @author Kohsuke Kawaguchi */ @Restricted(NoExternalUse.class) public final class AuthenticationProcessingFilter2 extends UsernamePasswordAuthenticationFilter { + @SuppressFBWarnings(value = "HARD_CODE_PASSWORD", justification = "This is a password parameter, not a password") public AuthenticationProcessingFilter2(String authenticationGatewayUrl) { setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/" + authenticationGatewayUrl, "POST")); // Jenkins/login.jelly & SetupWizard/authenticate-security-token.jelly @@ -58,54 +62,15 @@ public AuthenticationProcessingFilter2(String authenticationGatewayUrl) { setPasswordParameter("j_password"); } - /* TODO none of this compiles against Spring Security; rewrite (try InteractiveAuthenticationSuccessEvent & SimpleUrlAuthenticationFailureHandler): - - @Override - protected String determineTargetUrl(HttpServletRequest request) { - AbstractAuthenticationProcessingFilter f = new UsernamePasswordAuthenticationFilter(); - String targetUrl = request.getParameter("from"); - request.getSession().setAttribute("from", targetUrl); - - if (targetUrl == null) - return getDefaultTargetUrl(); - - if (!Util.isSafeToRedirectTo(targetUrl)) - return "."; // avoid open redirect - - // URL returned from determineTargetUrl() is resolved against the context path, - // whereas the "from" URL is resolved against the top of the website, so adjust this. - if(targetUrl.startsWith(request.getContextPath())) - return targetUrl.substring(request.getContextPath().length()); - - // not sure when this happens, but apparently this happens in some case. - // see #1274 - return targetUrl; - } - - /** - * @see AbstractProcessingFilter#determineFailureUrl(HttpServletRequest, AuthenticationException) - * / - @Override - protected String determineFailureUrl(HttpServletRequest request, AuthenticationException failed) { - Properties excMap = getExceptionMappings(); - String failedClassName = failed.getClass().getName(); - String whereFrom = request.getParameter("from"); - request.getSession().setAttribute("from", whereFrom); - return excMap.getProperty(failedClassName, getAuthenticationFailureUrl()); - } - */ - + @SuppressFBWarnings(value = "RV_RETURN_VALUE_IGNORED_NO_SIDE_EFFECT", justification = "request.getSession(true) does in fact have a side effect") @Override protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException { + if (SystemProperties.getInteger(SecurityRealm.class.getName() + ".sessionFixationProtectionMode", 1) == 2) { + // While use of SessionFixationProtectionStrategy is the canonical Spring Security approach, it may not be compatible with some security realms, so offer this alternative + request.getSession().invalidate(); + request.getSession(true); + } super.successfulAuthentication(request, response, chain, authResult); - // make sure we have a session to store this successful authentication, given that we no longer - // let HttpSessionContextIntegrationFilter2 to create sessions. - // SecurityContextPersistenceFilter stores the updated SecurityContext object into this session later - // (either when a redirect is issued, via its HttpResponseWrapper, or when the execution returns to its - // doFilter method. - /* TODO causes an ISE on the next line: - request.getSession().invalidate(); - */ HttpSession newSession = request.getSession(); if (!UserSeedProperty.DISABLE_USER_SEED) { diff --git a/core/src/main/java/hudson/security/AuthorizationStrategy.java b/core/src/main/java/hudson/security/AuthorizationStrategy.java index 66cab7d0b716..e1ce1596b74a 100644 --- a/core/src/main/java/hudson/security/AuthorizationStrategy.java +++ b/core/src/main/java/hudson/security/AuthorizationStrategy.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Seiji Sogabe, Tom Huybrechts - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,25 +21,34 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.security; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.DescriptorExtensionList; import hudson.Extension; import hudson.ExtensionPoint; -import hudson.model.*; +import hudson.model.AbstractDescribableImpl; +import hudson.model.AbstractItem; +import hudson.model.AbstractProject; +import hudson.model.Computer; +import hudson.model.Describable; +import hudson.model.Descriptor; +import hudson.model.Job; +import hudson.model.Node; +import hudson.model.User; +import hudson.model.View; import hudson.slaves.Cloud; import hudson.util.DescriptorList; +import java.io.Serializable; +import java.util.Collection; +import java.util.Collections; import jenkins.model.Jenkins; import jenkins.security.stapler.StaplerAccessibleType; import net.sf.json.JSONObject; import org.jenkinsci.Symbol; import org.kohsuke.stapler.StaplerRequest; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.io.Serializable; -import java.util.Collection; -import java.util.Collections; - /** * Controls authorization throughout Hudson. * @@ -55,7 +64,7 @@ * The corresponding {@link Describable} instance will be asked to create a new {@link AuthorizationStrategy} * every time the system configuration is updated. Implementations that keep more state in ACL beyond * the system configuration should use {@link jenkins.model.Jenkins#getAuthorizationStrategy()} to talk to the current - * instance to carry over the state. + * instance to carry over the state. * * @author Kohsuke Kawaguchi * @see SecurityRealm @@ -75,12 +84,12 @@ public abstract class AuthorizationStrategy extends AbstractDescribableImpl project) { - return getACL((Job)project); + public @NonNull ACL getACL(@NonNull AbstractProject project) { + return getACL((Job) project); } - public @NonNull ACL getACL(@NonNull Job project) { - return getRootACL(); + public @NonNull ACL getACL(@NonNull Job project) { + return getRootACL(); } /** @@ -99,13 +108,13 @@ public abstract class AuthorizationStrategy extends AbstractDescribableImpl * If such enumeration is impossible, do the best to list as many as possible, then * return it. In the worst case, just return an empty list. Doing so would prevent - * users from using role names as group names (see HUDSON-2716 for such one such report.) + * users from using role names as group names (see JENKINS-2716 for such one such report.) * * @return * never null. @@ -181,7 +190,7 @@ public abstract class AuthorizationStrategy extends AbstractDescribableImpl> all() { + public static @NonNull DescriptorExtensionList> all() { return Jenkins.get().getDescriptorList(AuthorizationStrategy.class); } @@ -193,7 +202,7 @@ public abstract class AuthorizationStrategy extends AbstractDescribableImpl LIST = new DescriptorList<>(AuthorizationStrategy.class); - + /** * {@link AuthorizationStrategy} that implements the semantics * of unsecured Hudson where everyone has full control. diff --git a/core/src/main/java/hudson/security/BasicAuthenticationFilter.java b/core/src/main/java/hudson/security/BasicAuthenticationFilter.java index c7eee8cd5db3..dd29dc3004fe 100644 --- a/core/src/main/java/hudson/security/BasicAuthenticationFilter.java +++ b/core/src/main/java/hudson/security/BasicAuthenticationFilter.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.security; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; @@ -66,7 +67,7 @@ * This causes the container to perform authentication, but there's no way * to find out whether the user has been successfully authenticated or not. * So to find this out, we then redirect the user to - * {@link jenkins.model.Jenkins#doSecured(StaplerRequest, StaplerResponse) {@code /secured/...} page}. + * {@link jenkins.model.Jenkins#doSecured(StaplerRequest, StaplerResponse) /secured/... page}. * *

    * The handler of the above URL checks if the user is authenticated, @@ -85,28 +86,29 @@ *

  • * This A → B → A redirect is a cyclic redirection, so we need to watch out for clients * that detect this as an error. - * + * * * @author Kohsuke Kawaguchi */ public class BasicAuthenticationFilter implements Filter { private ServletContext servletContext; + @Override public void init(FilterConfig filterConfig) throws ServletException { servletContext = filterConfig.getServletContext(); } - @SuppressWarnings("ACL.impersonate") + @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse rsp = (HttpServletResponse) response; String authorization = req.getHeader("Authorization"); String path = req.getServletPath(); - if(authorization==null || req.getUserPrincipal() !=null || path.startsWith("/secured/") + if (authorization == null || req.getUserPrincipal() != null || path.startsWith("/secured/") || !Jenkins.get().isUseSecurity()) { // normal requests, or security not enabled - if(req.getUserPrincipal()!=null) { + if (req.getUserPrincipal() != null) { // before we route this request, integrate the container authentication // to Spring Security. For anonymous users that doesn't have user principal, // AnonymousProcessingFilter that follows this should create @@ -114,7 +116,7 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha SecurityContextHolder.getContext().setAuthentication(new ContainerAuthentication(req)); } try { - chain.doFilter(request,response); + chain.doFilter(request, response); } finally { SecurityContextHolder.clearContext(); } @@ -128,18 +130,18 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha int idx = uidpassword.indexOf(':'); if (idx >= 0) { username = uidpassword.substring(0, idx); - password = uidpassword.substring(idx+1); + password = uidpassword.substring(idx + 1); } - if(username==null) { + if (username == null) { rsp.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - rsp.setHeader("WWW-Authenticate","Basic realm=\"Jenkins user\""); + rsp.setHeader("WWW-Authenticate", "Basic realm=\"Jenkins user\""); return; } { User u = BasicApiTokenHelper.isConnectingUsingApiToken(username, password); - if(u != null){ + if (u != null) { UserDetails userDetails = u.getUserDetailsForImpersonation2(); Authentication auth = u.impersonate(userDetails); @@ -147,7 +149,7 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha SecurityContextHolder.getContext().setAuthentication(auth); try { - chain.doFilter(request,response); + chain.doFilter(request, response); } finally { SecurityContextHolder.clearContext(); } @@ -156,40 +158,27 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha } - path = req.getContextPath()+"/secured"+path; + path = req.getContextPath() + "/secured" + path; String q = req.getQueryString(); - if(q!=null) - path += '?'+q; + if (q != null) + path += '?' + q; // prepare a redirect prepareRedirect(rsp, path); // ... but first let the container authenticate this request - RequestDispatcher d = servletContext.getRequestDispatcher("/j_security_check?j_username="+ - URLEncoder.encode(username,"UTF-8")+"&j_password="+URLEncoder.encode(password,"UTF-8")); - d.include(req,rsp); + RequestDispatcher d = servletContext.getRequestDispatcher("/j_security_check?j_username=" + + URLEncoder.encode(username, "UTF-8") + "&j_password=" + URLEncoder.encode(password, "UTF-8")); + d.include(req, rsp); } @SuppressFBWarnings(value = "UNVALIDATED_REDIRECT", justification = "Redirect is validated as processed.") private void prepareRedirect(HttpServletResponse rsp, String path) { rsp.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY); - rsp.setHeader("Location",path); + rsp.setHeader("Location", path); } - //public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { - // HttpServletRequest req = (HttpServletRequest) request; - // String authorization = req.getHeader("Authorization"); - // - // String path = req.getServletPath(); - // if(authorization==null || req.getUserPrincipal()!=null || path.startsWith("/secured/")) { - // chain.doFilter(request,response); - // } else { - // if(req.getQueryString()!=null) - // path += req.getQueryString(); - // ((HttpServletResponse)response).sendRedirect(req.getContextPath()+"/secured"+path); - // } - //} - + @Override public void destroy() { } } diff --git a/core/src/main/java/hudson/security/ChainedServletFilter.java b/core/src/main/java/hudson/security/ChainedServletFilter.java index 4c8805f9c83e..faf9171300a7 100644 --- a/core/src/main/java/hudson/security/ChainedServletFilter.java +++ b/core/src/main/java/hudson/security/ChainedServletFilter.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.security; import java.io.IOException; @@ -29,7 +30,6 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; - import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; @@ -64,6 +64,7 @@ public void setFilters(Collection filters) { this.filters = filters.toArray(new Filter[0]); } + @Override public void init(FilterConfig filterConfig) throws ServletException { if (LOGGER.isLoggable(Level.FINEST)) for (Filter f : filters) @@ -74,6 +75,7 @@ public void init(FilterConfig filterConfig) throws ServletException { } private static final Pattern UNINTERESTING_URIS = Pattern.compile("/(images|jsbundles|css|scripts|adjuncts)/|/favicon[.]ico|/ajax"); + @Override public void doFilter(ServletRequest request, ServletResponse response, final FilterChain chain) throws IOException, ServletException { String uri = request instanceof HttpServletRequest ? ((HttpServletRequest) request).getRequestURI() : "?"; @@ -81,20 +83,20 @@ public void doFilter(ServletRequest request, ServletResponse response, final Fil LOGGER.log(level, () -> "starting filter on " + uri); new FilterChain() { - private int position=0; + private int position = 0; // capture the array for thread-safety private final Filter[] filters = ChainedServletFilter.this.filters; @Override public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException { - if(position==filters.length) { + if (position == filters.length) { LOGGER.log(level, () -> uri + " end: " + status()); - chain.doFilter(request,response); + chain.doFilter(request, response); } else { Filter next = filters[position++]; try { LOGGER.log(level, () -> uri + " @" + position + " " + next + " »"); - next.doFilter(request,response,this); + next.doFilter(request, response, this); LOGGER.log(level, () -> uri + " @" + position + " " + next + " « success: " + status()); } catch (IOException | ServletException | RuntimeException x) { LOGGER.log(level, () -> uri + " @" + position + " " + next + " « " + x + ": " + status()); @@ -106,10 +108,11 @@ public void doFilter(ServletRequest request, ServletResponse response) throws IO private int status() { return response instanceof HttpServletResponse ? ((HttpServletResponse) response).getStatus() : 0; } - }.doFilter(request,response); + }.doFilter(request, response); } + @Override public void destroy() { for (Filter f : filters) f.destroy(); diff --git a/core/src/main/java/hudson/security/CliAuthenticator.java b/core/src/main/java/hudson/security/CliAuthenticator.java index 33daf307c1d3..3b64167c1401 100644 --- a/core/src/main/java/hudson/security/CliAuthenticator.java +++ b/core/src/main/java/hudson/security/CliAuthenticator.java @@ -21,13 +21,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.security; +import java.io.IOException; import org.acegisecurity.Authentication; import org.acegisecurity.AuthenticationException; -import java.io.IOException; - /** * @deprecated No longer used. */ diff --git a/core/src/main/java/hudson/security/ContainerAuthentication.java b/core/src/main/java/hudson/security/ContainerAuthentication.java index 16b6952b61a6..be7bdc01ab62 100644 --- a/core/src/main/java/hudson/security/ContainerAuthentication.java +++ b/core/src/main/java/hudson/security/ContainerAuthentication.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,16 +21,16 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package hudson.security; -import jenkins.model.Jenkins; +package hudson.security; -import javax.servlet.ServletRequest; -import javax.servlet.http.HttpServletRequest; import java.security.Principal; -import java.util.List; import java.util.ArrayList; import java.util.Collection; +import java.util.List; +import javax.servlet.ServletRequest; +import javax.servlet.http.HttpServletRequest; +import jenkins.model.Jenkins; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.springframework.security.core.Authentication; @@ -55,48 +55,55 @@ public final class ContainerAuthentication implements Authentication { /** * Servlet container can tie a {@link ServletRequest} to the request handling thread, * so we need to capture all the information upfront to allow {@link Authentication} - * to be passed to other threads, like update center does. See HUDSON-5382. + * to be passed to other threads, like update center does. See JENKINS-5382. */ public ContainerAuthentication(HttpServletRequest request) { this.principal = request.getUserPrincipal(); - if (principal==null) - throw new IllegalStateException(); // for anonymous users, we just don't call SecurityContextHolder.getContext().setAuthentication. + if (principal == null) + throw new IllegalStateException(); // for anonymous users, we just don't call SecurityContextHolder.getContext().setAuthentication. // Servlet API doesn't provide a way to list up all roles the current user // has, so we need to ask AuthorizationStrategy what roles it is going to check against. List l = new ArrayList<>(); - for( String g : Jenkins.get().getAuthorizationStrategy().getGroups()) { - if(request.isUserInRole(g)) + for (String g : Jenkins.get().getAuthorizationStrategy().getGroups()) { + if (request.isUserInRole(g)) l.add(new SimpleGrantedAuthority(g)); } l.add(SecurityRealm.AUTHENTICATED_AUTHORITY2); authorities = l; } + @Override public Collection getAuthorities() { return authorities; } + @Override public Object getCredentials() { return null; } + @Override public Object getDetails() { return null; } + @Override public String getPrincipal() { return principal.getName(); } + @Override public boolean isAuthenticated() { return true; } + @Override public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException { // noop } + @Override public String getName() { return getPrincipal(); } diff --git a/core/src/main/java/hudson/security/FederatedLoginService.java b/core/src/main/java/hudson/security/FederatedLoginService.java index 0d7567668a5c..2d176290d8be 100644 --- a/core/src/main/java/hudson/security/FederatedLoginService.java +++ b/core/src/main/java/hudson/security/FederatedLoginService.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.security; import edu.umd.cs.findbugs.annotations.CheckForNull; @@ -182,20 +183,19 @@ public final User locateUser() { * to the caller of your "doXyz" method, it will either render an error page or initiate * a user registration session (provided that {@link SecurityRealm} supports that.) */ - @SuppressWarnings("ACL.impersonate") @NonNull public User signin() throws UnclaimedIdentityException { User u = locateUser(); - if (u!=null) { + if (u != null) { // login as this user UserDetails d = Jenkins.get().getSecurityRealm().loadUserByUsername2(u.getId()); - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(d,"",d.getAuthorities()); + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(d, "", d.getAuthorities()); token.setDetails(d); SecurityContextHolder.getContext().setAuthentication(token); return u; } else { - // Unassociated identity. + // Unassociated identity. throw new UnclaimedIdentityException(this); } } @@ -210,7 +210,7 @@ public User signin() throws UnclaimedIdentityException { */ public void addToCurrentUser() throws IOException { User u = User.current(); - if (u==null) throw new IllegalStateException("Current request is unauthenticated"); + if (u == null) throw new IllegalStateException("Current request is unauthenticated"); addTo(u); } @@ -220,7 +220,7 @@ public void addToCurrentUser() throws IOException { */ public void addTo(User u) throws IOException { FederatedLoginServiceUserProperty p = u.getProperty(getUserPropertyClass()); - if (p==null) { + if (p == null) { p = (FederatedLoginServiceUserProperty) UserProperty.all().find(getUserPropertyClass()).newInstance(u); u.addProperty(p); } @@ -244,11 +244,12 @@ public UnclaimedIdentityException(FederatedIdentity identity) { this.identity = identity; } + @Override public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { SecurityRealm sr = Jenkins.get().getSecurityRealm(); if (sr.allowsSignup()) { try { - sr.commenceSignup(identity).generateResponse(req,rsp,node); + sr.commenceSignup(identity).generateResponse(req, rsp, node); return; } catch (UnsupportedOperationException e) { // fall through @@ -257,7 +258,7 @@ public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object nod // this security realm doesn't support user registration. // just report an error - req.getView(this,"error").forward(req,rsp); + req.getView(this, "error").forward(req, rsp); } } diff --git a/core/src/main/java/hudson/security/FederatedLoginServiceUserProperty.java b/core/src/main/java/hudson/security/FederatedLoginServiceUserProperty.java index 334fa1dcd1b0..0961b3a2d8e0 100644 --- a/core/src/main/java/hudson/security/FederatedLoginServiceUserProperty.java +++ b/core/src/main/java/hudson/security/FederatedLoginServiceUserProperty.java @@ -21,10 +21,10 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.security; import hudson.model.UserProperty; - import java.io.IOException; import java.util.Collection; import java.util.Collections; diff --git a/core/src/main/java/hudson/security/FullControlOnceLoggedInAuthorizationStrategy.java b/core/src/main/java/hudson/security/FullControlOnceLoggedInAuthorizationStrategy.java index 210951f481ff..7dbb0ab67021 100644 --- a/core/src/main/java/hudson/security/FullControlOnceLoggedInAuthorizationStrategy.java +++ b/core/src/main/java/hudson/security/FullControlOnceLoggedInAuthorizationStrategy.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Seiji Sogabe - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,10 +21,15 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.security; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.Extension; import hudson.model.Descriptor; +import java.util.Collections; +import java.util.List; +import javax.inject.Inject; import jenkins.model.Jenkins; import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; @@ -32,10 +37,6 @@ import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.DataBoundSetter; -import javax.inject.Inject; -import java.util.Collections; -import java.util.List; - /** * {@link AuthorizationStrategy} that grants full-control to authenticated user * and optionally read access to anonymous users @@ -48,7 +49,7 @@ public class FullControlOnceLoggedInAuthorizationStrategy extends AuthorizationS * default is to allow it */ private boolean denyAnonymousReadAccess = false; - + @DataBoundConstructor public FullControlOnceLoggedInAuthorizationStrategy() { } @@ -58,17 +59,18 @@ public ACL getRootACL() { return denyAnonymousReadAccess ? AUTHENTICATED_READ : ANONYMOUS_READ; } + @Override public List getGroups() { return Collections.emptyList(); } - + /** * If true, anonymous read access will be allowed */ public boolean isAllowAnonymousRead() { return !denyAnonymousReadAccess; } - + @DataBoundSetter public void setAllowAnonymousRead(boolean allowAnonymousRead) { this.denyAnonymousReadAccess = !allowAnonymousRead; @@ -78,10 +80,10 @@ public void setAllowAnonymousRead(boolean allowAnonymousRead) { private static final SparseACL ANONYMOUS_READ = new SparseACL(null); static { - ANONYMOUS_READ.add(ACL.EVERYONE, Jenkins.ADMINISTER,true); - ANONYMOUS_READ.add(ACL.ANONYMOUS, Jenkins.ADMINISTER,false); - ANONYMOUS_READ.add(ACL.ANONYMOUS, Permission.READ,true); - + ANONYMOUS_READ.add(ACL.EVERYONE, Jenkins.ADMINISTER, true); + ANONYMOUS_READ.add(ACL.ANONYMOUS, Jenkins.ADMINISTER, false); + ANONYMOUS_READ.add(ACL.ANONYMOUS, Permission.READ, true); + AUTHENTICATED_READ.add(ACL.EVERYONE, Jenkins.ADMINISTER, true); AUTHENTICATED_READ.add(ACL.ANONYMOUS, Jenkins.ADMINISTER, false); } @@ -96,6 +98,7 @@ public void setAllowAnonymousRead(boolean allowAnonymousRead) { @Extension @Symbol("loggedInUsersCanDoAnything") public static class DescriptorImpl extends Descriptor { + @SuppressFBWarnings(value = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD", justification = "for backward compatibility") public DescriptorImpl() { DESCRIPTOR = this; } diff --git a/core/src/main/java/hudson/security/GlobalSecurityConfiguration.java b/core/src/main/java/hudson/security/GlobalSecurityConfiguration.java index b765a80b0b1a..84f6b52e1e8a 100644 --- a/core/src/main/java/hudson/security/GlobalSecurityConfiguration.java +++ b/core/src/main/java/hudson/security/GlobalSecurityConfiguration.java @@ -21,37 +21,33 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.security; -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.BulkChange; import hudson.Extension; import hudson.Functions; import hudson.RestrictedSince; import hudson.markup.MarkupFormatter; +import hudson.model.Describable; import hudson.model.Descriptor; import hudson.model.Descriptor.FormException; -import hudson.model.Describable; import hudson.model.ManagementLink; import hudson.util.FormApply; - import java.io.IOException; import java.util.Set; import java.util.TreeSet; import java.util.function.Predicate; import java.util.logging.Level; import java.util.logging.Logger; - -import edu.umd.cs.findbugs.annotations.NonNull; import javax.servlet.ServletException; - import jenkins.model.GlobalConfigurationCategory; import jenkins.model.Jenkins; import jenkins.util.ServerTcpPort; import net.sf.json.JSONArray; import net.sf.json.JSONException; import net.sf.json.JSONObject; - import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; @@ -68,7 +64,7 @@ */ @Extension(ordinal = Integer.MAX_VALUE - 210) @Symbol("securityConfig") public class GlobalSecurityConfiguration extends ManagementLink implements Describable { - + private static final Logger LOGGER = Logger.getLogger(GlobalSecurityConfiguration.class.getName()); public SecurityRealm getSecurityRealm() { @@ -89,7 +85,7 @@ public int getSlaveAgentPort() { /** * @since 2.24 - * @return true if the slave agent port is enforced on this instance. + * @return true if the inbound agent port is enforced on this instance. */ @Restricted(NoExternalUse.class) public boolean isSlaveAgentPortEnforced() { @@ -115,11 +111,11 @@ public synchronized void doConfigure(StaplerRequest req, StaplerResponse rsp) th // for compatibility reasons, the actual value is stored in Jenkins JSONObject json = req.getSubmittedForm(); BulkChange bc = new BulkChange(Jenkins.get()); - try{ + try { boolean result = configure(req, json); - LOGGER.log(Level.FINE, "security saved: "+result); + LOGGER.log(Level.FINE, "security saved: " + result); Jenkins.get().save(); - FormApply.success(req.getContextPath()+"/manage").generateResponse(req, rsp, null); + FormApply.success(req.getContextPath() + "/manage").generateResponse(req, rsp, null); } catch (JSONException x) { LOGGER.warning(() -> "Bad JSON:\n" + json.toString(2)); throw x; @@ -143,7 +139,7 @@ public boolean configure(StaplerRequest req, JSONObject json) throws FormExcepti } else { j.setMarkupFormatter(null); } - + // Agent settings if (!isSlaveAgentPortEnforced()) { try { @@ -167,26 +163,26 @@ public boolean configure(StaplerRequest req, JSONObject json) throws FormExcepti // persist all the additional security configs boolean result = true; - for(Descriptor d : Functions.getSortedDescriptorsForGlobalConfigByDescriptor(FILTER)){ - result &= configureDescriptor(req,json,d); + for (Descriptor d : Functions.getSortedDescriptorsForGlobalConfigByDescriptor(FILTER)) { + result &= configureDescriptor(req, json, d); } - + return result; } - + private boolean configureDescriptor(StaplerRequest req, JSONObject json, Descriptor d) throws FormException { // collapse the structure to remain backward compatible with the JSON structure before 1. String name = d.getJsonSafeClassName(); JSONObject js = json.has(name) ? json.getJSONObject(name) : new JSONObject(); // if it doesn't have the property, the method returns invalid null object. json.putAll(js); return d.configure(req, js); - } + } @Override public String getDisplayName() { return getDescriptor().getDisplayName(); } - + @Override public String getDescription() { return Messages.GlobalSecurityConfiguration_Description(); @@ -194,14 +190,14 @@ public String getDescription() { @Override public String getIconFileName() { - return "secure.png"; + return "symbol-lock-closed"; } @Override public String getUrlName() { return "configureSecurity"; } - + @Override public Permission getRequiredPermission() { return Jenkins.SYSTEM_READ; @@ -209,11 +205,9 @@ public Permission getRequiredPermission() { @Restricted(NoExternalUse.class) @RestrictedSince("2.222") - @SuppressFBWarnings("MS_SHOULD_BE_FINAL") - public static Predicate FILTER = input -> input.getCategory() instanceof GlobalConfigurationCategory.Security; + public static final Predicate FILTER = input -> input.getCategory() instanceof GlobalConfigurationCategory.Security; /** - * @return * @see Describable#getDescriptor() */ @SuppressWarnings("unchecked") @@ -221,7 +215,7 @@ public Permission getRequiredPermission() { public Descriptor getDescriptor() { return Jenkins.get().getDescriptorOrDie(getClass()); } - + @Extension @Symbol("security") public static final class DescriptorImpl extends Descriptor { @Override diff --git a/core/src/main/java/hudson/security/GroupDetails.java b/core/src/main/java/hudson/security/GroupDetails.java index 543074ef0e3a..ae94f20a0392 100644 --- a/core/src/main/java/hudson/security/GroupDetails.java +++ b/core/src/main/java/hudson/security/GroupDetails.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.security; import java.util.Set; diff --git a/core/src/main/java/hudson/security/HttpSessionContextIntegrationFilter2.java b/core/src/main/java/hudson/security/HttpSessionContextIntegrationFilter2.java index 35baa6659f03..786df5d72879 100644 --- a/core/src/main/java/hudson/security/HttpSessionContextIntegrationFilter2.java +++ b/core/src/main/java/hudson/security/HttpSessionContextIntegrationFilter2.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,17 +21,18 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.security; import hudson.model.User; -import jenkins.security.seed.UserSeedProperty; +import java.io.IOException; +import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; -import javax.servlet.FilterChain; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; -import java.io.IOException; +import jenkins.security.seed.UserSeedProperty; import org.springframework.security.authentication.AnonymousAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContext; diff --git a/core/src/main/java/hudson/security/HudsonAuthenticationEntryPoint.java b/core/src/main/java/hudson/security/HudsonAuthenticationEntryPoint.java index c31be3b62fec..c81c642650ff 100644 --- a/core/src/main/java/hudson/security/HudsonAuthenticationEntryPoint.java +++ b/core/src/main/java/hudson/security/HudsonAuthenticationEntryPoint.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,20 +21,22 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.security; -import com.google.common.base.Strings; +import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN; + import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.Functions; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import java.text.MessageFormat; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.springframework.security.authentication.InsufficientAuthenticationException; @@ -52,7 +54,7 @@ * *

    * The page that programs see is entirely white, and it auto-redirects, - * so humans wouldn't notice it. + * so humans wouldn't notice it. * * @author Kohsuke Kawaguchi */ @@ -68,7 +70,7 @@ public HudsonAuthenticationEntryPoint(String loginFormUrl) { @Override public void commence(HttpServletRequest req, HttpServletResponse rsp, AuthenticationException reason) throws IOException, ServletException { String requestedWith = req.getHeader("X-Requested-With"); - if("XMLHttpRequest".equals(requestedWith)) { + if ("XMLHttpRequest".equals(requestedWith)) { // container authentication normally relies on session attribute to // remember where the user came from, so concurrent AJAX requests // often ends up sending users back to AJAX pages after successful login. @@ -78,9 +80,9 @@ public void commence(HttpServletRequest req, HttpServletResponse rsp, Authentica } else { // give the opportunity to include the target URL String uriFrom = req.getRequestURI(); - if(!Strings.isNullOrEmpty(req.getQueryString())) uriFrom += "?" + req.getQueryString(); + if (req.getQueryString() != null && !req.getQueryString().isEmpty()) uriFrom += "?" + req.getQueryString(); String loginForm = req.getContextPath() + loginFormUrl; - loginForm = MessageFormat.format(loginForm, URLEncoder.encode(uriFrom,"UTF-8")); + loginForm = MessageFormat.format(loginForm, URLEncoder.encode(uriFrom, "UTF-8")); req.setAttribute("loginForm", loginForm); rsp.setStatus(SC_FORBIDDEN); @@ -99,21 +101,21 @@ public void commence(HttpServletRequest req, HttpServletResponse rsp, Authentica PrintWriter out; try { - out = new PrintWriter(new OutputStreamWriter(rsp.getOutputStream())); + out = new PrintWriter(new OutputStreamWriter(rsp.getOutputStream(), StandardCharsets.UTF_8)); } catch (IllegalStateException e) { out = rsp.getWriter(); } printResponse(loginForm, out); - if (cause!=null) + if (cause != null) cause.report(out); out.printf( - "-->%n%n"+ + "-->%n%n" + ""); // Turn Off "Show Friendly HTTP Error Messages" Feature on the Server Side. // See http://support.microsoft.com/kb/294807 - for (int i=0; i < 10; i++) + for (int i = 0; i < 10; i++) out.print(" "); out.close(); } @@ -127,8 +129,8 @@ private void printResponse(String loginForm, PrintWriter out) { "" + "" + "%n" + - "%n%n"+ - "Authentication required%n"+ - " \\?\UNC\server\share - path = "\\\\?\\UNC\\" + canonicalPath.substring(2); - } else { - // prefix, canonical path should be normalized and absolute so this should work. - path = "\\\\?\\" + canonicalPath; - } - return Kernel32.INSTANCE.GetFileAttributesW(new WString(path)); + // allow lookup of paths longer than MAX_PATH + // http://msdn.microsoft.com/en-us/library/aa365247(v=VS.85).aspx + String canonicalPath = file.getCanonicalPath(); + String path; + if (canonicalPath.length() < 260) { + // path is short, use as-is + path = canonicalPath; + } else if (canonicalPath.startsWith("\\\\")) { + // network share + // \\server\share --> \\?\UNC\server\share + path = "\\\\?\\UNC\\" + canonicalPath.substring(2); + } else { + // prefix, canonical path should be normalized and absolute so this should work. + path = "\\\\?\\" + canonicalPath; + } + return Kernel32.INSTANCE.GetFileAttributesW(new WString(path)); } /** @@ -99,8 +99,8 @@ public static int getWin32FileAttributes(File file) throws IOException { public static void createSymbolicLink(File symlink, String target, boolean dirLink) throws IOException { if (!Kernel32.INSTANCE.CreateSymbolicLinkW( new WString(symlink.getPath()), new WString(target), - dirLink?Kernel32.SYMBOLIC_LINK_FLAG_DIRECTORY:0)) { - throw new WinIOException("Failed to create a symlink "+symlink+" to "+target); + dirLink ? Kernel32.SYMBOLIC_LINK_FLAG_DIRECTORY : 0)) { + throw new WinIOException("Failed to create a symlink " + symlink + " to " + target); } } @@ -114,7 +114,7 @@ public static boolean isJunctionOrSymlink(File file) throws IOException { public static File getTempDir() { Memory buf = new Memory(1024); - if (Kernel32.INSTANCE.GetTempPathW(512,buf)!=0) {// the first arg is number of wchar + if (Kernel32.INSTANCE.GetTempPathW(512, buf) != 0) { // the first arg is number of wchar return new File(buf.getWideString(0)); } else { return null; @@ -123,10 +123,10 @@ public static File getTempDir() { /*package*/ static Kernel32 load() { try { - return (Kernel32) Native.loadLibrary("kernel32", Kernel32.class); + return (Kernel32) Native.load("kernel32", Kernel32.class); } catch (Throwable e) { LOGGER.log(Level.SEVERE, "Failed to load Kernel32", e); - return InitializationErrorInvocationHandler.create(Kernel32.class,e); + return InitializationErrorInvocationHandler.create(Kernel32.class, e); } } diff --git a/core/src/main/java/hudson/util/jna/Options.java b/core/src/main/java/hudson/util/jna/Options.java index 4b1d1b78a161..2b75aac9f872 100644 --- a/core/src/main/java/hudson/util/jna/Options.java +++ b/core/src/main/java/hudson/util/jna/Options.java @@ -13,19 +13,23 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. */ + package hudson.util.jna; -import static com.sun.jna.Library.*; -import com.sun.jna.win32.W32APITypeMapper; -import com.sun.jna.win32.W32APIFunctionMapper; +import static com.sun.jna.Library.OPTION_FUNCTION_MAPPER; +import static com.sun.jna.Library.OPTION_TYPE_MAPPER; -import java.util.Map; +import com.sun.jna.win32.W32APIFunctionMapper; +import com.sun.jna.win32.W32APITypeMapper; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.util.HashMap; +import java.util.Map; /** * * @author TB */ +@SuppressFBWarnings(value = "MS_OOI_PKGPROTECT", justification = "for backward compatibility") public interface Options { Map UNICODE_OPTIONS = new HashMap() { { diff --git a/core/src/main/java/hudson/util/jna/RegistryKey.java b/core/src/main/java/hudson/util/jna/RegistryKey.java index 554a1263ec8f..cd9e9c0a07bc 100644 --- a/core/src/main/java/hudson/util/jna/RegistryKey.java +++ b/core/src/main/java/hudson/util/jna/RegistryKey.java @@ -13,10 +13,10 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. */ + package hudson.util.jna; import com.sun.jna.ptr.IntByReference; - import java.nio.charset.StandardCharsets; import java.util.Collection; import java.util.TreeMap; @@ -45,24 +45,24 @@ private RegistryKey(int handle) { path = ""; } - private RegistryKey(RegistryKey ancestor, String path,int handle) { + private RegistryKey(RegistryKey ancestor, String path, int handle) { this.handle = handle; this.root = ancestor.root; - this.path = combine(ancestor.path,path); + this.path = combine(ancestor.path, path); } private static String combine(String a, String b) { - if(a.length()==0) return b; - if(b.length()==0) return a; - return a+'\\'+b; + if (a.length() == 0) return b; + if (b.length() == 0) return a; + return a + '\\' + b; } /** * Converts a Windows buffer to a Java String. * * @param buf buffer - * @throws java.io.UnsupportedEncodingException on error * @return String + * @throws java.io.UnsupportedEncodingException on error */ static String convertBufferToString(byte[] buf) { return new String(buf, 0, buf.length - 2, StandardCharsets.UTF_16LE); @@ -97,7 +97,7 @@ private byte[] getValue(String valueName) { lpcbData = new IntByReference(); OUTER: - while(true) { + while (true) { int r = Advapi32.INSTANCE.RegQueryValueEx(handle, valueName, null, pType, lpData, lpcbData); switch (r) { case WINERROR.ERROR_MORE_DATA: @@ -106,8 +106,10 @@ private byte[] getValue(String valueName) { case WINERROR.ERROR_SUCCESS: return lpData; + + default: + throw new JnaException(r); } - throw new JnaException(r); } } @@ -125,7 +127,7 @@ private void check(int r) { */ public void setValue(String name, String value) { byte[] bytes = value.getBytes(StandardCharsets.UTF_16LE); - int newLength = bytes.length+2; // for 0 padding + int newLength = bytes.length + 2; // for 0 padding byte[] with0 = new byte[newLength]; System.arraycopy(bytes, 0, with0, 0, newLength); check(Advapi32.INSTANCE.RegSetValueEx(handle, name, 0, WINNT.REG_SZ, with0, with0.length)); @@ -155,9 +157,9 @@ public boolean valueExists(String name) { lpcbData = new IntByReference(); OUTER: - while(true) { + while (true) { int r = Advapi32.INSTANCE.RegQueryValueEx(handle, name, null, pType, lpData, lpcbData); - switch(r) { + switch (r) { case WINERROR.ERROR_MORE_DATA: lpData = new byte[lpcbData.getValue()]; continue OUTER; @@ -203,17 +205,17 @@ public Collection getSubKeys() { } public RegistryKey open(String subKeyName) { - return open(subKeyName,0xF003F/*KEY_ALL_ACCESS*/); + return open(subKeyName, 0xF003F/*KEY_ALL_ACCESS*/); } public RegistryKey openReadonly(String subKeyName) { - return open(subKeyName,0x20019/*KEY_READ*/); + return open(subKeyName, 0x20019/*KEY_READ*/); } public RegistryKey open(String subKeyName, int access) { IntByReference pHandle = new IntByReference(); check(Advapi32.INSTANCE.RegOpenKeyEx(handle, subKeyName, 0, access, pHandle)); - return new RegistryKey(this,subKeyName,pHandle.getValue()); + return new RegistryKey(this, subKeyName, pHandle.getValue()); } /** @@ -265,7 +267,7 @@ public TreeMap getValues() { break; // not supported yet } break; - + default: check(result); } @@ -282,11 +284,12 @@ protected void finalize() throws Throwable { } public void dispose() { - if(handle!=0) + if (handle != 0) Advapi32.INSTANCE.RegCloseKey(handle); handle = 0; } + @Override public void close() { dispose(); } diff --git a/core/src/main/java/hudson/util/jna/SHELLEXECUTEINFO.java b/core/src/main/java/hudson/util/jna/SHELLEXECUTEINFO.java index 0bfc5e627ff7..bca03457306d 100644 --- a/core/src/main/java/hudson/util/jna/SHELLEXECUTEINFO.java +++ b/core/src/main/java/hudson/util/jna/SHELLEXECUTEINFO.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.util.jna; import com.sun.jna.Pointer; @@ -57,7 +58,7 @@ * @author Kohsuke Kawaguchi * @see MSDN: SHELLEXECUTEINFO */ -@SuppressFBWarnings(value = {"UUF_UNUSED_PUBLIC_OR_PROTECTED_FIELD", "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD"}, +@SuppressFBWarnings(value = {"UUF_UNUSED_PUBLIC_OR_PROTECTED_FIELD", "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD"}, justification = "JNA Data Structure") public class SHELLEXECUTEINFO extends Structure { public int cbSize = size(); @@ -88,28 +89,26 @@ protected List getFieldOrder() { "hProcess"); } - @SuppressFBWarnings(value = {"UUF_UNUSED_PUBLIC_OR_PROTECTED_FIELD", "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD"}, + @SuppressFBWarnings(value = {"UUF_UNUSED_PUBLIC_OR_PROTECTED_FIELD", "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD"}, justification = "JNA Data Structure") public static class DUMMYUNIONNAME_union extends Union { public Pointer hIcon; public Pointer hMonitor; public DUMMYUNIONNAME_union() { - super(); } public DUMMYUNIONNAME_union(Pointer hIcon_or_hMonitor) { - super(); this.hMonitor = this.hIcon = hIcon_or_hMonitor; setType(Pointer.class); } public static class ByReference extends DUMMYUNIONNAME_union implements Structure.ByReference { - + } public static class ByValue extends DUMMYUNIONNAME_union implements Structure.ByValue { - + } } } diff --git a/core/src/main/java/hudson/util/jna/Shell32.java b/core/src/main/java/hudson/util/jna/Shell32.java index c330d430fad7..2007167befa7 100644 --- a/core/src/main/java/hudson/util/jna/Shell32.java +++ b/core/src/main/java/hudson/util/jna/Shell32.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.util.jna; import com.sun.jna.Native; @@ -30,7 +31,7 @@ * @author Kohsuke Kawaguchi */ public interface Shell32 extends StdCallLibrary { - Shell32 INSTANCE = (Shell32) Native.loadLibrary("shell32", Shell32.class); + Shell32 INSTANCE = (Shell32) Native.load("shell32", Shell32.class); /** * @return true if successful. Otherwise false. diff --git a/core/src/main/java/hudson/util/jna/WINBASE.java b/core/src/main/java/hudson/util/jna/WINBASE.java index f0ace4e4ccc9..695976d521c8 100644 --- a/core/src/main/java/hudson/util/jna/WINBASE.java +++ b/core/src/main/java/hudson/util/jna/WINBASE.java @@ -13,10 +13,11 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. */ + package hudson.util.jna; -import com.sun.jna.Structure; import com.sun.jna.Pointer; +import com.sun.jna.Structure; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.util.Arrays; import java.util.List; diff --git a/core/src/main/java/hudson/util/jna/WINERROR.java b/core/src/main/java/hudson/util/jna/WINERROR.java index 0f9f134f721a..027fa144642c 100644 --- a/core/src/main/java/hudson/util/jna/WINERROR.java +++ b/core/src/main/java/hudson/util/jna/WINERROR.java @@ -13,6 +13,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. */ + package hudson.util.jna; /** diff --git a/core/src/main/java/hudson/util/jna/WINNT.java b/core/src/main/java/hudson/util/jna/WINNT.java index ce484db6ce8b..6935041796ff 100644 --- a/core/src/main/java/hudson/util/jna/WINNT.java +++ b/core/src/main/java/hudson/util/jna/WINNT.java @@ -13,6 +13,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. */ + package hudson.util.jna; /** @@ -47,8 +48,8 @@ public interface WINNT { int KEY_NOTIFY = 0x0010; int KEY_CREATE_LINK = 0x0020; - int KEY_READ = ((STANDARD_RIGHTS_READ | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY) & (~SYNCHRONIZE)); - int KEY_WRITE = ((STANDARD_RIGHTS_WRITE | KEY_SET_VALUE | KEY_CREATE_SUB_KEY) & (~SYNCHRONIZE)); + int KEY_READ = ((STANDARD_RIGHTS_READ | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY) & ~SYNCHRONIZE); + int KEY_WRITE = ((STANDARD_RIGHTS_WRITE | KEY_SET_VALUE | KEY_CREATE_SUB_KEY) & ~SYNCHRONIZE); int REG_NONE = 0; // No value type int REG_SZ = 1; // Unicode nul terminated string diff --git a/core/src/main/java/hudson/util/jna/WinIOException.java b/core/src/main/java/hudson/util/jna/WinIOException.java index 0f2168bb7ddb..a5a14712fc32 100644 --- a/core/src/main/java/hudson/util/jna/WinIOException.java +++ b/core/src/main/java/hudson/util/jna/WinIOException.java @@ -2,7 +2,6 @@ import com.sun.jna.Native; import hudson.Util; - import java.io.IOException; /** @@ -31,7 +30,7 @@ public WinIOException(Throwable cause) { @Override public String getMessage() { - return super.getMessage()+" error="+errorCode+":"+ Util.getWin32ErrorMessage(errorCode); + return super.getMessage() + " error=" + errorCode + ":" + Util.getWin32ErrorMessage(errorCode); } public int getErrorCode() { diff --git a/core/src/main/java/hudson/util/jna/package-info.java b/core/src/main/java/hudson/util/jna/package-info.java index 637a0c66ffdd..a2abf2e79aa3 100644 --- a/core/src/main/java/hudson/util/jna/package-info.java +++ b/core/src/main/java/hudson/util/jna/package-info.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/core/src/main/java/hudson/util/xstream/ImmutableListConverter.java b/core/src/main/java/hudson/util/xstream/ImmutableListConverter.java index fe06ac741170..196e2289d0eb 100644 --- a/core/src/main/java/hudson/util/xstream/ImmutableListConverter.java +++ b/core/src/main/java/hudson/util/xstream/ImmutableListConverter.java @@ -22,6 +22,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.util.xstream; import com.google.common.collect.ImmutableList; @@ -33,12 +34,9 @@ import com.thoughtworks.xstream.converters.reflection.SerializableConverter; import com.thoughtworks.xstream.io.HierarchicalStreamReader; import com.thoughtworks.xstream.mapper.Mapper; - import hudson.util.RobustReflectionConverter; - import java.util.ArrayList; import java.util.List; - import jenkins.util.xstream.CriticalXStreamException; /** @@ -51,12 +49,12 @@ public class ImmutableListConverter extends CollectionConverter { private final SerializableConverter sc; public ImmutableListConverter(XStream xs) { - this(xs.getMapper(),xs.getReflectionProvider()); + this(xs.getMapper(), xs.getReflectionProvider()); } public ImmutableListConverter(Mapper mapper, ReflectionProvider reflectionProvider) { super(mapper); - sc = new SerializableConverter(mapper,reflectionProvider); + sc = new SerializableConverter(mapper, reflectionProvider); } @Override @@ -72,26 +70,26 @@ public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext co List items = new ArrayList(); if (reader.hasMoreChildren()) { reader.moveDown(); - // read the individual items from xml into a list - while (reader.hasMoreChildren()) { - reader.moveDown(); - try { - Object item = readItem(reader, context, items); - items.add(item); - } catch (CriticalXStreamException e) { - throw e; - } catch (XStreamException | LinkageError e) { - RobustReflectionConverter.addErrorInContext(context, e); - } + // read the individual items from xml into a list + while (reader.hasMoreChildren()) { + reader.moveDown(); + try { + Object item = readItem(reader, context, items); + items.add(item); + } catch (CriticalXStreamException e) { + throw e; + } catch (XStreamException | LinkageError e) { + RobustReflectionConverter.addErrorInContext(context, e); + } reader.moveUp(); - } + } // move back up past the elements element. reader.moveUp(); } return ImmutableList.copyOf(items); } else { - return ImmutableList.copyOf((List)super.unmarshal(reader, context)); + return ImmutableList.copyOf((List) super.unmarshal(reader, context)); } } diff --git a/core/src/main/java/hudson/util/xstream/ImmutableMapConverter.java b/core/src/main/java/hudson/util/xstream/ImmutableMapConverter.java index 256e403f5d68..d5821a5c0c95 100644 --- a/core/src/main/java/hudson/util/xstream/ImmutableMapConverter.java +++ b/core/src/main/java/hudson/util/xstream/ImmutableMapConverter.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.util.xstream; import com.google.common.collect.ImmutableMap; @@ -31,7 +32,6 @@ import com.thoughtworks.xstream.converters.reflection.SerializableConverter; import com.thoughtworks.xstream.io.HierarchicalStreamReader; import com.thoughtworks.xstream.mapper.Mapper; - import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -45,12 +45,12 @@ public class ImmutableMapConverter extends MapConverter { private final SerializableConverter sc; public ImmutableMapConverter(XStream xs) { - this(xs.getMapper(),xs.getReflectionProvider()); + this(xs.getMapper(), xs.getReflectionProvider()); } public ImmutableMapConverter(Mapper mapper, ReflectionProvider reflectionProvider) { super(mapper); - sc = new SerializableConverter(mapper,reflectionProvider); + sc = new SerializableConverter(mapper, reflectionProvider); } @Override @@ -60,7 +60,7 @@ public boolean canConvert(Class type) { @Override public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { - return ImmutableMap.copyOf((Map)super.unmarshal(reader, context)); + return ImmutableMap.copyOf((Map) super.unmarshal(reader, context)); } @Override diff --git a/core/src/main/java/hudson/util/xstream/ImmutableSetConverter.java b/core/src/main/java/hudson/util/xstream/ImmutableSetConverter.java index 1b2ab104ee82..b8c3c183984e 100644 --- a/core/src/main/java/hudson/util/xstream/ImmutableSetConverter.java +++ b/core/src/main/java/hudson/util/xstream/ImmutableSetConverter.java @@ -8,7 +8,6 @@ import com.thoughtworks.xstream.converters.reflection.SerializableConverter; import com.thoughtworks.xstream.io.HierarchicalStreamReader; import com.thoughtworks.xstream.mapper.Mapper; - import java.util.ArrayList; import java.util.List; @@ -19,12 +18,12 @@ public class ImmutableSetConverter extends CollectionConverter { private final SerializableConverter sc; public ImmutableSetConverter(XStream xs) { - this(xs.getMapper(),xs.getReflectionProvider()); + this(xs.getMapper(), xs.getReflectionProvider()); } public ImmutableSetConverter(Mapper mapper, ReflectionProvider reflectionProvider) { super(mapper); - sc = new SerializableConverter(mapper,reflectionProvider); + sc = new SerializableConverter(mapper, reflectionProvider); } @Override diff --git a/core/src/main/java/hudson/util/xstream/ImmutableSortedSetConverter.java b/core/src/main/java/hudson/util/xstream/ImmutableSortedSetConverter.java index b6f63a926e20..6a1481f9e85a 100644 --- a/core/src/main/java/hudson/util/xstream/ImmutableSortedSetConverter.java +++ b/core/src/main/java/hudson/util/xstream/ImmutableSortedSetConverter.java @@ -8,7 +8,6 @@ import com.thoughtworks.xstream.converters.reflection.SerializableConverter; import com.thoughtworks.xstream.io.HierarchicalStreamReader; import com.thoughtworks.xstream.mapper.Mapper; - import java.util.ArrayList; import java.util.List; @@ -19,12 +18,12 @@ public class ImmutableSortedSetConverter extends CollectionConverter { private final SerializableConverter sc; public ImmutableSortedSetConverter(XStream xs) { - this(xs.getMapper(),xs.getReflectionProvider()); + this(xs.getMapper(), xs.getReflectionProvider()); } public ImmutableSortedSetConverter(Mapper mapper, ReflectionProvider reflectionProvider) { super(mapper); - sc = new SerializableConverter(mapper,reflectionProvider); + sc = new SerializableConverter(mapper, reflectionProvider); } @Override diff --git a/core/src/main/java/hudson/util/xstream/MapperDelegate.java b/core/src/main/java/hudson/util/xstream/MapperDelegate.java index deea611a748b..78d045ca123c 100644 --- a/core/src/main/java/hudson/util/xstream/MapperDelegate.java +++ b/core/src/main/java/hudson/util/xstream/MapperDelegate.java @@ -9,6 +9,7 @@ * * Created on 22. January 2005 by Joe Walnes */ + package hudson.util.xstream; import com.thoughtworks.xstream.XStream; @@ -139,7 +140,7 @@ public Mapper lookupMapperOfType(Class type) { @Override public SingleValueConverter getConverterFromItemType(String fieldName, Class type, Class definedIn) { - return delegate.getConverterFromItemType(fieldName, type, definedIn); + return delegate.getConverterFromItemType(fieldName, type, definedIn); } /** @@ -148,7 +149,7 @@ public SingleValueConverter getConverterFromItemType(String fieldName, Class typ @Deprecated @Override public String aliasForAttribute(Class definedIn, String fieldName) { - return delegate.aliasForAttribute(definedIn, fieldName); + return delegate.aliasForAttribute(definedIn, fieldName); } /** @@ -157,7 +158,7 @@ public String aliasForAttribute(Class definedIn, String fieldName) { @Deprecated @Override public String attributeForAlias(Class definedIn, String alias) { - return delegate.attributeForAlias(definedIn, alias); + return delegate.attributeForAlias(definedIn, alias); } /** @@ -166,7 +167,7 @@ public String attributeForAlias(Class definedIn, String alias) { @Deprecated @Override public SingleValueConverter getConverterFromAttribute(Class type, String attribute) { - return delegate.getConverterFromAttribute(type, attribute); + return delegate.getConverterFromAttribute(type, attribute); } @Override diff --git a/core/src/main/java/hudson/views/BuildButtonColumn.java b/core/src/main/java/hudson/views/BuildButtonColumn.java index f0aa4436cfc6..5a48f0da6de8 100644 --- a/core/src/main/java/hudson/views/BuildButtonColumn.java +++ b/core/src/main/java/hudson/views/BuildButtonColumn.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Martin Eigenbrodt - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.views; import hudson.Extension; @@ -40,7 +41,7 @@ public String taskNoun(Object job) { return hudson.model.Messages.AbstractItem_TaskNoun(); } - @Extension(ordinal=DEFAULT_COLUMNS_ORDINAL_ACTIONS_START-1) @Symbol("buildButton") + @Extension(ordinal = DEFAULT_COLUMNS_ORDINAL_ACTIONS_START - 1) @Symbol("buildButton") public static class DescriptorImpl extends ListViewColumnDescriptor { @Override public String getDisplayName() { diff --git a/core/src/main/java/hudson/views/DefaultMyViewsTabBar.java b/core/src/main/java/hudson/views/DefaultMyViewsTabBar.java index 9ebc1e63599c..d697552a6857 100644 --- a/core/src/main/java/hudson/views/DefaultMyViewsTabBar.java +++ b/core/src/main/java/hudson/views/DefaultMyViewsTabBar.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2010, Winston.Prakash@Oracle.com - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.views; import hudson.Extension; diff --git a/core/src/main/java/hudson/views/DefaultViewsTabBar.java b/core/src/main/java/hudson/views/DefaultViewsTabBar.java index e9e9f56dbe11..6f697f96a86e 100644 --- a/core/src/main/java/hudson/views/DefaultViewsTabBar.java +++ b/core/src/main/java/hudson/views/DefaultViewsTabBar.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2010, Winston.Prakash@Oracle.com - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.views; import hudson.Extension; diff --git a/core/src/main/java/hudson/views/GlobalDefaultViewConfiguration.java b/core/src/main/java/hudson/views/GlobalDefaultViewConfiguration.java index 36b8aea6a6df..b60939aae5ee 100644 --- a/core/src/main/java/hudson/views/GlobalDefaultViewConfiguration.java +++ b/core/src/main/java/hudson/views/GlobalDefaultViewConfiguration.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.views; import hudson.Extension; @@ -36,7 +37,7 @@ * * @author Kohsuke Kawaguchi */ -@Extension(ordinal=300) @Symbol("defaultView") +@Extension(ordinal = 300) @Symbol("defaultView") public class GlobalDefaultViewConfiguration extends GlobalConfiguration { @Override public boolean configure(StaplerRequest req, JSONObject json) throws FormException { @@ -53,9 +54,7 @@ public boolean configure(StaplerRequest req, JSONObject json) throws FormExcepti // Fallback if the view is not specified j.setPrimaryView(j.getViews().iterator().next()); } - + return true; } } - - diff --git a/core/src/main/java/hudson/views/JobColumn.java b/core/src/main/java/hudson/views/JobColumn.java index b6f581c154c2..b2ec060f09c3 100644 --- a/core/src/main/java/hudson/views/JobColumn.java +++ b/core/src/main/java/hudson/views/JobColumn.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Martin Eigenbrodt - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.views; import hudson.Extension; @@ -37,7 +38,7 @@ public JobColumn() { } // put this in the middle of icons and properties - @Extension(ordinal=DEFAULT_COLUMNS_ORDINAL_ICON_END+1) @Symbol("jobName") + @Extension(ordinal = DEFAULT_COLUMNS_ORDINAL_ICON_END + 1) @Symbol("jobName") public static class DescriptorImpl extends ListViewColumnDescriptor { @Override public String getDisplayName() { diff --git a/core/src/main/java/hudson/views/LastDurationColumn.java b/core/src/main/java/hudson/views/LastDurationColumn.java index 04696704a65d..f1d7258e5b95 100644 --- a/core/src/main/java/hudson/views/LastDurationColumn.java +++ b/core/src/main/java/hudson/views/LastDurationColumn.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Martin Eigenbrodt - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.views; import hudson.Extension; @@ -32,7 +33,7 @@ public class LastDurationColumn extends ListViewColumn { public LastDurationColumn() { } - @Extension(ordinal=DEFAULT_COLUMNS_ORDINAL_PROPERTIES_START-4) @Symbol("lastDuration") + @Extension(ordinal = DEFAULT_COLUMNS_ORDINAL_PROPERTIES_START - 4) @Symbol("lastDuration") public static class DescriptorImpl extends ListViewColumnDescriptor { @Override public String getDisplayName() { diff --git a/core/src/main/java/hudson/views/LastFailureColumn.java b/core/src/main/java/hudson/views/LastFailureColumn.java index 1c272b855f8b..c31f3f9590a0 100644 --- a/core/src/main/java/hudson/views/LastFailureColumn.java +++ b/core/src/main/java/hudson/views/LastFailureColumn.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Martin Eigenbrodt - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.views; import hudson.Extension; @@ -32,7 +33,7 @@ public class LastFailureColumn extends ListViewColumn { public LastFailureColumn() { } - @Extension(ordinal=DEFAULT_COLUMNS_ORDINAL_PROPERTIES_START-2) @Symbol("lastFailure") + @Extension(ordinal = DEFAULT_COLUMNS_ORDINAL_PROPERTIES_START - 2) @Symbol("lastFailure") public static class DescriptorImpl extends ListViewColumnDescriptor { @Override public String getDisplayName() { diff --git a/core/src/main/java/hudson/views/LastStableColumn.java b/core/src/main/java/hudson/views/LastStableColumn.java index 0844121e5dcb..7dfd482eaab3 100644 --- a/core/src/main/java/hudson/views/LastStableColumn.java +++ b/core/src/main/java/hudson/views/LastStableColumn.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2009, Sun Microsystems, Inc., Jesse Glick - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.views; import hudson.Extension; @@ -32,7 +33,7 @@ public class LastStableColumn extends ListViewColumn { public LastStableColumn() { } - @Extension(ordinal=DEFAULT_COLUMNS_ORDINAL_PROPERTIES_START-3) @Symbol("lastStable") + @Extension(ordinal = DEFAULT_COLUMNS_ORDINAL_PROPERTIES_START - 3) @Symbol("lastStable") public static class DescriptorImpl extends ListViewColumnDescriptor { @Override public String getDisplayName() { diff --git a/core/src/main/java/hudson/views/LastSuccessColumn.java b/core/src/main/java/hudson/views/LastSuccessColumn.java index ebb5bc1bc944..98571e8e9bf3 100644 --- a/core/src/main/java/hudson/views/LastSuccessColumn.java +++ b/core/src/main/java/hudson/views/LastSuccessColumn.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Martin Eigenbrodt - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.views; import hudson.Extension; @@ -32,7 +33,7 @@ public class LastSuccessColumn extends ListViewColumn { public LastSuccessColumn() { } - @Extension(ordinal=DEFAULT_COLUMNS_ORDINAL_PROPERTIES_START-1) @Symbol("lastSuccess") + @Extension(ordinal = DEFAULT_COLUMNS_ORDINAL_PROPERTIES_START - 1) @Symbol("lastSuccess") public static class DescriptorImpl extends ListViewColumnDescriptor { @Override public String getDisplayName() { diff --git a/core/src/main/java/hudson/views/ListViewColumn.java b/core/src/main/java/hudson/views/ListViewColumn.java index 8c2312f3ca79..1796f4cc495c 100644 --- a/core/src/main/java/hudson/views/ListViewColumn.java +++ b/core/src/main/java/hudson/views/ListViewColumn.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Martin Eigenbrodt - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.views; import hudson.DescriptorExtensionList; @@ -30,19 +31,18 @@ import hudson.model.Descriptor; import hudson.model.Descriptor.FormException; import hudson.model.DescriptorVisibilityFilter; -import jenkins.model.Jenkins; import hudson.model.Item; import hudson.model.ItemGroup; import hudson.model.ListView; import hudson.model.View; import hudson.util.DescriptorList; -import org.kohsuke.stapler.export.Exported; - import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; +import jenkins.model.Jenkins; import net.sf.json.JSONObject; +import org.kohsuke.stapler.export.Exported; /** * Extension point for adding a column to a table rendering of {@link Item}s, such as {@link ListView}. @@ -115,6 +115,7 @@ public boolean shownByDefault() { * For compatibility reason, this method may not return a {@link ListViewColumnDescriptor} * and instead return a plain {@link Descriptor} instance. */ + @Override public Descriptor getDescriptor() { return Jenkins.get().getDescriptorOrDie(getClass()); } @@ -169,7 +170,7 @@ private static List createDefaultInitialColumnList(List> @Override public MyViewsTabBarDescriptor getDescriptor() { - return (MyViewsTabBarDescriptor)super.getDescriptor(); + return (MyViewsTabBarDescriptor) super.getDescriptor(); } /** @@ -83,12 +84,7 @@ public MyViewsTabBarDescriptor getDescriptor() { @SuppressWarnings("unused") // invoked from stapler view public List sort(@NonNull List views) { List result = new ArrayList<>(views); - result.sort(new Comparator() { - @Override - public int compare(View o1, View o2) { - return o1.getDisplayName().compareTo(o2.getDisplayName()); - } - }); + result.sort(Comparator.comparing(View::getDisplayName)); return result; } @@ -97,7 +93,7 @@ public int compare(View o1, View o2) { * * @author Kohsuke Kawaguchi */ - @Extension(ordinal=305) @Symbol("myView") + @Extension(ordinal = 305) @Symbol("myView") public static class GlobalConfigurationImpl extends GlobalConfiguration { public MyViewsTabBar getMyViewsTabBar() { return Jenkins.get().getMyViewsTabBar(); @@ -109,7 +105,7 @@ public boolean configure(StaplerRequest req, JSONObject json) throws FormExcepti Jenkins j = Jenkins.get(); if (json.has("myViewsTabBar")) { - j.setMyViewsTabBar(req.bindJSON(MyViewsTabBar.class,json.getJSONObject("myViewsTabBar"))); + j.setMyViewsTabBar(req.bindJSON(MyViewsTabBar.class, json.getJSONObject("myViewsTabBar"))); } else { j.setMyViewsTabBar(new DefaultMyViewsTabBar()); } diff --git a/core/src/main/java/hudson/views/MyViewsTabBarDescriptor.java b/core/src/main/java/hudson/views/MyViewsTabBarDescriptor.java index c98391e6b000..f191f05d1bd1 100644 --- a/core/src/main/java/hudson/views/MyViewsTabBarDescriptor.java +++ b/core/src/main/java/hudson/views/MyViewsTabBarDescriptor.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.views; import hudson.model.Descriptor; diff --git a/core/src/main/java/hudson/views/StatusColumn.java b/core/src/main/java/hudson/views/StatusColumn.java index 80813e00ea20..9d9e92d3dfdd 100644 --- a/core/src/main/java/hudson/views/StatusColumn.java +++ b/core/src/main/java/hudson/views/StatusColumn.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Martin Eigenbrodt - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.views; import hudson.Extension; @@ -38,7 +39,7 @@ public class StatusColumn extends ListViewColumn { public StatusColumn() { } - @Extension(ordinal=DEFAULT_COLUMNS_ORDINAL_ICON_START-1) @Symbol("status") + @Extension(ordinal = DEFAULT_COLUMNS_ORDINAL_ICON_START - 1) @Symbol("status") public static class DescriptorImpl extends ListViewColumnDescriptor { @Override public String getDisplayName() { diff --git a/core/src/main/java/hudson/views/StatusFilter.java b/core/src/main/java/hudson/views/StatusFilter.java index 33ff9d7a0b1e..f15132145017 100644 --- a/core/src/main/java/hudson/views/StatusFilter.java +++ b/core/src/main/java/hudson/views/StatusFilter.java @@ -21,21 +21,21 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.views; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.Extension; import hudson.model.Descriptor; import hudson.model.TopLevelItem; import hudson.model.View; +import java.util.ArrayList; +import java.util.List; import jenkins.model.ParameterizedJobMixIn; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.DataBoundConstructor; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.ArrayList; -import java.util.List; - /** * Job Filter that will filter jobs based on its disabled status */ @@ -61,7 +61,7 @@ public List filter(List added, List al List filtered = new ArrayList<>(); for (TopLevelItem item : added) { if (!(item instanceof ParameterizedJobMixIn.ParameterizedJob) // TODO or better to call the more generic Job.isBuildable? - || ((ParameterizedJobMixIn.ParameterizedJob) item).isDisabled() ^ statusFilter) + || ((ParameterizedJobMixIn.ParameterizedJob) item).isDisabled() ^ statusFilter) filtered.add(item); } return filtered; diff --git a/core/src/main/java/hudson/views/ViewJobFilter.java b/core/src/main/java/hudson/views/ViewJobFilter.java index 0f117f5d2758..576ec824d0c8 100644 --- a/core/src/main/java/hudson/views/ViewJobFilter.java +++ b/core/src/main/java/hudson/views/ViewJobFilter.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, Martin Eigenbrodt - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,17 +21,17 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.views; import hudson.DescriptorExtensionList; import hudson.ExtensionPoint; import hudson.model.Describable; import hudson.model.Descriptor; -import jenkins.model.Jenkins; import hudson.model.TopLevelItem; import hudson.model.View; - import java.util.List; +import jenkins.model.Jenkins; /** * Each ViewJobFilter contributes to or removes from the list of Jobs for a view. @@ -47,11 +47,12 @@ public static DescriptorExtensionList> return Jenkins.get().getDescriptorList(ViewJobFilter.class); } + @Override @SuppressWarnings("unchecked") - public Descriptor getDescriptor() { + public Descriptor getDescriptor() { return Jenkins.get().getDescriptorOrDie(getClass()); } - + /** * Choose which jobs to show for a view. * @param added which jobs have been added so far. This JobFilter can remove or add to this list. diff --git a/core/src/main/java/hudson/views/ViewsTabBar.java b/core/src/main/java/hudson/views/ViewsTabBar.java index 93aa30845640..195f72104aba 100644 --- a/core/src/main/java/hudson/views/ViewsTabBar.java +++ b/core/src/main/java/hudson/views/ViewsTabBar.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2010, Winston.Prakash@oracle.com, CloudBees, Inc. - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,21 +21,22 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.views; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.DescriptorExtensionList; import hudson.Extension; import hudson.ExtensionPoint; import hudson.model.AbstractDescribableImpl; import hudson.model.Descriptor; +import hudson.model.ListView; import hudson.model.View; import java.util.ArrayList; import java.util.Comparator; import java.util.List; -import edu.umd.cs.findbugs.annotations.NonNull; import jenkins.model.GlobalConfiguration; import jenkins.model.Jenkins; -import hudson.model.ListView; import net.sf.json.JSONObject; import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; @@ -68,7 +69,7 @@ public static DescriptorExtensionList> all( @Override public ViewsTabBarDescriptor getDescriptor() { - return (ViewsTabBarDescriptor)super.getDescriptor(); + return (ViewsTabBarDescriptor) super.getDescriptor(); } /** @@ -83,12 +84,7 @@ public ViewsTabBarDescriptor getDescriptor() { @SuppressWarnings("unused") // invoked from stapler view public List sort(@NonNull List views) { List result = new ArrayList<>(views); - result.sort(new Comparator() { - @Override - public int compare(View o1, View o2) { - return o1.getDisplayName().compareTo(o2.getDisplayName()); - } - }); + result.sort(Comparator.comparing(View::getDisplayName)); return result; } @@ -97,7 +93,7 @@ public int compare(View o1, View o2) { * * @author Kohsuke Kawaguchi */ - @Extension(ordinal=310) @Symbol("viewsTabBar") + @Extension(ordinal = 310) @Symbol("viewsTabBar") public static class GlobalConfigurationImpl extends GlobalConfiguration { public ViewsTabBar getViewsTabBar() { return Jenkins.get().getViewsTabBar(); @@ -109,7 +105,7 @@ public boolean configure(StaplerRequest req, JSONObject json) throws FormExcepti Jenkins j = Jenkins.get(); if (json.has("viewsTabBar")) { - j.setViewsTabBar(req.bindJSON(ViewsTabBar.class,json.getJSONObject("viewsTabBar"))); + j.setViewsTabBar(req.bindJSON(ViewsTabBar.class, json.getJSONObject("viewsTabBar"))); } else { j.setViewsTabBar(new DefaultViewsTabBar()); } diff --git a/core/src/main/java/hudson/views/ViewsTabBarDescriptor.java b/core/src/main/java/hudson/views/ViewsTabBarDescriptor.java index 73f0c85b825a..012a43ed9dd8 100644 --- a/core/src/main/java/hudson/views/ViewsTabBarDescriptor.java +++ b/core/src/main/java/hudson/views/ViewsTabBarDescriptor.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.views; import hudson.model.Descriptor; diff --git a/core/src/main/java/hudson/views/WeatherColumn.java b/core/src/main/java/hudson/views/WeatherColumn.java index d14e9ca5582b..ee04f7c0f08b 100644 --- a/core/src/main/java/hudson/views/WeatherColumn.java +++ b/core/src/main/java/hudson/views/WeatherColumn.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Martin Eigenbrodt - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -33,7 +33,7 @@ public class WeatherColumn extends ListViewColumn { public WeatherColumn() { } - @Extension(ordinal=DEFAULT_COLUMNS_ORDINAL_ICON_START-2) @Symbol("weather") + @Extension(ordinal = DEFAULT_COLUMNS_ORDINAL_ICON_START - 2) @Symbol("weather") public static class DescriptorImpl extends ListViewColumnDescriptor { @Override public String getDisplayName() { diff --git a/core/src/main/java/hudson/widgets/BuildHistoryWidget.java b/core/src/main/java/hudson/widgets/BuildHistoryWidget.java index 09e25880ee7d..da3576771416 100644 --- a/core/src/main/java/hudson/widgets/BuildHistoryWidget.java +++ b/core/src/main/java/hudson/widgets/BuildHistoryWidget.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,15 +21,15 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.widgets; -import jenkins.model.Jenkins; import hudson.model.Queue.Item; import hudson.model.Queue.Task; -import jenkins.widgets.HistoryPageFilter; - import java.util.LinkedList; import java.util.List; +import jenkins.model.Jenkins; +import jenkins.widgets.HistoryPageFilter; /** * Displays the build history on the side panel. @@ -40,13 +40,13 @@ * * @author Kohsuke Kawaguchi */ -public class BuildHistoryWidget extends HistoryWidget { +public class BuildHistoryWidget extends HistoryWidget { /** * @param owner * The parent model object that owns this widget. */ - public BuildHistoryWidget(Task owner, Iterable baseList,Adapter adapter) { - super(owner,baseList, adapter); + public BuildHistoryWidget(Task owner, Iterable baseList, Adapter adapter) { + super(owner, baseList, adapter); } /** @@ -66,7 +66,7 @@ public List getQueuedItems() { list.addFirst(item); } } - return list; + return list; } @Override diff --git a/core/src/main/java/hudson/widgets/HistoryWidget.java b/core/src/main/java/hudson/widgets/HistoryWidget.java index 596fa205ee8b..aba195ab7c74 100644 --- a/core/src/main/java/hudson/widgets/HistoryWidget.java +++ b/core/src/main/java/hudson/widgets/HistoryWidget.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,13 +21,20 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.widgets; +import edu.umd.cs.findbugs.annotations.CheckForNull; import hudson.Functions; -import jenkins.util.SystemProperties; import hudson.model.ModelObject; import hudson.model.Run; - +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import javax.servlet.ServletException; +import jenkins.util.SystemProperties; import jenkins.widgets.HistoryPageEntry; import jenkins.widgets.HistoryPageFilter; import org.kohsuke.stapler.Header; @@ -35,14 +42,6 @@ import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; -import edu.umd.cs.findbugs.annotations.CheckForNull; -import javax.servlet.ServletException; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - /** * Displays the history of records (normally {@link Run}s) on the side panel. * @@ -52,7 +51,7 @@ * Type individual record. * @author Kohsuke Kawaguchi */ -public class HistoryWidget extends Widget { +public class HistoryWidget extends Widget { /** * The given data model of records. Newer ones first. */ @@ -91,7 +90,7 @@ public HistoryWidget(O owner, Iterable baseList, Adapter adapter) StaplerRequest currentRequest = Stapler.getCurrentRequest(); this.adapter = adapter; this.baseList = baseList; - this.baseUrl = Functions.getNearestAncestorUrl(currentRequest,owner); + this.baseUrl = Functions.getNearestAncestorUrl(currentRequest, owner); this.owner = owner; this.newerThan = getPagingParam(currentRequest, "newer-than"); this.olderThan = getPagingParam(currentRequest, "older-than"); @@ -129,9 +128,9 @@ protected HistoryPageFilter updateFirstTransientBuildKey(HistoryPageFilter histo } private Iterable> updateFirstTransientBuildKey(Iterable> source) { - String key=null; + String key = null; for (HistoryPageEntry t : source) { - if(adapter.isBuilding(t.getEntry())) { + if (adapter.isBuilding(t.getEntry())) { key = adapter.getKey(t.getEntry()); } } @@ -143,12 +142,12 @@ private Iterable> updateFirstTransientBuildKey(Iterable> getRenderList() { - if(trimmed) { + if (trimmed) { List> pageEntries = toPageEntries(baseList); - if(pageEntries.size() > THRESHOLD) { - return updateFirstTransientBuildKey(pageEntries.subList(0,THRESHOLD)); + if (pageEntries.size() > THRESHOLD) { + return updateFirstTransientBuildKey(pageEntries.subList(0, THRESHOLD)); } else { - trimmed=false; + trimmed = false; return updateFirstTransientBuildKey(pageEntries); } } else { @@ -214,8 +213,8 @@ public void setTrimmed(boolean trimmed) { * The build 'number' to fetch. This is string because various variants * uses non-numbers as the build key. */ - public void doAjax( StaplerRequest req, StaplerResponse rsp, - @Header("n") String n ) throws IOException, ServletException { + public void doAjax(StaplerRequest req, StaplerResponse rsp, + @Header("n") String n) throws IOException, ServletException { rsp.setContentType("text/html;charset=UTF-8"); @@ -223,39 +222,39 @@ public void doAjax( StaplerRequest req, StaplerResponse rsp, List items = new ArrayList<>(); if (n != null) { - String nn=null; // we'll compute next n here + String nn = null; // we'll compute next n here // list up all builds >=n. for (T t : baseList) { - if(adapter.compare(t,n)>=0) { + if (adapter.compare(t, n) >= 0) { items.add(t); - if(adapter.isBuilding(t)) + if (adapter.isBuilding(t)) nn = adapter.getKey(t); // the next fetch should start from youngest build in progress } else break; } - if (nn==null) { + if (nn == null) { if (items.isEmpty()) { // nothing to report back. next fetch should retry the same 'n' - nn=n; + nn = n; } else { // every record fetched this time is frozen. next fetch should start from the next build - nn=adapter.getNextKey(adapter.getKey(items.get(0))); + nn = adapter.getNextKey(adapter.getKey(items.get(0))); } } baseList = items; - rsp.setHeader("n",nn); + rsp.setHeader("n", nn); firstTransientBuildKey = nn; // all builds >= nn should be marked transient } HistoryPageFilter page = getHistoryPageFilter(); - req.getView(page,"ajaxBuildHistory.jelly").forward(req,rsp); + req.getView(page, "ajaxBuildHistory.jelly").forward(req, rsp); } - static final int THRESHOLD = SystemProperties.getInteger(HistoryWidget.class.getName()+".threshold",30); + static final int THRESHOLD = SystemProperties.getInteger(HistoryWidget.class.getName() + ".threshold", 30); public String getNextBuildNumberToFetch() { return nextBuildNumberToFetch; @@ -270,8 +269,11 @@ public interface Adapter { * If record is newer than the key, return a positive number. */ int compare(T record, String key); + String getKey(T record); + boolean isBuilding(T record); + String getNextKey(String key); } diff --git a/core/src/main/java/hudson/widgets/RenderOnDemandClosure.java b/core/src/main/java/hudson/widgets/RenderOnDemandClosure.java index 29a52d3f60ba..9092526f109b 100644 --- a/core/src/main/java/hudson/widgets/RenderOnDemandClosure.java +++ b/core/src/main/java/hudson/widgets/RenderOnDemandClosure.java @@ -21,11 +21,21 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package hudson.widgets; import hudson.Util; import hudson.model.Descriptor; import hudson.util.PackedMap; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.servlet.ServletException; import org.apache.commons.jelly.JellyContext; import org.apache.commons.jelly.JellyTagException; import org.apache.commons.jelly.Script; @@ -37,16 +47,6 @@ import org.kohsuke.stapler.jelly.DefaultScriptInvoker; import org.xml.sax.SAXException; -import javax.servlet.ServletException; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.logging.Level; -import java.util.logging.Logger; - /** * Captured Jelly {@link Script} that can be rendered later on demand from JavaScript. * @@ -57,23 +57,23 @@ public class RenderOnDemandClosure { * Captures the recursive taglib call stack. */ private final Script[] bodyStack; - private final Map variables; + private final Map variables; private final String currentDescriptorByNameUrl; private final String[] adjuncts; public RenderOnDemandClosure(JellyContext context, String attributesToCapture) { List - - - + +

    + + \ No newline at end of file diff --git a/core/src/main/resources/hudson/model/Cause/RemoteCause/description.jelly b/core/src/main/resources/hudson/model/Cause/RemoteCause/description.jelly new file mode 100644 index 000000000000..57d84a3d7190 --- /dev/null +++ b/core/src/main/resources/hudson/model/Cause/RemoteCause/description.jelly @@ -0,0 +1,27 @@ + + + + ${%blurb(it.addr, it.note)} + diff --git a/core/src/main/resources/hudson/model/Cause/RemoteCause/description.properties b/core/src/main/resources/hudson/model/Cause/RemoteCause/description.properties new file mode 100644 index 000000000000..5274b4ad9f9d --- /dev/null +++ b/core/src/main/resources/hudson/model/Cause/RemoteCause/description.properties @@ -0,0 +1 @@ +blurb = Started by remote host {0} with note: {1} diff --git a/core/src/main/resources/hudson/model/Cause/RemoteCause/description_pt_BR.properties b/core/src/main/resources/hudson/model/Cause/RemoteCause/description_pt_BR.properties new file mode 100644 index 000000000000..0d08d7aa9c54 --- /dev/null +++ b/core/src/main/resources/hudson/model/Cause/RemoteCause/description_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +blurb=Iniciado pelo hospedeiro remoto {0} com a nota: {1} diff --git a/core/src/main/resources/hudson/model/Cause/UpstreamCause/description.properties b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description.properties index 6465016a40c6..1deb78946fef 100644 --- a/core/src/main/resources/hudson/model/Cause/UpstreamCause/description.properties +++ b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description.properties @@ -20,6 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -started_by_project=Started by upstream project {0} build number {1} -started_by_project_with_deleted_build=Started by upstream project {0} build number {1} +started_by_project=Started by upstream project {0} build number {1} +started_by_project_with_deleted_build=Started by upstream project {0} build number {1} caused_by=originally caused by: diff --git a/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_bg.properties b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_bg.properties index e628fd6eede0..fb6513a12ab9 100644 --- a/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_bg.properties +++ b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_bg.properties @@ -22,10 +22,10 @@ started_by_project_with_deleted_build=\ \u0421\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u043e \u0437\u0430\u0440\u0430\u0434\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u043e\u0442 \u043a\u043e\u0439\u0442\u043e \u0442\u043e\u0437\u0438 \u0437\u0430\u0432\u0438\u0441\u0438:\ - {0}, \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 \u2116\u200a{1} + {0}, \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 \u2116\u200a{1} caused_by=\ \u043f\u044a\u0440\u0432\u043e\u043d\u0430\u0447\u0430\u043b\u043d\u043e \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u043e \u043f\u043e\u0440\u0430\u0434\u0438: started_by_project=\ \u0421\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u043e \u0437\u0430\u0440\u0430\u0434\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u043e\u0442 \u043a\u043e\u0439\u0442\u043e \u0442\u043e\u0437\u0438 \u0437\u0430\u0432\u0438\u0441\u0438:\ - {0}, \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435\ - \u2116\u200a{1} + {0}, \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435\ + \u2116\u200a{1} diff --git a/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_cs.properties b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_cs.properties index 6dadacc8d5b3..a774d761620e 100644 --- a/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_cs.properties +++ b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_cs.properties @@ -1,4 +1,4 @@ # This file is under the MIT License by authors -started_by_project=Spu\u0161t\u011Bno nad\u0159azen\u00FDm projektem {0} build \u010D\u00EDslo {1} -started_by_project_with_deleted_build=Spu\u0161t\u011Bno nad\u0159azen\u00FDm projektem {0} build \u010D\u00EDslo {1} +started_by_project=Spu\u0161t\u011Bno nad\u0159azen\u00FDm projektem {0} build \u010D\u00EDslo {1} +started_by_project_with_deleted_build=Spu\u0161t\u011Bno nad\u0159azen\u00FDm projektem {0} build \u010D\u00EDslo {1} diff --git a/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_da.properties b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_da.properties index d5d6abbe7ecf..c6817615ff64 100644 --- a/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_da.properties +++ b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_da.properties @@ -20,5 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -started_by_project=Startet af upstream projekt {0} byg nummer {1} -started_by_project_with_deleted_build=Startet af upstream projekt {0} byg nummer {1} +started_by_project=Startet af upstream projekt {0} byg nummer {1} +started_by_project_with_deleted_build=Startet af upstream projekt {0} byg nummer {1} diff --git a/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_de.properties b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_de.properties index e06ec4c0fa9a..1e8fe895152a 100644 --- a/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_de.properties +++ b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_de.properties @@ -21,6 +21,6 @@ # THE SOFTWARE. caused_by=urspr\u00FCnglich ausgel\u00F6st durch: -started_by_project=Gestartet durch vorgelagertes Projekt {0}, Build {1} -started_by_project_with_deleted_build=Gestartet durch vorgelagertes Projekt {0}, Build {1} +started_by_project=Gestartet durch vorgelagertes Projekt {0}, Build {1} +started_by_project_with_deleted_build=Gestartet durch vorgelagertes Projekt {0}, Build {1} diff --git a/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_es.properties b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_es.properties index 7dd9d5530e9e..119f06882497 100644 --- a/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_es.properties +++ b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_es.properties @@ -21,5 +21,5 @@ # THE SOFTWARE. -started_by_project=Lanzado por la ejecuci\u00F3n n\u00FAmero {1} del proyecto padre\: {0} -started_by_project_with_deleted_build=Lanzado por la ejecuci\u00F3n n\u00FAmero {1} del proyecto padre\: {0} +started_by_project=Lanzado por la ejecuci\u00F3n n\u00FAmero {1} del proyecto padre\: {0} +started_by_project_with_deleted_build=Lanzado por la ejecuci\u00F3n n\u00FAmero {1} del proyecto padre\: {0} diff --git a/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_fi.properties b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_fi.properties index 9cff3e9b6528..8c7a1c1dbc47 100644 --- a/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_fi.properties +++ b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_fi.properties @@ -20,5 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -started_by_project=K\u00E4ynnist\u00E4j\u00E4 yl\u00E4virran projekti {0} k\u00E4\u00E4nn\u00F6snumero {1} -started_by_project_with_deleted_build=K\u00E4ynnist\u00E4j\u00E4 yl\u00E4virran projekti {0} k\u00E4\u00E4nn\u00F6snumero {1} +started_by_project=K\u00E4ynnist\u00E4j\u00E4 yl\u00E4virran projekti {0} k\u00E4\u00E4nn\u00F6snumero {1} +started_by_project_with_deleted_build=K\u00E4ynnist\u00E4j\u00E4 yl\u00E4virran projekti {0} k\u00E4\u00E4nn\u00F6snumero {1} diff --git a/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_fr.properties b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_fr.properties index 7f46cd410c42..740edeb2da45 100644 --- a/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_fr.properties +++ b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_fr.properties @@ -21,6 +21,6 @@ # THE SOFTWARE. caused_by=Originellement lanc\u00E9 par: -started_by_project=Lanc\u00E9 par le projet amont {0} avec le num\u00E9ro de construction {1} -started_by_project_with_deleted_build=Lanc\u00E9 par le projet amont {0} avec le num\u00E9ro de construction {1} +started_by_project=Lanc\u00E9 par le projet amont {0} avec le num\u00E9ro de construction {1} +started_by_project_with_deleted_build=Lanc\u00E9 par le projet amont {0} avec le num\u00E9ro de construction {1} diff --git a/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_it.properties b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_it.properties index da8d3d0d795b..b34f9c8b3a39 100644 --- a/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_it.properties +++ b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_it.properties @@ -22,8 +22,8 @@ # THE SOFTWARE. caused_by=originariamente scatenata da: -started_by_project=Avviata dal progetto upstream {0}, compilazione numero {0}, compilazione numero {1} started_by_project_with_deleted_build=Avviata dal progetto upstream {0}, compilazione numero {1} + class="model-link model-link--float" href="{3}/{2}">{0}, compilazione numero {1} diff --git a/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_ja.properties b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_ja.properties index 897136e18892..31abd832036b 100644 --- a/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_ja.properties +++ b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_ja.properties @@ -20,6 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -started_by_project=\u4e0a\u6d41\u30d7\u30ed\u30b8\u30a7\u30af\u30c8{0}\u306e#{1}\u304c\u5b9f\u884c -started_by_project_with_deleted_build=\u4e0a\u6d41\u30d7\u30ed\u30b8\u30a7\u30af\u30c8{0}\u306e#{1}\u304c\u5b9f\u884c +started_by_project=\u4e0a\u6d41\u30d7\u30ed\u30b8\u30a7\u30af\u30c8{0}\u306e#{1}\u304c\u5b9f\u884c +started_by_project_with_deleted_build=\u4e0a\u6d41\u30d7\u30ed\u30b8\u30a7\u30af\u30c8{0}\u306e#{1}\u304c\u5b9f\u884c caused_by=\u5143\u306e\u539f\u56e0: diff --git a/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_lv.properties b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_lv.properties index d6eb00c13ed0..0cc40b263090 100644 --- a/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_lv.properties +++ b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_lv.properties @@ -1,5 +1,5 @@ # This file is under the MIT License by authors caused_by=s\u0101kotn\u0113ji izrais\u012Bjis: -started_by_project=S\u0101kts no aug\u0161upstraumes projekta {0} b\u016Bv\u0113juma {1} -started_by_project_with_deleted_build=S\u0101kts no aug\u0161upstraumes projekta {0} b\u016Bv\u0113juma {1} +started_by_project=S\u0101kts no aug\u0161upstraumes projekta {0} b\u016Bv\u0113juma {1} +started_by_project_with_deleted_build=S\u0101kts no aug\u0161upstraumes projekta {0} b\u016Bv\u0113juma {1} diff --git a/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_nl.properties b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_nl.properties index 8fffede35055..77a8f2b8784f 100644 --- a/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_nl.properties +++ b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_nl.properties @@ -1,5 +1,5 @@ # This file is under the MIT License by authors caused_by=oorspronkelijk veroorzaakt door: -started_by_project=Gestart door stroomopwaarts project {0}, bouwpoging {1} -started_by_project_with_deleted_build=Gestart door stroomopwaarts project {0}, bouwpoging {1} +started_by_project=Gestart door stroomopwaarts project {0}, bouwpoging {1} +started_by_project_with_deleted_build=Gestart door stroomopwaarts project {0}, bouwpoging {1} diff --git a/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_pl.properties b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_pl.properties index ca975f6e8e65..7d6fa87a6d70 100644 --- a/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_pl.properties +++ b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_pl.properties @@ -20,6 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -started_by_project=Wystartowany przez projekt nadrz\u0119dny {0} o numerze {1} -started_by_project_with_deleted_build=Wystartowany przez projekt nadrz\u0119dny {0} o numerze {1} +started_by_project=Wystartowany przez projekt nadrz\u0119dny {0} o numerze {1} +started_by_project_with_deleted_build=Wystartowany przez projekt nadrz\u0119dny {0} o numerze {1} caused_by=Pierwotnie spowodowany przez: diff --git a/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_pt_BR.properties b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_pt_BR.properties index bcd1781af945..02fb9c7e324f 100644 --- a/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_pt_BR.properties +++ b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_pt_BR.properties @@ -22,5 +22,5 @@ # Started by upstream project {0} build number {1} caused_by=Criado por originalidade de: -started_by_project=Iniciado pelo build {1} do projeto {0} -started_by_project_with_deleted_build=Iniciado pelo build {1} do projeto {0} +started_by_project=Iniciado pelo build {1} do projeto {0} +started_by_project_with_deleted_build=Iniciado pelo build {1} do projeto {0} diff --git a/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_ru.properties b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_ru.properties index d3ebf3a40bb1..4447b383be74 100644 --- a/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_ru.properties +++ b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_ru.properties @@ -1,5 +1,5 @@ # This file is under the MIT License by authors caused_by=\u043F\u0435\u0440\u0432\u043E\u043D\u0430\u0447\u0430\u043B\u044C\u043D\u043E \u0437\u0430\u043F\u0443\u0449\u0435\u043D\u0430: -started_by_project=\u0412\u044B\u0437\u0432\u0430\u043D \u0432\u043E\u0441\u0445\u043E\u0434\u044F\u0449\u0438\u043C \u043F\u0440\u043E\u0435\u043A\u0442\u043E\u043C {0}, \u0441\u0431\u043E\u0440\u043A\u0430 \u043D\u043E\u043C\u0435\u0440 {1} -started_by_project_with_deleted_build=\u0412\u044B\u0437\u0432\u0430\u043D \u0432\u043E\u0441\u0445\u043E\u0434\u044F\u0449\u0438\u043C \u043F\u0440\u043E\u0435\u043A\u0442\u043E\u043C {0}, \u0441\u0431\u043E\u0440\u043A\u0430 \u043D\u043E\u043C\u0435\u0440 {1} +started_by_project=\u0412\u044B\u0437\u0432\u0430\u043D \u0432\u043E\u0441\u0445\u043E\u0434\u044F\u0449\u0438\u043C \u043F\u0440\u043E\u0435\u043A\u0442\u043E\u043C {0}, \u0441\u0431\u043E\u0440\u043A\u0430 \u043D\u043E\u043C\u0435\u0440 {1} +started_by_project_with_deleted_build=\u0412\u044B\u0437\u0432\u0430\u043D \u0432\u043E\u0441\u0445\u043E\u0434\u044F\u0449\u0438\u043C \u043F\u0440\u043E\u0435\u043A\u0442\u043E\u043C {0}, \u0441\u0431\u043E\u0440\u043A\u0430 \u043D\u043E\u043C\u0435\u0440 {1} diff --git a/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_sk.properties b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_sk.properties index 2027b4fb2660..6cbaae3dc1a5 100644 --- a/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_sk.properties +++ b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_sk.properties @@ -1,5 +1,5 @@ # This file is under the MIT License by authors caused_by=p\u00F4vodn\u00E1 pr\u00ED\u010Dina: -started_by_project=Na\u0161tartovan\u00E9 upstream projektom {0} \u010D\u00EDslo zostavenia {1} -started_by_project_with_deleted_build=Na\u0161tartovan\u00E9 upstream projektom {0} \u010D\u00EDslo zostavenia {1} +started_by_project=Na\u0161tartovan\u00E9 upstream projektom {0} \u010D\u00EDslo zostavenia {1} +started_by_project_with_deleted_build=Na\u0161tartovan\u00E9 upstream projektom {0} \u010D\u00EDslo zostavenia {1} diff --git a/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_sr.properties b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_sr.properties index 327dc4258303..6db47bf0da33 100644 --- a/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_sr.properties +++ b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_sr.properties @@ -1,5 +1,5 @@ # This file is under the MIT License by authors -started_by_project=\u0417\u0430\u043F\u043E\u0447\u0435\u0442\u043E \u043E\u0434 \u0441\u0442\u0440\u0430\u043D\u0435 \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0430 {0} \u0431\u0440\u043E\u0458 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 {1} -started_by_project_with_deleted_build=\u0417\u0430\u043F\u043E\u0447\u0435\u0442\u043E \u043E\u0434 \u0441\u0442\u0440\u0430\u043D\u0435 \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0430 {0} \u0431\u0440\u043E\u0458 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 {1} +started_by_project=\u0417\u0430\u043F\u043E\u0447\u0435\u0442\u043E \u043E\u0434 \u0441\u0442\u0440\u0430\u043D\u0435 \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0430 {0} \u0431\u0440\u043E\u0458 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 {1} +started_by_project_with_deleted_build=\u0417\u0430\u043F\u043E\u0447\u0435\u0442\u043E \u043E\u0434 \u0441\u0442\u0440\u0430\u043D\u0435 \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0430 {0} \u0431\u0440\u043E\u0458 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 {1} caused_by=\u043F\u0440\u0432\u043E\u0431\u0438\u0442\u043D\u043E \u043F\u043E\u043A\u0440\u0435\u043D\u0443\u0442 \u0437\u0431\u043E\u0433: diff --git a/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_sv_SE.properties b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_sv_SE.properties index 19a14d946d67..69cb7058fa97 100644 --- a/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_sv_SE.properties +++ b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_sv_SE.properties @@ -1,5 +1,5 @@ # This file is under the MIT License by authors caused_by=ursprungligen p\u00E5 grund av: -started_by_project=Startad av projekt uppstr\u00F6ms {0} byggnummer {1} -started_by_project_with_deleted_build=Startad av projekt uppstr\u00F6ms {0} byggnummer {1} +started_by_project=Startad av projekt uppstr\u00F6ms {0} byggnummer {1} +started_by_project_with_deleted_build=Startad av projekt uppstr\u00F6ms {0} byggnummer {1} diff --git a/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_uk.properties b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_uk.properties index a137decaa7b6..4c0f2cbed9ed 100644 --- a/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_uk.properties +++ b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_uk.properties @@ -20,5 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -started_by_project=\u0417\u0430\u043F\u0443\u0449\u0435\u043D\u043E \u043A\u0435\u0440\u0456\u0432\u043D\u0438\u043C \u043F\u0440\u043E\u0435\u043A\u0442\u043E\u043C {0}, \u043F\u043E\u0431\u0443\u0434\u043E\u0432\u0430 \u043D\u043E\u043C\u0435\u0440 {1} -started_by_project_with_deleted_build=\u0417\u0430\u043F\u0443\u0449\u0435\u043D\u043E \u043A\u0435\u0440\u0456\u0432\u043D\u0438\u043C \u043F\u0440\u043E\u0435\u043A\u0442\u043E\u043C {0}, \u043F\u043E\u0431\u0443\u0434\u043E\u0432\u0430 \u043D\u043E\u043C\u0435\u0440 {1} +started_by_project=\u0417\u0430\u043F\u0443\u0449\u0435\u043D\u043E \u043A\u0435\u0440\u0456\u0432\u043D\u0438\u043C \u043F\u0440\u043E\u0435\u043A\u0442\u043E\u043C {0}, \u043F\u043E\u0431\u0443\u0434\u043E\u0432\u0430 \u043D\u043E\u043C\u0435\u0440 {1} +started_by_project_with_deleted_build=\u0417\u0430\u043F\u0443\u0449\u0435\u043D\u043E \u043A\u0435\u0440\u0456\u0432\u043D\u0438\u043C \u043F\u0440\u043E\u0435\u043A\u0442\u043E\u043C {0}, \u043F\u043E\u0431\u0443\u0434\u043E\u0432\u0430 \u043D\u043E\u043C\u0435\u0440 {1} diff --git a/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_zh_TW.properties b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_zh_TW.properties index c9e7e445a39a..2ed479cac029 100644 --- a/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_zh_TW.properties +++ b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_zh_TW.properties @@ -20,6 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -started_by_project=\u7531\u4e0a\u6e38\u5c08\u6848 {0} \u7684\u7b2c {1} \u6b21\u5efa\u7f6e\u6240\u89f8\u767c -started_by_project_with_deleted_build=\u7531\u4e0a\u6e38\u5c08\u6848 {0} \u7684\u7b2c {1} \u6b21\u5efa\u7f6e\u6240\u89f8\u767c +started_by_project=\u7531\u4e0a\u6e38\u5c08\u6848 {0} \u7684\u7b2c {1} \u6b21\u5efa\u7f6e\u6240\u89f8\u767c +started_by_project_with_deleted_build=\u7531\u4e0a\u6e38\u5c08\u6848 {0} \u7684\u7b2c {1} \u6b21\u5efa\u7f6e\u6240\u89f8\u767c caused_by=\u8d77\u56e0: diff --git a/core/src/main/resources/hudson/model/Cause/UserCause/description_ar.properties b/core/src/main/resources/hudson/model/Cause/UserCause/description_ar.properties deleted file mode 100644 index 6d09df96bd70..000000000000 --- a/core/src/main/resources/hudson/model/Cause/UserCause/description_ar.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -started_by_user=\u0628\u062F\u0623\u062A \u0628\u0648\u0627\u0633\u0637\u0629 \u0627\u0644\u0645\u0633\u062A\u062E\u062F\u0645 {0} diff --git a/core/src/main/resources/hudson/model/Cause/description.jelly b/core/src/main/resources/hudson/model/Cause/description.jelly index cc10129381d0..c2c8a2748d56 100644 --- a/core/src/main/resources/hudson/model/Cause/description.jelly +++ b/core/src/main/resources/hudson/model/Cause/description.jelly @@ -23,5 +23,5 @@ THE SOFTWARE. --> - + ${it.shortDescription} diff --git a/core/src/main/resources/hudson/model/CauseAction/summary.jelly b/core/src/main/resources/hudson/model/CauseAction/summary.jelly index 1c7f6d0dff09..ccde699aee2a 100644 --- a/core/src/main/resources/hudson/model/CauseAction/summary.jelly +++ b/core/src/main/resources/hudson/model/CauseAction/summary.jelly @@ -24,7 +24,7 @@ THE SOFTWARE. - +

    diff --git a/core/src/main/resources/hudson/model/Computer/_api.jelly b/core/src/main/resources/hudson/model/Computer/_api.jelly index eb0dd1a306da..b7d8267ffffa 100644 --- a/core/src/main/resources/hudson/model/Computer/_api.jelly +++ b/core/src/main/resources/hudson/model/Computer/_api.jelly @@ -31,9 +31,17 @@ THE SOFTWARE.

    Fetch/Update config.xml

    - To programmatically obtain config.xml, hit this URL. - You can also POST an updated config.xml to the same URL to programmatically + To programmatically obtain config.xml, hit this URL. + You can also POST an updated config.xml to the same URL to programmatically update the configuration of a node.

    +

    Marking this node temporarily offline

    +

    + You can POST to this URL + to mark this node temporary offline, or bring it back online. + Or you can POST to this URL + to mark this node temporary offline, or adjust the offline cause message if it is already offline. +

    +
    diff --git a/core/src/main/resources/hudson/model/Computer/_script_pt_BR.properties b/core/src/main/resources/hudson/model/Computer/_script_pt_BR.properties new file mode 100644 index 000000000000..71699e49211a --- /dev/null +++ b/core/src/main/resources/hudson/model/Computer/_script_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +This\ execution\ happens\ in\ the\ agent\ JVM.=Este\ execu\u00E7\u00E3o\ acontece\ na\ JVM\ do\ agente. diff --git a/core/src/main/resources/hudson/model/Computer/builds.jelly b/core/src/main/resources/hudson/model/Computer/builds.jelly index a0eaf9ddc365..805f32563ddc 100644 --- a/core/src/main/resources/hudson/model/Computer/builds.jelly +++ b/core/src/main/resources/hudson/model/Computer/builds.jelly @@ -28,7 +28,6 @@ THE SOFTWARE.

    - ${%title(it.displayName)}

    @@ -36,7 +35,6 @@ THE SOFTWARE.

    -
    diff --git a/core/src/main/resources/hudson/model/Computer/builds_pt_BR.properties b/core/src/main/resources/hudson/model/Computer/builds_pt_BR.properties index a6f5a4d2cf72..6ddc64585797 100644 --- a/core/src/main/resources/hudson/model/Computer/builds_pt_BR.properties +++ b/core/src/main/resources/hudson/model/Computer/builds_pt_BR.properties @@ -20,5 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -# Build History on {0} -title=T\u00edtulo +title=T\u00EDtulo +disclaimer=Este hist\u00F3rico n\u00E3o \u00E9 garantido de conter todas as subtarefas executadas no n\u00F3, por exemplo, subtarefas do Jenkins Pipeline n\u00E3o ser\u00E3o mostradas. diff --git a/core/src/main/resources/hudson/model/Computer/configure.jelly b/core/src/main/resources/hudson/model/Computer/configure.jelly index bf209f136f45..6a470d7255b4 100644 --- a/core/src/main/resources/hudson/model/Computer/configure.jelly +++ b/core/src/main/resources/hudson/model/Computer/configure.jelly @@ -36,9 +36,11 @@ THE SOFTWARE. - - - +
    + + + +
    diff --git a/core/src/main/resources/hudson/model/Computer/delete_pt_BR.properties b/core/src/main/resources/hudson/model/Computer/delete_pt_BR.properties index 60797521ae90..6c5dc74df3f7 100644 --- a/core/src/main/resources/hudson/model/Computer/delete_pt_BR.properties +++ b/core/src/main/resources/hudson/model/Computer/delete_pt_BR.properties @@ -21,3 +21,4 @@ # THE SOFTWARE. Yes=Sim +delete.agent=Remover o agente '{0}'? diff --git a/core/src/main/resources/hudson/model/Computer/index.jelly b/core/src/main/resources/hudson/model/Computer/index.jelly index 015283e4fdce..aec2a86e2072 100644 --- a/core/src/main/resources/hudson/model/Computer/index.jelly +++ b/core/src/main/resources/hudson/model/Computer/index.jelly @@ -36,6 +36,7 @@ THE SOFTWARE.
    +
    @@ -52,7 +53,9 @@ THE SOFTWARE.

    - + + + ${it.caption} (${it.node.nodeDescription}) diff --git a/core/src/main/resources/hudson/model/Computer/index_pt_BR.properties b/core/src/main/resources/hudson/model/Computer/index_pt_BR.properties index 3e3c76a033cb..4eb5e3670e98 100644 --- a/core/src/main/resources/hudson/model/Computer/index_pt_BR.properties +++ b/core/src/main/resources/hudson/model/Computer/index_pt_BR.properties @@ -31,6 +31,4 @@ submit.not.temporarilyOffline=Marcar esse n\u00f3 para ficar temporariamente off title.projects_tied_on=Projetos vinculados a {0} # Update offline reason submit.updateOfflineCause=Atualizar o motivo de ficar offline -anonymous\ user=usu\u00e1rio an\u00f4nimo Labels=R\u00f3tulos -Created\ by=Criado por diff --git a/core/src/main/resources/hudson/model/Computer/markOffline.jelly b/core/src/main/resources/hudson/model/Computer/markOffline.jelly index a39339c86168..c31f3e9070d5 100644 --- a/core/src/main/resources/hudson/model/Computer/markOffline.jelly +++ b/core/src/main/resources/hudson/model/Computer/markOffline.jelly @@ -24,6 +24,10 @@ THE SOFTWARE. + + + + diff --git a/core/src/main/resources/hudson/model/Computer/sidepanel.jelly b/core/src/main/resources/hudson/model/Computer/sidepanel.jelly index 9e471add60d8..928ae5915984 100644 --- a/core/src/main/resources/hudson/model/Computer/sidepanel.jelly +++ b/core/src/main/resources/hudson/model/Computer/sidepanel.jelly @@ -33,12 +33,12 @@ THE SOFTWARE. - - - + + - + diff --git a/core/src/main/resources/hudson/model/ComputerSet/index.jelly b/core/src/main/resources/hudson/model/ComputerSet/index.jelly index 64b3bc53373f..7ab107d0ed35 100644 --- a/core/src/main/resources/hudson/model/ComputerSet/index.jelly +++ b/core/src/main/resources/hudson/model/ComputerSet/index.jelly @@ -32,25 +32,48 @@ THE SOFTWARE. - - - - - - - - - - - + +
    +
    +

    ${%Manage nodes and clouds}

    +
    + +
    +
    + + +
    +
    +
    + +
    S${%Name}${m.columnCaption} -
    + + + + + + + + + + + + + - - + + + @@ -58,11 +81,13 @@ THE SOFTWARE. - @@ -85,15 +110,8 @@ THE SOFTWARE. - +
    S${%Name}${m.columnCaption} +
    - + +
    + +
    ${c.displayName} + ${c.displayName} + + - - - +
    + + + +
    - -
    -
    - - -
    -
    diff --git a/core/src/main/resources/hudson/model/ComputerSet/index_pt_BR.properties b/core/src/main/resources/hudson/model/ComputerSet/index_pt_BR.properties index b76a78af2600..2f2a14a1f888 100644 --- a/core/src/main/resources/hudson/model/ComputerSet/index_pt_BR.properties +++ b/core/src/main/resources/hudson/model/ComputerSet/index_pt_BR.properties @@ -20,8 +20,8 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Configure=Configurar Refresh\ status=Atualizar o status Name=Nome -Nodes=N\u00f3s +Nodes=N\u00F3s Data\ obtained=Dados obtidos +Manage\ nodes\ and\ clouds=Gerenciar\ n\u00F3s\ e\ nuvens diff --git a/core/src/main/resources/hudson/model/ComputerSet/new.jelly b/core/src/main/resources/hudson/model/ComputerSet/new.jelly index 85879e6d9f82..9eed3d1eb2c5 100644 --- a/core/src/main/resources/hudson/model/ComputerSet/new.jelly +++ b/core/src/main/resources/hudson/model/ComputerSet/new.jelly @@ -32,11 +32,11 @@ THE SOFTWARE. - + - diff --git a/core/src/main/resources/hudson/model/ComputerSet/new_pt_BR.properties b/core/src/main/resources/hudson/model/ComputerSet/new_pt_BR.properties index feb350c3dd96..36570082da4a 100644 --- a/core/src/main/resources/hudson/model/ComputerSet/new_pt_BR.properties +++ b/core/src/main/resources/hudson/model/ComputerSet/new_pt_BR.properties @@ -20,5 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Node\ name=Nome do n\u00f3 -Copy\ Existing\ Node=Copiar um n\u00f3 existente +Node\ name=Nome do n\u00F3 +Copy\ Existing\ Node=Copiar um n\u00F3 existente +New\ node=Novo\ n\u00F3 diff --git a/core/src/main/resources/hudson/model/ComputerSet/sidepanel.jelly b/core/src/main/resources/hudson/model/ComputerSet/sidepanel.jelly index 6940dd6714e4..c2687fa0dfb9 100644 --- a/core/src/main/resources/hudson/model/ComputerSet/sidepanel.jelly +++ b/core/src/main/resources/hudson/model/ComputerSet/sidepanel.jelly @@ -32,11 +32,11 @@ THE SOFTWARE. - - - + + - + diff --git a/core/src/main/resources/hudson/model/ComputerSet/sidepanel_pt_BR.properties b/core/src/main/resources/hudson/model/ComputerSet/sidepanel_pt_BR.properties index faa5701beeb7..54b86b0cfa14 100644 --- a/core/src/main/resources/hudson/model/ComputerSet/sidepanel_pt_BR.properties +++ b/core/src/main/resources/hudson/model/ComputerSet/sidepanel_pt_BR.properties @@ -22,5 +22,6 @@ Back\ to\ Dashboard=Voltar ao painel principal Manage\ Jenkins=Gerenciar Jenkins -Configure=Configurar -New\ Node=Novo n\u00f3 +New\ Node=Novo n\u00F3 +Configure\ Clouds=Configurar\ nuvens +Node\ Monitoring=Monitora\u00E7\u00E3o\ de\ n\u00F3 diff --git a/core/src/main/resources/hudson/model/ComputerSet/sidepanel_zh_TW.properties b/core/src/main/resources/hudson/model/ComputerSet/sidepanel_zh_TW.properties index b0145f00ee4f..7749de480d09 100644 --- a/core/src/main/resources/hudson/model/ComputerSet/sidepanel_zh_TW.properties +++ b/core/src/main/resources/hudson/model/ComputerSet/sidepanel_zh_TW.properties @@ -21,7 +21,9 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Back\ to\ Dashboard=\u56de\u5230\u5100\u8868\u677f +Back\ to\ Dashboard=\u8fd4\u56de\u8cc7\u8a0a\u4e3b\u9801 Manage\ Jenkins=\u7ba1\u7406 Jenkins New\ Node=\u65b0\u589e\u7bc0\u9ede Configure=\u8a2d\u5b9a +Configure\ Clouds=\u8a2d\u5b9a\u96f2\u7aef +Node\ Monitoring=\u7bc0\u9ede\u76e3\u8996 diff --git a/core/src/main/resources/hudson/model/DirectoryBrowserSupport/dir.jelly b/core/src/main/resources/hudson/model/DirectoryBrowserSupport/dir.jelly index 875432a28195..104bda035f73 100644 --- a/core/src/main/resources/hudson/model/DirectoryBrowserSupport/dir.jelly +++ b/core/src/main/resources/hudson/model/DirectoryBrowserSupport/dir.jelly @@ -33,13 +33,15 @@ THE SOFTWARE.
    - + ${it.owner.name} / ${p.title} / - - + +
    @@ -47,7 +49,7 @@ THE SOFTWARE. ${%No files in directory}

    - + ${%Symlinks are hidden}

    @@ -62,7 +64,7 @@ THE SOFTWARE. - + ${t.title} @@ -71,7 +73,7 @@ THE SOFTWARE. ${t.title} - + / @@ -87,16 +89,17 @@ THE SOFTWARE. ${h.humanReadableByteSize(x.getSize())} - + - - + + - - ${%view} - + + + +
    @@ -104,8 +107,8 @@ THE SOFTWARE. @@ -114,7 +117,7 @@ THE SOFTWARE.

    - + ${%Symlinks are hidden}

    diff --git a/core/src/main/resources/hudson/model/DirectoryBrowserSupport/dir_pt_BR.properties b/core/src/main/resources/hudson/model/DirectoryBrowserSupport/dir_pt_BR.properties index da72b1eab64a..0ab204560a1e 100644 --- a/core/src/main/resources/hudson/model/DirectoryBrowserSupport/dir_pt_BR.properties +++ b/core/src/main/resources/hudson/model/DirectoryBrowserSupport/dir_pt_BR.properties @@ -22,4 +22,6 @@ all\ files\ in\ zip=Todos os arquivos em .zip view=ver -No\ files\ in\ directory=Nenhum arquivo no diret\u00f3rio +No\ files\ in\ directory=Nenhum arquivo no diret\u00F3rio +Symlinks\ are\ hidden=Liga\u00E7\u00F5es\ simb\u00F3licas\ est\u00E3o\ escondidas +N/A=N/A diff --git a/core/src/main/resources/hudson/model/DirectoryBrowserSupport/plaindir_pt_BR.properties b/core/src/main/resources/hudson/model/DirectoryBrowserSupport/plaindir_pt_BR.properties new file mode 100644 index 000000000000..563b35a6bc28 --- /dev/null +++ b/core/src/main/resources/hudson/model/DirectoryBrowserSupport/plaindir_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +No\ files\ in\ directory=Nenhum\ arquivo\ no\ diret\u00F3rio diff --git a/core/src/main/resources/hudson/model/EnvironmentContributor/EnvVarsHtml/index.groovy b/core/src/main/resources/hudson/model/EnvironmentContributor/EnvVarsHtml/index.groovy index 76a5d72b74de..5edef210b2ab 100644 --- a/core/src/main/resources/hudson/model/EnvironmentContributor/EnvVarsHtml/index.groovy +++ b/core/src/main/resources/hudson/model/EnvironmentContributor/EnvVarsHtml/index.groovy @@ -3,16 +3,11 @@ import hudson.model.EnvironmentContributor import hudson.scm.SCM def st = namespace("jelly:stapler") +def l = namespace(lib.LayoutTagLib) -st.contentType(value: "text/html;charset=UTF-8") - -html { - head { - title(_("Available Environmental Variables")) - style(type:"text/css", "dt { font-weight: bold; }") - } - body { - p "The following variables are available to shell scripts" +l.layout(title: _("Available Environmental Variables"), type: 'one-column') { + l.main_panel { + p _("blurb") dl { EnvironmentContributor.all().each { e -> st.include(it:e, page:"buildEnv", optional:true) } diff --git a/core/src/main/resources/hudson/model/EnvironmentContributor/EnvVarsHtml/index.properties b/core/src/main/resources/hudson/model/EnvironmentContributor/EnvVarsHtml/index.properties new file mode 100644 index 000000000000..24a187866d49 --- /dev/null +++ b/core/src/main/resources/hudson/model/EnvironmentContributor/EnvVarsHtml/index.properties @@ -0,0 +1 @@ +blurb=The following variables are available to shell and batch build steps: diff --git a/core/src/main/resources/hudson/model/EnvironmentContributor/EnvVarsHtml/index_de.properties b/core/src/main/resources/hudson/model/EnvironmentContributor/EnvVarsHtml/index_de.properties index c01a5bb92d84..f85cb0145b42 100644 --- a/core/src/main/resources/hudson/model/EnvironmentContributor/EnvVarsHtml/index_de.properties +++ b/core/src/main/resources/hudson/model/EnvironmentContributor/EnvVarsHtml/index_de.properties @@ -1,2 +1 @@ -Available\ Environmental\ Variables=Verf\u00FCgbare Umgebungsvariablen -The\ following\ variables\ are\ available\ to\ shell\ scripts=Die folgenden Variablen sind innerhalb von Shell-Skripten sichtbar: +Available\ Environment\ Variables=Verf\u00FCgbare Umgebungsvariablen diff --git a/core/src/main/resources/hudson/model/EnvironmentContributor/EnvVarsHtml/index_fr.properties b/core/src/main/resources/hudson/model/EnvironmentContributor/EnvVarsHtml/index_fr.properties index f937abbc85d2..a69313856283 100644 --- a/core/src/main/resources/hudson/model/EnvironmentContributor/EnvVarsHtml/index_fr.properties +++ b/core/src/main/resources/hudson/model/EnvironmentContributor/EnvVarsHtml/index_fr.properties @@ -1,2 +1 @@ -Available\ Environmental\ Variables=Variables d'environnement disponibles -The\ following\ variables\ are\ available\ to\ shell\ scripts=Les variables suivantes sont mises \u00E0 disposition des scripts shell +Available\ Environment\ Variables=Variables d'environnement disponibles diff --git a/core/src/main/resources/hudson/model/EnvironmentContributor/EnvVarsHtml/index_it.properties b/core/src/main/resources/hudson/model/EnvironmentContributor/EnvVarsHtml/index_it.properties index ff52a78b8a3c..b1f37e34927a 100644 --- a/core/src/main/resources/hudson/model/EnvironmentContributor/EnvVarsHtml/index_it.properties +++ b/core/src/main/resources/hudson/model/EnvironmentContributor/EnvVarsHtml/index_it.properties @@ -22,5 +22,3 @@ # THE SOFTWARE. Available\ Environmental\ Variables=Variabili d''ambiente disponibili -The\ following\ variables\ are\ available\ to\ shell\ scripts=Per gli script \ - shell sono disponibili le seguenti variabili: diff --git a/core/src/main/resources/hudson/model/EnvironmentContributor/EnvVarsHtml/index_ja.properties b/core/src/main/resources/hudson/model/EnvironmentContributor/EnvVarsHtml/index_ja.properties index 785aa635b7e7..f4433bf8cebb 100644 --- a/core/src/main/resources/hudson/model/EnvironmentContributor/EnvVarsHtml/index_ja.properties +++ b/core/src/main/resources/hudson/model/EnvironmentContributor/EnvVarsHtml/index_ja.properties @@ -1,2 +1 @@ -Available\ Environmental\ Variables=\u5229\u7528\u53EF\u80FD\u306A\u74B0\u5883\u5909\u6570 -The\ following\ variables\ are\ available\ to\ shell\ scripts=\u30B7\u30A7\u30EB\u30B9\u30AF\u30EA\u30D7\u30C8\u3067\u306F\u3001\u6B21\u306E\u5909\u6570\u3092\u5229\u7528\u3067\u304D\u307E\u3059\u3002 +Available\ Environment\ Variables=\u5229\u7528\u53EF\u80FD\u306A\u74B0\u5883\u5909\u6570 diff --git a/core/src/main/resources/hudson/model/EnvironmentContributor/EnvVarsHtml/index_nl.properties b/core/src/main/resources/hudson/model/EnvironmentContributor/EnvVarsHtml/index_nl.properties index 1e16e54b83b1..8b22c3eda484 100644 --- a/core/src/main/resources/hudson/model/EnvironmentContributor/EnvVarsHtml/index_nl.properties +++ b/core/src/main/resources/hudson/model/EnvironmentContributor/EnvVarsHtml/index_nl.properties @@ -1,2 +1 @@ -Available\ Environmental\ Variables=Beschikbare omgevingsparameters -The\ following\ variables\ are\ available\ to\ shell\ scripts=Volgende parameters zijn beschikbaar voor gebruik in uw scripts: +Available\ Environment\ Variables=Beschikbare omgevingsparameters diff --git a/core/src/main/resources/hudson/model/EnvironmentContributor/EnvVarsHtml/index_sr.properties b/core/src/main/resources/hudson/model/EnvironmentContributor/EnvVarsHtml/index_sr.properties index afcfba7fc8de..9824c15ba4b2 100644 --- a/core/src/main/resources/hudson/model/EnvironmentContributor/EnvVarsHtml/index_sr.properties +++ b/core/src/main/resources/hudson/model/EnvironmentContributor/EnvVarsHtml/index_sr.properties @@ -1,4 +1,3 @@ # This file is under the MIT License by authors -Available\ Environmental\ Variables=\u0421\u043B\u043E\u0431\u043E\u0434\u043D\u0438\u0445 \u0413\u043B\u043E\u0431\u0430\u043B\u043D\u0438\u0445 \u041F\u0440\u043E\u043C\u0435\u043D\u0459\u0438\u0432\u0430 -The\ following\ variables\ are\ available\ to\ shell\ scripts=\u041F\u0440\u0430\u0442\u0435\u045B\u0430 \u043F\u0440\u043E\u043C\u0435\u043D\u0459\u0438\u0432\u0430 \u0441\u0443 \u0434\u043E\u0441\u0442\u0443\u043F\u043Da \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u0438\u043C\u0430 +Available\ Environment\ Variables=\u0421\u043B\u043E\u0431\u043E\u0434\u043D\u0438\u0445 \u0413\u043B\u043E\u0431\u0430\u043B\u043D\u0438\u0445 \u041F\u0440\u043E\u043C\u0435\u043D\u0459\u0438\u0432\u0430 diff --git a/core/src/main/resources/hudson/model/EnvironmentContributor/EnvVarsHtml/index_zh_TW.properties b/core/src/main/resources/hudson/model/EnvironmentContributor/EnvVarsHtml/index_zh_TW.properties index 5496197a8e9f..0604952e052b 100644 --- a/core/src/main/resources/hudson/model/EnvironmentContributor/EnvVarsHtml/index_zh_TW.properties +++ b/core/src/main/resources/hudson/model/EnvironmentContributor/EnvVarsHtml/index_zh_TW.properties @@ -1,24 +1 @@ -# The MIT License -# -# Copyright (c) 2013, Chunghwa Telecom Co., Ltd., Pei-Tang Huang -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Available\ Environmental\ Variables=\u53ef\u7528\u7684\u74b0\u5883\u8b8a\u6578 -The\ following\ variables\ are\ available\ to\ shell\ scripts=\u4e0b\u5217\u8b8a\u6578\u53ef\u4ee5\u5728 Shell Script \u4e2d\u4f7f\u7528 +blurb=\u4e0b\u5217\u8b8a\u6578\u5728 Shell \u548c\u6279\u6b21\u5efa\u7f6e\u968e\u6bb5\u4e2d\u53ef\u4ee5\u4f7f\u7528\: diff --git a/core/src/main/resources/hudson/model/FileParameterValue/value_pt_BR.properties b/core/src/main/resources/hudson/model/FileParameterValue/value_pt_BR.properties index 32170fb5eae3..bf98f34f69e0 100644 --- a/core/src/main/resources/hudson/model/FileParameterValue/value_pt_BR.properties +++ b/core/src/main/resources/hudson/model/FileParameterValue/value_pt_BR.properties @@ -21,3 +21,5 @@ # THE SOFTWARE. view=ver +nofile=(nenhum arquivo foi subido) +open=abrir diff --git a/core/src/main/resources/hudson/model/FileParameterValue/value_zh_TW.properties b/core/src/main/resources/hudson/model/FileParameterValue/value_zh_TW.properties index 1e76c9afd116..985d19e6146a 100644 --- a/core/src/main/resources/hudson/model/FileParameterValue/value_zh_TW.properties +++ b/core/src/main/resources/hudson/model/FileParameterValue/value_zh_TW.properties @@ -1,23 +1,3 @@ -# The MIT License -# -# Copyright (c) 2013, Chunghwa Telecom Co., Ltd., Pei-Tang Huang -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - +nofile=(\u6c92\u6709\u4e0a\u50b3\u6a94\u6848) view=\u6aa2\u8996 +open=\u958b\u555f diff --git a/core/src/main/resources/hudson/model/Fingerprint/index_zh_TW.properties b/core/src/main/resources/hudson/model/Fingerprint/index_zh_TW.properties index ecc956571147..5299da762e80 100644 --- a/core/src/main/resources/hudson/model/Fingerprint/index_zh_TW.properties +++ b/core/src/main/resources/hudson/model/Fingerprint/index_zh_TW.properties @@ -1,17 +1,17 @@ # The MIT License -# +# # Copyright (c) 2013, Chunghwa Telecom Co., Ltd., Pei-Tang Huang -# +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: -# +# # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. -# +# # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -19,10 +19,8 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. - -Back\ to\ Dashboard=\u56de\u5230\u5100\u8868\u677f - -introduced={0}\u524d\u7522\u51fa\uff0c\u4f86\u81ea +introduced={0}\u524d\u7522\u51fa\uff0c\u4f86\u81ea +Back\ to\ Dashboard=\u8fd4\u56de\u8cc7\u8a0a\u4e3b\u9801 outside\ Jenkins=Jenkins \u4e4b\u5916 Usage=\u4f7f\u7528\u72c0\u6cc1 This\ file\ has\ not\ been\ used\ anywhere\ else.=\u5b8c\u5168\u6c92\u4eba\u7528\u5230\u9019\u500b\u6a94\u6848\u3002 diff --git a/core/src/main/resources/hudson/model/Job/_api.jelly b/core/src/main/resources/hudson/model/Job/_api.jelly index bcab50acda35..36954e743d5f 100644 --- a/core/src/main/resources/hudson/model/Job/_api.jelly +++ b/core/src/main/resources/hudson/model/Job/_api.jelly @@ -47,18 +47,18 @@ THE SOFTWARE.

    To programmatically schedule a new build, post to this URL. If the build has parameters, post to this URL and provide the parameters as form data. - Either way, the successful queueing will result in 201 status code with Location HTTP header - pointing the URL of the item in the queue. By polling the api/xml sub-URL of the queue item, + Either way, the successful queueing will result in 201 status code with Location HTTP header + pointing the URL of the item in the queue. By polling the api/xml sub-URL of the queue item, you can track the status of the queued task. Generally, the task will go through some state transitions, then eventually it becomes either cancelled (look for the "cancelled" boolean property), or gets executed - (look for the "executable" property that typically points to the AbstractBuild object.) + (look for the "executable" property that typically points to the AbstractBuild object.)

    To programmatically schedule SCM polling, post to this URL.

    If security is enabled, the recommended method is to provide the username/password of an - account with build permission in the request. Tools such as curl and wget + account with build permission in the request. Tools such as curl and wget have parameters to specify these credentials. Another alternative (but deprecated) is to configure the 'Trigger builds remotely' section in the job configuration. Then building or polling can be triggered by including a parameter called token in the request. diff --git a/core/src/main/resources/hudson/model/Job/buildTimeTrend.jelly b/core/src/main/resources/hudson/model/Job/buildTimeTrend.jelly index 41ae8ec5bf5b..5e31711bd21f 100644 --- a/core/src/main/resources/hudson/model/Job/buildTimeTrend.jelly +++ b/core/src/main/resources/hudson/model/Job/buildTimeTrend.jelly @@ -32,25 +32,24 @@ THE SOFTWARE.

    ${%Timeline}

    -

    ${%Build Time Trend}

    [${%Build time graph}]
    - +
    ${handler.setBuilds(it.builds)} + data-is-distributed-build-enabled="${isDistributedBuildEnabled}"> - + diff --git a/core/src/main/resources/hudson/model/Job/buildTimeTrend_pt_BR.properties b/core/src/main/resources/hudson/model/Job/buildTimeTrend_pt_BR.properties index 19793e2899e5..4f88f31d7645 100644 --- a/core/src/main/resources/hudson/model/Job/buildTimeTrend_pt_BR.properties +++ b/core/src/main/resources/hudson/model/Job/buildTimeTrend_pt_BR.properties @@ -20,9 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -title={0} Tend\u00eancia de tempo de builds -Duration=Dura\u00e7\u00e3o -Build\ Time\ Trend=Tend\u00eancia de tempo de Build +title={0} Tend\u00EAncia de tempo de constru\u00E7\u00F5es +Duration=Dura\u00E7\u00E3o +Build\ Time\ Trend=Tend\u00EAncia\ de\ tempo\ de\ constru\u00E7\u00E3o Timeline=Linha do tempo -Build=Build +Build=Constru\u00E7\u00E3o Agent=Agente +Build\ time\ graph=Gr\u00E1fico\ de\ tempo\ de\ constru\u00E7\u00E3o diff --git a/core/src/main/resources/hudson/model/Job/buildTimeTrend_resources.js b/core/src/main/resources/hudson/model/Job/buildTimeTrend_resources.js index efeb5489d3ca..a5feb6e9bc45 100644 --- a/core/src/main/resources/hudson/model/Job/buildTimeTrend_resources.js +++ b/core/src/main/resources/hudson/model/Job/buildTimeTrend_resources.js @@ -3,22 +3,21 @@ */ function buildTimeTrend_displayBuilds(data) { var p = document.getElementById('trend'); - var isMasterSlaveEnabled = 'true' === p.getAttribute("data-is-master-slave-enabled"); - var imagesURL = document.head.getAttribute('data-imagesurl'); + var isDistributedBuildsEnabled = 'true' === p.getAttribute("data-is-distributed-build-enabled"); var rootURL = document.head.getAttribute('data-rooturl'); for (var x = 0; data.length > x; x++) { var e = data[x]; var tr = new Element('tr'); tr.insert(new Element('td', {data: e.iconColorOrdinal}). - insert(new Element('a', {href: e.number + '/console'}). - insert(new Element('img', {width: 16, height: 16, src: imagesURL+ '/16x16/' + e.buildStatusUrl, alt: e.iconColorDescription})))); + insert(new Element('a', {class: 'build-status-link', href: e.number + '/console'}). + insert(generateSVGIcon(e.iconName)))); tr.insert(new Element('td', {data: e.number}). insert(new Element('a', {href: e.number + '/', 'class': 'model-link inside'}). update(e.displayName.escapeHTML()))); tr.insert(new Element('td', {data: e.duration}). update(e.durationString.escapeHTML())); - if (isMasterSlaveEnabled) { + if (isDistributedBuildsEnabled) { var buildInfo = null; var buildInfoStr = (e.builtOnStr || '').escapeHTML(); if(e.builtOn) { @@ -33,3 +32,63 @@ function buildTimeTrend_displayBuilds(data) { } ts_refresh(p); } + +/** + * Generate SVG Icon + */ +function generateSVGIcon(iconName, iconSizeClass) { + + const imagesURL = document.head.getAttribute('data-imagesurl'); + + const isInProgress = iconName.endsWith("anime"); + let buildStatus = 'never-built'; + switch (iconName) { + case 'red': + case 'red-anime': + buildStatus = 'last-failed'; + break; + case 'yellow': + case 'yellow-anime': + buildStatus = 'last-unstable'; + break; + case 'blue': + case 'blue-anime': + buildStatus = 'last-successful'; + break; + case 'grey': + case 'grey-anime': + case 'disabled': + case 'disabled-anime': + buildStatus = 'last-disabled'; + break; + case 'aborted': + case 'aborted-anime': + buildStatus = 'last-aborted'; + break; + case 'nobuilt': + case 'nobuilt-anime': + buildStatus = 'never-built'; + break + } + + const svg1 = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); + svg1.setAttribute('class', 'svg-icon'); + svg1.setAttribute('viewBox', "0 0 24 24"); + const use1 = document.createElementNS('http://www.w3.org/2000/svg', 'use'); + use1.setAttribute('href', imagesURL + '/build-status/build-status-sprite.svg#build-status-' + (isInProgress ? 'in-progress' : 'static')) + svg1.appendChild(use1); + + const svg2 = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); + svg2.setAttribute('class', 'svg-icon icon-' + iconName + ' ' + (iconSizeClass || 'icon-sm')); + svg2.setAttribute('viewBox', "0 0 24 24"); + const use2 = document.createElementNS('http://www.w3.org/2000/svg', 'use'); + use2.setAttribute('href', imagesURL + '/build-status/build-status-sprite.svg#' + buildStatus) + svg2.appendChild(use2); + + const span = new Element('span', {class: 'build-status-icon__wrapper icon-' + iconName}). + insert(new Element('span', {class: 'build-status-icon__outer'}). + insert(svg1)). + insert(svg2); + + return span; +} \ No newline at end of file diff --git a/core/src/main/resources/hudson/model/Job/configure.jelly b/core/src/main/resources/hudson/model/Job/configure.jelly index b4d8be5a0535..36f509fc06ab 100644 --- a/core/src/main/resources/hudson/model/Job/configure.jelly +++ b/core/src/main/resources/hudson/model/Job/configure.jelly @@ -37,17 +37,19 @@ THE SOFTWARE.
    -
    +
    -
    ${%LOADING}
    +
    - - - +
    + + + +
    diff --git a/core/src/main/resources/hudson/model/Job/configure_pt_BR.properties b/core/src/main/resources/hudson/model/Job/configure_pt_BR.properties index 86d47d7336e9..7e47671c969f 100644 --- a/core/src/main/resources/hudson/model/Job/configure_pt_BR.properties +++ b/core/src/main/resources/hudson/model/Job/configure_pt_BR.properties @@ -20,10 +20,8 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Strategy=Estrat\u00E9gia -name=Nome do {0} -Description=Descri\u00e7\u00e3o +Description=Descri\u00E7\u00E3o Save=Salvar LOADING=CARREGANDO -# Apply Apply=Aplicar +Config=Configura\u00E7\u00E3o de {0} diff --git a/core/src/main/resources/hudson/model/Job/index_ar.properties b/core/src/main/resources/hudson/model/Job/index_ar.properties deleted file mode 100644 index b38939c893f7..000000000000 --- a/core/src/main/resources/hudson/model/Job/index_ar.properties +++ /dev/null @@ -1,5 +0,0 @@ -# This file is under the MIT License by authors - -Disable\ Project=\u0639\u0637\u0644 \u0627\u0644\u0645\u0634\u0631\u0648\u0639 -Enable=\u062A\u0641\u0639\u064A\u0644 -This\ project\ is\ currently\ disabled=\u0647\u0630\u0627 \u0627\u0644\u0645\u0634\u0631\u0648\u0639 \u062D\u0627\u0644\u064A\u0627\u064B \u0645\u0639\u0637\u0644 diff --git a/core/src/main/resources/hudson/model/Job/permalinks_ar.properties b/core/src/main/resources/hudson/model/Job/permalinks_ar.properties deleted file mode 100644 index 8de5310e98ff..000000000000 --- a/core/src/main/resources/hudson/model/Job/permalinks_ar.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -Permalinks=\u0631\u0627\u0628\u0637 \u062F\u0627\u0626\u0645 diff --git a/core/src/main/resources/hudson/model/Label/index.jelly b/core/src/main/resources/hudson/model/Label/index.jelly index a5b4ea43ad92..f39235ebe467 100644 --- a/core/src/main/resources/hudson/model/Label/index.jelly +++ b/core/src/main/resources/hudson/model/Label/index.jelly @@ -28,7 +28,6 @@ THE SOFTWARE.

    - ${it.name}

    @@ -46,7 +45,7 @@ THE SOFTWARE. - + ${c.displayName} diff --git a/core/src/main/resources/hudson/model/Label/sidepanel.jelly b/core/src/main/resources/hudson/model/Label/sidepanel.jelly index 7d662a0a4564..1f5dcc9af35c 100644 --- a/core/src/main/resources/hudson/model/Label/sidepanel.jelly +++ b/core/src/main/resources/hudson/model/Label/sidepanel.jelly @@ -32,12 +32,12 @@ THE SOFTWARE. - + - + - + - \ No newline at end of file + diff --git a/core/src/main/resources/hudson/model/Label/sidepanel_zh_TW.properties b/core/src/main/resources/hudson/model/Label/sidepanel_zh_TW.properties index 57a4adf16cce..369c0f936758 100644 --- a/core/src/main/resources/hudson/model/Label/sidepanel_zh_TW.properties +++ b/core/src/main/resources/hudson/model/Label/sidepanel_zh_TW.properties @@ -20,6 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Back\ to\ Dashboard=\u56de\u5230\u5100\u8868\u677f +Back\ to\ Dashboard=\u8fd4\u56de\u8cc7\u8a0a\u4e3b\u9801 Overview=\u7e3d\u89bd Load\ Statistics=\u8ca0\u8f09\u7d71\u8a08 +Configure=\u8a2d\u5b9a diff --git a/core/src/main/resources/hudson/model/ListView/_api.jelly b/core/src/main/resources/hudson/model/ListView/_api.jelly index f13fb3e146fc..61b3dad05431 100644 --- a/core/src/main/resources/hudson/model/ListView/_api.jelly +++ b/core/src/main/resources/hudson/model/ListView/_api.jelly @@ -26,22 +26,22 @@ THE SOFTWARE.

    Fetch/Update config.xml

    - To programmatically obtain config.xml, hit this URL. - You can also POST an updated config.xml to the same URL to programmatically + To programmatically obtain config.xml, hit this URL. + You can also POST an updated config.xml to the same URL to programmatically update the configuration of a view.

    Add Job to View

    To add a job to this view, send a POST request to this URL with - query parameter name=JOBNAME. You'll get 200 status code if the job was successfully added to + query parameter name=JOBNAME. You'll get 200 status code if the job was successfully added to this view, or 4xx/5xx code if it fails.

    Remove Job from View

    To remove a job from this view, send a POST request to this URL with - query parameter name=JOBNAME. You'll get 200 status code if the job was successfully removed + query parameter name=JOBNAME. You'll get 200 status code if the job was successfully removed from this view, or 4xx/5xx code if it fails.

    diff --git a/core/src/main/resources/hudson/model/ListView/configure-entries-resources.js b/core/src/main/resources/hudson/model/ListView/configure-entries-resources.js new file mode 100644 index 000000000000..7f4621d7a7db --- /dev/null +++ b/core/src/main/resources/hudson/model/ListView/configure-entries-resources.js @@ -0,0 +1,8 @@ +Behaviour.specify("#recurse", 'ListView', 0, function (e) { + var nestedElements = $$('SPAN.nested') + e.onclick = function () { + nestedElements.each(function (el) { + e.checked ? el.show() : el.hide(); + }); + } +}); diff --git a/core/src/main/resources/hudson/model/ListView/configure-entries.jelly b/core/src/main/resources/hudson/model/ListView/configure-entries.jelly index b47bdf048c10..fe7be59bb14b 100644 --- a/core/src/main/resources/hudson/model/ListView/configure-entries.jelly +++ b/core/src/main/resources/hudson/model/ListView/configure-entries.jelly @@ -26,9 +26,10 @@ THE SOFTWARE. --> + - + @@ -70,18 +71,5 @@ THE SOFTWARE. - - diff --git a/core/src/main/resources/hudson/model/ListView/configure-entries_pt_BR.properties b/core/src/main/resources/hudson/model/ListView/configure-entries_pt_BR.properties index 0f25167d79e1..8ff5e9897a58 100644 --- a/core/src/main/resources/hudson/model/ListView/configure-entries_pt_BR.properties +++ b/core/src/main/resources/hudson/model/ListView/configure-entries_pt_BR.properties @@ -21,8 +21,6 @@ # THE SOFTWARE. Jobs=Jobs -All\ selected\ jobs=Todas as jobs selecionadas -Status\ Filter=Status do filtro Use\ a\ regular\ expression\ to\ include\ jobs\ into\ the\ view=Use uma express\u00e3o regular para incluir jobs na view Recurse\ in\ subfolders=Recursivo nos sub-diret\u00F3rios Regular\ expression=Express\u00e3o regular @@ -30,5 +28,3 @@ Columns=Colunas Add\ column=Adicionar coluna Job\ Filters=Filtrar jobs Add\ Job\ Filter=Adicionar filtro de job -Disabled\ jobs\ only=Desabilitar jobs -Enabled\ jobs\ only=Habilitar jobs diff --git a/core/src/main/resources/hudson/model/ListView/newJobButtonBar_pt_BR.properties b/core/src/main/resources/hudson/model/ListView/newJobButtonBar_pt_BR.properties new file mode 100644 index 000000000000..ca64e6a7086e --- /dev/null +++ b/core/src/main/resources/hudson/model/ListView/newJobButtonBar_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Add\ to\ current\ view=Adicionar\ a\ vis\u00E3o\ atual diff --git a/core/src/main/resources/hudson/model/LoadStatistics/main.jelly b/core/src/main/resources/hudson/model/LoadStatistics/main.jelly index a6a83bea4574..fec30dee412b 100644 --- a/core/src/main/resources/hudson/model/LoadStatistics/main.jelly +++ b/core/src/main/resources/hudson/model/LoadStatistics/main.jelly @@ -27,7 +27,6 @@ THE SOFTWARE.

    - ${%title(it.displayName)}

    @@ -76,7 +75,7 @@ THE SOFTWARE.

    ${%blurb} diff --git a/core/src/main/resources/hudson/model/LoadStatistics/main_pt_BR.properties b/core/src/main/resources/hudson/model/LoadStatistics/main_pt_BR.properties index b4625ff49cb9..e3afbf8e8072 100644 --- a/core/src/main/resources/hudson/model/LoadStatistics/main_pt_BR.properties +++ b/core/src/main/resources/hudson/model/LoadStatistics/main_pt_BR.properties @@ -20,41 +20,53 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -# Load statistics: {0} -title=Estat\u00edsticas de carga: {0} +title=Estat\u00EDsticas de carga: {0} +timeScale10sec=Cada ponto \u00E9 10 segundos +timeScaleHour=Cada ponto \u00E9 uma hora +timeScaleMinute=Cada ponto \u00E9 um minuto +blurb=\ + Estat\u00EDsticas de carga mantem o rastreamento de quatro m\u00E9tricas chaves de uso de recursos: \ +

    \ +
    N\u00FAmero de executores ativos
    \ +
    \ + Para um computador: se o computador estiver ativo ent\u00E3o isto \u00E9 n\u00FAmero de executores que \ + um computador tem; se o computador est\u00E1 inativo ent\u00E3o o n\u00FAmero \u00E9 zero.
    \ + Para uma etiqueta: \u00E9 a soma de todos os executadores atrav\u00E9s de todos os computadores ativos relacionados a \ + esta etiqueta.
    \ + Para o Jenkins inteiro: esta \u00E9 a soma de todos os executadores em todos os computadores ativos nesta instala\u00E7\u00E3o \ + do Jenkins.
    \ + Outras altera\u00E7\u00F5es de configura\u00E7\u00E3o, este valor pode tamb\u00E9m mudar quando os agentes ficarem fora do ar. \ +
    \ +
    N\u00FAmero de executores ocupados
    \ +
    \ + Esta linha rastreia o n\u00FAmero de executadores (junto com os executadores contatos acima) que estam encarregados \ + das constru\u00E7\u00F5es. A raz\u00E3o deste n\u00FAmero de executores ativos fornece a voc\u00EA a utiliza\u00E7\u00E3o de recursos. Se todos os \ + seus executores estiverem ocupados por um prolongado per\u00EDodo de tempo, considere adicionar mais computadores \ + para seu agrupamento de Jenkins. \ +
    \ +
    N\u00FAmero de executores dispon\u00EDveis
    \ +
    \ + Esta linha rastreia o n\u00FAmero de executores (juntamente com a contagem de executores ativos acima) que est\u00E3o \ + dispon\u00EDveis para serem encarregados das constru\u00E7\u00F5es. A raz\u00E3o disto para o n\u00FAmero total de executores fornece a \ + voc\u00EA a disponibilidade de recursos. Se nenhum dos executores estiver dispon\u00EDvel por um longo per\u00EDodo de tempo, \ + considere adicionar mais computadores para seu agrupamento de Jenkins. \ +
    \ +
    Tamanho da fila
    \ +
    \ + Este \u00E9 o n\u00FAmero de jobs que est\u00E3o na fila de constru\u00E7\u00E3o, esperando por um executor dispon\u00EDvel (deste computador, \ + desta etiqueta ou no pr\u00F3prio Jenkins, respectivamente). Isto n\u00E3o inclui jobs que est\u00E3o em per\u00EDodo de repouso nem \ + inclui jobs que est\u00E3o na fila porque constru\u00E7\u00F5es anteriores j\u00E1 estava em progresso. \ + Se esta linha nunca ficar acima de 0 isto significa que seu Jenkins ir\u00E1 executar mais constru\u00E7\u00F5es se forem \ + adicionados mais computadores. \ +
    \ +
    \ +

    Nota: o n\u00FAmero de executores ocupados e o n\u00FAmero de executores dispon\u00EDveis n\u00E3o precisa ser necessariamente \ + igual ao n\u00FAmero de executores ativos j\u00E1 que executores podem ser suspensos de aceitar constru\u00E7\u00F5es e estarem, \ + portanto, nem ocupados nem dispon\u00EDveis.

    \ +

    O gr\u00E1fico \u00E9 uma m\u00E9dia exponencial m\u00F3vel de pontos de valores coletados periodicamente. Tr\u00EAs passagens de tempo \ + s\u00E3o atualizadas a cada 10 segundos, 1 minuto e uma hora, respectivamente.

    Short=Curto -Load\ statistics\ graph=Gr\u00e1fico de estat\u00edsticas de carga -Medium=M\u00e9dia -Timespan=Intervalo -# \ -# Load statistics keep track of three key metrics of resource utilization: \ -#
    \ -#
    Total number of executors
    \ -#
    \ -# For a computer, this is the number of executors that the computer has. \ -# For a label, this is the sum of all executors across all computers in this label. \ -# For the entire Jenkins, this is the sum of all executors across all computers in this Jenkins installation. \ -# Other than configuration changes, this value can also change when slaves go offline. \ -#
    \ -#
    Number of busy executors
    \ -#
    \ -# This line tracks the number of executors (among the executors counted above) \ -# that are carrying out builds. The ratio of this to the total number of executors \ -# gives you the resource utilization. If all your executors are busy for \ -# a prolonged period of time, consider adding more computers to your Jenkins cluster.\ -#
    \ -#
    Queue length
    \ -#
    \ -# This is the number of jobs that are in the build queue, waiting for an \ -# available executor (of this computer, of this label, or in this Jenkins, respectively.) \ -# This doesn't include jobs that are in the quiet period, nor does it include \ -# jobs that are in the queue because earlier builds are still in progress. \ -# If this line ever goes above 0, that means your Jenkins will run more builds by \ -# adding more computers.\ -#
    \ -#
    \ -# The graph is exponential moving average of periodically collected data values. \ -# 3 timespans are updated every 10 seconds, 1 minute, and 1 hour respectively. -blurb= As estat\u00EDsticas carregadas rastreiam tr\u00EAs m\u00E9tricas de utiliza\u00E7\u00E3o de recursos:
    N\u00FAmero total de de executores
    Para um computador, este \u00E9 o n\u00FAmero de executores que o computador tem. Para um r\u00F3tulo, esta \u00E9 a soma de todos os executores entre todos os computadores neste r\u00F3tulo. Para todo o Jenkins, esta \u00E9 a soma de todos os executores entre todos os computadores que utilizam o Jenkins. Al\u00E9m das altera\u00E7\u00F5es na configura\u00E7\u00E3o, este valor tamb\u00E9m pode mudar quando um "slave" fica indispon\u00EDvel.
    N\u00FAmero de executores ocupados
    Esta linha rastreia o n\u00FAmero de executores (entre todos os executores contados anteriormente) que est\u00E3o construindo. A rela\u00E7\u00E3o deste com o n\u00FAmero total de executores possibilita conhecer a utiliza\u00E7\u00E3o do recurso. Se todos os seus executores est\u00E3o ocupados por um longo per\u00EDodo de tempo, considere adicionar mais computadores ao "cluster" do Jenkins.
    Comprimento da fila
    Este \u00E9 o n\u00FAmero de trabalhos que est\u00E3o na fila de builds, esperando por um executor dispon\u00EDvel (do computador, com r\u00F3tulo, ou do pr\u00F3prio Jenkins, respectivamente). Isto n\u00E3o inclui trabalhos que est\u00E3o em per\u00EDodo de espera, nem inclui trabalhos que est\u00E3o na fila devido o builds prematuras est\u00E3o em progresso. Se esta linha nunca passa de zero, significa que o Jenkins realizar\u00E1 mais builds adicionando mais computadores.
    O gr\u00E1fico \u00E9 a m\u00E9dia de movimenta\u00E7\u00E3o exponencial de dados coletados periodicamente. 3 per\u00EDodos s\u00E3o atualizados a cada 10 segundos, 1 minuto, e 1 hora respectivamente. -# Estes usu\u00E1rios podem se logar no Jenkins. Este \u00E9 um super conjunto desta lista, \ +Medium=M\u00E9dico Long=Longo +Load\ statistics\ graph=Carregar gr\u00E1fico de estat\u00EDsticas +Timespan=Intervalo de tempo diff --git a/core/src/main/resources/hudson/model/LoadStatistics/resources.js b/core/src/main/resources/hudson/model/LoadStatistics/resources.js index b1baf2bd2876..b4bdc926a0d8 100644 --- a/core/src/main/resources/hudson/model/LoadStatistics/resources.js +++ b/core/src/main/resources/hudson/model/LoadStatistics/resources.js @@ -23,25 +23,26 @@ */ (function(){ document.addEventListener("DOMContentLoaded", function() { - var graphLocation = document.querySelector('.js-load-graph'); + const graphLocation = document.querySelector('.js-load-graph'); if (graphLocation) { - var type = graphLocation.getAttribute("data-graph-type"); - var parentSelector = graphLocation.getAttribute("data-graph-parent-selector"); - var baseUrl = graphLocation.getAttribute("data-graph-base-url"); - var graphAlt = graphLocation.getAttribute("data-graph-alt"); + const type = graphLocation.getAttribute("data-graph-type"); + const parentSelector = graphLocation.getAttribute("data-graph-parent-selector"); + const baseUrl = graphLocation.getAttribute("data-graph-base-url"); + const graphAlt = graphLocation.getAttribute("data-graph-alt"); - var parent = document.querySelector(parentSelector); + const parent = document.querySelector(parentSelector); if (parent) { - var availableWidth = parent.offsetWidth; - var padding = 30; + const availableWidth = parent.offsetWidth; + const padding = 30; // for some browsers, the perfect width is not enough - var quirkyBrowserAdjustment = 15; - var graphWidth = availableWidth - padding - quirkyBrowserAdjustment; + const quirkyBrowserAdjustment = 15; + const graphWidth = availableWidth - padding - quirkyBrowserAdjustment; // type in {sec10, min, hour} - var graphUrl = baseUrl + "/graph?type=" + type + "&width=" + graphWidth + "&height=500"; - var graphImgTag = document.createElement("img"); + const graphUrl = baseUrl + "/graph?type=" + type + "&width=" + graphWidth + "&height=500"; + const graphImgTag = document.createElement("img"); graphImgTag.src = graphUrl; + graphImgTag.srcset = graphUrl + "&scale=2 2x"; graphImgTag.alt = graphAlt; graphLocation.appendChild(graphImgTag); } diff --git a/core/src/main/resources/hudson/model/Messages.properties b/core/src/main/resources/hudson/model/Messages.properties index 2e6fa2bcfa74..33e069d4bb73 100644 --- a/core/src/main/resources/hudson/model/Messages.properties +++ b/core/src/main/resources/hudson/model/Messages.properties @@ -23,7 +23,7 @@ # THE SOFTWARE. AbstractBuild.BuildingRemotely=Building remotely on {0} -AbstractBuild.BuildingOnMaster=Building on master +AbstractBuild.BuildingOnMaster=Building on the built-in node AbstractBuild_Building=Building AbstractBuild.BuildingInWorkspace=\ in workspace {0} AbstractBuild.KeptBecause=This build is kept because of {0}. @@ -106,7 +106,7 @@ Computer.CreatePermission.Description=This permission allows users to create age Computer.ConnectPermission.Description=This permission allows users to connect agents or mark agents as online. Computer.DisconnectPermission.Description=This permission allows users to disconnect agents or mark agents as temporarily offline. Computer.BuildPermission.Description=This permission allows users to run jobs as them on agents. -Computer.BadChannel=Agent node offline or not a remote channel (such as master node). +Computer.BadChannel=Agent node offline or not a remote channel (such as the built-in node). ComputerSet.NoSuchSlave=No such agent: {0} ComputerSet.SlaveAlreadyExists=Agent called \u2018{0}\u2019 already exists @@ -125,8 +125,8 @@ FreeStyleProject.Description=\ HealthReport.EmptyString= Hudson.BadPortNumber=Bad port number {0} -Hudson.Computer.Caption=Master -Hudson.Computer.DisplayName=master +Hudson.Computer.Caption=Built-In Node +Hudson.Computer.DisplayName=Built-In Node Hudson.ControlCodeNotAllowed=No control code is allowed: {0} Hudson.DisplayName=Jenkins Hudson.JobAlreadyExists=A job already exists with the name \u2018{0}\u2019 @@ -139,6 +139,7 @@ Hudson.NotJDKDir={0} doesn\u2019t look like a JDK directory Hudson.Permissions.Title=Overall Hudson.USER_CONTENT_README=Files in this directory will be served under your http://yourjenkins/userContent/ Hudson.UnsafeChar=\u2018{0}\u2019 is an unsafe character +Hudson.TrailingDot=A name cannot end with \u2018.\u2019 Hudson.ViewAlreadyExists=A view already exists with the name "{0}" Hudson.ViewName=All Hudson.NotANumber=Not a number @@ -150,8 +151,8 @@ Hudson.MustBeAtMost=Must be {0} or less Hudson.NotUsesUTF8ToDecodeURL=\ Your container doesn\u2019t use UTF-8 to decode URLs. If you use non-ASCII characters as a job name etc, \ this will cause problems. \ - See Containers and \ - Tomcat i18n for more details. + See Containers and \ + Tomcat i18n for more details. Hudson.AdministerPermission.Description=\ This permission grants the ability to make system-wide configuration changes, \ as well as perform highly sensitive operations that amounts to full local system access \ @@ -168,7 +169,7 @@ Hudson.ReadPermission.Description=\ add "authenticated" pseudo-user and grant the read access. Hudson.RunScriptsPermission.Description=\ Deprecated - please use the Overall/Administer permission instead -Hudson.NodeDescription=the master Jenkins node +Hudson.NodeDescription=the Jenkins controller''s built-in node Item.Permissions.Title=Job Item.CREATE.description=Create a new job. @@ -177,6 +178,7 @@ Item.CONFIGURE.description=Change the configuration of a job. Item.READ.description=See a job. (You may deny this permission but allow Discover to force an anonymous user to log in to see the job.) Item.RENAME.description=Rename a job. ItemGroupMixIn.may_not_copy_as_it_contains_secrets_and_=May not copy {0} as it contains secrets and {1} has {2}/{3} but not /{4} +JDK.DisplayName=JDK Job.AllRecentBuildFailed=All recent builds failed. Job.BuildStability=Build stability: {0} Job.NOfMFailed={0} out of the last {1} builds failed. @@ -189,6 +191,8 @@ Label.GroupOf=group of {0} Label.InvalidLabel=invalid label Label.ProvisionedFrom=Provisioned from {0} LabelExpression.InvalidBooleanExpression=Invalid boolean expression: {0} +LabelExpression_ObsoleteMasterLabel=This expression includes the label master that is no longer used for the built-in node. Use built-in instead. \ + Learn more. LabelExpression.LabelLink=Label {1} matches {3,choice,0#no nodes|1#1 node|1<{3} nodes}{4,choice,0#|1# and 1 cloud|1< and {4} clouds}. \ Permissions or other restrictions provided by plugins may further reduce that list. LabelExpression.NoMatch=No agent/cloud matches this label expression. @@ -253,7 +257,7 @@ Run.Summary.Unknown=? Slave.InvalidConfig.Executors=Invalid agent configuration for {0}. Invalid number of executors. Slave.InvalidConfig.NoName=Invalid agent configuration. Name is empty -Slave.Network.Mounted.File.System.Warning=Are you sure you want to use network mounted file system for FS root? Note that this directory does not need to be visible to the master. +Slave.Network.Mounted.File.System.Warning=Are you sure you want to use network mounted file system for FS root? Note that this directory does not need to be visible to the controller. Slave.Remote.Director.Mandatory=Remote directory is mandatory Slave.Terminated={0} agent was terminated Slave.Remote.Relative.Path.Warning=Are you sure you want to use a relative path for the FS root? Note that relative \ @@ -296,7 +300,7 @@ UpdateCenter.PluginCategory.builder=Build Tools UpdateCenter.PluginCategory.buildwrapper=Build Wrappers UpdateCenter.PluginCategory.cli=Command Line Interface UpdateCenter.PluginCategory.cloud=Cloud Providers -UpdateCenter.PluginCategory.cluster=Cluster Management and Distributed Build +UpdateCenter.PluginCategory.cluster=Cluster Management UpdateCenter.PluginCategory.database=Database UpdateCenter.PluginCategory.deployment=Deployment UpdateCenter.PluginCategory.devops=DevOps @@ -305,7 +309,7 @@ UpdateCenter.PluginCategory.dotnet=.NET Development UpdateCenter.PluginCategory.external=External Site/Tool Integrations UpdateCenter.PluginCategory.groovy-related=Groovy-related UpdateCenter.PluginCategory.ios=iOS Development -UpdateCenter.PluginCategory.library=Library plugins (for use by other plugins) +UpdateCenter.PluginCategory.api-plugin=Library plugins (for use by other plugins) UpdateCenter.PluginCategory.listview-column=List view columns UpdateCenter.PluginCategory.maven=Maven UpdateCenter.PluginCategory.misc=Miscellaneous @@ -322,7 +326,7 @@ UpdateCenter.PluginCategory.scala=Scala Development UpdateCenter.PluginCategory.scm=Source Code Management UpdateCenter.PluginCategory.scm-related=Source Code Management related UpdateCenter.PluginCategory.security=Security -UpdateCenter.PluginCategory.slaves=Agent Launchers and Controllers +UpdateCenter.PluginCategory.agent=Agent Management UpdateCenter.PluginCategory.test=Testing UpdateCenter.PluginCategory.theme=UI Themes UpdateCenter.PluginCategory.trigger=Build Triggers diff --git a/core/src/main/resources/hudson/model/Messages_ar.properties b/core/src/main/resources/hudson/model/Messages_ar.properties deleted file mode 100644 index 6d27ef301bf6..000000000000 --- a/core/src/main/resources/hudson/model/Messages_ar.properties +++ /dev/null @@ -1 +0,0 @@ -FreeStyleProject.Description=\u0647\u0630\u0647 \u0647\u064A \u0627\u0644\u0645\u064A\u0632\u0629 \u0627\u0644\u0631\u0626\u064A\u0633\u064A\u0629 \u0641\u064A \u062C\u0646\u0643\u0646\u0632. \u062C\u0646\u0643\u0646\u0632 \u0633\u064A\u0628\u0646\u064A \u0644\u0643 \u0645\u0634\u0631\u0648\u0639\u0643\u060C \u064A\u0633\u062A\u062E\u062F\u0645 \u0623\u062F\u0648\u0627\u062A \u0645\u0631\u0627\u0642\u0628\u0629 \u0627\u0644\u0645\u0635\u062F\u0631 \u0627\u0644\u0628\u0631\u0645\u062C\u064A\u060C \u0648\u064A\u0645\u0643\u0646 \u062D\u062A\u0649 \u0627\u0633\u062A\u062E\u062F\u0627\u0645\u0647\u0627 \uFEF7\u0634\u064A\u0627\u0621 \u063A\u064A\u0631 \u0628\u0646\u0627\u0621 \u0627\u0644\u0645\u0634\u0631\u0648\u0639. diff --git a/core/src/main/resources/hudson/model/Messages_bg.properties b/core/src/main/resources/hudson/model/Messages_bg.properties index 4f46c7c3267a..66e2a4ecad58 100644 --- a/core/src/main/resources/hudson/model/Messages_bg.properties +++ b/core/src/main/resources/hudson/model/Messages_bg.properties @@ -219,9 +219,9 @@ Hudson.NotUsesUTF8ToDecodeURL=\ \u041a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044a\u0442 \u0437\u0430 \u0441\u044a\u0440\u0432\u043b\u0435\u0442\u0438 \u043d\u0435 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430 UTF-8 \u0437\u0430 \u0434\u0435\u043a\u043e\u0434\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0430\u0434\u0440\u0435\u0441\u0438. \u0417\u043d\u0430\u0446\u0438\ \u0438\u0437\u0432\u044a\u043d ASCII \u0432 \u0438\u043c\u0435\u043d\u0430\u0442\u0430 \u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0438 \u0438 \u0434\u0440. \u0449\u0435 \u043f\u0440\u0438\u0447\u0438\u043d\u044f\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0438. \u0417\u0430 \u043f\u043e\u0432\u0435\u0447\u0435\ \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043f\u043e\u0433\u043b\u0435\u0434\u043d\u0435\u0442\u0435\ - \u041a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0438\ + \u041a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0438\ \u0438\ - \ + \ \u0418\u043d\u0442\u0435\u0440\u043d\u0430\u0446\u0438\u043e\u043d\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043d\u0430 Tomcat. Hudson.AdministerPermission.Description=\ \u0422\u043e\u0432\u0430 \u0434\u0430\u0432\u0430 \u043f\u0440\u0430\u0432\u043e \u0437\u0430 \u043f\u0440\u043e\u043c\u044f\u043d\u0430 \u043d\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u0438\u0442\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438, \u043a\u0430\u043a\u0442\u043e \u0438 \u043f\u044a\u043b\u0435\u043d \u0434\u043e\u0441\u0442\u044a\u043f \u0434\u043e\ @@ -433,7 +433,7 @@ UpdateCenter.PluginCategory.groovy-related=\ \u0421\u0432\u044a\u0440\u0437\u0430\u043d\u0438 \u0441 Groovy UpdateCenter.PluginCategory.ios=\ \u041f\u0440\u043e\u0433\u0440\u0430\u043c\u0438\u0440\u0430\u043d\u0435 \u0437\u0430 iOS -UpdateCenter.PluginCategory.library=\ +UpdateCenter.PluginCategory.api-plugin=\ \u041f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0438-\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 (\u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u0442 \u0441\u0435 \u043e\u0442 \u0434\u0440\u0443\u0433\u0438 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0438) UpdateCenter.PluginCategory.listview-column=\ \u041a\u043e\u043b\u043e\u043d\u0438 \u0432 \u0441\u043f\u0438\u0441\u044a\u0447\u043d\u0438\u044f \u0438\u0437\u0433\u043b\u0435\u0434 @@ -637,7 +637,7 @@ ComputerSet.SpecifySlaveToCopy=\ Slave.WindowsSlave=\ \u0422\u043e\u0432\u0430 \u0435 \u0430\u0433\u0435\u043d\u0442 \u0437\u0430 Windows # Agent Launchers and Controllers -UpdateCenter.PluginCategory.slaves=\ +UpdateCenter.PluginCategory.agent=\ \u0421\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435 \u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 \u0430\u0433\u0435\u043d\u0442\u0438 MultiStageTimeSeries.EMPTY_STRING=\ diff --git a/core/src/main/resources/hudson/model/Messages_de.properties b/core/src/main/resources/hudson/model/Messages_de.properties index b1b4d55d2199..9de8c93e009d 100644 --- a/core/src/main/resources/hudson/model/Messages_de.properties +++ b/core/src/main/resources/hudson/model/Messages_de.properties @@ -69,7 +69,7 @@ AbstractProject.CancelPermission.Description=\ Dieses Recht erlaubt, laufende Builds abzubrechen. Api.MultipleMatch=XPath \u201E{0}\u201C stimmt mit {1} Knoten \u00FCberein. \ - Erstellen Sie einen XPath-Ausdruck, der mit genau einem Knoten \u00FCbereinstimmt, oder verwenden Sie den Parameter wrapper, um alle Knoten unterhalb eines gemeinsamen Elternknotens zusammenzufassen. + Erstellen Sie einen XPath-Ausdruck, der mit genau einem Knoten \u00FCbereinstimmt, oder verwenden Sie den Parameter wrapper, um alle Knoten unterhalb eines gemeinsamen Elternknotens zusammenzufassen. Api.NoXPathMatch=XPath \u201E{0}\u201C lieferte keinen Treffer BallColor.Aborted=Abgebrochen @@ -142,8 +142,8 @@ Hudson.NotANegativeNumber=Keine negative Zahl. Hudson.NotUsesUTF8ToDecodeURL=\ Ihr Servlet-Container verwendet kein UTF-8, um URLs zu dekodieren. Falls Sie Nicht-ASCII-Zeichen \ in Elementnamen usw. verwenden, kann dies Probleme mit sich bringen. Beachten Sie bitte die Hinweise zu \ - Servlet-Containern bzw. \ - Tomcat i18N). + Servlet-Containern bzw. \ + Tomcat i18N). Hudson.AdministerPermission.Description=\ Diese Berechtigung erlaubt die Durchf\u00FChrung systemweiter Konfigurations\u00E4nderungen, sowie administrativer Aktionen, die effektiv vollen Systemzugriff erlauben (insoweit dem Jenkins-Account von Betriebssystem-Berechtigungen erlaubt). Hudson.ReadPermission.Description=\ @@ -311,7 +311,7 @@ UpdateCenter.PluginCategory.dotnet=.NET-Entwicklung UpdateCenter.PluginCategory.external=Integration externer Sites und Werkzeuge UpdateCenter.PluginCategory.groovy-related=Groovy (weiteres Umfeld) UpdateCenter.PluginCategory.ios=iOS-Entwicklung -UpdateCenter.PluginCategory.library=Programmbibliotheken (von anderen Plugins verwendet) +UpdateCenter.PluginCategory.api-plugin=Programmbibliotheken (von anderen Plugins verwendet) UpdateCenter.PluginCategory.listview-column=Spalten f\u00FCr Listenansichten UpdateCenter.PluginCategory.maven=Maven bzw. Plugins mit besonderer Maven-Unterst\u00FCtzung UpdateCenter.PluginCategory.misc=Verschiedenes @@ -326,7 +326,7 @@ UpdateCenter.PluginCategory.scala=Scala-Entwicklung UpdateCenter.PluginCategory.scm=Versionsverwaltung UpdateCenter.PluginCategory.scm-related=Versionsverwaltung (weiteres Umfeld) UpdateCenter.PluginCategory.security=Sicherheit -UpdateCenter.PluginCategory.slaves=Agenten-Start und -Steuerung +UpdateCenter.PluginCategory.agent=Agenten-Start und -Steuerung UpdateCenter.PluginCategory.test=Testen UpdateCenter.PluginCategory.trigger=Build-Ausl\u00F6ser UpdateCenter.PluginCategory.ui=Benutzeroberfl\u00E4che diff --git a/core/src/main/resources/hudson/model/Messages_es.properties b/core/src/main/resources/hudson/model/Messages_es.properties index ca81dbbb0145..a40a0cb3d3ce 100644 --- a/core/src/main/resources/hudson/model/Messages_es.properties +++ b/core/src/main/resources/hudson/model/Messages_es.properties @@ -99,8 +99,8 @@ Hudson.NotANegativeNumber=No es un n\u00famero negativo Hudson.NotUsesUTF8ToDecodeURL=\ El contenedor de servlets no usa UTF-8 para decodificar URLs. Esto causar\u00e1 problemas si se usan nombres \ con caracteres no ASCII. Echa un vistazo a \ - Containers y a \ - Tomcat i18n para mas detalles. + Containers y a \ + Tomcat i18n para mas detalles. Hudson.AdministerPermission.Description=\ Este permiso garantiza la posibilidad de hacer cambios de configuraci\u00f3n en el sistema, \ as\u00ed como el realizar operaciones sobre el sistema de archivos local. \ @@ -194,7 +194,7 @@ UpdateCenter.PluginCategory.post-build=Plugins que a\u00f1aden acciones de post- UpdateCenter.PluginCategory.report=Plugins para generar informes UpdateCenter.PluginCategory.scm=Plugins de repositorios de software UpdateCenter.PluginCategory.scm-related=Plugins relacionados con la gesti\u00f3n repositorios -UpdateCenter.PluginCategory.slaves=Plugins para el control de nodos +UpdateCenter.PluginCategory.agent=Plugins para el control de nodos UpdateCenter.PluginCategory.trigger=Plugins lanzadores de tareas diff --git a/core/src/main/resources/hudson/model/Messages_fr.properties b/core/src/main/resources/hudson/model/Messages_fr.properties index 6c06b576dd3f..f051b4d0e741 100644 --- a/core/src/main/resources/hudson/model/Messages_fr.properties +++ b/core/src/main/resources/hudson/model/Messages_fr.properties @@ -80,8 +80,8 @@ Hudson.NotANegativeNumber=Ceci n''est pas un nombre n\u00e9gatif Hudson.NotUsesUTF8ToDecodeURL=\ Votre conteneur n''utilise pas UTF-8 pour d\u00e9coder les URLs. Si vous utilisez des caract\u00e8res non-ASCII \ dans le nom d''un job ou autre, cela causera des probl\u00e8mes. \ - Consultez les pages sur les conteneurs et \ - sur Tomcat i18n pour plus de d\u00e9tails. + Consultez les pages sur les conteneurs et \ + sur Tomcat i18n pour plus de d\u00e9tails. Hudson.AdministerPermission.Description=\ Ce droit permet de faire des changements de configuration au niveau de tout le syst\u00e8me, \ et de r\u00e9aliser des op\u00e9rations tr\u00e8s d\u00e9licates qui n\u00e9cessitent un acc\u00e8s complet \u00e0 tout le syst\u00e8me \ diff --git a/core/src/main/resources/hudson/model/Messages_it.properties b/core/src/main/resources/hudson/model/Messages_it.properties index 2850538382cd..498514bcf843 100644 --- a/core/src/main/resources/hudson/model/Messages_it.properties +++ b/core/src/main/resources/hudson/model/Messages_it.properties @@ -195,8 +195,8 @@ Hudson.NotJDKDir={0} non sembra essere una directory JDK Hudson.NotUsesUTF8ToDecodeURL=Il container non utilizza UTF-8 per \ decodificare gli URL. L''utilizzo di caratteri non ASCII come nome processo \ o in altri ambiti causer problemi. Si vedano le pagine \ - Container \ - e Internazionalizzazione \ + Container \ + e Internazionalizzazione \ di Tomcat per ulteriori dettagli. Hudson.Permissions.Title=Generale Hudson.ReadPermission.Description=Il permesso di lettura necessario per \ @@ -403,7 +403,7 @@ UpdateCenter.PluginCategory.dotnet=Sviluppo .NET UpdateCenter.PluginCategory.external=Integrazioni siti/strumenti esterni UpdateCenter.PluginCategory.groovy-related=Componenti legati a Groovy UpdateCenter.PluginCategory.ios=Sviluppo iOS -UpdateCenter.PluginCategory.library=Componenti libreria (per l''utilizzo da \ +UpdateCenter.PluginCategory.api-plugin=Componenti libreria (per l''utilizzo da \ parte di altri componenti aggiuntivi) UpdateCenter.PluginCategory.listview-column=Colonne visualizzazione elenco UpdateCenter.PluginCategory.maven=Maven @@ -423,7 +423,7 @@ UpdateCenter.PluginCategory.scm=Gestione del codice sorgente UpdateCenter.PluginCategory.scm-related=Componenti legati alla gestione del \ codice sorgente UpdateCenter.PluginCategory.security=Sicurezza -UpdateCenter.PluginCategory.slaves=Avvio e controllo agenti +UpdateCenter.PluginCategory.agent=Avvio e controllo agenti UpdateCenter.PluginCategory.test=Test UpdateCenter.PluginCategory.theme=Temi interfaccia utente UpdateCenter.PluginCategory.trigger=Trigger compilazione diff --git a/core/src/main/resources/hudson/model/Messages_ja.properties b/core/src/main/resources/hudson/model/Messages_ja.properties index 101aec7f0625..23b55b656e5d 100644 --- a/core/src/main/resources/hudson/model/Messages_ja.properties +++ b/core/src/main/resources/hudson/model/Messages_ja.properties @@ -116,8 +116,8 @@ Hudson.NotANonNegativeNumber=0\u4ee5\u4e0a\u306e\u6570\u5b57\u3092\u6307\u5b9a\u Hudson.NotANegativeNumber=\u8ca0\u306e\u6570\u5b57\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002 Hudson.NotUsesUTF8ToDecodeURL=\ URL\u304cUTF-8\u3067\u30c7\u30b3\u30fc\u30c9\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\u30b8\u30e7\u30d6\u540d\u306a\u3069\u306bnon-ASCII\u306a\u6587\u5b57\u3092\u4f7f\u7528\u3059\u308b\u5834\u5408\u306f\u3001\ - \u30b3\u30f3\u30c6\u30ca\u306e\u8a2d\u5b9a\u3084\ - Tomcat i18N\u3092\u53c2\u8003\u306b\u8a2d\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002 + \u30b3\u30f3\u30c6\u30ca\u306e\u8a2d\u5b9a\u3084\ + Tomcat i18N\u3092\u53c2\u8003\u306b\u8a2d\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002 Hudson.AdministerPermission.Description=\ (OS\u304c\u8a31\u53ef\u3059\u308b\u7bc4\u56f2\u5185\u3067\u306e\uff09\u30ed\u30fc\u30ab\u30eb\u30b7\u30b9\u30c6\u30e0\u5168\u4f53\u3078\u306e\u30a2\u30af\u30bb\u30b9\u306b\u76f8\u5f53\u3059\u308b\u3001\ \u3068\u3066\u3082\u6ce8\u610f\u304c\u5fc5\u8981\u306a\u64cd\u4f5c\u3068\u540c\u7a0b\u5ea6\u306e\u3001\u30b7\u30b9\u30c6\u30e0\u5168\u4f53\u306e\u8a2d\u5b9a\u5909\u66f4\u3092\u8a31\u53ef\u3057\u307e\u3059\u3002 diff --git a/core/src/main/resources/hudson/model/Messages_lt.properties b/core/src/main/resources/hudson/model/Messages_lt.properties index 1865a6e0d01f..5d2571900abd 100644 --- a/core/src/main/resources/hudson/model/Messages_lt.properties +++ b/core/src/main/resources/hudson/model/Messages_lt.properties @@ -115,8 +115,8 @@ Hudson.NotANegativeNumber=Ne neigiamas skai\u010dius Hudson.NotUsesUTF8ToDecodeURL=\ J\u016bs\u0173 konteineris nenaudoja UTF-8 nuorod\u0173 dekodavimui. Jei j\u016bs naudojate ne-ASCII simbolius darb\u0173 pavadinimams ir pan., \ tai sukels problem\u0173. \ - Daugiau informacijos apie Konteinerius ir \ - Tomcat i18n. + Daugiau informacijos apie Konteinerius ir \ + Tomcat i18n. Hudson.AdministerPermission.Description=\ \u0160i teis\u0117 duoda galimyb\u0119 daryti sistemos lygio konfig\u016bracijos pakeitimus, \ taip pat vykdyti labai jautrius veiksmus, \u012fskaitant piln\u0105 prieig\u0105 prie sistemos \ @@ -252,7 +252,7 @@ UpdateCenter.PluginCategory.dotnet=.NET k\u016brimas UpdateCenter.PluginCategory.external=I\u0161orin\u0117 svetain\u0117/\u012franki\u0173 integracija UpdateCenter.PluginCategory.groovy-related=Groovy-susij\u0119s UpdateCenter.PluginCategory.ios=iOS k\u016brimas -UpdateCenter.PluginCategory.library=Bibliotek\u0173 priedai (naudojami kit\u0173 pried\u0173) +UpdateCenter.PluginCategory.api-plugin=Bibliotek\u0173 priedai (naudojami kit\u0173 pried\u0173) UpdateCenter.PluginCategory.listview-column=Rodinio s\u0105ra\u0161o stulpeliai UpdateCenter.PluginCategory.maven=Maven UpdateCenter.PluginCategory.misc=\u012evair\u016bs @@ -268,7 +268,7 @@ UpdateCenter.PluginCategory.scala=Scala k\u016brimas UpdateCenter.PluginCategory.scm=I\u0161eities kodo valdymas UpdateCenter.PluginCategory.scm-related=Susij\u0119 su i\u0161eities kodo valdymu UpdateCenter.PluginCategory.security=Saugumas -UpdateCenter.PluginCategory.slaves=Agent\u0173 paleid\u0117jai ir valdytojai +UpdateCenter.PluginCategory.agent=Agent\u0173 paleid\u0117jai ir valdytojai UpdateCenter.PluginCategory.test=Testavimas UpdateCenter.PluginCategory.trigger=Vykdymo trigeriai UpdateCenter.PluginCategory.ui=Naudotojo s\u0105saja diff --git a/core/src/main/resources/hudson/model/Messages_pt_BR.properties b/core/src/main/resources/hudson/model/Messages_pt_BR.properties index fdb8542dbfa5..b614251b9361 100644 --- a/core/src/main/resources/hudson/model/Messages_pt_BR.properties +++ b/core/src/main/resources/hudson/model/Messages_pt_BR.properties @@ -21,432 +21,367 @@ # THE SOFTWARE. AbstractBuild.BuildingRemotely=Construindo remotamente em {0} -AbstractBuild.KeptBecause=mantido por causa de {0} - -AbstractItem.NewNameInUse=O nome {0} j\u00e1 esta em uso. - +AbstractBuild.KeptBecause=Esta constru\u00E7\u00E3o \u00E9 mantida por causa de {0}. +AbstractItem.NewNameInUse=O nome {0} j\u00E1 est\u00E1 em uso. AbstractProject.Pronoun=Projeto AbstractProject.Aborted=Abortado -AbstractProject.Disabled=builds desabilitada +AbstractProject.Disabled=Constru\u00E7\u00E3o desabilitada AbstractProject.NoSCM=Nenhum SCM -AbstractProject.NoWorkspace=Nenhum workspace est\u00e1 dispon\u00edvel, assim n\u00e3o pode checar por atualiza\u00e7\u00f5es. +AbstractProject.NoWorkspace=Nenhum espa\u00E7o de trabalho est\u00E1 dispon\u00EDvel portanto n\u00E3o \u00E9 poss\u00EDvel verificar atualiza\u00E7\u00F5es. AbstractProject.PollingABorted=Pesquisa SCM abortada -AbstractProject.ScmAborted=Check out SCM abortada -AbstractProject.WorkspaceOffline=O workspace est\u00e1 offline. - -Api.MultipleMatch=XPath "{0}" corresponde a {1} n\u00f3s. \ - Crie um XPath que apenas corresponda a um, ou use o par\u00e2metro de pesquisa "agrupador" para agrupa-los sob um elemento raiz. -Api.NoXPathMatch=XPath {0} n\u00e3o tem correspondente - +AbstractProject.ScmAborted=Dar sa\u00EDda do SCM abortada +AbstractProject.WorkspaceOffline=O espa\u00E7o de trabalho est\u00E1 fora de servi\u00E7o. +Api.MultipleMatch=XPath "{0}" corresponde a {1} n\u00F3s. \ + Crie um XPath que apenas corresponda a um ou use o par\u00E2metro de pesquisa "agrupador" para agrup\u00E1-los sob um \ + elemento raiz. +Api.NoXPathMatch=XPath {0} n\u00E3o tem correspondente BallColor.Aborted=Abortado BallColor.Disabled=Desabilitado BallColor.Failed=Falhou BallColor.InProgress=Em progresso BallColor.Pending=Pendente BallColor.Success=Sucesso -BallColor.Unstable=Inst\u00e1vel - - +BallColor.Unstable=Inst\u00E1vel Executor.NotAvailable=N/D - - -FreeStyleProject.DisplayName=Construir um projeto de software free-style -FreeStyleProject.Description=Esta \u00e9 a central de funcionalidades do Jenkins. Ele construir\u00e1 seu projeto,e voc\u00ea pode combinar qualquer SCM com qualquer sistema de builds, e ele at\u00e9 mesmo pode ser usado para outras jobs diferentes de builds de software. - -Hudson.BadPortNumber=N\u00famero de porta ruim {0} -Hudson.Computer.Caption=Master -Hudson.Computer.DisplayName=master -Hudson.ControlCodeNotAllowed=Nenhum c\u00f3digo de controle e permitido: {0} +FreeStyleProject.DisplayName=Construir um projeto de software de estilo livre. +FreeStyleProject.Description=Esta \u00E9 a central de funcionalidades do Jenkins. Ele construir\u00E1 seu projeto e voc\u00EA pode \ + combinar qualquer SCM com qualquer sistema de builds, e ele at\u00E9 mesmo pode ser usado para outras jobs diferentes de \ + constru\u00E7\u00F5es de software. +Hudson.BadPortNumber=N\u00FAmero de porta ruim {0} +Hudson.Computer.Caption=Mestre +Hudson.Computer.DisplayName=mestre +Hudson.ControlCodeNotAllowed=Nenhum c\u00F3digo de controle e permitido: {0} Hudson.DisplayName=Jenkins -Hudson.JobAlreadyExists=Uma job j\u00e1 existe com o nome ''{0}'' -Hudson.NoJavaInPath=Java n\u00e3o esta em seu PATH. Talvez voce precise configurar as JDKs? +Hudson.JobAlreadyExists=Um job j\u00E1 existe com o nome ''{0}'' +Hudson.NoJavaInPath=O java n\u00E3o est\u00E1 em seu PATH. Talvez voce precise configurar as JDKs? Hudson.NoName=Nenhum nome foi especificado -Hudson.NoSuchDirectory=Tal diret\u00f3rio n\u00e3o existe: {0} -Hudson.NotAPlugin={0} n\u00e3o eh um plugin Jenkins -Hudson.NotJDKDir={0} n\u00e3o parece um diret\u00f3rio JDK +Hudson.NoSuchDirectory=Tal diret\u00F3rio n\u00E3o existe: {0} +Hudson.NotAPlugin={0} n\u00E3o \u00E9 uma extens\u00E3o do Jenkins +Hudson.NotJDKDir={0} n\u00E3o parece um diret\u00F3rio JDK Hudson.Permissions.Title=Total -Hudson.UnsafeChar=''{0}'' n\u00e3o \u00e9 um caracter seguro +Hudson.UnsafeChar=''{0}'' n\u00E3o \u00E9 um caracter seguro Hudson.ViewName=Tudo - Item.Permissions.Title=Job - -Job.AllRecentBuildFailed=Todas os builds recentes falharam. -Job.BuildStability=Estabilidade de builds: {0} -Job.NOfMFailed={0} das ultimas {1} builds falharam. -Job.NoRecentBuildFailed=Nenhuma builds recente falhou. +Job.AllRecentBuildFailed=Todas os constru\u00E7\u00F5es recentes falharam. +Job.BuildStability=Estabilidade de constru\u00E7\u00F5es: {0} +Job.NOfMFailed={0} das \u00FAltimas {1} constru\u00E7\u00F5es falharam. +Job.NoRecentBuildFailed=Nenhuma constru\u00E7\u00E3o recente falhou. Job.Pronoun=Projeto Job.minutes=minutos -Job.NoRenameWhileBuilding=N\u00e3o \u00e9 poss\u00edvel renomear enquanto o job est\u00e1 em constru\u00e7\u00e3o - +Job.NoRenameWhileBuilding=N\u00E3o \u00E9 poss\u00EDvel renomear enquanto o job est\u00E1 em constru\u00E7\u00E3o Queue.BlockedBy=Bloqueado por {0} -Queue.InProgress=Uma builds j\u00e1 esta em progresso -Queue.InQuietPeriod=Em per\u00edodo de sil\u00eancio. Expira em {0} +Queue.InProgress=Uma constru\u00E7\u00E3o j\u00E1 esta em progresso +Queue.InQuietPeriod=Em per\u00EDodo de sil\u00EAncio. Expira em {0} Queue.Unknown=??? - -Run.BuildAborted=build foi abortado +Run.BuildAborted=constru\u00E7\u00E3o foi abortada Run.MarkedExplicitly=Explicitamente marcada para manter o registro Run.Permissions.Title=Executar -Run.UnableToDelete=N\u00e3o foi poss\u00edvel excluir {0}: {1} - - -View.Permissions.Title=Vis\u00e3o -Permalink.LastBuild=\u00daltimo build -Permalink.LastStableBuild=\u00daltimo build est\u00e1vel -Permalink.LastSuccessfulBuild=\u00daltimo build bem sucedido -Permalink.LastFailedBuild=\u00daltimo build que falhou -# Waiting for next available executor -Queue.WaitingForNextAvailableExecutor=Esperando pelo pr\u00f3ximo executor dispon\u00edvel -# {0} {0,choice,0#tests|1#test|1Failed to resolve host name {0}. \ -# -UpdateCenter.Status.UnknownHostException=Erro ao resolver o nome do host {0}. \ - -# \ -# Your container doesn''t use UTF-8 to decode URLs. If you use non-ASCII characters as a job name etc, \ -# this will cause problems. \ -# See Containers and \ -# Tomcat i18n for more details. -Hudson.NotUsesUTF8ToDecodeURL=n\u00e3o use caracteres UTF-8 nas URLs -# Checking internet connectivity -UpdateCenter.Status.CheckingInternet=Checando conex\u00e3o com a Internet -# \ -# This permission allows users to delete existing views. -View.DeletePermission.Description=Permite aos usu\u00e1rios removerem as Views -# Checking jenkins-ci.org connectivity -UpdateCenter.Status.CheckingJavaNet=Verificando conectividade com o site jenkins-ci.org -# Authentication and User Management -UpdateCenter.PluginCategory.user= Autentica\u00e7\u00e3o de gerenciamento de usu\u00e1rio -# My View -MyView.DisplayName=Minha view -# Files in this directory will be served under your http://server/hudson/userContent/ -Hudson.USER_CONTENT_README=Arquivos que ser\u00e3o disponibilizados no seu endere\u00e7o http://server/hudson/ArquivosDoUsuario/ -# Source Code Management related -UpdateCenter.PluginCategory.scm-related=Gerenciamento de c\u00f3digo fonte -# Upstream project {0} is already building. -AbstractProject.UpstreamBuildInProgress=Projeto {0} j\u00e1 esta em builds -# A view with name {0} does not exist -MyViewsProperty.ViewExistsCheck.NotExist= A view {0} n\u00e3o existe -# {0} {0,choice,0#test failures|1#test failure|1Erro ao resolver o nome do hospedeiro {0}. \ + Talvez voc\u00EA precise configurar um proxy HTTP? +Hudson.NotUsesUTF8ToDecodeURL=n\u00E3o use caracteres UTF-8 nas URLs +UpdateCenter.Status.CheckingInternet=Checando conex\u00E3o com a Internet +View.DeletePermission.Description=\ + Esta permiss\u00E3o concede direito aos usu\u00E1rios de apagarem vis\u00F5es existentes. +UpdateCenter.Status.CheckingJavaNet=Verificando conectividade com o centro de atualiza\u00E7\u00E3o +UpdateCenter.PluginCategory.user= Autentica\u00E7\u00E3o de gerenciamento de usu\u00E1rio +MyView.DisplayName=Minha vis\u00E3o +Hudson.USER_CONTENT_README=Arquivos que ser\u00E3o disponibilizados no seu endere\u00E7o http://server/hudson/ArquivosDoUsuario/ +UpdateCenter.PluginCategory.scm-related=Gerenciamento de c\u00F3digo fonte +AbstractProject.UpstreamBuildInProgress=Projeto {0} j\u00E1 est\u00E1 em constru\u00E7\u00E3o +MyViewsProperty.ViewExistsCheck.NotExist= A vis\u00E3o {0} n\u00E3o existe +AbstractItem.NoSuchJobExists=n\u00E3o existe o trabalho ''{0}'' Run.Summary.BackToNormal=Voltar ao normal -# Boolean Value BooleanParameterDefinition.DisplayName=Valor booleano -# Build Wrappers UpdateCenter.PluginCategory.buildwrapper=Construir pacotes -# \ -# The read permission is necessary for viewing almost all pages of Jenkins. \ -# This permission is useful when you don''t want unauthenticated users to see \ -# Jenkins pages — revoke this permission from the anonymous user, then \ -# add "authenticated" pseudo-user and grant the read access. -Hudson.ReadPermission.Description=Permiss\u00e3o de leitura -# Node is being removed -Hudson.NodeBeingRemoved=O n\u00f3 est\u00e1 sendo removido -# A view already exists with the name "{0}" -Hudson.ViewAlreadyExists=J\u00e1 existe uma View com esse nome "{0}" -# Build Notifiers -UpdateCenter.PluginCategory.notifier=Notificacao de builds -# Provisioned from {0} +Hudson.ReadPermission.Description=\ + A permiss\u00E3o de leitura \u00E9 necess\u00E1ria para ver praticamente todas as p\u00E1ginas\ + do Jenkins. Esta permiss\u00E3o \u00E9 \u00FAtil quando voc\u00EA n\u00E3o quer que usu\u00E1rios \ + n\u00E3o-autenticados veja as p\u00E1ginas do Jenkins: revogue essa permiss\u00E3o para \ + o usu\u00E1rio an\u00F4nimo ent\u00E3o adicione o pseudo usu\u00E1rio "autenticado" e conceda \ + o direito de leitura. +Hudson.NodeBeingRemoved=O n\u00F3 est\u00E1 sendo removido +Hudson.ViewAlreadyExists=J\u00E1 existe uma vis\u00E3o com esse nome "{0}" +UpdateCenter.PluginCategory.notifier=Notificacao de constru\u00E7\u00F5es Label.ProvisionedFrom=Aprovisionado para {0} -# aborted Run.Summary.Aborted=Abortado -# Build Reports -UpdateCenter.PluginCategory.report=Relat\u00f3rio de builds -# Source Code Management -UpdateCenter.PluginCategory.scm=Gerenciamento de c\u00f3digo fonte -# \ -# This permission allows users to change the configuration of views. -View.ConfigurePermission.Description=Permite aos usu\u00e1rios configurar as views -# Scheduling a new build to get a workspace. -AbstractProject.NewBuildForWorkspace=Agendando uma novo build para obter um novo workspace -# {0} doesn''t have label {1} -Node.LabelMissing=R\u00f3tulo n\u00e3o encontrado -# {0} is reserved for jobs tied to it +UpdateCenter.PluginCategory.report=Relat\u00F3rio de constru\u00E7\u00F5es +UpdateCenter.PluginCategory.scm=Gerenciamento de c\u00F3digo fonte +View.ConfigurePermission.Description=\ + Permite aos usu\u00E1rios configurar as vis\u00F5es. +AbstractProject.NewBuildForWorkspace=Agendando uma nova constru\u00E7\u00E3o para obter um novo espa\u00E7o de trabalho +Node.LabelMissing=R\u00F3tulo n\u00E3o encontrado Node.BecauseNodeIsReserved={0} foi reservado para trabalhos vinculados -# Started by remote host {0} with note: {1} -Cause.RemoteCause.ShortDescriptionWithNote=Host remoto {0} iniciado com a nota: {1} -# Password Parameter -PasswordParameterDefinition.DisplayName=Par\u00e2metro da senha -# {0} more {0,choice,0#tests are|1#test is|1configure HTTP proxy? -UpdateCenter.Status.ConnectionFailed=Erro ao conectar {0} / -# Maven +UpdateCenter.Status.ConnectionFailed=\ + Erro ao conectar em {0}. \ + Talvez vo\u00EA precise configurar um proxy HTTP? UpdateCenter.PluginCategory.maven=Maven -# Artifact Uploaders UpdateCenter.PluginCategory.upload=Carregadores de artefatos -# Last unstable build -Permalink.LastUnstableBuild=\u00daltimo build inst\u00e1vel -# ? +Permalink.LastUnstableBuild=\u00DAltima constru\u00E7\u00E3o inst\u00E1vel Run.Summary.Unknown=? -# Parameters -# \ -# This permission grants the ability to start a new build. -AbstractProject.BuildPermission.Description=Permiss\u00e3o para iniciar um novo build -# Are you sure you want to use network mounted file system for FS root? Note that this directory does not need to be visible to the master. -Slave.Network.Mounted.File.System.Warning=Tem certeza que quer usar uma parti\u00e7\u00e3o da rede para seu FS ROOT? -# group of {0} +AbstractProject.BuildPermission.Description=\ + Permiss\u00E3o para iniciar um novo build +Slave.Network.Mounted.File.System.Warning=Tem certeza que quer usar um sistema de arquivos de rede montado como seu sistema de arquivos raiz? Note que este diret\u00F3rio n\u00E3o precisa ser vis\u00EDvel para o controlador. Label.GroupOf=Grupo de {0} -# All nodes of label ''{0}'' are offline -Queue.AllNodesOffline=Todos os rotulos ''{0}'' est\u00e3o offline. -# Busy executors +Queue.AllNodesOffline=Todos os rotulos ''{0}'' est\u00E3o fora de servi\u00E7o. LoadStatistics.Legends.BusyExecutors=Executores ocupados. ManageJenkinsAction.DisplayName=Gerenciar Jenkins -# Workspace of {0} AbstractProject.WorkspaceTitle=Workspace de {0} -# List view columns -UpdateCenter.PluginCategory.listview-column=Lista as colunas da view -# {0} is waiting for a checkpoint on {1} -Run._is_waiting_for_a_checkpoint_on_={0} est\u00e1 aguardando por um checkpoint em {1} -# \ in workspace {0} -AbstractBuild.BuildingInWorkspace=\ no workspace {0} -# Jenkins is restarting -Jenkins.IsRestarting=O Jenkins est\u00e1 reiniciando -# Awaiting build to get a workspace. -AbstractProject.AwaitingBuildForWorkspace=Aguardando o build obter um workspace. -# You must use the Save button if you wish to rename a job. -Job.you_must_use_the_save_button_if_you_wish=Voc\u00ea deve usar o bot\u00e3o Salvar se deseja renomear um job. -# Item +UpdateCenter.PluginCategory.listview-column=Lista as colunas da vis\u00E3o +Run._is_waiting_for_a_checkpoint_on_={0} est\u00E1 aguardando por um ponto de verifica\u00E7\u00E3o em {1} +AbstractBuild.BuildingInWorkspace=\ no espa\u00E7o de trabalho {0} +Jenkins.IsRestarting=O Jenkins est\u00E1 reiniciando +AbstractProject.AwaitingBuildForWorkspace=Aguardando a constru\u00E7\u00E3o obter um espa\u00E7o de trabalho. +Job.you_must_use_the_save_button_if_you_wish=Voc\u00EA deve usar o bot\u00E3o Salvar se deseja renomear um job. AbstractItem.Pronoun=job -# Building AbstractBuild_Building=Construindo -# Create a new job. Item.CREATE.description=Cria um novo job. -# The remote root must be an absolute path. -Slave.the_remote_root_must_be_an_absolute_path=A raiz remota deve ser um caminho absoluto. -# See a job. (You may deny this permission but allow Discover to force an anonymous user to log in to see the job.) -Item.READ.description=Ver um job. (Voc\u00ea pode impedir essa permiss\u00e3o mas permitir Discover para forcar um usu\u00e1rio an\u00f4nimo a logar para ver o job) -# This permission grants the ability to retrieve the artifacts produced by \ -# builds. If you don\u2019t want an user to access the artifacts, you can do so by \ -# revoking this permission. -Run.ArtifactsPermission.Description=Esta permiss\u00e3o permite a habilidade de obter os artefatos produzidos por \ - builds. Se voc\u00ea n\u00e3o quer que um usu\u00e1rio accesse os artefatos, voc\u00ea pode \ - revogar esta permiss\u00e3o. -# Invalid boolean expression: {0} -LabelExpression.InvalidBooleanExpression=Espress\u00e3o booleana inv\u00e1lida: {0} -# originally caused by: +Item.READ.description=Ver um job. (Voc\u00EA pode impedir essa permiss\u00E3o mas permitir Discover para forcar um usu\u00E1rio an\u00F4nimo a logar para ver o job) +Run.ArtifactsPermission.Description=\ + Esta permiss\u00E3o concede a habilidade de obter os artefatos produzidos por \ + constru\u00E7\u00F5es. Voc\u00EA pode revogar essa permiss\u00E3o caso n\u00E3o queira que um \ + usu\u00E1rio tenha acesso aos artefatos. +LabelExpression.InvalidBooleanExpression=Espress\u00E3o booleana inv\u00E1lida: {0} Cause.UpstreamCause.CausedBy=originalmente causado por: -# Invalid token provided. -BuildAuthorizationToken.InvalidTokenProvided=Token inv\u00e1lido fornecido. -# Text Parameter -TextParameterDefinition.DisplayName=Par\u00e2metro de texto +BuildAuthorizationToken.InvalidTokenProvided=Token inv\u00E1lido fornecido. +TextParameterDefinition.DisplayName=Par\u00E2metro de texto # Downloaded Successfully. Will be activated during the next boot -UpdateCenter.DownloadButNotActivated=Download finalizado com sucesso. Ser\u00e1 ativado no pr\u00f3ximo boot -# {0} doesn\u2019t have a permission to run on {1} -Node.LackingBuildPermission={0} n\u00e3o tem permiss\u00e3o para executar em {1} -# Not built -ResultTrend.NotBuilt=N\u00e3o constru\u00eddo -# There are no nodes with the label \u2018{0}\u2019 -Queue.LabelHasNoNodes=N\u00e3o h\u00e1 n\u00f3s com o r\u00f3tulo \u2018{0}\u2019 -# The display name, "{0}", is already in use by another job and could cause confusion and delay. -Jenkins.CheckDisplayName.DisplayNameNotUniqueWarning=O nome de exibi\u00e7\u00e3o "{0}", est\u00e1 em uso atualmente por outro job e pode causar confus\u00e3o e atrazo. -# Not built -BallColor.NotBuilt=N\u00e3o constru\u00eddo -# We need to schedule a new build to get a workspace, but deferring {0}ms in the hope that one will become available soon -AbstractProject.AwaitingWorkspaceToComeOnline=\u00c9 necess\u00e1rio agendar um novo build para obter um workspace, mas adiando {0}ms na esperan\u00e7a que um esteja dispon\u00edvel em breve -# Success +UpdateCenter.DownloadButNotActivated=Baixa de atualiza\u00E7\u00E3o finalizada com sucesso. Ser\u00E1 ativada na pr\u00F3xima reinicializa\u00E7\u00E3o +Node.LackingBuildPermission={0} n\u00E3o tem permiss\u00E3o para executar em {1} +ResultTrend.NotBuilt=N\u00E3o constru\u00EDdo +Queue.LabelHasNoNodes=N\u00E3o h\u00E1 n\u00F3s com o r\u00F3tulo \u2018{0}\u2019 +Jenkins.CheckDisplayName.DisplayNameNotUniqueWarning=O nome de exibi\u00E7\u00E3o "{0}", est\u00E1 em uso atualmente por outro job e pode causar confus\u00E3o e atraso. +BallColor.NotBuilt=N\u00E3o constru\u00EDdo +AbstractProject.AwaitingWorkspaceToComeOnline=\u00C9 necess\u00E1rio agendar uma nova constru\u00E7\u00E3o para obter um espa\u00E7o de trabalho mas adiando em {0}ms na esperan\u00E7a que um esteja dispon\u00EDvel em breve ResultTrend.Success=Sucesso -# N/A UpdateCenter.n_a=N/D -# Fixed ResultTrend.Fixed=Resolvido -# Now unstable -ResultTrend.NowUnstable=Inst\u00e1vel agora -# Unstable -ResultTrend.Unstable=Inst\u00e1vel -# Downstream project {0} is already building. -AbstractProject.DownstreamBuildInProgress=Projeto descendente {0} j\u00e1 est\u00e1 em constru\u00e7\u00e3o. -# (from {0}) +ResultTrend.NowUnstable=Inst\u00E1vel agora +ResultTrend.Unstable=Inst\u00E1vel +AbstractProject.DownstreamBuildInProgress=Projeto descendente {0} j\u00E1 est\u00E1 em constru\u00E7\u00E3o. Descriptor.From=(de {0}) -# This permission grants discover access to jobs. Lower than read permissions, it allows you to \ -# redirect anonymous users to the login page when they try to access a job url. \ -# Without it they would get a 404 error and wouldn't be able to discover project names. -AbstractProject.DiscoverPermission.Description=Esta permiss\u00e3o deixa descobrir accesso aos jobs. Menor que permiss\u00f5es de leitura, permite que \ - usu\u00e1rios an\u00f4nimos sejam redirecionados \u00e0 p\u00e1gina de login quando tentam acessar a URL de um job. \ - Sem isso eles receberiam um erro 404 e n\u00e3o seriam capazes de rescobrir nomes de projetos. -# not built -Run.Summary.NotBuilt=N\u00e3o constru\u00eddos -# Failure +AbstractProject.DiscoverPermission.Description=\ + Esta permiss\u00E3o concede o accesso de descoberta de jobs. Menos que permiss\u00F5es de leitura, \ + permite que voc\u00EA redirecione usu\u00E1rios an\u00F4nimos \u00E0 p\u00E1gina de entrada quando eles tentam \ + acessar a URL de um job. Sem isso eles receberiam um erro 404 e n\u00E3o seriam capazes \ + de descobrir nomes de projetos. +Run.Summary.NotBuilt=N\u00E3o constru\u00EDdos ResultTrend.Failure=Falha -# This permission grants the ability to wipe out the contents of a workspace. -AbstractProject.WipeOutPermission.Description=Esta permiss\u00e3o deixa que seja eleminado o conte\u00fado de um workspace. -# Requires Choices. +AbstractProject.WipeOutPermission.Description=\ + Esta permiss\u00E3o concede a capacidade de eliminar o conte\u00FAdo de um espa\u00E7o de trabalho. ChoiceParameterDefinition.MissingChoices=Exige escolhas. -# Aborted ResultTrend.Aborted=Abortado -# This permission allows users to see views (implied by generic read access). -View.ReadPermission.Description=Esta permiss\u00e3o deixa que usu\u00e1rios vejam views (inpl\u00edcito pela permiss\u00e3o gen\u00e9rica de leitura). -# "{0}" is not allowed name -Jenkins.NotAllowedName="{0}" n\u00e3o \u00e9 um nome permitido -# Workspace of {0} on {1} +View.ReadPermission.Description=\ + Esta permiss\u00E3o deixa que usu\u00E1rios vejam views (inpl\u00EDcito pela permiss\u00E3o gen\u00E9rica de leitura). +Jenkins.NotAllowedName="{0}" n\u00E3o \u00E9 um nome permitido AbstractProject.WorkspaceTitleOnComputer=Workspace {0} em {1} -# This permission grants the ability to cancel a scheduled, or abort a running, build. -AbstractProject.CancelPermission.Description=Esta permiss\u00e3o deixa que seja cancelado um build agendado ou abortado um em execu\u00e7\u00e3o. -# The display name, "{0}", is used as a name by a job and could cause confusing search results. -Jenkins.CheckDisplayName.NameNotUniqueWarning=O nome de exibi\u00e7\u00e3o "{0}", \u00e9 usado por um job e pode causar confus\u00e3o nos resultados da pesquisa. -# Custom workspace is empty. -AbstractProject.CustomWorkspaceEmpty=O workspace customizado est\u00e1 vazio. -# Artifacts of {0} {1} +AbstractProject.CancelPermission.Description=\ + Esta permiss\u00E3o deixa que seja cancelado uma constru\u00E7\u00E3o agendada ou abortar uma em execu\u00E7\u00E3o. +Jenkins.CheckDisplayName.NameNotUniqueWarning=O nome de exibi\u00E7\u00E3o "{0}", \u00E9 usado por um job e pode causar confus\u00E3o nos resultados da pesquisa. +AbstractProject.CustomWorkspaceEmpty=O espa\u00E7o de trabalho customizado est\u00E1 vazio. Run.ArtifactsBrowserTitle=Artefatos de {0} {1} -# Build with Parameters -# Still unstable -ResultTrend.StillUnstable=Ainda inst\u00e1vel -# Running as {0} +ResultTrend.StillUnstable=Ainda inst\u00E1vel Run.running_as_=Executando como {0} -# Still failing ResultTrend.StillFailing=Ainda falhando -# Change the configuration of a job. -Item.CONFIGURE.description=Mudar a configura\u00e7\u00e3o de um job. -# Delete a job. -Item.DELETE.description=Excuir um job. -HealthReport.EmptyString= +Item.CONFIGURE.description=Mudar a configura\u00E7\u00E3o de um job. +Item.DELETE.description=Excluir um job. +ParametersDefinitionProperty.DisplayName=Esta constru\u00E7\u00E3o \u00E9 parametrizada +Computer.NoSuchSlaveExistsWithoutAdvice=Nenhum agente "{0}" existe. +Slave.InvalidConfig.NoName=Configura\u00E7\u00E3o de agente inv\u00E1lida. Nome est\u00E1 vazio +ManagementLink.Category.TROUBLESHOOTING=Resolu\u00E7\u00E3o de erros +ManagementLink.Category.STATUS=Informa\u00E7\u00E3o de estado +Item.RENAME.description=Renomear um job +FileParameterValue.IndexTitle=Par\u00E2metros de arquivo +LabelExpression.LabelLink=R\u00F3tulo {1} combina {3,choice,0#no nodes|1#1 node|1<{3} nodes}{4,choice,0#|1# and 1 cloud|1< and {4} clouds}. \ + Permiss\u00F5es e outras restri\u00E7\u00F5es fornecidas por extens\u00F5es pode reduzir ainda mais essa lista. +AbstractItem.NoSuchJobExistsWithoutSuggestion=Nenhum job '{0}' existe. +UpdateCenter.PluginCategory.groovy-related=Relacionado ao Groovy +Queue.FinishedWaiting=Terminou de aguardar +Slave.Remote.Relative.Path.Warning=Voc\u00EA tem certeza de que quer usar um caminho relativo para o sistema de arquivos raiz? Perceba que \ + caminhos relativos requerem que voc\u00EA tenha certeza que o lan\u00E7ador selecionado provenha um diret\u00F3rio atual consistente. Usar \ + um caminho absoluto \u00E9 altamente recomend\u00E1vel. +LabelExpression_ObsoleteMasterLabel=Esta express\u00E3o inclui o r\u00F3tulo mestre que n\u00E3o \u00E9 mais utilizado. Utilize embutido \ + no lugar. Veja mais informa\u00E7\u00F5es. +Hudson.MustBeAtLeast=Precisa ser {0} ou maior +Queue.ExceptionCanRun=Exce\u00E7\u00E3o de avalia\u00E7\u00E3o se a fila pode executar a tarefa MultiStageTimeSeries.EMPTY_STRING= -ParametersDefinitionProperty.DisplayName=Este build \u00e9 parametrizado +TimeZoneProperty.DisplayName=Fuso hor\u00E1rio definido pelo usu\u00E1rio +UpdateCenter.PluginCategory.theme=Temas de interface de usu\u00E1rio +Node.Mode.NORMAL=Usar este n\u00F3 o m\u00E1ximo poss\u00EDvel +UpdateCenter.PluginCategory.database=Banco de dados +CLI.online-node.shortDescription=Continue usando o n\u00F3 para realizar constru\u00E7\u00F5es para cancelar o comando anterior de "n\u00F3 fora de servi\u00E7o". +AbstractItem.FailureToStopBuilds=Falha ao tentar interromper e parar \ + {0,choice,1#{0,number,integer} build|1<{0,number,integer} builds} de {1} +Computer.DisconnectPermission.Description=Esta permiss\u00E3o concede aos usu\u00E1rios a capacidade de desconectar agentes ou marcar agentes como temporariamente fora de servi\u00E7o. +ManagementLink.Category.CONFIGURATION=Configura\u00E7\u00E3o de sistema +Computer.Permissions.Title=Agente +UpdateCenter.PluginCategory.dotnet=Desenvolvimento .NET +UpdateCenter.CoreUpdateMonitor.DisplayName=Notifica\u00E7\u00E3o de atualiza\u00E7\u00E3o do Jenkins +LabelExpression.NoMatch_DidYouMean=Nenhum agente/nuvem combina com esta express\u00E3o de r\u00F3tulo. Voc\u00EA quis dizer '{1}' ao inv\u00E9s de '{0}'? +User.IllegalFullname="{0}" est\u00E1 proibido como um nome completo por raz\u00F5es de seguran\u00E7a. +Queue.executor_slot_already_in_use=Abertura para executor j\u00E1 em uso +AbstractItem.TaskNoun=Construir +Queue.node_has_been_removed_from_configuration={0} foi removido da configura\u00E7\u00E3o +ManagementLink.Category.TOOLS=Ferramentas e a\u00E7\u00F5es +Computer.BadChannel=N\u00F3 de agente fora de servi\u00E7o ou n\u00E3o \u00E9 um canal remoto (como o n\u00F3 embutido). +UpdateCenter.PluginCategory.ios=Desenvolvimento iOS +UpdateCenter.PluginCategory.devsecops=DevSecOps +UpdateCenter.PluginCategory.deployment=Implanta\u00E7\u00E3o +TimeZoneProperty.current_time_in_=Hora atual em {0}: {1} +Queue.ExceptionCanTake=Exce\u00E7\u00E3o durante avalia\u00E7\u00E3o se o n\u00F3 pode cuidar da tarefa +UpdateCenter.PluginCategory.test=Testando +Api.WrapperParamInvalid=O par\u00E2metro de inv\u00F3lucro pode contem apenas caracteres alfanum\u00E9ricos e tra\u00E7o/ponto/sublinhado. O primeiro caracter ter que ser uma letra ou sublinhado. +Hudson.MustBeAtMost=Precisa ser {0} ou menos +ItemGroupMixIn.may_not_copy_as_it_contains_secrets_and_=Pode n\u00E3o conseguir copiar {0} j\u00E1 que contem segredos e {1} tem {2}/{3} mas n\u00E3o /{4} +Computer.NoSuchSlaveExists=Nenhum agente "{0}" existe. Voc\u00EA quiser dizer "{1}"? +LoadStatistics.Legends.OnlineExecutors=Executores ligados +View.DisplayNameNotUniqueWarning=O nome de exibi\u00E7\u00E3o "{0}" j\u00E1 est\u00E1 em uso por outra vis\u00E3o e \ + pode causar confus\u00E3o e demora. +ComputerSet.SpecifySlaveToCopy=Especifique qual agente copiar +UpdateCenter.PluginCategory.devops=DevOps +LoadStatistics.Legends.IdleExecutors=Executores ociosos +UpdateCenter.PluginCategory.ruby=Desenvolvimento em Ruby +UpdateCenter.PluginCategory.agent=Gerenciamento de agente +LoadStatistics.Legends.DefinedExecutors=Executores definidos +Run.NotStartedYet=Ainda n\u00E3o iniciado +Computer.ExtendedReadPermission.Description=Esta permiss\u00E3o concede direito para usu\u00E1rios lerem a configura\u00E7\u00E3o do agente. +TimeZoneProperty.current_time_on_server_in_in_proposed_di=Hora atual no servidor {0}: {1}; na exibi\u00E7\u00E3o de zona proposta: {2} +UpdateCenter.PluginCategory.android=Desenvolvimento em Android +Computer.ConnectPermission.Description=Esta permiss\u00E3o concede direito para usu\u00E1rios se conectarem com agentes ou marcarem agentes com ligados +ManagementLink.Category.UNCATEGORIZED=N\u00E3o categorizado +UpdateCenter.PluginCategory.scala=Desenvolvimento em Scala +Hudson.RunScriptsPermission.Description= \ + Descontinuado - por favor use a permiss\u00E3o Global/Administrador no lugar +Computer.CreatePermission.Description=Esta permiss\u00E3o concede o direito de usu\u00E1rios criarem agentes. +TopLevelItemDescriptor.NotApplicableIn={0} itens n\u00E3o s\u00E3o compat\u00EDveis com {1} +UpdateCenter.PluginCategory.security=Seguran\u00E7a +Computer.Caption=Agente {0} +UpdateCenter.DisplayName=Centro de atualiza\u00E7\u00E3o +Jenkins.SystemRead.Description= \ + Esta permiss\u00E3o concede acesso de somente leitura para vastas partes da configura\u00E7\u00E3o global do sistema. +Slave.InvalidConfig.Executors=Configura\u00E7\u00E3o de agente inv\u00E1lida para {0}. N\u00FAmero inv\u00E1lido de executores. +UpdateCenter.PluginCategory.python=Desenvolvimento em Python +LabelExpression.NoMatch=Nenhum agente/nuvem combina com esta express\u00E3o de r\u00F3tulo. +Computer.ConfigurePermission.Description=Esta permiss\u00E3o concede direto a usu\u00E1rios o direito de configurar agentes. +ManagementLink.Category.MISC=Outro +User.IllegalUsername="{0}" \u00E9 proibindo como nome de usu\u00E1rio por raz\u00F5es de seguran\u00E7a. +Hudson.TrailingDot=Um nome n\u00E3o pode come\u00E7ar com '.' +UpdateCenter.PluginCategory.parameter=Par\u00E2metros de constru\u00E7\u00E3o +Run.running_as_SYSTEM=Rodando como SISTEMA +AbstractItem.NewNameUnchanged=O novo nome \u00E9 igual ao nome atual. +Slave.WindowsSlave=Este \u00E9 um agente Windows +CLI.clear-queue.shortDescription=Limpa a fila de constru\u00E7\u00E3o. +Permalink.LastCompletedBuild=\u00DAltima constru\u00E7\u00E3o completada. +HealthReport.EmptyString= +JDK.DisplayName=JDK +TimeZoneProperty.DisplayDefaultTimeZone=Padr\u00E3o +AbstractItem.BeingDeleted={0} est\u00E1 atualmente sendo apagado +Node.BecauseNodeIsNotAcceptingTasks='{0}' n\u00E3o est\u00E1 aceitando tarefas +LoadStatistics.Legends.ConnectingExecutors=Executores conectando +AbstractProject.PollingVetoed=Sondagem do SCM vetada por {0} +Jenkins.Manage.Description= \ + Esta permiss\u00E3o concede a habilidade de configurar partes da configura\u00E7\u00E3o global do sistema \ + onde n\u00E3o se espera que hajam impactos na estabilidade global e de seguran\u00E7a do sistema. +UpdateCenter.PluginCategory.orchestration=Orquestra\u00E7\u00E3o +UpdateCenter.PluginCategory.runcondition=Condi\u00E7\u00F5es de execu\u00E7\u00E3o para a extens\u00E3o Run Condition +ManagementLink.Category.SECURITY=Seguran\u00E7a +Computer.DeletePermission.Description=Esta permiss\u00E3o concede a usu\u00E1rios o direito de apagar agentes existentes. +Computer.BuildPermission.Description=Esta permiss\u00E3o concede a usu\u00E1rios o direito de executar jobs como eles em agentes. +Slave.Terminated=O agente {0} foi terminado +UpdateCenter.PluginCategory.view=Vis\u00F5es +UpdateCenter.PluginCategory.api-plugin=Biblioteca de extens\u00F5es (para usar com outras extens\u00F5es) +UpdateCenter.PluginCategory.cloud=Provedores de nuvem +LoadStatistics.Legends.AvailableExecutors=Executores dispon\u00EDveis +Slave.UnixSlave=Este \u00E9 um agente Unix +Build.post_build_steps_failed=Passos p\u00F3s constru\u00E7\u00E3o falharam diff --git a/core/src/main/resources/hudson/model/Messages_sr.properties b/core/src/main/resources/hudson/model/Messages_sr.properties index 53af2dab99fc..ec285a88bbe3 100644 --- a/core/src/main/resources/hudson/model/Messages_sr.properties +++ b/core/src/main/resources/hudson/model/Messages_sr.properties @@ -27,7 +27,7 @@ UpdateCenter.PluginCategory.deployment=\u0418\u043D\u0441\u0442\u0430\u043B\u043 UpdateCenter.PluginCategory.external=\u0418\u043D\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0458\u0430 \u0435\u043A\u0441\u0442\u0435\u0440\u043D\u0438\u043C \u0441\u0435\u0440\u0432\u0438\u0441\u0438\u043C\u0430 \u0438 \u0430\u043B\u0430\u0442\u0438\u043C\u0430 UpdateCenter.PluginCategory.groovy-related=\u0423 \u0432\u0435\u0437\u0438 \u0441\u0430 Groovy UpdateCenter.PluginCategory.ios=iOS \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u0438\u0440\u0430\u045A\u0435 -UpdateCenter.PluginCategory.library=\u0411\u0438\u0431\u043B\u0438\u043E\u0442\u0435\u043A\u0435 \u0437\u0430 \u043C\u043E\u0434\u0443\u043B\u0435 (\u0443 \u043A\u043E\u0440\u0438\u0441\u0442 \u0434\u0440\u0443\u0433\u0438\u0445 \u043C\u043E\u0434\u0443\u043B\u0430) +UpdateCenter.PluginCategory.api-plugin=\u0411\u0438\u0431\u043B\u0438\u043E\u0442\u0435\u043A\u0435 \u0437\u0430 \u043C\u043E\u0434\u0443\u043B\u0435 (\u0443 \u043A\u043E\u0440\u0438\u0441\u0442 \u0434\u0440\u0443\u0433\u0438\u0445 \u043C\u043E\u0434\u0443\u043B\u0430) UpdateCenter.PluginCategory.maven=Maven UpdateCenter.PluginCategory.cluster=\u0423\u043F\u0440\u0430\u0432\u0459\u0430\u045A\u0435 \u043A\u043B\u0430\u0441\u0442\u0435\u0440\u0430 \u0438 \u0440\u0430\u0441\u043F\u043E\u0434\u0435\u0459\u0435\u043D\u043E \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 UpdateCenter.PluginCategory.android=Android \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u0438\u0440\u0430\u045A\u0435 @@ -38,7 +38,7 @@ UpdateCenter.PluginCategory.scm=\u0421\u0438\u0441\u0442\u0435\u043C \u0437\u043 UpdateCenter.PluginCategory.scala=Scala \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u0438\u0440\u0430\u045A\u0435 UpdateCenter.PluginCategory.scm-related=\u0412\u0435\u0437\u0430\u043D\u043E \u0441\u0430 \u0441\u0438\u0441\u0442\u0435\u043C\u043E\u043C \u0437\u0430 \u0443\u043F\u0440\u0430\u0432\u0459\u0430\u045A\u0435 \u0438\u0437\u0432\u043E\u0440\u043D\u043E\u0433 \u043A\u043E\u0434\u0430 UpdateCenter.PluginCategory.security=\u0411\u0435\u0437\u0431\u0435\u0434\u043D\u043E\u0441\u0442 -UpdateCenter.PluginCategory.slaves=\u041F\u043E\u043A\u0440\u0435\u0442\u0430\u045A\u0435 \u0438 \u0443\u043F\u0440\u0430\u0432\u0459\u0430\u045A\u0435 \u0430\u0433\u0435\u043D\u0430\u0442\u0430 +UpdateCenter.PluginCategory.agent=\u041F\u043E\u043A\u0440\u0435\u0442\u0430\u045A\u0435 \u0438 \u0443\u043F\u0440\u0430\u0432\u0459\u0430\u045A\u0435 \u0430\u0433\u0435\u043D\u0430\u0442\u0430 UpdateCenter.PluginCategory.test=\u0422\u0435\u0441\u0442\u0438\u0440\u0430\u045A\u0435 UpdateCenter.PluginCategory.trigger=\u0410\u0443\u0442\u043E\u043C\u0430\u0442\u0441\u043A\u0438 \u0441\u0442\u0430\u0440\u0442 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 \u043D\u0430\u043F\u0430\u0441\u0432\u0430= @@ -111,8 +111,8 @@ Hudson.NotANumber=\u041D\u0438\u0458\u0435 \u0431\u0440\u043E\u0458\u043A\u0430 Hudson.NotAPositiveNumber=\u041D\u0438\u0458\u0435 \u043F\u043E\u0437\u0438\u0442\u0438\u0432\u0430\u043D \u0431\u0440\u043E\u0458. Hudson.NotANonNegativeNumber=\u0411\u0440\u043E\u0458 \u043D\u0435\u043C\u043E\u0436\u0435 \u0431\u0438\u0442\u0438 \u043D\u0435\u0433\u0430\u0442\u0438\u0432\u0430\u043D. Hudson.NotANegativeNumber=\u041D\u0438\u0458\u0435 \u043D\u0435\u0433\u0430\u0442\u0438\u0432\u0430\u043D \u0431\u0440\u043E\u0458. -Hudson.NotUsesUTF8ToDecodeURL=URL \u0430\u0434\u0440\u0435\u0441\u0435 \u0432\u0430\u0448\u0435\u0433 \u043A\u043E\u043D\u0442\u0435\u0458\u043D\u0435\u0440\u0430 \u043D\u0438\u0441\u0443 \u0443\u043D\u0435\u0448\u0435\u043D\u0438 \u043F\u043E \u0444\u043E\u0440\u043C\u0430\u0442\u0443 UTF-8. \u0418\u043C\u0435\u043D\u0430 \u0441\u0430 \u0437\u043D\u0430\u0446\u0438\u043C\u0430 \u0438\u0437\u0432\u0430\u043D ASCII \u043C\u043E\u0433\u0443 \u0438\u0437\u0430\u0437\u0432\u0430\u0442\u0438 \u043F\u0440\u043E\u0431\u043B\u0435\u043C\u0435. \u041C\u043E\u043B\u0438\u043C\u043E \u0432\u0430\u0441 \u043F\u0440\u043E\u0447\u0438\u0442\u0430\u0458\u0442\u0435 Containers \u0438 \ - Tomcat i18n. +Hudson.NotUsesUTF8ToDecodeURL=URL \u0430\u0434\u0440\u0435\u0441\u0435 \u0432\u0430\u0448\u0435\u0433 \u043A\u043E\u043D\u0442\u0435\u0458\u043D\u0435\u0440\u0430 \u043D\u0438\u0441\u0443 \u0443\u043D\u0435\u0448\u0435\u043D\u0438 \u043F\u043E \u0444\u043E\u0440\u043C\u0430\u0442\u0443 UTF-8. \u0418\u043C\u0435\u043D\u0430 \u0441\u0430 \u0437\u043D\u0430\u0446\u0438\u043C\u0430 \u0438\u0437\u0432\u0430\u043D ASCII \u043C\u043E\u0433\u0443 \u0438\u0437\u0430\u0437\u0432\u0430\u0442\u0438 \u043F\u0440\u043E\u0431\u043B\u0435\u043C\u0435. \u041C\u043E\u043B\u0438\u043C\u043E \u0432\u0430\u0441 \u043F\u0440\u043E\u0447\u0438\u0442\u0430\u0458\u0442\u0435 Containers \u0438 \ + Tomcat i18n. Hudson.AdministerPermission.Description=\u0414\u0430\u0458\u0435 \u043F\u0440\u0430\u0432\u043E \u0434\u0430 \u043C\u0435\u045A\u0430 \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430 \u0441\u0438\u0441\u0442\u0435\u043C\u0430, \u043A\u0430\u043E \u0438 \u043A\u043E\u043C\u043F\u043B\u0435\u0442\u0430\u043D \u043F\u0440\u0438\u0441\u0442\u0443\u043F \u043B\u043E\u043A\u0430\u043B\u043D\u043E\u0433 \u0441\u0438\u0441\u0442\u0435\u043C\u0430 \u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0430 \u0443 \u0458\u0435\u0434\u043D\u0430\u043A\u0435 \u043F\u043E \u043E\u043A\u0432\u0438\u0440\u0443 \u043F\u0440\u0430\u0432\u0430 \u0443 \u0441\u043A\u043B\u0430\u0434\u0443 \u0441\u0430 \u043E\u043F\u0435\u0440\u0430\u0442\u0438\u0432\u043D\u0438 \u0441\u0438\u0441\u0442\u0435\u043C\u043E\u043C. Hudson.ReadPermission.Description= Hudson.NodeDescription=\u0433\u043B\u0430\u0432\u043D\u0430 Jenkins \u043C\u0430\u0448\u0438\u043D\u0430 diff --git a/core/src/main/resources/hudson/model/Messages_zh_TW.properties b/core/src/main/resources/hudson/model/Messages_zh_TW.properties index ac7fe192affe..acef3ae546d0 100644 --- a/core/src/main/resources/hudson/model/Messages_zh_TW.properties +++ b/core/src/main/resources/hudson/model/Messages_zh_TW.properties @@ -113,8 +113,8 @@ Hudson.NotANonNegativeNumber=\u4e0d\u80fd\u70ba\u8ca0\u6578 Hudson.NotANegativeNumber=\u4e0d\u662f\u8ca0\u6578 Hudson.NotUsesUTF8ToDecodeURL=\ \u60a8\u7684\u5bb9\u5668\u4e0d\u662f\u4f7f\u7528 UTF-8 \u89e3\u8b6f URL\u3002\u5982\u679c\u60a8\u5728\u4f5c\u696d\u7b49\u540d\u7a31\u4e2d\u4f7f\u7528\u4e86\u975e ASCII \u5b57\u5143\uff0c\u53ef\u80fd\u6703\u9020\u6210\u554f\u984c\u3002\ - \u8acb\u53c3\u8003 Container \u53ca \ - Tomcat i18n \u8cc7\u6599\u3002 + \u8acb\u53c3\u8003 Container \u53ca \ + Tomcat i18n \u8cc7\u6599\u3002 Hudson.AdministerPermission.Description=\ \u6388\u8207\u8b8a\u66f4\u6574\u500b\u7cfb\u7d71\u8a2d\u5b9a\u7684\u6b0a\u9650\u3002\ \u5305\u62ec\u57f7\u884c\u9ad8\u5ea6\u654f\u611f\u7684\u4f5c\u696d\uff0c\u751a\u81f3\u53ef\u4ee5\u5b58\u53d6\u6574\u500b\u672c\u5730\u7cfb\u7d71 \ diff --git a/core/src/main/resources/hudson/model/ModifiableItemGroup/_api.jelly b/core/src/main/resources/hudson/model/ModifiableItemGroup/_api.jelly index 6d9e72c067c7..b7f5b7b55749 100644 --- a/core/src/main/resources/hudson/model/ModifiableItemGroup/_api.jelly +++ b/core/src/main/resources/hudson/model/ModifiableItemGroup/_api.jelly @@ -27,17 +27,17 @@ THE SOFTWARE.

    Create Job

    - To create a new job, post config.xml to this URL with - query parameter name=JOBNAME. You need to send a Content-Type: application/xml + To create a new job, post config.xml to this URL with + query parameter name=JOBNAME. You need to send a Content-Type: application/xml header. You will get a 200 status code if the creation is successful, - or 4xx/5xx code if it fails. config.xml is the format Jenkins uses to store the project + or 4xx/5xx code if it fails. config.xml is the format Jenkins uses to store the project in the file system, so you can see examples of them in the Jenkins home directory, or by retrieving - the XML configuration of existing jobs from /job/JOBNAME/config.xml. + the XML configuration of existing jobs from /job/JOBNAME/config.xml.

    Copy Job

    To copy a job, send a POST request to this URL with - three query parameters name=NEWJOBNAME&mode=copy&from=FROMJOBNAME + three query parameters name=NEWJOBNAME&mode=copy&from=FROMJOBNAME

    diff --git a/core/src/main/resources/hudson/model/NoFingerprintMatch/index.jelly b/core/src/main/resources/hudson/model/NoFingerprintMatch/index.jelly index 21ceb2d4f7e4..109a94a8113c 100644 --- a/core/src/main/resources/hudson/model/NoFingerprintMatch/index.jelly +++ b/core/src/main/resources/hudson/model/NoFingerprintMatch/index.jelly @@ -25,8 +25,7 @@ THE SOFTWARE. - - + @@ -34,8 +33,7 @@ THE SOFTWARE.

    - - ${%No matching record found} + ${title}

    diff --git a/core/src/main/resources/hudson/model/NoFingerprintMatch/index_zh_TW.properties b/core/src/main/resources/hudson/model/NoFingerprintMatch/index_zh_TW.properties index d1f632d60324..b7a12fe41e3e 100644 --- a/core/src/main/resources/hudson/model/NoFingerprintMatch/index_zh_TW.properties +++ b/core/src/main/resources/hudson/model/NoFingerprintMatch/index_zh_TW.properties @@ -1,17 +1,17 @@ # The MIT License -# +# # Copyright (c) 2013, Chunghwa Telecom Co., Ltd., Pei-Tang Huang -# +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: -# +# # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. -# +# # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,7 +21,6 @@ # THE SOFTWARE. No\ matching\ record\ found=\u6c92\u6709\u7b26\u5408\u7684\u8a18\u9304\u3002 -Back\ to\ Dashboard=\u56de\u5230\u5100\u8868\u677f description=\u6c92\u6709\u4efb\u4f55\u7b26\u5408\u6307\u7d0b {0} \u7684\u8cc7\u6599\u3002 cause.1=\ @@ -30,3 +29,4 @@ cause.1=\ cause.2=\ \u4e5f\u6709\u53ef\u80fd\u662f\u5c08\u6848\u8a2d\u5b9a\u51fa\u4e86\u554f\u984c\uff0c\u4e0d\u6703\u8a18\u9304\u6307\u7d0b\u3002 \ \u8acb\u6aa2\u67e5\u5c08\u6848\u8a2d\u5b9a\u3002 +Back\ to\ Dashboard=\u8fd4\u56de\u8cc7\u8a0a\u4e3b\u9801 diff --git a/core/src/main/resources/hudson/model/Node/help-labelString.html b/core/src/main/resources/hudson/model/Node/help-labelString.html index a7cfc252c15f..1d4adca301bb 100644 --- a/core/src/main/resources/hudson/model/Node/help-labelString.html +++ b/core/src/main/resources/hudson/model/Node/help-labelString.html @@ -3,7 +3,7 @@

    For example, if you have multiple Windows agents and you have a job that must run on Windows, then you could configure all your Windows agents to have - the label windows, and then tie that job to this label. + the label windows, and then tie that job to this label.
    This would ensure that your job runs on one of your Windows agents, but not on any agents without this label. @@ -13,11 +13,11 @@ is installed on the agent.

    Multiple labels must be separated by a space. For example, - windows docker would assign two labels to the agent: windows - and docker. + windows docker would assign two labels to the agent: windows + and docker.

    Labels may contain any non-space characters, but you should avoid special - characters such as any of these: !&|<>(), as other Jenkins + characters such as any of these: !&|<>(), as other Jenkins features allow for defining label expressions, where these characters may be used.

    diff --git a/core/src/main/resources/hudson/model/Node/help-labelString_bg.html b/core/src/main/resources/hudson/model/Node/help-labelString_bg.html index 92be73dc9ff0..3ffc312e39c5 100644 --- a/core/src/main/resources/hudson/model/Node/help-labelString_bg.html +++ b/core/src/main/resources/hudson/model/Node/help-labelString_bg.html @@ -4,7 +4,7 @@

    Например, ако имате множество компютри с Windows и задача за изграждане, която може да се изпълни само под Windows, можете да маркирате машините с етикет - windows и да обвържете задачата с този етикет. + windows и да обвържете задачата с този етикет.
    Така конкретното изграждане ще се изпълни само на машина с такъв етикет.

    @@ -13,10 +13,10 @@ наличието на определена програма на машината и др.

    Множество етикети се въвеждат разделени с интервал. Например: - windows docker означава, че машината има два етикета — windows - и docker. + windows docker означава, че машината има два етикета — windows + и docker.

    Етикетите могат да съдържат произволни знаци, но трябва да избягвате специални - знаци като: !&|<>(), защото Jenkins позволява дефинирането на + знаци като: !&|<>(), защото Jenkins позволява дефинирането на изрази с етикети, в които тези знаци може да се използват.

    diff --git a/core/src/main/resources/hudson/model/Node/help-labelString_it.html b/core/src/main/resources/hudson/model/Node/help-labelString_it.html index b3ede9e95bb1..0ab9c3b533d2 100644 --- a/core/src/main/resources/hudson/model/Node/help-labelString_it.html +++ b/core/src/main/resources/hudson/model/Node/help-labelString_it.html @@ -4,7 +4,7 @@

    Ad esempio, se si dispone di più agenti Windows e di un processo che deve essere eseguito su Windows, è possibile configurare tutti gli agenti Windows - in modo che questi abbiano l'etichetta windows e quindi collegare + in modo che questi abbiano l'etichetta windows e quindi collegare quel processo a quest'etichetta.
    Ciò farebbe sì che il processo venga eseguito su uno degli agenti Windows, @@ -16,12 +16,12 @@ installato un particolare strumento.

    Eventuali etichette multiple devono essere separate da spazi. Ad esempio, - windows docker assegnerebbe due etichette all'agente: - windows e docker. + windows docker assegnerebbe due etichette all'agente: + windows e docker.

    Le etichette possono contenere qualunque carattere diverso da uno spazio, ma sarebbe preferibile evitare i caratteri speciali come questi: - !&|<>(), in quanto altre funzionalità di Jenkins + !&|<>(), in quanto altre funzionalità di Jenkins consentono di definire espressioni etichetta in cui questi caratteri potrebbero essere utilizzati.

    diff --git a/core/src/main/resources/hudson/model/Node/help-labelString_ru.html b/core/src/main/resources/hudson/model/Node/help-labelString_ru.html index 9d6a2098fef3..a59ac7416d2c 100644 --- a/core/src/main/resources/hudson/model/Node/help-labelString_ru.html +++ b/core/src/main/resources/hudson/model/Node/help-labelString_ru.html @@ -2,7 +2,7 @@ Метки (ярлыки) используются для группирования нескольких узлов в одну логическую группу.

    Например, если у вас есть несколько узлов под управлением ОС Windows и проекты, требующие - для сборки эту ОС, вы можете присвоить таким узлам метку windows, + для сборки эту ОС, вы можете присвоить таким узлам метку windows, и затем связать проект с этой меткой.
    Это гарантирует сборку проекта на одном из узлов под управлением ОС Windows, а не на @@ -11,10 +11,10 @@ Метки не обязательно описывают ОС узла: они могут также использоваться для обозначения архитектуры CPU или наличия определённого ПО.

    - Метки разделяются пробелами. Например, строка windows docker пометит узел двумя - метками: windows и docker. + Метки разделяются пробелами. Например, строка windows docker пометит узел двумя + метками: windows и docker.

    Метки могут содержать любые непробельные знаки, однако, следует избегать следующих - специальных символов: !&|<>(), так как они могут быть некорректно + специальных символов: !&|<>(), так как они могут быть некорректно обработаны в других местах. diff --git a/core/src/main/resources/hudson/model/Node/help-name.html b/core/src/main/resources/hudson/model/Node/help-name.html index aa412606d46e..5b39a3eefa91 100644 --- a/core/src/main/resources/hudson/model/Node/help-name.html +++ b/core/src/main/resources/hudson/model/Node/help-name.html @@ -5,6 +5,6 @@ but it is often convenient to make them the same.

    The name may not contain any characters from this list: - ?*/\%!@#$^&|<>[]:; + ?*/\%!@#$^&|<>[]:; diff --git a/core/src/main/resources/hudson/model/Node/help-name_bg.html b/core/src/main/resources/hudson/model/Node/help-name_bg.html index edf4a8f841bf..73cb117aea6d 100644 --- a/core/src/main/resources/hudson/model/Node/help-name_bg.html +++ b/core/src/main/resources/hudson/model/Node/help-name_bg.html @@ -5,6 +5,6 @@ еднакви.

    Името не трябва да съдържа никой от следните знаци: - ?*/\%!@#$^&|<>[]:; + ?*/\%!@#$^&|<>[]:; diff --git a/core/src/main/resources/hudson/model/Node/help-name_it.html b/core/src/main/resources/hudson/model/Node/help-name_it.html index bf44682fbe21..d352329f4c42 100644 --- a/core/src/main/resources/hudson/model/Node/help-name_it.html +++ b/core/src/main/resources/hudson/model/Node/help-name_it.html @@ -6,6 +6,6 @@ applicabile), ma spesso è comodo che coincidano.

    Il nome non può contenere alcun carattere incluso in quest'elenco: - ?*/\%!@#$^&|<>[]:; + ?*/\%!@#$^&|<>[]:; diff --git a/core/src/main/resources/hudson/model/Node/help-name_ru.html b/core/src/main/resources/hudson/model/Node/help-name_ru.html index c789319f388d..1bcea11b8a56 100644 --- a/core/src/main/resources/hudson/model/Node/help-name_ru.html +++ b/core/src/main/resources/hudson/model/Node/help-name_ru.html @@ -5,6 +5,6 @@ присвоен узлу, но обычно принято делать их одинаковыми.

    Имя не может содержать следующие символы: - ?*/\%!@#$^&|<>[]:; + ?*/\%!@#$^&|<>[]:; diff --git a/core/src/main/resources/hudson/model/Node/help-numExecutors.html b/core/src/main/resources/hudson/model/Node/help-numExecutors.html index 62ee113d3564..89d1af51791c 100644 --- a/core/src/main/resources/hudson/model/Node/help-numExecutors.html +++ b/core/src/main/resources/hudson/model/Node/help-numExecutors.html @@ -9,12 +9,12 @@ the second build could take advantage of the spare I/O capacity at that moment.

    - Agents (nodes that are not the master) must have at least one executor. + Agents (nodes that are not the built-in node) must have at least one executor. To temporarily prevent any builds from being executed on an agent, use the Mark this node temporarily offline button on the agent's page.

    - For the master, set the number of executors to zero to prevent it from - executing builds locally. - Note: master will always be able to run flyweight tasks including + For the built-in node, set the number of executors to zero to prevent it from + executing builds locally on the controller. + Note: The built-in node will always be able to run flyweight tasks including Pipeline's top-level task. diff --git a/core/src/main/resources/hudson/model/Node/help-numExecutors_bg.html b/core/src/main/resources/hudson/model/Node/help-numExecutors_bg.html index 072890e7e7ca..fb0f905ef0bc 100644 --- a/core/src/main/resources/hudson/model/Node/help-numExecutors_bg.html +++ b/core/src/main/resources/hudson/model/Node/help-numExecutors_bg.html @@ -14,5 +14,5 @@ Временно извън линия от страницата на агента.

    Това не се отнася до управляващия компютър на Jenkins. Ако зададете броя - изграждания да е 0, на него няма да се изграждат никакви задания. + изграждания да е 0, на него няма да се изграждат никакви задания. diff --git a/core/src/main/resources/hudson/model/Node/help-numExecutors_fr.html b/core/src/main/resources/hudson/model/Node/help-numExecutors_fr.html index dc98ace04755..4fc2733a30ea 100644 --- a/core/src/main/resources/hudson/model/Node/help-numExecutors_fr.html +++ b/core/src/main/resources/hudson/model/Node/help-numExecutors_fr.html @@ -2,7 +2,7 @@ Ceci contrôle le nombre de builds simultanés que Jenkins peut exécuter. Cette valeur impacte donc la charge générale du système. Une bonne valeur pour commencer serait le nombre de processeurs sur - votre systéme. + votre système.

    Un nombre de builds simultanés supérieur à cette valeur augmentera la @@ -11,6 +11,6 @@ pendant qu'un autre build est en attente sur les entrées/sorties.

    - En mode maître/agent, une valeur de 0 garantit que le maître ne fera - pas lui-même de build. + En mode contrôleur/agent, une valeur de 0 garantit que le contrôleur ne déclenchera pas + pas de build. diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/help.html b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/help.html index 5b5b3814df46..0ad5c21cb27f 100644 --- a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/help.html +++ b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/help.html @@ -12,7 +12,7 @@ the parameter type. These name-value pairs will be exported as environment variables when the build starts, allowing subsequent parts of the build configuration (such as build steps) to access those values, e.g. by using the - ${PARAMETER_NAME} syntax (or %PARAMETER_NAME% on Windows). + ${PARAMETER_NAME} syntax (or %PARAMETER_NAME% on Windows).
    This also implies that each parameter defined here should have a unique Name. @@ -30,7 +30,7 @@ of the same project will only succeed if the parameter values are different, or if the Execute concurrent builds if necessary option is enabled.

    - See the Parameterized Builds documentation for more information about this feature. diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/help_bg.html b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/help_bg.html index d9c3e4b8997e..e1c6c18263de 100644 --- a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/help_bg.html +++ b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/help_bg.html @@ -13,8 +13,8 @@ Всеки параметър има име и стойност, която зависи от вида на параметъра. Тези двойки име-стойност се изнасят като променливи на средата при стартиране на изграждането, което позволява на последващите стъпки от - него да достъпват стойностите чрез синтаксиса ${ИМЕ_НА_ПАРАМЕТЪР} - (под Windows e %ИМЕ_НА_ПАРАМЕТЪР%). + него да достъпват стойностите чрез синтаксиса ${ИМЕ_НА_ПАРАМЕТЪР} + (под Windows e %ИМЕ_НА_ПАРАМЕТЪР%).
    Това е и причината името на всеки параметър да е уникално.

    @@ -31,6 +31,6 @@ на друго ще е успешно, ако поне един от параметрите е различен, освен ако не е зададена опцията Едновременно изграждане при необходимост.

    - За повече информация вижте страницата за параметризираните изграждания в уикито. diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/help_de.html b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/help_de.html index 15fb51e81c59..42b0cd89c0d7 100644 --- a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/help_de.html +++ b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/help_de.html @@ -10,6 +10,6 @@ nach Namen unterschieden. Sie können daher auch mehrere Parameter verwenden, solange diese unterschiedliche Namen tragen.

    - Auf der Jenkins website + Auf der Jenkins website finden Sie weitere Informationen über parametrisierte Builds. diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/help_fr.html b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/help_fr.html index 589f9d10ddc7..56c3ed5ca7a4 100644 --- a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/help_fr.html +++ b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/help_fr.html @@ -9,6 +9,6 @@ nom. Vous pouvez donc avoir de multiples paramètres, s'ils ont bien des noms distincts.

    - Consultez cette page + Consultez cette page pour plus de discussions autour de cette fonctionnalité. diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/help_it.html b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/help_it.html index 8edae0193171..cccfa4f90736 100644 --- a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/help_it.html +++ b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/help_it.html @@ -15,7 +15,7 @@ come variabili d'ambiente all'avvio della compilazione, consentendo ai passaggi successivi della configurazione della compilazione (come le istruzioni di compilazione) di accedere a tali valori, ad esempio utilizzando - la sintassi ${NOME_PARAMETRO} (o %NOME_PARAMETRO% su + la sintassi ${NOME_PARAMETRO} (o %NOME_PARAMETRO% su Windows).
    Ciò implica anche che ogni parametro definito qui debba avere un @@ -36,7 +36,7 @@ dei parametri sono diversi, o se l'opzione Esegui compilazioni concorrenti se necessario è abilitata.

    - Si veda la documentazione sulle compilazioni parametrizzate per ulteriori informazioni su questa funzionalità. diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/help_ja.html b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/help_ja.html index 86a0381cf4e2..ba083784fd04 100644 --- a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/help_ja.html +++ b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/help_ja.html @@ -7,5 +7,5 @@ ここでは、ビルドが必要とするパラメータを設定します。パラメータは名前で識別するので、異なる名前を使用すれば複数のパラメータを使用できます。

    - この機能の詳細については、Wikiの項目を参照してください。 + この機能の詳細については、Wikiの項目を参照してください。 diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/help_tr.html b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/help_tr.html index 5b885ac6a6d5..4451919d0f14 100644 --- a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/help_tr.html +++ b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/help_tr.html @@ -9,6 +9,6 @@ by their names, and so you can have multiple parameters provided that they have different names.

    - See the Jenkins site + See the Jenkins site for more discussions about this feature. diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/help_zh_TW.html b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/help_zh_TW.html index 050c733cb855..c265951d63c6 100644 --- a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/help_zh_TW.html +++ b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/help_zh_TW.html @@ -7,6 +7,6 @@ 參數之間是以名稱來區隔,所以如果您要用到多個參數,請指定不同的名稱。

    - 請參考這篇 Wiki + 請參考這篇 Wiki 條目有關本功能的更多討論。 diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/index.jelly b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/index.jelly index e2f26050a6ae..7a6dea4def1f 100644 --- a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/index.jelly +++ b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/index.jelly @@ -38,7 +38,7 @@ THE SOFTWARE. -

    ${%LOADING}
    +

    ${it.job.pronoun} ${it.job.displayName}

    ${%description}

    diff --git a/core/src/main/resources/hudson/model/PasswordParameterDefinition/help.html b/core/src/main/resources/hudson/model/PasswordParameterDefinition/help.html index 0b9e3662e5e7..e78469f69529 100644 --- a/core/src/main/resources/hudson/model/PasswordParameterDefinition/help.html +++ b/core/src/main/resources/hudson/model/PasswordParameterDefinition/help.html @@ -1,5 +1,5 @@
    Pass a password to your build. The password entered here is made available to the build in plain text as an environment variable like a string parameter would be. - The value will be stored encrypted on the Jenkins master, similar to passwords in Jenkins configuration. + The value will be stored encrypted on the Jenkins controller, similar to passwords in Jenkins configuration.
    \ No newline at end of file diff --git a/core/src/main/resources/hudson/model/PasswordParameterValue/value_pt_BR.properties b/core/src/main/resources/hudson/model/PasswordParameterValue/value_pt_BR.properties new file mode 100644 index 000000000000..a00ef7240204 --- /dev/null +++ b/core/src/main/resources/hudson/model/PasswordParameterValue/value_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +hidden=senha n\u00E3o mostrada abaixo diff --git a/core/src/main/resources/hudson/model/PasswordParameterValue/value_zh_TW.properties b/core/src/main/resources/hudson/model/PasswordParameterValue/value_zh_TW.properties new file mode 100644 index 000000000000..8fcf0fe24773 --- /dev/null +++ b/core/src/main/resources/hudson/model/PasswordParameterValue/value_zh_TW.properties @@ -0,0 +1 @@ +hidden=(\u5df2\u96b1\u85cf\u5bc6\u78bc) diff --git a/core/src/main/resources/hudson/model/PermalinkProjectAction/Permalink/link_ar.properties b/core/src/main/resources/hudson/model/PermalinkProjectAction/Permalink/link_ar.properties deleted file mode 100644 index ceea51b670e4..000000000000 --- a/core/src/main/resources/hudson/model/PermalinkProjectAction/Permalink/link_ar.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -format=\u0645\u0646\u0630 {0} ({1}), {2} diff --git a/core/src/main/resources/hudson/model/ProxyView/configure-entries.jelly b/core/src/main/resources/hudson/model/ProxyView/configure-entries.jelly index 42942970a6cd..5b672c4364e0 100644 --- a/core/src/main/resources/hudson/model/ProxyView/configure-entries.jelly +++ b/core/src/main/resources/hudson/model/ProxyView/configure-entries.jelly @@ -26,7 +26,7 @@ THE SOFTWARE. - ${inst.viewName} diff --git a/core/src/main/resources/hudson/model/Run/KeepLogBuildBadge/badge_zh_TW.properties b/core/src/main/resources/hudson/model/Run/KeepLogBuildBadge/badge_zh_TW.properties index e1766f3a970d..8228fc698d18 100644 --- a/core/src/main/resources/hudson/model/Run/KeepLogBuildBadge/badge_zh_TW.properties +++ b/core/src/main/resources/hudson/model/Run/KeepLogBuildBadge/badge_zh_TW.properties @@ -20,4 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Keep\ this\ build\ forever=\u6C38\u4E45\u4FDD\u7559\u6B64\u5EFA\u7F6E +Keep\ this\ build\ forever=\u6c38\u4e45\u4fdd\u7559\u6b64\u5efa\u7f6e diff --git a/core/src/main/resources/hudson/model/Run/_api.jelly b/core/src/main/resources/hudson/model/Run/_api.jelly index d116b13d2778..7d3fbb722c48 100644 --- a/core/src/main/resources/hudson/model/Run/_api.jelly +++ b/core/src/main/resources/hudson/model/Run/_api.jelly @@ -28,15 +28,15 @@ THE SOFTWARE.
    Build number
    - This URL returns the build number in text/plain format. + This URL returns the build number in text/plain format.
    Build timestamp
    - This URL returns the build timestamp. You can also use the format query parameter + This URL returns the build timestamp. You can also use the format query parameter to control the date format, which follows - the SimpleDateFormat format pattern. + the SimpleDateFormat format pattern. (example) - You can also use the Accept-Language HTTP header to control the locale + You can also use the Accept-Language HTTP header to control the locale in which the date is formatted.
    @@ -47,13 +47,13 @@ THE SOFTWARE. You'll basically send GET request to this URL (or this URL if you want HTML that can be put into &lt;pre> tag.) - The start parameter controls the byte offset of where you start. + The start parameter controls the byte offset of where you start.

    - The response will contain a chunk of the console output, as well as the X-Text-Size header that represents + The response will contain a chunk of the console output, as well as the X-Text-Size header that represents the bytes offset (of the raw log file). - This is the number you want to use as the start parameter for the next call. + This is the number you want to use as the start parameter for the next call.

    - If the response also contains the X-More-Data: true header, the server is indicating that the build + If the response also contains the X-More-Data: true header, the server is indicating that the build is in progress, and you need to repeat the request after some delay. The Jenkins UI waits 5 seconds before making the next call. When this header is not present, you know that you've retrieved all the data and the build is complete.

    diff --git a/core/src/main/resources/hudson/model/Run/artifacts-index.jelly b/core/src/main/resources/hudson/model/Run/artifacts-index.jelly index b954198257ad..4a5f41c21b5b 100644 --- a/core/src/main/resources/hudson/model/Run/artifacts-index.jelly +++ b/core/src/main/resources/hudson/model/Run/artifacts-index.jelly @@ -28,14 +28,12 @@ THE SOFTWARE. - - ${%Build Artifacts} - + ${%Build Artifacts}
    ${%Build} ${%Duration}${%Agent}
    - + ${f.displayPath} @@ -49,4 +47,4 @@ THE SOFTWARE. - \ No newline at end of file + diff --git a/core/src/main/resources/hudson/model/Run/configure.jelly b/core/src/main/resources/hudson/model/Run/configure.jelly index a62494b48505..e28e225d6ed9 100644 --- a/core/src/main/resources/hudson/model/Run/configure.jelly +++ b/core/src/main/resources/hudson/model/Run/configure.jelly @@ -27,8 +27,9 @@ THE SOFTWARE. -
    ${%LOADING}
    +
    + diff --git a/core/src/main/resources/hudson/model/Run/configure_ar.properties b/core/src/main/resources/hudson/model/Run/configure_ar.properties deleted file mode 100644 index 7d8a4917007b..000000000000 --- a/core/src/main/resources/hudson/model/Run/configure_ar.properties +++ /dev/null @@ -1,6 +0,0 @@ -# This file is under the MIT License by authors - -Description=\u0627\u0644\u0634\u0631\u062D -DisplayName=\u0627\u0644\u0627\u0633\u0645 -LOADING=\u062A\u062D\u0645\u064A\u0644 -Save=\u062D\u0641\u0638 diff --git a/core/src/main/resources/hudson/model/Run/confirmDelete_zh_TW.properties b/core/src/main/resources/hudson/model/Run/confirmDelete_zh_TW.properties index 263f43e67078..bb92913ba3ad 100644 --- a/core/src/main/resources/hudson/model/Run/confirmDelete_zh_TW.properties +++ b/core/src/main/resources/hudson/model/Run/confirmDelete_zh_TW.properties @@ -20,7 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. +delete.build=\u78ba\u5b9a\u8981\u522a\u9664\u5efa\u7f6e\u300c{0}\u300d\u55ce\uff1f Warning=\u8b66\u544a -delete.build=\u78ba\u5b9a\u8981\u522a\u9664\u9019\u6b21\u5efa\u7f6e\u55ce? ({0}) - Yes=\u662f diff --git a/core/src/main/resources/hudson/model/Run/console.jelly b/core/src/main/resources/hudson/model/Run/console.jelly index 132ed4747b63..d77128466612 100644 --- a/core/src/main/resources/hudson/model/Run/console.jelly +++ b/core/src/main/resources/hudson/model/Run/console.jelly @@ -32,9 +32,7 @@ THE SOFTWARE. - - ${%Console Output} - + ${%Console Output} @@ -54,7 +52,7 @@ THE SOFTWARE.
                 
    - +
    diff --git a/core/src/main/resources/hudson/model/Run/console_ar.properties b/core/src/main/resources/hudson/model/Run/console_ar.properties deleted file mode 100644 index a95bb493e11b..000000000000 --- a/core/src/main/resources/hudson/model/Run/console_ar.properties +++ /dev/null @@ -1,4 +0,0 @@ -# This file is under the MIT License by authors - -Console\ Output=\u062E\u0631\u062C \u0627\u0644\u0643\u0648\u0646\u0633\u0648\u0644 -View\ as\ plain\ text=\u0645\u0634\u0627\u0647\u062F\u0629 \u0643\u0646\u0635 \u0628\u0633\u064A\u0637 diff --git a/core/src/main/resources/hudson/model/Run/console_fr.properties b/core/src/main/resources/hudson/model/Run/console_fr.properties index ecf28ef26d4b..79988c043de1 100644 --- a/core/src/main/resources/hudson/model/Run/console_fr.properties +++ b/core/src/main/resources/hudson/model/Run/console_fr.properties @@ -21,5 +21,5 @@ # THE SOFTWARE. Console\ Output=Sortie de la console -View\ as\ plain\ text=Afficher ous forme de texte simple +View\ as\ plain\ text=Voir en texte brut skipSome=Ignore {0,number,integer} Ko. Log complet diff --git a/core/src/main/resources/hudson/model/Run/console_zh_TW.properties b/core/src/main/resources/hudson/model/Run/console_zh_TW.properties index b2fd5e2c756a..c3372e796215 100644 --- a/core/src/main/resources/hudson/model/Run/console_zh_TW.properties +++ b/core/src/main/resources/hudson/model/Run/console_zh_TW.properties @@ -1,18 +1,18 @@ # The MIT License -# +# # Copyright (c) 2004-2013, Sun Microsystems, Inc., Chunghwa Telecom Co., Ltd., # and Pei-Tang Huang -# +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: -# +# # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. -# +# # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -20,6 +20,5 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. - -Console\ Output=\u7D42\u7AEF\u6A5F\u8F38\u51FA -skipSome=\u7565\u904e {0,number,integer} KB... \u5b8c\u6574\u5167\u5bb9 +skipSome=\u7565\u904e {0,number,integer} KB... \u5b8c\u6574\u5167\u5bb9 +Console\ Output=\u4e3b\u63a7\u53f0\u8f38\u51fa diff --git a/core/src/main/resources/hudson/model/Run/delete-retry_zh_TW.properties b/core/src/main/resources/hudson/model/Run/delete-retry_zh_TW.properties new file mode 100644 index 000000000000..95af11e8548a --- /dev/null +++ b/core/src/main/resources/hudson/model/Run/delete-retry_zh_TW.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Frederic Gurr +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +Not\ successful=\u5617\u8a66\u522a\u9664\u5efa\u7f6e\u6642\u5931\u6557 +Retry\ delete=\u91cd\u65b0\u5617\u8a66\u522a\u9664 +Show\ reason=\u986f\u793a\u539f\u56e0 diff --git a/core/src/main/resources/hudson/model/Run/delete.jelly b/core/src/main/resources/hudson/model/Run/delete.jelly index 7cf622fb29c0..83e3cbd77e71 100644 --- a/core/src/main/resources/hudson/model/Run/delete.jelly +++ b/core/src/main/resources/hudson/model/Run/delete.jelly @@ -26,8 +26,8 @@ THE SOFTWARE. Displays the link to delete the build. --> - - + + diff --git a/core/src/main/resources/hudson/model/Run/delete_ar.properties b/core/src/main/resources/hudson/model/Run/delete_ar.properties deleted file mode 100644 index 83c2a42c4b15..000000000000 --- a/core/src/main/resources/hudson/model/Run/delete_ar.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -Delete\ this\ build=\u0627\u062D\u0630\u0641 \u0647\u0630\u0627 \u0627\u0644\u0628\u0646\u0627\u0621 diff --git a/core/src/main/resources/hudson/model/Run/delete_fr.properties b/core/src/main/resources/hudson/model/Run/delete_fr.properties index b9f4b5857168..f4480b69a862 100644 --- a/core/src/main/resources/hudson/model/Run/delete_fr.properties +++ b/core/src/main/resources/hudson/model/Run/delete_fr.properties @@ -20,4 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Delete\ this\ build=Supprimer le build +delete.build=Supprimer le build "{0}" diff --git a/core/src/main/resources/hudson/model/Run/delete_pt_BR.properties b/core/src/main/resources/hudson/model/Run/delete_pt_BR.properties index e0be9539c120..5be55014c23a 100644 --- a/core/src/main/resources/hudson/model/Run/delete_pt_BR.properties +++ b/core/src/main/resources/hudson/model/Run/delete_pt_BR.properties @@ -20,4 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Delete\ this\ build=Excluir este build +delete.build=Apagar a constru\u00E7\u00E3o '{0}' diff --git a/core/src/main/resources/hudson/model/Run/delete_zh_TW.properties b/core/src/main/resources/hudson/model/Run/delete_zh_TW.properties index 0a577250dc13..7a82a22dab50 100644 --- a/core/src/main/resources/hudson/model/Run/delete_zh_TW.properties +++ b/core/src/main/resources/hudson/model/Run/delete_zh_TW.properties @@ -1,17 +1,17 @@ # The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc. -# +# +# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Frederic Gurr +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: -# +# # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. -# +# # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -19,5 +19,5 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. - -Delete\ this\ build=\u522A\u9664\u9019\u6B21\u5EFA\u69CB +Delete\ this\ build=\u522a\u9664\u5efa\u7f6e +delete.build=\u522a\u9664\u5efa\u7f6e\u300c{0}\u300d diff --git a/core/src/main/resources/hudson/model/Run/logKeep_ar.properties b/core/src/main/resources/hudson/model/Run/logKeep_ar.properties deleted file mode 100644 index f1a456d5d784..000000000000 --- a/core/src/main/resources/hudson/model/Run/logKeep_ar.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -Keep\ this\ build\ forever=\u0623\u062D\u062A\u0641\u0638 \u062F\u0627\u0626\u0645\u0627 \u0628\u0647\u062F\u0627 \u0627\u0644\u0628\u0646\u0627\u0621 diff --git a/core/src/main/resources/hudson/model/Run/logKeep_zh_TW.properties b/core/src/main/resources/hudson/model/Run/logKeep_zh_TW.properties index 01bfc8f233c7..3f1b6f397db2 100644 --- a/core/src/main/resources/hudson/model/Run/logKeep_zh_TW.properties +++ b/core/src/main/resources/hudson/model/Run/logKeep_zh_TW.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,5 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Don't\ keep\ this\ build\ forever=\u4e0d\u8981\u6c38\u4e45\u4fdd\u5b58\u9019\u6b21\u5efa\u7f6e -Keep\ this\ build\ forever=\u6c38\u4e45\u4fdd\u5b58\u9019\u6b21\u5efa\u7f6e +Don't\ keep\ this\ build\ forever=\u4e0d\u8981\u6c38\u4e45\u4fdd\u7559\u6b64\u5efa\u7f6e +Keep\ this\ build\ forever=\u6c38\u4e45\u4fdd\u7559\u6b64\u5efa\u7f6e diff --git a/core/src/main/resources/hudson/model/RunParameterDefinition/config_ru.properties b/core/src/main/resources/hudson/model/RunParameterDefinition/config_ru.properties index f8ff0f56ce70..46cd35fdf206 100644 --- a/core/src/main/resources/hudson/model/RunParameterDefinition/config_ru.properties +++ b/core/src/main/resources/hudson/model/RunParameterDefinition/config_ru.properties @@ -21,3 +21,10 @@ # THE SOFTWARE. Project=\u041F\u0440\u043E\u0435\u043A\u0442 +Description=\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 +Completed\ Builds\ Only=\u0422\u043e\u043b\u044c\u043a\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u044b\u0435 \u0441\u0431\u043e\u0440\u043a\u0438 +All\ Builds=\u0412\u0441\u0435 \u0441\u0431\u043e\u0440\u043a\u0438 +Name=\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 +Filter=\u0424\u0438\u043b\u044c\u0442\u0440 +Stable\ Builds\ Only=\u0422\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u044b\u0435 \u0441\u0431\u043e\u0440\u043a\u0438 +Successful\ Builds\ Only=\u0422\u043e\u043b\u044c\u043a\u043e \u0443\u0441\u043f\u0435\u0448\u043d\u044b\u0435 \u0441\u0431\u043e\u0440\u043a\u0438 \ No newline at end of file diff --git a/core/src/main/resources/hudson/model/RunParameterDefinition/config_zh_TW.properties b/core/src/main/resources/hudson/model/RunParameterDefinition/config_zh_TW.properties index 3fa1b388f7d4..4edc0ff3da9e 100644 --- a/core/src/main/resources/hudson/model/RunParameterDefinition/config_zh_TW.properties +++ b/core/src/main/resources/hudson/model/RunParameterDefinition/config_zh_TW.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2013, Chunghwa Telecom Co., Ltd., Pei-Tang Huang +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -23,3 +23,8 @@ Name=\u540d\u7a31 Project=\u5c08\u6848 Description=\u8aaa\u660e +All\ Builds=\u6240\u6709\u5efa\u7f6e +Filter=\u7be9\u9078\u689d\u4ef6 +Successful\ Builds\ Only=\u53ea\u986f\u793a\u6210\u529f\u7684\u5efa\u7f6e +Completed\ Builds\ Only=\u53ea\u986f\u793a\u5df2\u5b8c\u6210\u7684\u5efa\u7f6e +Stable\ Builds\ Only=\u53ea\u986f\u793a\u7a69\u5b9a\u7684\u5efa\u7f6e diff --git a/core/src/main/resources/hudson/model/Slave/help-launcher_pt_BR.properties b/core/src/main/resources/hudson/model/Slave/help-launcher_pt_BR.properties new file mode 100644 index 000000000000..374fd2957c82 --- /dev/null +++ b/core/src/main/resources/hudson/model/Slave/help-launcher_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Controls\ how\ Jenkins\ starts\ this\ agent.=Controla\ como\ o\ Jenkins\ inicia\ este\ agente. diff --git a/core/src/main/resources/hudson/model/Slave/help-launcher_zh_TW.properties b/core/src/main/resources/hudson/model/Slave/help-launcher_zh_TW.properties new file mode 100644 index 000000000000..2c6136dfee3c --- /dev/null +++ b/core/src/main/resources/hudson/model/Slave/help-launcher_zh_TW.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Controls\ how\ Jenkins\ starts\ this\ agent.=\u63a7\u5236 Jenkins \u5982\u4f55\u555f\u52d5\u6b64 Agent\u3002 diff --git a/core/src/main/resources/hudson/model/Slave/help-remoteFS.html b/core/src/main/resources/hudson/model/Slave/help-remoteFS.html index 9b74e2e95c07..ca9aa4bfce47 100644 --- a/core/src/main/resources/hudson/model/Slave/help-remoteFS.html +++ b/core/src/main/resources/hudson/model/Slave/help-remoteFS.html @@ -2,12 +2,12 @@

    An agent needs to have a directory dedicated to Jenkins. Specify the path to this directory on the agent. It is best to use - an absolute path, such as /var/jenkins or c:\jenkins. + an absolute path, such as /var/jenkins or c:\jenkins. This should be a path local to the agent machine. There is no need for - this path to be visible from the master. + this path to be visible from the controller.

    Agents do not maintain important data; all job configurations, build logs and - artifacts are stored on the master, so it would be possible to use a temporary + artifacts are stored on the controller, so it would be possible to use a temporary directory as the agent root directory.
    However, by giving an agent a directory that is not deleted after a machine @@ -16,7 +16,7 @@ out source code again when builds start to run on this agent again after a reboot.

    - If you use a relative path, such as ./jenkins-agent, the path will be + If you use a relative path, such as ./jenkins-agent, the path will be relative to the working directory provided by the Launch method.

    • For launchers where Jenkins controls starting the agent process, such diff --git a/core/src/main/resources/hudson/model/Slave/help-remoteFS_bg.html b/core/src/main/resources/hudson/model/Slave/help-remoteFS_bg.html index e5cf4dfb31bc..9135d1618082 100644 --- a/core/src/main/resources/hudson/model/Slave/help-remoteFS_bg.html +++ b/core/src/main/resources/hudson/model/Slave/help-remoteFS_bg.html @@ -2,7 +2,7 @@

      Компютърът за изграждания трябва да има директория, която да се ползва само от Jenkins. Укажете пътя до директорията. Най-добре ползвайте - абсолютен път като /var/jenkins или c:\jenkins. + абсолютен път като /var/jenkins или c:\jenkins. Това е локален път — както се вижда на машината за изграждания. Няма нужда пътят да се вижда от командната машина.

      @@ -17,7 +17,7 @@ или ресурси от системите за контрол на версии при стартирането на ново изграждане след рестартиране.

      - Ако използвате относителен път като ./jenkins-agent, пътят се определя + Ако използвате относителен път като ./jenkins-agent, пътят се определя спрямо работната директория указана в Начина за стартиране.

      • При стартиранията, при които Jenkins управлява пускането на агента, diff --git a/core/src/main/resources/hudson/model/Slave/help-remoteFS_fr.html b/core/src/main/resources/hudson/model/Slave/help-remoteFS_fr.html index 1a56f7440535..10588de6920f 100644 --- a/core/src/main/resources/hudson/model/Slave/help-remoteFS_fr.html +++ b/core/src/main/resources/hudson/model/Slave/help-remoteFS_fr.html @@ -1,10 +1,10 @@ 

        Un agent a besoin d'un répertoire dédié à Jenkins. Spécifiez ici le - chemin absolu vers le répertoire de travail sur l'agent, par exemple - '/var/jenkins' ou 'c:\jenkins'. Cela doit être un chemin local à la machine + chemin absolu (local à l'agent) vers le répertoire de travail sur l'agent, par exemple + '/var/jenkins' ou 'c:\jenkins'. Le chemin doit être local à la machine agent. En règle générale, il n'est pas nécessaire que ce chemin soit - visible depuis le maître. + visible depuis le contrôleur.

        Les agents ne conservent pas de données importantes (autres que les diff --git a/core/src/main/resources/hudson/model/Slave/help-remoteFS_it.html b/core/src/main/resources/hudson/model/Slave/help-remoteFS_it.html index fe232787498e..05a4a4ebccb7 100644 --- a/core/src/main/resources/hudson/model/Slave/help-remoteFS_it.html +++ b/core/src/main/resources/hudson/model/Slave/help-remoteFS_it.html @@ -2,7 +2,7 @@

        Un agente deve avere una directory dedicata a Jenkins. Specificare il percorso a questa directory sull'agente. È meglio utilizzare un percorso - assoluto, come /var/jenkins o c:\jenkins. + assoluto, come /var/jenkins o c:\jenkins. Questo percorso deve essere locale al computer agente. Non è necessario che questo percorso sia visibile dal master.

        @@ -18,7 +18,7 @@ eseguire nuovamente il checkout del codice sorgente quando delle compilazioni riprendono ad essere eseguite dopo un riavvio.

        - Se si utilizza un percorso relativo, come ./jenkins-agent, il + Se si utilizza un percorso relativo, come ./jenkins-agent, il percorso sarà relativo alla directory di lavoro fornita dal Metodo di avvio.

          diff --git a/core/src/main/resources/hudson/model/StringParameterDefinition/config_pt_BR.properties b/core/src/main/resources/hudson/model/StringParameterDefinition/config_pt_BR.properties index 27ba76ec3a05..6b4e422d05a8 100644 --- a/core/src/main/resources/hudson/model/StringParameterDefinition/config_pt_BR.properties +++ b/core/src/main/resources/hudson/model/StringParameterDefinition/config_pt_BR.properties @@ -21,5 +21,6 @@ # THE SOFTWARE. Name=Nome -Default\ Value=Valor padr\u00e3o -Description=Descri\u00e7\u00e3o +Default\ Value=Valor\ padr\u00E3o +Description=Descri\u00E7\u00E3o +Trim\ the\ string=Remover espa\u00E7os em branco da sequ\u00EAncia de caracteres diff --git a/core/src/main/resources/hudson/model/StringParameterDefinition/config_zh_TW.properties b/core/src/main/resources/hudson/model/StringParameterDefinition/config_zh_TW.properties index eadfc25e444c..b7b3721a903a 100644 --- a/core/src/main/resources/hudson/model/StringParameterDefinition/config_zh_TW.properties +++ b/core/src/main/resources/hudson/model/StringParameterDefinition/config_zh_TW.properties @@ -24,3 +24,4 @@ Name=\u540d\u7a31 Default\ Value=\u9810\u8a2d\u503c Description=\u8aaa\u660e +Trim\ the\ string=\u4fee\u526a (Trim) \u5b57\u4e32 diff --git a/core/src/main/resources/hudson/model/TaskAction/log.jelly b/core/src/main/resources/hudson/model/TaskAction/log.jelly index f7be5cfb7a1d..7011f6d56c70 100644 --- a/core/src/main/resources/hudson/model/TaskAction/log.jelly +++ b/core/src/main/resources/hudson/model/TaskAction/log.jelly @@ -32,7 +32,7 @@ THE SOFTWARE.
                 
          - +
          diff --git a/core/src/main/resources/hudson/model/TimeZoneProperty/config_pt_BR.properties b/core/src/main/resources/hudson/model/TimeZoneProperty/config_pt_BR.properties new file mode 100644 index 000000000000..5b2fb4f9533f --- /dev/null +++ b/core/src/main/resources/hudson/model/TimeZoneProperty/config_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +title=Fuso hor\u00E1rio diff --git a/core/src/main/resources/hudson/model/TimeZoneProperty/config_zh_TW.properties b/core/src/main/resources/hudson/model/TimeZoneProperty/config_zh_TW.properties new file mode 100644 index 000000000000..3ba2475a9d58 --- /dev/null +++ b/core/src/main/resources/hudson/model/TimeZoneProperty/config_zh_TW.properties @@ -0,0 +1,20 @@ +# The MIT License +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +title=\u6642\u5340 diff --git a/core/src/main/resources/hudson/model/TreeView/ajaxRows.jelly b/core/src/main/resources/hudson/model/TreeView/ajaxRows.jelly deleted file mode 100644 index a6812a20cd58..000000000000 --- a/core/src/main/resources/hudson/model/TreeView/ajaxRows.jelly +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - -
          -
          -
          diff --git a/core/src/main/resources/hudson/model/TreeView/main.jelly b/core/src/main/resources/hudson/model/TreeView/main.jelly deleted file mode 100644 index 0f149020059f..000000000000 --- a/core/src/main/resources/hudson/model/TreeView/main.jelly +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/core/src/main/resources/hudson/model/TreeView/newView.jelly b/core/src/main/resources/hudson/model/TreeView/newView.jelly deleted file mode 100644 index 9f22b566acf1..000000000000 --- a/core/src/main/resources/hudson/model/TreeView/newView.jelly +++ /dev/null @@ -1,26 +0,0 @@ - - - - \ No newline at end of file diff --git a/core/src/main/resources/hudson/model/TreeView/newViewDetail.jelly b/core/src/main/resources/hudson/model/TreeView/newViewDetail.jelly deleted file mode 100644 index b7c7ea166613..000000000000 --- a/core/src/main/resources/hudson/model/TreeView/newViewDetail.jelly +++ /dev/null @@ -1,28 +0,0 @@ - - - -
          - Experimental: show hierarchical views -
          \ No newline at end of file diff --git a/core/src/main/resources/hudson/model/TreeView/sidepanel2.jelly b/core/src/main/resources/hudson/model/TreeView/sidepanel2.jelly deleted file mode 100644 index dc3d0e79382a..000000000000 --- a/core/src/main/resources/hudson/model/TreeView/sidepanel2.jelly +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - diff --git a/core/src/main/resources/hudson/model/TreeView/sidepanel2_bg.properties b/core/src/main/resources/hudson/model/TreeView/sidepanel2_bg.properties deleted file mode 100644 index 6c612eb9e6eb..000000000000 --- a/core/src/main/resources/hudson/model/TreeView/sidepanel2_bg.properties +++ /dev/null @@ -1,24 +0,0 @@ -# The MIT License -# -# Bulgarian translation: Copyright (c) 2016, Alexander Shopov -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -New\ View=\ - \u041d\u043e\u0432 \u0438\u0437\u0433\u043b\u0435\u0434 diff --git a/core/src/main/resources/hudson/model/TreeView/sidepanel2_da.properties b/core/src/main/resources/hudson/model/TreeView/sidepanel2_da.properties deleted file mode 100644 index 448476e66208..000000000000 --- a/core/src/main/resources/hudson/model/TreeView/sidepanel2_da.properties +++ /dev/null @@ -1,23 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc. Kohsuke Kawaguchi. Knud Poulsen. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -New\ View=Ny visning diff --git a/core/src/main/resources/hudson/model/TreeView/sidepanel2_de.properties b/core/src/main/resources/hudson/model/TreeView/sidepanel2_de.properties deleted file mode 100644 index ce2c2658a4f9..000000000000 --- a/core/src/main/resources/hudson/model/TreeView/sidepanel2_de.properties +++ /dev/null @@ -1 +0,0 @@ -New\ View=Neue Ansicht diff --git a/core/src/main/resources/hudson/model/TreeView/sidepanel2_es.properties b/core/src/main/resources/hudson/model/TreeView/sidepanel2_es.properties deleted file mode 100644 index 4df3f2f5318f..000000000000 --- a/core/src/main/resources/hudson/model/TreeView/sidepanel2_es.properties +++ /dev/null @@ -1,23 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -New\ View=Nueva vista diff --git a/core/src/main/resources/hudson/model/TreeView/sidepanel2_fr.properties b/core/src/main/resources/hudson/model/TreeView/sidepanel2_fr.properties deleted file mode 100644 index f4253389b678..000000000000 --- a/core/src/main/resources/hudson/model/TreeView/sidepanel2_fr.properties +++ /dev/null @@ -1,23 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Eric Lefevre-Ardant -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -New\ View=Nouvelle vue diff --git a/core/src/main/resources/hudson/model/TreeView/sidepanel2_it.properties b/core/src/main/resources/hudson/model/TreeView/sidepanel2_it.properties deleted file mode 100644 index 260b76d71e9b..000000000000 --- a/core/src/main/resources/hudson/model/TreeView/sidepanel2_it.properties +++ /dev/null @@ -1,24 +0,0 @@ -# The MIT License -# -# Italian localization plugin for Jenkins -# Copyright 2020 Alessandro Menti -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -New\ View=Nuova vista diff --git a/core/src/main/resources/hudson/model/TreeView/sidepanel2_ja.properties b/core/src/main/resources/hudson/model/TreeView/sidepanel2_ja.properties deleted file mode 100644 index 78f5e6bb3258..000000000000 --- a/core/src/main/resources/hudson/model/TreeView/sidepanel2_ja.properties +++ /dev/null @@ -1,23 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, Seiji Sogabe -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -New\ View=\u65B0\u898F\u30D3\u30E5\u30FC diff --git a/core/src/main/resources/hudson/model/TreeView/sidepanel2_pt_BR.properties b/core/src/main/resources/hudson/model/TreeView/sidepanel2_pt_BR.properties deleted file mode 100644 index 6054ccefe284..000000000000 --- a/core/src/main/resources/hudson/model/TreeView/sidepanel2_pt_BR.properties +++ /dev/null @@ -1,23 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc., Cleiber Silva -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -New\ View=Nova view diff --git a/core/src/main/resources/hudson/model/TreeView/sidepanel2_sr.properties b/core/src/main/resources/hudson/model/TreeView/sidepanel2_sr.properties deleted file mode 100644 index f8ec299e020f..000000000000 --- a/core/src/main/resources/hudson/model/TreeView/sidepanel2_sr.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -New\ View=\u041D\u043E\u0432\u0438 \u043F\u0440\u0435\u0433\u043B\u0435\u0434 diff --git a/core/src/main/resources/hudson/model/TreeView/sidepanel2_zh_TW.properties b/core/src/main/resources/hudson/model/TreeView/sidepanel2_zh_TW.properties deleted file mode 100644 index 4d5595a24263..000000000000 --- a/core/src/main/resources/hudson/model/TreeView/sidepanel2_zh_TW.properties +++ /dev/null @@ -1,23 +0,0 @@ -# The MIT License -# -# Copyright (c) 2013, Chunghwa Telecom Co., Ltd., Pei-Tang Huang -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -New\ View=\u65b0\u589e\u8996\u666f diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CompleteBatchJob/Failure/status_pt_BR.properties b/core/src/main/resources/hudson/model/UpdateCenter/CompleteBatchJob/Failure/status_pt_BR.properties new file mode 100644 index 000000000000..609668d667b3 --- /dev/null +++ b/core/src/main/resources/hudson/model/UpdateCenter/CompleteBatchJob/Failure/status_pt_BR.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Failure=Falha +Details=Detalhes diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CompleteBatchJob/Failure/status_zh_TW.properties b/core/src/main/resources/hudson/model/UpdateCenter/CompleteBatchJob/Failure/status_zh_TW.properties new file mode 100644 index 000000000000..bfd9d733b13e --- /dev/null +++ b/core/src/main/resources/hudson/model/UpdateCenter/CompleteBatchJob/Failure/status_zh_TW.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Failure=\u5931\u6557 +Details=\u8a73\u60c5 diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CompleteBatchJob/Pending/status_pt_BR.properties b/core/src/main/resources/hudson/model/UpdateCenter/CompleteBatchJob/Pending/status_pt_BR.properties new file mode 100644 index 000000000000..f38f204b35a2 --- /dev/null +++ b/core/src/main/resources/hudson/model/UpdateCenter/CompleteBatchJob/Pending/status_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Pending=Pendente diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CompleteBatchJob/Pending/status_zh_TW.properties b/core/src/main/resources/hudson/model/UpdateCenter/CompleteBatchJob/Pending/status_zh_TW.properties new file mode 100644 index 000000000000..0c9453a9e5a3 --- /dev/null +++ b/core/src/main/resources/hudson/model/UpdateCenter/CompleteBatchJob/Pending/status_zh_TW.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Pending=\u64f1\u7f6e diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CompleteBatchJob/Running/status_pt_BR.properties b/core/src/main/resources/hudson/model/UpdateCenter/CompleteBatchJob/Running/status_pt_BR.properties new file mode 100644 index 000000000000..606d0f70ed0c --- /dev/null +++ b/core/src/main/resources/hudson/model/UpdateCenter/CompleteBatchJob/Running/status_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Running=Rodando diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CompleteBatchJob/Running/status_zh_TW.properties b/core/src/main/resources/hudson/model/UpdateCenter/CompleteBatchJob/Running/status_zh_TW.properties new file mode 100644 index 000000000000..6aa7185d0da3 --- /dev/null +++ b/core/src/main/resources/hudson/model/UpdateCenter/CompleteBatchJob/Running/status_zh_TW.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Running=\u6b63\u5728\u57f7\u884c diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CompleteBatchJob/Success/status_pt_BR.properties b/core/src/main/resources/hudson/model/UpdateCenter/CompleteBatchJob/Success/status_pt_BR.properties new file mode 100644 index 000000000000..633b83950a46 --- /dev/null +++ b/core/src/main/resources/hudson/model/UpdateCenter/CompleteBatchJob/Success/status_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Success=Sucesso diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CompleteBatchJob/Success/status_zh_TW.properties b/core/src/main/resources/hudson/model/UpdateCenter/CompleteBatchJob/Success/status_zh_TW.properties new file mode 100644 index 000000000000..c16c6d08ca22 --- /dev/null +++ b/core/src/main/resources/hudson/model/UpdateCenter/CompleteBatchJob/Success/status_zh_TW.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Success=\u6210\u529f diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CompleteBatchJob/row_pt_BR.properties b/core/src/main/resources/hudson/model/UpdateCenter/CompleteBatchJob/row_pt_BR.properties new file mode 100644 index 000000000000..d9293f548a38 --- /dev/null +++ b/core/src/main/resources/hudson/model/UpdateCenter/CompleteBatchJob/row_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Loading\ plugin\ extensions=Carregando\ extens\u00F5es\ plug\u00E1veis diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CompleteBatchJob/row_zh_TW.properties b/core/src/main/resources/hudson/model/UpdateCenter/CompleteBatchJob/row_zh_TW.properties new file mode 100644 index 000000000000..81a338cdd4ff --- /dev/null +++ b/core/src/main/resources/hudson/model/UpdateCenter/CompleteBatchJob/row_zh_TW.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Loading\ plugin\ extensions=\u6b63\u5728\u8f09\u5165\u5916\u639b\u7a0b\u5f0f diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/description.jelly b/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/description.jelly new file mode 100644 index 000000000000..bb405e931933 --- /dev/null +++ b/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/description.jelly @@ -0,0 +1,4 @@ + + + ${%blurb} + diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/description.properties b/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/description.properties new file mode 100644 index 000000000000..620850a3f956 --- /dev/null +++ b/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/description.properties @@ -0,0 +1 @@ +blurb = When a new release of Jenkins has been released, this informs administrators about it. diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/description_pt_BR.properties b/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/description_pt_BR.properties new file mode 100644 index 000000000000..290d1175dca1 --- /dev/null +++ b/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/description_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +blurb=Quando uma nova vers\u00E3o do Jenkins for liberada, isto informa administradores sobre isso. diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/description_zh_TW.properties b/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/description_zh_TW.properties new file mode 100644 index 000000000000..bdd38ec80afa --- /dev/null +++ b/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/description_zh_TW.properties @@ -0,0 +1 @@ +blurb=\u7576 Jenkins \u6709\u65b0\u7248\u672c\u767c\u4f48\u6642\u901a\u77e5\u7ba1\u7406\u54e1\u3002 diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_pt_BR.properties b/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_pt_BR.properties index f604966589ad..604c452d4b6e 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_pt_BR.properties +++ b/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_pt_BR.properties @@ -20,12 +20,11 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -# Upgrade to Jenkins {0} is complete, awaiting restart. -UpgradeComplete=Atualiza\u00e7\u00e3o do Jenkins {0} completa, aguardando reiniciar. -UpgradeCompleteRestartNotSupported=Atualiza\u00e7\u00e3o do Jenkins {0} completa, aguardando reiniciar. -# Upgrade to Jenkins {0} is in progress or failed. -UpgradeProgress=Atualiza\u00e7\u00e3o para Jenkins {0} est\u00e1 em andamento ou falhou. -Or\ Upgrade\ Automatically=Ou fazer a atualiza\u00e7\u00e3o automaticamente. -# New version of Jenkins ({0}) is available for download \ -# (changelog). -NewVersionAvailable=Nova vers\u00e3o do Jenkins ({0}) est\u00e1 dispon\u00edvel em download +UpgradeComplete=Atualiza\u00E7\u00E3o do Jenkins {0} completa, aguardando reiniciar. +UpgradeCompleteRestartNotSupported=Atualiza\u00E7\u00E3o do Jenkins {0} completa, aguardando reiniciar. +UpgradeProgress=Atualiza\u00E7\u00E3o para Jenkins {0} est\u00E1 em andamento. +NewVersionAvailable=Uma nova vers\u00E3o do Jenkins ({0}) est\u00E1 dispon\u00EDvel em baixar \ + (registro de altera\u00E7\u00F5es). +UpgradeFailed=Atualiza\u00E7\u00E3o do Jenkins {0} falhou: {1}. +Retry=Tentar novamente +Or\ Upgrade\ Automatically=Ou atualizar automaticamente diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_zh_TW.properties b/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_zh_TW.properties index e6305137c8d6..f06d09d42810 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_zh_TW.properties +++ b/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_zh_TW.properties @@ -1,18 +1,17 @@ # The MIT License -# -# Copyright (c) 2004-2013, Sun Microsystems, Inc., Chunghwa Telecom Co., Ltd., -# and Pei-Tang Huang -# +# +# Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: -# +# # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. -# +# # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -20,9 +19,10 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. - -UpgradeComplete=Jenkins {0} \u5347\u7248\u5b8c\u6210\uff0c\u7b49\u5019\u91cd\u65b0\u555f\u52d5\u3002 -UpgradeCompleteRestartNotSupported=Jenkins {0} \u5347\u7248\u5b8c\u6210\uff0c\u7b49\u5019\u91cd\u65b0\u555f\u52d5\u3002 -UpgradeProgress=Jenkins {0} \u5347\u7d1a\u4f5c\u696d\u6b63\u5728\u9032\u884c\u4e2d\u6216\u662f\u5df2\u7d93\u5931\u6557\u3002 -NewVersionAvailable=\u65b0\u7248\u7684 Jenkins ({0}) \u5df2\u7d93\u53ef\u4ee5\u4e0b\u8f09 (\u6539\u7248\u8a18\u9304)\u3002 +NewVersionAvailable=\u65b0\u7248\u7684 Jenkins ({0}) \u5df2\u7d93\u53ef\u4ee5\u4e0b\u8f09 (\u6539\u7248\u8a18\u9304)\u3002 +UpgradeComplete=\u5df2\u6210\u529f\u5347\u7d1a\u5230 Jenkins {0}\uff0c\u6b63\u5728\u7b49\u5019\u91cd\u65b0\u555f\u52d5\u3002 +UpgradeCompleteRestartNotSupported=\u5df2\u6210\u529f\u5347\u7d1a\u5230 Jenkins {0}\uff0c\u6b63\u5728\u7b49\u5019\u91cd\u65b0\u555f\u52d5\u3002 +UpgradeProgress=\u6b63\u5728\u57f7\u884c Jenkins {0} \u5347\u7d1a\u4f5c\u696d\u3002 +UpgradeFailed=\u5347\u7d1a\u5230 Jenkins {0} \u6642\u5931\u6557\: {1}\u3002 Or\ Upgrade\ Automatically=\u6216\u662f\u81ea\u52d5\u5347\u7248 +Retry=\u91cd\u8a66 diff --git a/core/src/main/resources/hudson/model/UpdateCenter/DownloadJob/Failure/status_zh_TW.properties b/core/src/main/resources/hudson/model/UpdateCenter/DownloadJob/Failure/status_zh_TW.properties index 8783fa6b2e12..a19e5656b9f3 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/DownloadJob/Failure/status_zh_TW.properties +++ b/core/src/main/resources/hudson/model/UpdateCenter/DownloadJob/Failure/status_zh_TW.properties @@ -21,4 +21,4 @@ # THE SOFTWARE. Failure=\u5931\u6557 -Details=\u8A73\u7D30\u8CC7\u6599 +Details=\u8a73\u60c5 diff --git a/core/src/main/resources/hudson/model/UpdateCenter/DownloadJob/Installing/status_zh_TW.properties b/core/src/main/resources/hudson/model/UpdateCenter/DownloadJob/Installing/status_zh_TW.properties index dd44a261c03d..a981577d166b 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/DownloadJob/Installing/status_zh_TW.properties +++ b/core/src/main/resources/hudson/model/UpdateCenter/DownloadJob/Installing/status_zh_TW.properties @@ -20,4 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Installing=\u5B89\u88DD\u4E2D +Installing=\u6b63\u5728\u5b89\u88dd diff --git a/core/src/main/resources/hudson/model/UpdateCenter/DownloadJob/Skipped/status_pt_BR.properties b/core/src/main/resources/hudson/model/UpdateCenter/DownloadJob/Skipped/status_pt_BR.properties new file mode 100644 index 000000000000..5bd55e6b8e96 --- /dev/null +++ b/core/src/main/resources/hudson/model/UpdateCenter/DownloadJob/Skipped/status_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Skipped=Desconsiderado diff --git a/core/src/main/resources/hudson/model/UpdateCenter/DownloadJob/Skipped/status_zh_TW.properties b/core/src/main/resources/hudson/model/UpdateCenter/DownloadJob/Skipped/status_zh_TW.properties new file mode 100644 index 000000000000..bbc08e3a824a --- /dev/null +++ b/core/src/main/resources/hudson/model/UpdateCenter/DownloadJob/Skipped/status_zh_TW.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Skipped=\u5df2\u7565\u904e diff --git a/core/src/main/resources/hudson/model/UpdateCenter/EnableJob/row_pt_BR.properties b/core/src/main/resources/hudson/model/UpdateCenter/EnableJob/row_pt_BR.properties new file mode 100644 index 000000000000..febc3941680f --- /dev/null +++ b/core/src/main/resources/hudson/model/UpdateCenter/EnableJob/row_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Enabled\ Dependency=Depend\u00EAncia\ habilitada diff --git a/core/src/main/resources/hudson/model/UpdateCenter/EnableJob/row_zh_TW.properties b/core/src/main/resources/hudson/model/UpdateCenter/EnableJob/row_zh_TW.properties new file mode 100644 index 000000000000..c456059cc8d7 --- /dev/null +++ b/core/src/main/resources/hudson/model/UpdateCenter/EnableJob/row_zh_TW.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Enabled\ Dependency=\u5df2\u555f\u7528\u7684\u76f8\u4f9d\u6027 diff --git a/core/src/main/resources/hudson/model/UpdateCenter/NoOpJob/row_pt_BR.properties b/core/src/main/resources/hudson/model/UpdateCenter/NoOpJob/row_pt_BR.properties new file mode 100644 index 000000000000..a8a6deaab722 --- /dev/null +++ b/core/src/main/resources/hudson/model/UpdateCenter/NoOpJob/row_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Already\ Installed=J\u00E1\ instalado diff --git a/core/src/main/resources/hudson/model/UpdateCenter/NoOpJob/row_zh_TW.properties b/core/src/main/resources/hudson/model/UpdateCenter/NoOpJob/row_zh_TW.properties new file mode 100644 index 000000000000..45ec2dc966be --- /dev/null +++ b/core/src/main/resources/hudson/model/UpdateCenter/NoOpJob/row_zh_TW.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Already\ Installed=\u65e9\u5df2\u5b89\u88dd diff --git a/core/src/main/resources/hudson/model/UpdateCenter/RestartJenkinsJob/Pending/status_zh_TW.properties b/core/src/main/resources/hudson/model/UpdateCenter/RestartJenkinsJob/Pending/status_zh_TW.properties index 02e1a1460356..0c9453a9e5a3 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/RestartJenkinsJob/Pending/status_zh_TW.properties +++ b/core/src/main/resources/hudson/model/UpdateCenter/RestartJenkinsJob/Pending/status_zh_TW.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Pending=\u64F1\u7F6E\u4E2D +Pending=\u64f1\u7f6e diff --git a/core/src/main/resources/hudson/model/UpdateCenter/RestartJenkinsJob/Running/status_zh_TW.properties b/core/src/main/resources/hudson/model/UpdateCenter/RestartJenkinsJob/Running/status_zh_TW.properties index 9b7017d2f08f..6aa7185d0da3 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/RestartJenkinsJob/Running/status_zh_TW.properties +++ b/core/src/main/resources/hudson/model/UpdateCenter/RestartJenkinsJob/Running/status_zh_TW.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2013, Chunghwa Telecom Co., Ltd., Pei-Tang Huang +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Running=\u57f7\u884c\u4e2d +Running=\u6b63\u5728\u57f7\u884c diff --git a/core/src/main/resources/hudson/model/UpdateCenter/RestartJenkinsJob/row_zh_TW.properties b/core/src/main/resources/hudson/model/UpdateCenter/RestartJenkinsJob/row_zh_TW.properties index 567aec664b35..ef0a02f78232 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/RestartJenkinsJob/row_zh_TW.properties +++ b/core/src/main/resources/hudson/model/UpdateCenter/RestartJenkinsJob/row_zh_TW.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Restarting\ Jenkins=\u6B63\u5728\u91CD\u65B0\u555F\u52D5Jenkins +Restarting\ Jenkins=\u6b63\u5728\u91cd\u65b0\u555f\u52d5 Jenkins diff --git a/core/src/main/resources/hudson/model/UpdateCenter/body_zh_TW.properties b/core/src/main/resources/hudson/model/UpdateCenter/body_zh_TW.properties index 8673a27129bc..7011f98e939a 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/body_zh_TW.properties +++ b/core/src/main/resources/hudson/model/UpdateCenter/body_zh_TW.properties @@ -1,18 +1,18 @@ # The MIT License -# +# # Copyright (c) 2004-2013, Sun Microsystems, Inc., Chunghwa Telecom Co., Ltd., # and Pei-Tang Huang -# +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: -# +# # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. -# +# # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -20,7 +20,6 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. - -Go\ back\ to\ the\ top\ page=\u56DE\u5230\u9996\u9801 -you\ can\ start\ using\ the\ installed\ plugins\ right\ away=\u4F60\u53EF\u4EE5\u958B\u59CB\u4F7F\u7528\u5DF2\u5B89\u88DD\u597D\u7684\u63D2\u4EF6 -warning=\u7576\u5B89\u88DD\u5B8C\u6210\u4E14\u6C92\u6709\u5DE5\u4F5C\u6B63\u5728\u57F7\u884C\u6642\uFF0C\u91CD\u555FJenkins +warning=\u7576\u5b89\u88dd\u5b8c\u6210\u4e14\u6c92\u6709\u5de5\u4f5c\u6b63\u5728\u57f7\u884c\u6642\uff0c\u91cd\u555f Jenkins +Go\ back\ to\ the\ top\ page=\u56de\u5230\u9996\u9801 +you\ can\ start\ using\ the\ installed\ plugins\ right\ away=\u4f60\u53ef\u4ee5\u958b\u59cb\u4f7f\u7528\u5df2\u5b89\u88dd\u597d\u7684\u5916\u639b diff --git a/core/src/main/resources/hudson/model/UpdateCenter/index.jelly b/core/src/main/resources/hudson/model/UpdateCenter/index.jelly index ae6bbc924005..8e8209cdafba 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/index.jelly +++ b/core/src/main/resources/hudson/model/UpdateCenter/index.jelly @@ -29,52 +29,11 @@ THE SOFTWARE. +

          ${%Installing Plugins/Upgrades}

          - - -
          diff --git a/core/src/main/resources/hudson/model/UpdateCenter/index_zh_TW.properties b/core/src/main/resources/hudson/model/UpdateCenter/index_zh_TW.properties index ecf8faef5920..ec951c1afafd 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/index_zh_TW.properties +++ b/core/src/main/resources/hudson/model/UpdateCenter/index_zh_TW.properties @@ -22,4 +22,4 @@ # THE SOFTWARE. Update\ Center=\u66f4\u65b0\u4e2d\u5fc3 -Installing\ Plugins/Upgrades=\u6B63\u5728\u5B89\u88DD/\u5347\u7D1A Plugins +Installing\ Plugins/Upgrades=\u6b63\u5728\u5b89\u88dd/\u5347\u7d1a\u5916\u639b diff --git a/core/src/main/resources/hudson/model/UpdateCenter/sidepanel.jelly b/core/src/main/resources/hudson/model/UpdateCenter/sidepanel.jelly index d9625aa282f4..a3e3c7b87893 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/sidepanel.jelly +++ b/core/src/main/resources/hudson/model/UpdateCenter/sidepanel.jelly @@ -31,7 +31,7 @@ THE SOFTWARE. - + diff --git a/core/src/main/resources/hudson/model/UpdateCenter/sidepanel_zh_TW.properties b/core/src/main/resources/hudson/model/UpdateCenter/sidepanel_zh_TW.properties index f0a33307b74f..9b5510b5e4f1 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/sidepanel_zh_TW.properties +++ b/core/src/main/resources/hudson/model/UpdateCenter/sidepanel_zh_TW.properties @@ -21,6 +21,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Back\ to\ Dashboard=\u8FD4\u56DEDashboard Manage\ Jenkins=\u7ba1\u7406 Jenkins Manage\ Plugins=\u7BA1\u7406\u5916\u639B\u7A0B\u5F0F +Back\ to\ Dashboard=\u8fd4\u56de\u8cc7\u8a0a\u4e3b\u9801 diff --git a/core/src/main/resources/hudson/model/UpdateCenter/update-center.js b/core/src/main/resources/hudson/model/UpdateCenter/update-center.js new file mode 100644 index 000000000000..acb0e8ee559a --- /dev/null +++ b/core/src/main/resources/hudson/model/UpdateCenter/update-center.js @@ -0,0 +1,38 @@ +function submitScheduleForm(el) { + var form = document.getElementById("scheduleRestart"); + form.action = el.checked ? "safeRestart" : "cancelRestart"; + crumb.appendToForm(form); + form.submit(); +} + +function refresh() { + window.setTimeout(function() { + new Ajax.Request("./body", { + onSuccess: function(rsp) { + var div = document.createElement('div'); + div.innerHTML = rsp.responseText; + + var rows = div.children[0].rows; + for(var i=0; i - - - + + + +
          + +
          +
          diff --git a/core/src/main/resources/hudson/model/UsageStatistics/global.properties b/core/src/main/resources/hudson/model/UsageStatistics/global.properties index 8b38ffef7695..01971f396652 100644 --- a/core/src/main/resources/hudson/model/UsageStatistics/global.properties +++ b/core/src/main/resources/hudson/model/UsageStatistics/global.properties @@ -21,5 +21,5 @@ # THE SOFTWARE. statsBlurb=\ - Help make Jenkins better by sending anonymous usage statistics and crash reports to the Jenkins project. + Help make Jenkins better by sending anonymous usage statistics and crash reports to the Jenkins project diff --git a/core/src/main/resources/hudson/model/User/builds.jelly b/core/src/main/resources/hudson/model/User/builds.jelly index 5f9d042f957c..8387f082829a 100644 --- a/core/src/main/resources/hudson/model/User/builds.jelly +++ b/core/src/main/resources/hudson/model/User/builds.jelly @@ -27,12 +27,8 @@ THE SOFTWARE.

          - ${%title(it)}

          -

          - ${%disclaimer} -

          diff --git a/core/src/main/resources/hudson/model/User/builds.properties b/core/src/main/resources/hudson/model/User/builds.properties index efbcf60db211..b3a7cb0edc77 100644 --- a/core/src/main/resources/hudson/model/User/builds.properties +++ b/core/src/main/resources/hudson/model/User/builds.properties @@ -20,4 +20,3 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. title=Builds for {0} -disclaimer=This does not include stages from pipeline jobs. diff --git a/core/src/main/resources/hudson/model/User/configure_zh_TW.properties b/core/src/main/resources/hudson/model/User/configure_zh_TW.properties index 6d1ae29c3061..67f56b774d6c 100644 --- a/core/src/main/resources/hudson/model/User/configure_zh_TW.properties +++ b/core/src/main/resources/hudson/model/User/configure_zh_TW.properties @@ -1,18 +1,18 @@ # The MIT License -# +# # Copyright (c) 2004-2013, Sun Microsystems, Inc., Chunghwa Telecom Co., Ltd., # and Pei-Tang Huang -# +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: -# +# # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. -# +# # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -20,8 +20,7 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. - -title=\u4f7f\u7528\u8005 ''{0}'' \u8a2d\u5b9a -Full\ name=\u60a8\u7684\u540d\u5b57 +title=\u4f7f\u7528\u8005 ''{0}'' \u7684\u8a2d\u5b9a +Full\ name=\u5168\u540d Description=\u8aaa\u660e Save=\u5132\u5b58 diff --git a/core/src/main/resources/hudson/model/User/delete_zh_TW.properties b/core/src/main/resources/hudson/model/User/delete_zh_TW.properties index 8277d9d4868c..4b0d9a13858a 100644 --- a/core/src/main/resources/hudson/model/User/delete_zh_TW.properties +++ b/core/src/main/resources/hudson/model/User/delete_zh_TW.properties @@ -1,25 +1,2 @@ -# The MIT License -# -# Copyright (c) 2013, Chunghwa Telecom Co., Ltd., Pei-Tang Huang -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -delete.user=\u60a8\u78ba\u5b9a\u8981\u7531 Jenkins \u4e2d\u522a\u9664\u9019\u500b\u4f7f\u7528\u8005? ({0}) - +delete.user=\u60a8\u78ba\u5b9a\u8981\u522a\u9664 Jenkins \u4f7f\u7528\u8005\u300c{0}\u300d\u55ce\uff1f Yes=\u662f diff --git a/core/src/main/resources/hudson/model/User/index.jelly b/core/src/main/resources/hudson/model/User/index.jelly index b16f2b3e6376..9e4046dc746b 100644 --- a/core/src/main/resources/hudson/model/User/index.jelly +++ b/core/src/main/resources/hudson/model/User/index.jelly @@ -27,7 +27,9 @@ THE SOFTWARE.

          - + + + ${it.fullName}

          diff --git a/core/src/main/resources/hudson/model/User/index_pt_BR.properties b/core/src/main/resources/hudson/model/User/index_pt_BR.properties index c3fa7344c9a2..f5fea2185c1c 100644 --- a/core/src/main/resources/hudson/model/User/index_pt_BR.properties +++ b/core/src/main/resources/hudson/model/User/index_pt_BR.properties @@ -1,4 +1,24 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -Jenkins\ User\ Id=Identifica\u00e7\u00e3o de Usu\u00E1rio Groups=Grupos +Jenkins\ User\ ID=ID\ do\ usu\u00E1rio\ do\ Jenkins diff --git a/core/src/main/resources/hudson/model/User/sidepanel.jelly b/core/src/main/resources/hudson/model/User/sidepanel.jelly index 46bad7a60514..4093ab5ea00a 100644 --- a/core/src/main/resources/hudson/model/User/sidepanel.jelly +++ b/core/src/main/resources/hudson/model/User/sidepanel.jelly @@ -33,8 +33,8 @@ THE SOFTWARE. - - + + diff --git a/core/src/main/resources/hudson/model/View/AsynchPeople/index.jelly b/core/src/main/resources/hudson/model/View/AsynchPeople/index.jelly index 7a8313a79cac..ef6d4bc68850 100644 --- a/core/src/main/resources/hudson/model/View/AsynchPeople/index.jelly +++ b/core/src/main/resources/hudson/model/View/AsynchPeople/index.jelly @@ -28,84 +28,36 @@ THE SOFTWARE. -

          - - ${%People} - - - - ${it.parent.displayName} -

          -

          ${%blurb}

          - - - - - - - - - +
          - ${%User ID}${%Name}${%Last Commit Activity}${%On}
          + + + + + + + + + + diff --git a/core/src/main/resources/hudson/model/View/AsynchPeople/index_ar.properties b/core/src/main/resources/hudson/model/View/AsynchPeople/index_ar.properties deleted file mode 100644 index a9c8e758f05f..000000000000 --- a/core/src/main/resources/hudson/model/View/AsynchPeople/index_ar.properties +++ /dev/null @@ -1,27 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Last\ Active=\u0622\u062E\u0631 \u0646\u0634\u0627\u0637 -Name=\u0627\u0644\u0627\u0633\u0645 -On=\u0641\u064A -People=\u0627\u0644\u0623\u0641\u0631\u0627\u062F -User\ Id=\u0645\u0639\u0631\u0641 \u0627\u0644\u0645\u0633\u062A\u062E\u062F\u0645 diff --git a/core/src/main/resources/hudson/model/View/AsynchPeople/index_bg.properties b/core/src/main/resources/hudson/model/View/AsynchPeople/index_bg.properties index 8f97078287e8..37cf81ebfe97 100644 --- a/core/src/main/resources/hudson/model/View/AsynchPeople/index_bg.properties +++ b/core/src/main/resources/hudson/model/View/AsynchPeople/index_bg.properties @@ -28,7 +28,7 @@ People=\ \u041f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438 All\ People=\ \u0412\u0441\u0438\u0447\u043a\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438 -User\ Id=\ +User\ ID=\ \u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043d\u0430 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b blurb=\ \u0412\u043a\u043b\u044e\u0447\u0432\u0430 \u0432\u0441\u0438\u0447\u043a\u0438 \u043f\u043e\u0437\u043d\u0430\u0442\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438, \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u043d\u043e \u0442\u0435\u0437\u0438, \u043a\u043e\u0438\u0442\u043e \u0442\u0435\u043a\u0443\u0449\u0430\u0442\u0430 \u043e\u0431\u043b\u0430\u0441\u0442\ diff --git a/core/src/main/resources/hudson/model/View/AsynchPeople/index_ca.properties b/core/src/main/resources/hudson/model/View/AsynchPeople/index_ca.properties index 1aeb0b601784..2c0a54936568 100644 --- a/core/src/main/resources/hudson/model/View/AsynchPeople/index_ca.properties +++ b/core/src/main/resources/hudson/model/View/AsynchPeople/index_ca.properties @@ -4,4 +4,4 @@ Last\ Active=Darrer actiu Name=Nom On=Actiu People=Persones -User\ Id=Identificador d''''usuari +User\ ID=Identificador d''''usuari diff --git a/core/src/main/resources/hudson/model/View/AsynchPeople/index_cs.properties b/core/src/main/resources/hudson/model/View/AsynchPeople/index_cs.properties index e81a79eb0165..1b2211e3d495 100644 --- a/core/src/main/resources/hudson/model/View/AsynchPeople/index_cs.properties +++ b/core/src/main/resources/hudson/model/View/AsynchPeople/index_cs.properties @@ -24,4 +24,4 @@ Last\ Active=Posledn\u00ED aktivita Name=Jm\u00E9no On=Na People=Lid\u00E9 -User\ Id=U\u017Eivatelsk\u00E9 ID +User\ ID=U\u017Eivatelsk\u00E9 ID diff --git a/core/src/main/resources/hudson/model/View/AsynchPeople/index_da.properties b/core/src/main/resources/hudson/model/View/AsynchPeople/index_da.properties index 37e54399303e..f4e1e48d6f89 100644 --- a/core/src/main/resources/hudson/model/View/AsynchPeople/index_da.properties +++ b/core/src/main/resources/hudson/model/View/AsynchPeople/index_da.properties @@ -25,5 +25,5 @@ Last\ Active=Sidst aktiv People=Personer Name=Navn All\ People=Alle Personer -User\ Id=Bruger-ID +User\ ID=Bruger-ID blurb=Inkluderer alle kendte "brugere", inklusiv login-identiteter som kan findes ud fra nuv\u00E6rende sikkerhedsniveau samt personer n\u00E6vnt i commit-beskeder i registrerede changelogs. diff --git a/core/src/main/resources/hudson/model/View/AsynchPeople/index_de.properties b/core/src/main/resources/hudson/model/View/AsynchPeople/index_de.properties index 2dc1e3c71622..7451548bafbf 100644 --- a/core/src/main/resources/hudson/model/View/AsynchPeople/index_de.properties +++ b/core/src/main/resources/hudson/model/View/AsynchPeople/index_de.properties @@ -24,6 +24,6 @@ Name=Name On=Job All\ People=Alle Benutzer People=Benutzer -User\ Id=Jenkins Benutzer Id +User\ ID=Jenkins Benutzer Id blurb=Beinhaltet alle bekannten Benutzer, einschlie\u00DFlich der Login-Benutzer des aktuellen Sicherheitsbereichs, sowie Namen, die in Commit-Kommentaren von Changelogs erw\u00E4hnt werden. Last\ Commit\ Activity=Letzte SCM-Aktivit\u00E4t diff --git a/core/src/main/resources/hudson/model/View/AsynchPeople/index_el.properties b/core/src/main/resources/hudson/model/View/AsynchPeople/index_el.properties index f9e8fd487e16..d5726bd7a422 100644 --- a/core/src/main/resources/hudson/model/View/AsynchPeople/index_el.properties +++ b/core/src/main/resources/hudson/model/View/AsynchPeople/index_el.properties @@ -24,4 +24,4 @@ Last\ Active=\u03A4\u03B5\u03BB\u03B5\u03C5\u03C4\u03B1\u03AF\u03B1 \u03C7\u03C1 Name=\u038C\u03BD\u03BF\u03BC\u03B1 On=\u03A4\u03B5\u03BB\u03B5\u03C5\u03C4\u03B1\u03AF\u03B1 \u03B5\u03BD\u03B5\u03C1\u03B3\u03AE \u03B1\u03BD\u03B1\u03C6\u03BF\u03C1\u03AC \u03C3\u03C4\u03BF project People=\u0386\u03BD\u03B8\u03C1\u03C9\u03C0\u03BF\u03B9 -User\ Id=Id \u03C7\u03C1\u03AE\u03C3\u03C4\u03B7 +User\ ID=Id \u03C7\u03C1\u03AE\u03C3\u03C4\u03B7 diff --git a/core/src/main/resources/hudson/model/View/AsynchPeople/index_es.properties b/core/src/main/resources/hudson/model/View/AsynchPeople/index_es.properties index 71372f35e418..e3169cefb1d4 100644 --- a/core/src/main/resources/hudson/model/View/AsynchPeople/index_es.properties +++ b/core/src/main/resources/hudson/model/View/AsynchPeople/index_es.properties @@ -26,5 +26,5 @@ On=En All\ People=Todos People=Actividad -User\ Id=Nombre de Usario +User\ ID=Nombre de Usario blurb=Incluye todos los "usuarios" conocidos, incluyendo las identidades de acceso que se pueden enumerar en el dominio de seguridad actual, as\u00ED como las personas mencionadas en los mensajes de confirmaci\u00F3n en los registros de cambios registrados. diff --git a/core/src/main/resources/hudson/model/View/AsynchPeople/index_es_AR.properties b/core/src/main/resources/hudson/model/View/AsynchPeople/index_es_AR.properties index 48f85499964a..36c7f14c1076 100644 --- a/core/src/main/resources/hudson/model/View/AsynchPeople/index_es_AR.properties +++ b/core/src/main/resources/hudson/model/View/AsynchPeople/index_es_AR.properties @@ -3,4 +3,4 @@ Last\ Active=\u00FAltimo activo Name=Nombre People=Personas -User\ Id=ID del usuario +User\ ID=ID del usuario diff --git a/core/src/main/resources/hudson/model/View/AsynchPeople/index_fi.properties b/core/src/main/resources/hudson/model/View/AsynchPeople/index_fi.properties index 8eb0aab87cf0..5dba6e4b1d53 100644 --- a/core/src/main/resources/hudson/model/View/AsynchPeople/index_fi.properties +++ b/core/src/main/resources/hudson/model/View/AsynchPeople/index_fi.properties @@ -24,4 +24,4 @@ Last\ Active=Viimeksi Aktiivisena Name=Nimi On=Viimeksi Aktiivinen Ty\u00F6 People=K\u00E4ytt\u00E4j\u00E4t -User\ Id=K\u00E4ytt\u00E4j\u00E4tunnus +User\ ID=K\u00E4ytt\u00E4j\u00E4tunnus diff --git a/core/src/main/resources/hudson/model/View/AsynchPeople/index_fr.properties b/core/src/main/resources/hudson/model/View/AsynchPeople/index_fr.properties index 3bfc37e8159f..bb620a2dc18e 100644 --- a/core/src/main/resources/hudson/model/View/AsynchPeople/index_fr.properties +++ b/core/src/main/resources/hudson/model/View/AsynchPeople/index_fr.properties @@ -22,8 +22,8 @@ Name=Nom complet All\ People=Tout le monde -Last\ Active=Dernire activit +Last\ Commit\ Activity=Derni\u00e8re activit\u00E9 de commit On=Sur People=Utilisateurs -User\ Id=Identifiant +User\ ID=Identifiant blurb=Inclus tout les utilisateurs connus, ce qui comprend les login que le domaine de s\u00E9curit\u00E9 (security realm) actuel peut \u00E9num\u00E9rer, ainsi que les personnes mentionn\u00E9(e)s dans les message de commit reli\u00E9s au changelogs. diff --git a/core/src/main/resources/hudson/model/View/AsynchPeople/index_hu.properties b/core/src/main/resources/hudson/model/View/AsynchPeople/index_hu.properties index c71fa161a001..1204de4b64e2 100644 --- a/core/src/main/resources/hudson/model/View/AsynchPeople/index_hu.properties +++ b/core/src/main/resources/hudson/model/View/AsynchPeople/index_hu.properties @@ -25,4 +25,4 @@ Last\ Active=Utols\u00F3 aktivit\u00E1s Name=N\u00E9v On=Ebben People=Emberek -User\ Id=Felhaszn\u00E1l\u00F3 azonos\u00EDt\u00F3 +User\ ID=Felhaszn\u00E1l\u00F3 azonos\u00EDt\u00F3 diff --git a/core/src/main/resources/hudson/model/View/AsynchPeople/index_ja.properties b/core/src/main/resources/hudson/model/View/AsynchPeople/index_ja.properties index fa8162178bab..06e6427d2065 100644 --- a/core/src/main/resources/hudson/model/View/AsynchPeople/index_ja.properties +++ b/core/src/main/resources/hudson/model/View/AsynchPeople/index_ja.properties @@ -20,7 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -User\ Id=\u30e6\u30fc\u30b6\u30fcID +User\ ID=\u30e6\u30fc\u30b6\u30fcID Name=\u540d\u524d Last\ Active=\u6700\u8fd1\u306e\u6d3b\u52d5 On=\u5834\u6240 diff --git a/core/src/main/resources/hudson/model/View/AsynchPeople/index_ko.properties b/core/src/main/resources/hudson/model/View/AsynchPeople/index_ko.properties index c36e71e58a30..cdc20f664691 100644 --- a/core/src/main/resources/hudson/model/View/AsynchPeople/index_ko.properties +++ b/core/src/main/resources/hudson/model/View/AsynchPeople/index_ko.properties @@ -24,4 +24,3 @@ Last\ Active=\uB9C8\uC9C0\uB9C9 \uD65C\uB3D9\uC0AC\uD56D Name=\uC774\uB984 On=\uC811\uC18D \uC911 People=\uC0AC\uC6A9\uC790 -User\ Id= diff --git a/core/src/main/resources/hudson/model/View/AsynchPeople/index_lt.properties b/core/src/main/resources/hudson/model/View/AsynchPeople/index_lt.properties index 43e2b4e3bc41..e06e63585d95 100644 --- a/core/src/main/resources/hudson/model/View/AsynchPeople/index_lt.properties +++ b/core/src/main/resources/hudson/model/View/AsynchPeople/index_lt.properties @@ -24,4 +24,4 @@ All\ People=Visi vartotojai Last\ Active=Paskutiniai Veiksmai Name=Vardas People=Vartotojai -User\ Id=Slapyvardis +User\ ID=Slapyvardis diff --git a/core/src/main/resources/hudson/model/View/AsynchPeople/index_lv.properties b/core/src/main/resources/hudson/model/View/AsynchPeople/index_lv.properties index 927d020d3c67..eb87dd8e7aec 100644 --- a/core/src/main/resources/hudson/model/View/AsynchPeople/index_lv.properties +++ b/core/src/main/resources/hudson/model/View/AsynchPeople/index_lv.properties @@ -25,4 +25,4 @@ Last\ Active=Ped\u0113j\u0101 aktivit\u0101te Name=V\u0101rds On=Uz People=Cilv\u0113ki -User\ Id=Lietot\u0101ja identifikators +User\ ID=Lietot\u0101ja identifikators diff --git a/core/src/main/resources/hudson/model/View/AsynchPeople/index_nb_NO.properties b/core/src/main/resources/hudson/model/View/AsynchPeople/index_nb_NO.properties index 6aa6c2e8508d..1bf1361e303d 100644 --- a/core/src/main/resources/hudson/model/View/AsynchPeople/index_nb_NO.properties +++ b/core/src/main/resources/hudson/model/View/AsynchPeople/index_nb_NO.properties @@ -24,4 +24,4 @@ Last\ Active=Sist aktiv Name=Navn On=P\u00E5 People=Folk -User\ Id=Bruker Id +User\ ID=Bruker Id diff --git a/core/src/main/resources/hudson/model/View/AsynchPeople/index_nl.properties b/core/src/main/resources/hudson/model/View/AsynchPeople/index_nl.properties index f696b19bbd21..8d3da753d0f5 100644 --- a/core/src/main/resources/hudson/model/View/AsynchPeople/index_nl.properties +++ b/core/src/main/resources/hudson/model/View/AsynchPeople/index_nl.properties @@ -25,5 +25,5 @@ All\ People=Iedereen Last\ Active=Laatst actief On= People=Mensen -User\ Id=Id gebruiker +User\ ID=Id gebruiker blurb=Dit zijn alle bekende \u201Cgebruikers\u201D, inclusief geregistreerde inloggers, plus alle mensen genoemd in wijzingings logboeken die wijzinging hebben gedaan. diff --git a/core/src/main/resources/hudson/model/View/AsynchPeople/index_pt_BR.properties b/core/src/main/resources/hudson/model/View/AsynchPeople/index_pt_BR.properties index 960d16f03e40..4b08d44a7031 100644 --- a/core/src/main/resources/hudson/model/View/AsynchPeople/index_pt_BR.properties +++ b/core/src/main/resources/hudson/model/View/AsynchPeople/index_pt_BR.properties @@ -21,9 +21,9 @@ # THE SOFTWARE. Name=Nome -Last\ Active=\u00DAltima atividade On=Em People=Pessoas All\ People=Todas as pessoas -User\ Id=ID do usu\u00E1rio -blurb=Inclui todos os "usu\u00E1rios" conhecidos, incluindo identidades de usu\u00e1rios as quais o reino de seguran\u00E7a consegue enumerar, assim como pessoas mencionadas nas mensagens de commits nos registros de mudan\u00E7as gravados. +User\ ID=ID do usu\u00E1rio +blurb=Inclui todos os "usu\u00E1rios" conhecidos, incluindo identidades de usu\u00E1rios as quais o dom\u00EDnio de seguran\u00E7a consegue enumerar, assim como pessoas mencionadas nas mensagens de confirma\u00E7\u00E3o nos registros de mudan\u00E7as gravados. +Last\ Commit\ Activity=\u00DAltima\ atividade\ de\ confirma\u00E7\u00E3o diff --git a/core/src/main/resources/hudson/model/View/AsynchPeople/index_pt_PT.properties b/core/src/main/resources/hudson/model/View/AsynchPeople/index_pt_PT.properties index bae373c40b66..6594baaf85c1 100644 --- a/core/src/main/resources/hudson/model/View/AsynchPeople/index_pt_PT.properties +++ b/core/src/main/resources/hudson/model/View/AsynchPeople/index_pt_PT.properties @@ -4,4 +4,4 @@ Last\ Active=Ultima Actividade Name=Nome On=Ligado People=Pessoas -User\ Id=Id do Utilizado +User\ ID=Id do Utilizado diff --git a/core/src/main/resources/hudson/model/View/AsynchPeople/index_ro.properties b/core/src/main/resources/hudson/model/View/AsynchPeople/index_ro.properties index 36f88fb85302..08df8df5d343 100644 --- a/core/src/main/resources/hudson/model/View/AsynchPeople/index_ro.properties +++ b/core/src/main/resources/hudson/model/View/AsynchPeople/index_ro.properties @@ -24,4 +24,4 @@ Last\ Active=Activ ultima oar\u0103 Name=Nume On=Pe People=Contribuitori -User\ Id=Id utilizator +User\ ID=Id utilizator diff --git a/core/src/main/resources/hudson/model/View/AsynchPeople/index_sr.properties b/core/src/main/resources/hudson/model/View/AsynchPeople/index_sr.properties index a44ab2742a40..def84ef624f4 100644 --- a/core/src/main/resources/hudson/model/View/AsynchPeople/index_sr.properties +++ b/core/src/main/resources/hudson/model/View/AsynchPeople/index_sr.properties @@ -2,9 +2,8 @@ People=\u041A\u043E\u0440\u0438\u0441\u043D\u0438\u0446\u0438 blurb=\u0422\u0430\u0431\u0435\u043B\u0430 \u0441\u0432\u0438\u0445 Jenkins \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u043A\u0430, \u0443\u043A\u0459\u0443\u0447\u0443\u0458\u0443\u045B\u0438 \u0441\u0432\u0435 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u043A\u0435 \u043A\u043E\u0458e \u0441\u0438\u0441\u0442\u0435\u043C \u0430\u0443\u0442\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0446\u0438\u0458\u0435 \u043C\u043E\u0436\u0435 \u043D\u0430\u0432\u0435\u0441\u0442\u0438, \u0438 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u0446\u0438 \u043D\u0430\u0432\u0435\u0434\u0435\u043D\u0438 \u0443 \u043A\u043E\u043C\u0438\u0442-\u043F\u043E\u0440\u0443\u043A\u0430\u043C\u0430 \u0435\u0432\u0438\u0434\u0435\u043D\u0442\u0438\u0440\u0430\u043D\u0438 \u0443 \u0434\u043D\u0435\u0432\u043D\u0438\u043A\u0430\u043C\u0430 \u043F\u0440\u043E\u043C\u0435\u043D\u0430. -User\ Id=\u0418\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0446\u0438\u043E\u043D\u0438 \u0431\u0440\u043E\u0458 +User\ ID=\u0418\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0446\u0438\u043E\u043D\u0438 \u0431\u0440\u043E\u0458 Name=\u0418\u043C\u0435 Last\ Commit\ Activity=\u0417\u0430\u0434\u045A\u0435 \u0430\u043A\u0442\u0438\u0432\u0430\u043D On=\u043D\u0430 All\ People=\u0421\u0432\u0438 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u0446\u0438 -Last\ Active=\u0417\u0430\u0434\u045A\u0430 \u0430\u043A\u0442\u0438\u0432\u043D\u043E\u0441\u0442 diff --git a/core/src/main/resources/hudson/model/View/AsynchPeople/index_sv_SE.properties b/core/src/main/resources/hudson/model/View/AsynchPeople/index_sv_SE.properties index 6d299d167705..812769679f08 100644 --- a/core/src/main/resources/hudson/model/View/AsynchPeople/index_sv_SE.properties +++ b/core/src/main/resources/hudson/model/View/AsynchPeople/index_sv_SE.properties @@ -25,5 +25,5 @@ Last\ Active=Senast aktiv Name=Namn On=P\u00E5 People=Personer -User\ Id=Anv\u00E4ndar-ID +User\ ID=Anv\u00E4ndar-ID blurb=Alla k\u00E4nda "anv\u00E4ndare", inklusive identiteter som det aktuella s\u00E4kerhetsomr\u00E5det kan numrera samt personer n\u00E4mnda i kommit-meddelanden i sparade f\u00F6r\u00E4ndringsloggar. diff --git a/core/src/main/resources/hudson/model/View/AsynchPeople/index_tr.properties b/core/src/main/resources/hudson/model/View/AsynchPeople/index_tr.properties index 452ed949ba48..3f272c0f2603 100644 --- a/core/src/main/resources/hudson/model/View/AsynchPeople/index_tr.properties +++ b/core/src/main/resources/hudson/model/View/AsynchPeople/index_tr.properties @@ -24,4 +24,4 @@ Name=\u0130sim Last\ Active=Son Aktif On=A\u00e7\u0131k People=\u0130nsanlar -User\ Id=Kullan\u0131c\u0131 ad\u0131 +User\ ID=Kullan\u0131c\u0131 ad\u0131 diff --git a/core/src/main/resources/hudson/model/View/AsynchPeople/index_uk.properties b/core/src/main/resources/hudson/model/View/AsynchPeople/index_uk.properties index b8cbbc04e8f8..02444de307d3 100644 --- a/core/src/main/resources/hudson/model/View/AsynchPeople/index_uk.properties +++ b/core/src/main/resources/hudson/model/View/AsynchPeople/index_uk.properties @@ -4,4 +4,4 @@ Last\ Active=\u0427\u0430\u0441 \u043E\u0441\u0442\u0430\u043D\u043D\u044C\u043E Name=\u0406\u043C\u2019\u044F On=\u041F\u0440\u043E\u0435\u043A\u0442 People=\u041B\u044E\u0434\u0438 -User\ Id=\u041B\u043E\u0433\u0456\u043D +User\ ID=\u041B\u043E\u0433\u0456\u043D diff --git a/core/src/main/resources/hudson/model/View/AsynchPeople/index_zh_TW.properties b/core/src/main/resources/hudson/model/View/AsynchPeople/index_zh_TW.properties index c8c158966140..c355f15327e4 100644 --- a/core/src/main/resources/hudson/model/View/AsynchPeople/index_zh_TW.properties +++ b/core/src/main/resources/hudson/model/View/AsynchPeople/index_zh_TW.properties @@ -20,10 +20,11 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. - +blurb=\u5305\u542b\u6240\u6709\u5df2\u77e5\u7684\u300c\u4f7f\u7528\u8005\u300d\uff0c\u6db5\u84cb\u76ee\u524d\u7684\u5b89\u5168\u9818\u57df\u53ef\u5217\u8209\u7684\u767b\u5165\u8eab\u4efd\uff0c\u4ee5\u53ca\u8b8a\u66f4\u8a18\u9304\u4e2d\u63d0\u4ea4\u8a0a\u606f\u88e1\u63d0\u5230\u7684\u4eba\u54e1\u3002 People=\u4eba\u54e1 -User\ Id=\u4f7f\u7528\u8005 ID +User\ ID=\u4f7f\u7528\u8005 ID Name=\u540d\u7a31 Last\ Active=\u6700\u8fd1\u4e00\u6b21\u6d3b\u52d5 -On=\u6a21\u7d44 -All\ People=\u6240\u6709\u4EBA\u54E1 +On=\u65bc +All\ People=\u6240\u6709\u4eba\u54e1 +Last\ Commit\ Activity=\u6700\u5f8c\u63d0\u4ea4\u52d5\u614b diff --git a/core/src/main/resources/hudson/model/View/AsynchPeople/people-resources.js b/core/src/main/resources/hudson/model/View/AsynchPeople/people-resources.js new file mode 100644 index 000000000000..742edca86429 --- /dev/null +++ b/core/src/main/resources/hudson/model/View/AsynchPeople/people-resources.js @@ -0,0 +1,57 @@ +function display(data) { + var p = document.getElementById('people'); + p.show(); + var rootURL = document.head.getAttribute('data-rooturl'); + for (var x = 0; data.length > x; x++) { + var e = data[x]; + var id = 'person-' + e.id; + var r = document.getElementById(id); + if (r == null) { + r = document.createElement('tr'); + r.id = id; + p.appendChild(r); + } else { + while (r.firstChild) { + r.removeChild(r.firstChild); + } + } + + var d = document.createElement('td'); + var wrapper = document.createElement('div'); + wrapper.className = 'jenkins-table__cell__button-wrapper'; + d.className = 'jenkins-table__cell--tight jenkins-table__icon'; + var icon = document.getElementById('person-circle') + wrapper.innerHTML = icon.children[0].outerHTML; + d.appendChild(wrapper); + r.appendChild(d); + + d = document.createElement('td'); + var a = document.createElement('a'); + a.href = rootURL + "/" + e.url; + a.className = "jenkins-table__link" + a.appendChild(document.createTextNode(e.id)); + d.appendChild(a); + r.appendChild(d); + + d = document.createElement('td'); + d.appendChild(document.createTextNode(e.fullName)); + r.appendChild(d); + + d = document.createElement('td'); + d.setAttribute('data', e.timeSortKey); + d.appendChild(document.createTextNode(e.lastChangeTimeString)); + r.appendChild(d); + + d = document.createElement('td'); + if (e.projectUrl != null) { + a = document.createElement('a'); + a.href = rootURL + "/" + e.projectUrl; + a.className = 'jenkins-table__link model-link inside'; + a.appendChild(document.createTextNode(e.projectFullDisplayName)); + d.appendChild(a); + } + r.appendChild(d); + + ts_refresh(p); + } +} diff --git a/core/src/main/resources/hudson/model/View/People/index_ar.properties b/core/src/main/resources/hudson/model/View/People/index_ar.properties deleted file mode 100644 index 607f24471364..000000000000 --- a/core/src/main/resources/hudson/model/View/People/index_ar.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -People=\u0627\u0644\u0645\u0633\u062A\u062E\u062F\u0645\u0648\u0646 diff --git a/core/src/main/resources/hudson/model/View/People/index_zh_TW.properties b/core/src/main/resources/hudson/model/View/People/index_zh_TW.properties index 083d9157ba0f..d6051dacdb9c 100644 --- a/core/src/main/resources/hudson/model/View/People/index_zh_TW.properties +++ b/core/src/main/resources/hudson/model/View/People/index_zh_TW.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2013, Chunghwa Telecom Co., Ltd., Pei-Tang Huang +# Copyright 2014 Harald Albers # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -19,5 +19,5 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. - -People=\u4F7F\u7528\u8005 +Moved\ to\ asyncPeople=\u56e0\u70ba\u6548\u80fd\u56e0\u7d20\uff0c\u5df2\u79fb\u52d5\u5230 asynchPeople\u3002 +People=\u4eba\u54e1 diff --git a/core/src/main/resources/hudson/model/View/_api.jelly b/core/src/main/resources/hudson/model/View/_api.jelly index d40233ef67b6..8404aca86701 100644 --- a/core/src/main/resources/hudson/model/View/_api.jelly +++ b/core/src/main/resources/hudson/model/View/_api.jelly @@ -26,8 +26,8 @@ THE SOFTWARE.

          Fetch/Update config.xml

          - To programmatically obtain config.xml, hit this URL. - You can also POST an updated config.xml to the same URL to programmatically + To programmatically obtain config.xml, hit this URL. + You can also POST an updated config.xml to the same URL to programmatically update the configuration of a view.

          diff --git a/core/src/main/resources/hudson/model/View/builds.jelly b/core/src/main/resources/hudson/model/View/builds.jelly index 233b0e78211a..19149c83c413 100644 --- a/core/src/main/resources/hudson/model/View/builds.jelly +++ b/core/src/main/resources/hudson/model/View/builds.jelly @@ -28,18 +28,17 @@ THE SOFTWARE. -

          - - ${%buildHistory(it.class.name=='hudson.model.AllView' ? app.displayName : it.displayName)} -

          -

          - ${%disclaimer} -

          +
          +
          +

          + ${%buildHistory(it.class.name=='hudson.model.AllView' ? app.displayName : it.displayName)} +

          +
          +
          -
          diff --git a/core/src/main/resources/hudson/model/View/builds.properties b/core/src/main/resources/hudson/model/View/builds.properties index 9d25cb555ef6..d319e63a1563 100644 --- a/core/src/main/resources/hudson/model/View/builds.properties +++ b/core/src/main/resources/hudson/model/View/builds.properties @@ -21,4 +21,3 @@ # THE SOFTWARE. buildHistory=Build History of {0} -disclaimer=This history is not guaranteed to include all subtasks executed on the node, e.g. Jenkins Pipeline subtasks will not be displayed. diff --git a/core/src/main/resources/hudson/model/View/builds_ar.properties b/core/src/main/resources/hudson/model/View/builds_ar.properties deleted file mode 100644 index 95c1e944b09c..000000000000 --- a/core/src/main/resources/hudson/model/View/builds_ar.properties +++ /dev/null @@ -1,4 +0,0 @@ -# This file is under the MIT License by authors - -Export\ as\ plain\ XML=\u062A\u0635\u062F\u064A\u0631 \u0643\u0645\u0644\u0641 XML -buildHistory=\u062A\u0627\u0631\u064A\u062E \u0627\u0644\u0628\u0646\u0627\u0621 \u0644\u0640 {0} diff --git a/core/src/main/resources/hudson/model/View/builds_pt_BR.properties b/core/src/main/resources/hudson/model/View/builds_pt_BR.properties index e80fffcf5a3c..e77249c8d1cc 100644 --- a/core/src/main/resources/hudson/model/View/builds_pt_BR.properties +++ b/core/src/main/resources/hudson/model/View/builds_pt_BR.properties @@ -21,5 +21,4 @@ # THE SOFTWARE. buildHistory=Hist\u00f3rico de builds de {0} -Export\ as\ plain\ XML=Exportar para XML diff --git a/core/src/main/resources/hudson/model/View/builds_zh_TW.properties b/core/src/main/resources/hudson/model/View/builds_zh_TW.properties index 497ef9fe414c..751abc5f50c6 100644 --- a/core/src/main/resources/hudson/model/View/builds_zh_TW.properties +++ b/core/src/main/resources/hudson/model/View/builds_zh_TW.properties @@ -1,17 +1,17 @@ # The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc. -# +# +# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: -# +# # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. -# +# # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -19,6 +19,5 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. - -Export\ as\ plain\ XML=\u532F\u51FA\u6210 XML -buildHistory={0} \u5EFA\u7F6E\u6B77\u7A0B +buildHistory={0} \u7684\u5efa\u7f6e\u6b77\u7a0b +Export\ as\ plain\ XML=\u532f\u51fa\u6210 XML diff --git a/core/src/main/resources/hudson/model/View/configure_ar.properties b/core/src/main/resources/hudson/model/View/configure_ar.properties deleted file mode 100644 index b9e6b5408980..000000000000 --- a/core/src/main/resources/hudson/model/View/configure_ar.properties +++ /dev/null @@ -1,6 +0,0 @@ -# This file is under the MIT License by authors - -Description=\u0627\u0644\u0648\u0635\u0641 -Filter\ build\ executors=\u062A\u0635\u064A\u0629 \u0627\u0644\u0646\u0627\u0629 -Filter\ build\ queue=\u062A\u0635\u0641\u064A\u0629 \u0637\u0627\u0628\u0648\u0631 \u0627\u0644\u0628\u0646\u0627\u0621 -Name=\u0627\u0644\u0627\u0633\u0645 diff --git a/core/src/main/resources/hudson/model/View/configure_pt_BR.properties b/core/src/main/resources/hudson/model/View/configure_pt_BR.properties index f785bacd9296..f16cbaf4ee1d 100644 --- a/core/src/main/resources/hudson/model/View/configure_pt_BR.properties +++ b/core/src/main/resources/hudson/model/View/configure_pt_BR.properties @@ -21,9 +21,9 @@ # THE SOFTWARE. Name=Nome -Description=Descri\u00e7\u00e3o -Filter\ build\ queue=Filtrar a lista de builds -Filter\ build\ executors=Filtar a lista de executores - +Description=Descri\u00E7\u00E3o +Filter\ build\ queue=Filtrar a lista de constru\u00E7\u00F5es +Filter\ build\ executors=Filtrar a lista de executores OK=OK Edit\ View=Editar View +Apply=Aplicar diff --git a/core/src/main/resources/hudson/model/View/configure_zh_TW.properties b/core/src/main/resources/hudson/model/View/configure_zh_TW.properties index 1fdbf0253150..55b92b066395 100644 --- a/core/src/main/resources/hudson/model/View/configure_zh_TW.properties +++ b/core/src/main/resources/hudson/model/View/configure_zh_TW.properties @@ -26,6 +26,5 @@ Name=\u540d\u7a31 Description=\u8aaa\u660e Filter\ build\ queue=\u7be9\u9078\u5efa\u7f6e\u4f47\u5217 Filter\ build\ executors=\u7be9\u9078\u5efa\u7f6e\u57f7\u884c\u7a0b\u5f0f - -OK=\u78BA\u5B9A - +OK=\u78ba\u5b9a +Apply=\u5957\u7528 diff --git a/core/src/main/resources/hudson/model/View/delete_fr.properties b/core/src/main/resources/hudson/model/View/delete_fr.properties index ccf5fb6dcb5e..75cacbba26a4 100644 --- a/core/src/main/resources/hudson/model/View/delete_fr.properties +++ b/core/src/main/resources/hudson/model/View/delete_fr.properties @@ -20,5 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Are\ you\ sure\ about\ deleting\ the\ view?=Etes-vous sr de vouloir supprimer la vue? Yes=Oui +delete.view=Supprimer la vue \u2018{0}\u2019 ? diff --git a/core/src/main/resources/hudson/model/View/delete_pt_BR.properties b/core/src/main/resources/hudson/model/View/delete_pt_BR.properties index 371f566ea400..709912a6fa17 100644 --- a/core/src/main/resources/hudson/model/View/delete_pt_BR.properties +++ b/core/src/main/resources/hudson/model/View/delete_pt_BR.properties @@ -20,5 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Are\ you\ sure\ about\ deleting\ the\ view?=Tem certeza que deseja excluir essa view? Yes=Sim +delete.view=Apagar a vis\u00E3o '{0}'? diff --git a/core/src/main/resources/hudson/model/View/delete_zh_TW.properties b/core/src/main/resources/hudson/model/View/delete_zh_TW.properties index d4a0a2b9d916..4c506afadb04 100644 --- a/core/src/main/resources/hudson/model/View/delete_zh_TW.properties +++ b/core/src/main/resources/hudson/model/View/delete_zh_TW.properties @@ -20,5 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. +delete.view=\u78ba\u5b9a\u8981\u522a\u9664\u8996\u666f\u300c{0}\u300d\u55ce? Are\ you\ sure\ about\ deleting\ the\ view?=\u60a8\u78ba\u5b9a\u8981\u522a\u9664\u9019\u500b\u8996\u666f\u55ce? Yes=\u662f diff --git a/core/src/main/resources/hudson/model/View/index.jelly b/core/src/main/resources/hudson/model/View/index.jelly index f53d03ee487b..5ab71ed6dd9c 100644 --- a/core/src/main/resources/hudson/model/View/index.jelly +++ b/core/src/main/resources/hudson/model/View/index.jelly @@ -44,11 +44,14 @@ THE SOFTWARE. - + diff --git a/core/src/main/resources/hudson/model/View/index_zh_TW.properties b/core/src/main/resources/hudson/model/View/index_zh_TW.properties index d7971f186231..ce6812022666 100644 --- a/core/src/main/resources/hudson/model/View/index_zh_TW.properties +++ b/core/src/main/resources/hudson/model/View/index_zh_TW.properties @@ -20,4 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Dashboard=\u5100\u8868\u677f +Dashboard=\u8cc7\u8a0a\u4e3b\u9801 diff --git a/core/src/main/resources/hudson/model/View/main_zh_TW.properties b/core/src/main/resources/hudson/model/View/main_zh_TW.properties new file mode 100644 index 000000000000..0c601fc4237c --- /dev/null +++ b/core/src/main/resources/hudson/model/View/main_zh_TW.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright 2017 CloudBees, Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +broken=\u53d6\u5f97\u6b64\u8996\u666f\u4e2d\u7684\u4f5c\u696d\u6642\u767c\u751f\u932f\u8aa4\uff0c\u8acb\u6aa2\u67e5 Jenkins \u65e5\u8a8c\u4ee5\u7372\u5f97\u8a73\u7d30\u8cc7\u8a0a\u3002 diff --git a/core/src/main/resources/hudson/model/View/newJob.jelly b/core/src/main/resources/hudson/model/View/newJob.jelly index 5467f5d9506e..f9c6bcd6f8d5 100644 --- a/core/src/main/resources/hudson/model/View/newJob.jelly +++ b/core/src/main/resources/hudson/model/View/newJob.jelly @@ -39,7 +39,7 @@ THE SOFTWARE.
          - +
          » ${%ItemName.help}
          » ${%ItemName.validation.required}
          diff --git a/core/src/main/resources/hudson/model/View/newJobButtonBar_pt_BR.properties b/core/src/main/resources/hudson/model/View/newJobButtonBar_pt_BR.properties new file mode 100644 index 000000000000..d9f62b5886c7 --- /dev/null +++ b/core/src/main/resources/hudson/model/View/newJobButtonBar_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +OK=OK diff --git a/core/src/main/resources/hudson/model/View/newJobButtonBar_zh_TW.properties b/core/src/main/resources/hudson/model/View/newJobButtonBar_zh_TW.properties new file mode 100644 index 000000000000..3dd60a554eb0 --- /dev/null +++ b/core/src/main/resources/hudson/model/View/newJobButtonBar_zh_TW.properties @@ -0,0 +1 @@ +OK=\u78ba\u5b9a diff --git a/core/src/main/resources/hudson/model/View/newJob_ar.properties b/core/src/main/resources/hudson/model/View/newJob_ar.properties deleted file mode 100644 index 808df1cbb05f..000000000000 --- a/core/src/main/resources/hudson/model/View/newJob_ar.properties +++ /dev/null @@ -1,4 +0,0 @@ -# This file is under the MIT License by authors - -CopyExisting=\u0646\u0633\u062E {0} \u0645\u0648\u062C\u0648\u062F -JobName=\u0627\u0633\u0645 {0} diff --git a/core/src/main/resources/hudson/model/View/newJob_pt_BR.properties b/core/src/main/resources/hudson/model/View/newJob_pt_BR.properties index 03b8d12c5c2f..efb1128734c1 100644 --- a/core/src/main/resources/hudson/model/View/newJob_pt_BR.properties +++ b/core/src/main/resources/hudson/model/View/newJob_pt_BR.properties @@ -20,6 +20,11 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -JobName=Nome do {0} -CopyExisting=Copiar {0} existente NewJob=Novo {0} +ItemName.label=Entre com um nome de item +CopyOption.label=Copiar de +ItemType.validation.required=Por favor selecione um tipo de item +ItemName.validation.required=Este campo n\u00E3o pode ser vazio, por favor entre com um nome v\u00E1lido +CopyOption.placeholder=Digite para autocompletar +CopyOption.description=Se voc\u00EA quiser criar um novo item \u00E0 partir de um existente voc\u00EA pode usar esta op\u00E7\u00E3o: +ItemName.help=Campo requerido diff --git a/core/src/main/resources/hudson/model/View/newJob_zh_TW.properties b/core/src/main/resources/hudson/model/View/newJob_zh_TW.properties index 537b4be97ad2..2b5f607ee58d 100644 --- a/core/src/main/resources/hudson/model/View/newJob_zh_TW.properties +++ b/core/src/main/resources/hudson/model/View/newJob_zh_TW.properties @@ -21,6 +21,13 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -CopyExisting=\u8907\u88FD\u65E2\u6709\u7684{0} -JobName={0}\u540D\u7A31 NewJob=\u65b0\u589e{0} +JobName={0}\u540d\u7a31 +ItemName.help=\u5fc5\u586b\u6b04\u4f4d +ItemName.label=\u8f38\u5165\u9805\u76ee\u540d\u7a31 +ItemName.validation.required=\u6b64\u6b04\u4f4d\u4e0d\u5f97\u7559\u767d\uff0c\u8acb\u8f38\u5165\u6709\u6548\u7684\u540d\u7a31 +ItemType.validation.required=\u8acb\u9078\u64c7\u9805\u76ee\u985e\u578b +CopyOption.placeholder=\u8f38\u5165\u4ee5\u81ea\u52d5\u5b8c\u6210 +CopyOption.description=\u5982\u679c\u60a8\u8981\u5f9e\u5176\u4ed6\u65e2\u6709\u7684\u9805\u76ee\u5efa\u7acb\uff0c\u60a8\u53ef\u4ee5\u4f7f\u7528\u6b64\u9078\u9805\: +CopyOption.label=\u8907\u88fd\u81ea +CopyExisting=\u8907\u88fd\u65e2\u6709\u7684{0} diff --git a/core/src/main/resources/hudson/model/View/noJob.jelly b/core/src/main/resources/hudson/model/View/noJob.jelly index 5e744c21fab9..4145b1118be8 100644 --- a/core/src/main/resources/hudson/model/View/noJob.jelly +++ b/core/src/main/resources/hudson/model/View/noJob.jelly @@ -24,19 +24,8 @@ THE SOFTWARE. - -
          -
          ${%description_1} - ${%description_2} + ${%description_2} -
          -
          diff --git a/core/src/main/resources/hudson/model/View/sidepanel.jelly b/core/src/main/resources/hudson/model/View/sidepanel.jelly index a8d1b128ddf5..c5e00f427a20 100644 --- a/core/src/main/resources/hudson/model/View/sidepanel.jelly +++ b/core/src/main/resources/hudson/model/View/sidepanel.jelly @@ -40,7 +40,7 @@ THE SOFTWARE. - + @@ -51,16 +51,16 @@ THE SOFTWARE. - + - + - + diff --git a/core/src/main/resources/hudson/model/View/sidepanel_ar.properties b/core/src/main/resources/hudson/model/View/sidepanel_ar.properties deleted file mode 100644 index be151a26e171..000000000000 --- a/core/src/main/resources/hudson/model/View/sidepanel_ar.properties +++ /dev/null @@ -1,29 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Build\ History=\u062A\u0627\u0631\u064A\u062E \u0627\u0644\u0628\u0646\u0627\u0621 -Check\ File\ Fingerprint=\u0641\u062D\u0635 \u0628\u0635\u0645\u0629 \u0627\u0644\u0645\u0644\u0641 -Delete\ View=\u0627\u0632\u0627\u0644\u062A \u0647\u064A\u0626\u0629 \u0627\u0644\u0635\u0641\u062D\u0629 -Edit\ View=\u062A\u062D\u0631\u064A\u0631 \u0627\u0644\u0639\u0631\u0636 -NewJob=\u062C\u062F\u064A\u062F {0} -People=\u0627\u0644\u0645\u0633\u062A\u062E\u062F\u0645\u0648\u0646 -Project\ Relationship=\u0635\u0644\u0629 \u0627\u0644\u0645\u0634\u0631\u0648\u0639 diff --git a/core/src/main/resources/hudson/model/View/sidepanel_zh_TW.properties b/core/src/main/resources/hudson/model/View/sidepanel_zh_TW.properties index ab7ad3fdbbb6..0e582d798b63 100644 --- a/core/src/main/resources/hudson/model/View/sidepanel_zh_TW.properties +++ b/core/src/main/resources/hudson/model/View/sidepanel_zh_TW.properties @@ -21,10 +21,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -NewJob=\u65B0\u589E{0} -People=\u4F7F\u7528\u8005 +NewJob=\u65b0\u589e{0} +People=\u4eba\u54e1 Build\ History=\u5efa\u7f6e\u6b77\u7a0b -Edit\ View=\u7DE8\u8F2F\u7248\u9762 +Edit\ View=\u7de8\u8f2f\u8996\u666f Delete\ View=\u522a\u9664\u8996\u666f -Project\ Relationship=\u5c08\u6848\u95dc\u9023 +Project\ Relationship=\u5c08\u6848\u95dc\u806f Check\ File\ Fingerprint=\u6aa2\u67e5\u6a94\u6848\u6307\u7d0b diff --git a/core/src/main/resources/hudson/model/labels/LabelAtom/configure_zh_TW.properties b/core/src/main/resources/hudson/model/labels/LabelAtom/configure_zh_TW.properties index 5a964888c04b..174fa7aa06b0 100644 --- a/core/src/main/resources/hudson/model/labels/LabelAtom/configure_zh_TW.properties +++ b/core/src/main/resources/hudson/model/labels/LabelAtom/configure_zh_TW.properties @@ -1,17 +1,17 @@ # The MIT License -# +# # Copyright (c) 2013, Chunghwa Telecom Co., Ltd., Pei-Tang Huang -# +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: -# +# # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. -# +# # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -19,7 +19,7 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. - title={0} \u8a2d\u5b9a Name=\u540d\u7a31 Save=\u5132\u5b58 +Description=\u8aaa\u660e diff --git a/core/src/main/resources/hudson/model/queue/CauseOfBlockage/BecauseLabelIsBusy/summary_zh_TW.properties b/core/src/main/resources/hudson/model/queue/CauseOfBlockage/BecauseLabelIsBusy/summary_zh_TW.properties new file mode 100644 index 000000000000..e8f7e0d9a6f6 --- /dev/null +++ b/core/src/main/resources/hudson/model/queue/CauseOfBlockage/BecauseLabelIsBusy/summary_zh_TW.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +# note for translators: this message is referenced from st:structuredMessageFormat +description=\u6b63\u5728\u7b49\u5f85\u300c{0}\u300d\u4e2d\u7684\u57f7\u884c\u7a0b\u5f0f diff --git a/core/src/main/resources/hudson/model/queue/CauseOfBlockage/BecauseLabelIsOffline/summary_zh_TW.properties b/core/src/main/resources/hudson/model/queue/CauseOfBlockage/BecauseLabelIsOffline/summary_zh_TW.properties new file mode 100644 index 000000000000..95338ea0b4c7 --- /dev/null +++ b/core/src/main/resources/hudson/model/queue/CauseOfBlockage/BecauseLabelIsOffline/summary_zh_TW.properties @@ -0,0 +1,25 @@ +# The MIT License +# +# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +# note for translators: this message is referenced from st:structuredMessageFormat +description=\u6240\u6709\u6a19\u7c64\u70ba\u300c{0}\u300d\u7684\u7bc0\u9ede\u90fd\u96e2\u7dda\u4e86 +description_no_nodes=\u6c92\u6709\u6a19\u7c64\u70ba\u300c{0}\u300d\u7684\u7bc0\u9ede diff --git a/core/src/main/resources/hudson/model/queue/CauseOfBlockage/BecauseNodeIsBusy/summary_zh_TW.properties b/core/src/main/resources/hudson/model/queue/CauseOfBlockage/BecauseNodeIsBusy/summary_zh_TW.properties new file mode 100644 index 000000000000..2fe0a6766fbb --- /dev/null +++ b/core/src/main/resources/hudson/model/queue/CauseOfBlockage/BecauseNodeIsBusy/summary_zh_TW.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +# note for translators: this message is referenced from st:structuredMessageFormat +description=\u6b63\u5728\u7b49\u5f85\u300c{0}\u300d\u4e2d\u7684\u57f7\u884c\u7a0b\u5f0f diff --git a/core/src/main/resources/hudson/model/queue/CauseOfBlockage/BecauseNodeIsOffline/summary_zh_TW.properties b/core/src/main/resources/hudson/model/queue/CauseOfBlockage/BecauseNodeIsOffline/summary_zh_TW.properties new file mode 100644 index 000000000000..9207eaf2a7bc --- /dev/null +++ b/core/src/main/resources/hudson/model/queue/CauseOfBlockage/BecauseNodeIsOffline/summary_zh_TW.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +# note for translators: this message is referenced from st:structuredMessageFormat +description={0} \u5df2\u96e2\u7dda diff --git a/core/src/main/resources/hudson/model/queue/Messages_zh_TW.properties b/core/src/main/resources/hudson/model/queue/Messages_zh_TW.properties index e7afb1a4de68..5ce057a3db59 100644 --- a/core/src/main/resources/hudson/model/queue/Messages_zh_TW.properties +++ b/core/src/main/resources/hudson/model/queue/Messages_zh_TW.properties @@ -20,4 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -QueueSorter.installDefaultQueueSorter=\u5b89\u88dd\u9810\u8a2d\u4f47\u5217\u6392\u5e8f\u7a0b\u5f0f +QueueSorter.installDefaultQueueSorter=\u6b63\u5728\u5b89\u88dd\u9810\u8a2d\u4f47\u5217\u6392\u5e8f\u7a0b\u5f0f diff --git a/core/src/main/resources/hudson/node_monitors/AbstractDiskSpaceMonitor/config_pt.properties b/core/src/main/resources/hudson/node_monitors/AbstractDiskSpaceMonitor/config_pt.properties deleted file mode 100644 index 285498a0d9a1..000000000000 --- a/core/src/main/resources/hudson/node_monitors/AbstractDiskSpaceMonitor/config_pt.properties +++ /dev/null @@ -1,24 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributers -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Free\ Space\ Threshold=Limite de espa\u00e7o livre - diff --git a/core/src/main/resources/hudson/node_monitors/ClockMonitor/help.html b/core/src/main/resources/hudson/node_monitors/ClockMonitor/help.html index 31c27afba00b..4311cc9b4f95 100644 --- a/core/src/main/resources/hudson/node_monitors/ClockMonitor/help.html +++ b/core/src/main/resources/hudson/node_monitors/ClockMonitor/help.html @@ -1,5 +1,5 @@
          - This monitors the clock difference between the master and nodes. + This monitors the clock difference between the controller and nodes. While Jenkins itself is generally capable of tolerating clock differences between systems, version control activities and distributed file access (such as NFS, Windows file shares) tend to have strange problems when systems involved have different clocks. diff --git a/core/src/main/resources/hudson/node_monitors/DiskSpaceMonitor/help.html b/core/src/main/resources/hudson/node_monitors/DiskSpaceMonitor/help.html index d714c0e18402..1b6db0303d7f 100644 --- a/core/src/main/resources/hudson/node_monitors/DiskSpaceMonitor/help.html +++ b/core/src/main/resources/hudson/node_monitors/DiskSpaceMonitor/help.html @@ -1,7 +1,7 @@
          - This monitors the available disk space of $JENKINS_HOME on each agent, and if it gets below + This monitors the available disk space of $JENKINS_HOME on each agent, and if it gets below a threshold, the agent will be marked offline.

          This directory is where all your builds are performed, so if it fills up, all the builds will fail. -

          \ No newline at end of file +
          diff --git a/core/src/main/resources/hudson/node_monitors/DiskSpaceMonitor/help_bg.html b/core/src/main/resources/hudson/node_monitors/DiskSpaceMonitor/help_bg.html index 77788a4b36c6..ba17348d3d2f 100644 --- a/core/src/main/resources/hudson/node_monitors/DiskSpaceMonitor/help_bg.html +++ b/core/src/main/resources/hudson/node_monitors/DiskSpaceMonitor/help_bg.html @@ -1,6 +1,6 @@
          Този датчик указва свободното дисково пространство на файловата система, в - която е разположена директорията $JENKINS_HOME. Ако то падне под + която е разположена директорията $JENKINS_HOME. Ако то падне под определена стойност, машината ще бъде указана като извън линия.

          diff --git a/core/src/main/resources/hudson/node_monitors/DiskSpaceMonitor/help_it.html b/core/src/main/resources/hudson/node_monitors/DiskSpaceMonitor/help_it.html index 70d53c184840..11931c4fa56b 100644 --- a/core/src/main/resources/hudson/node_monitors/DiskSpaceMonitor/help_it.html +++ b/core/src/main/resources/hudson/node_monitors/DiskSpaceMonitor/help_it.html @@ -1,6 +1,6 @@

          Questo modulo mantiene sotto controllo lo spazio su disco disponibile su - ogni agente per $JENKINS_HOME e, se diminuisce al di sotto di + ogni agente per $JENKINS_HOME e, se diminuisce al di sotto di una certa soglia, l'agente sarà contrassegnato come non in linea.

          diff --git a/core/src/main/resources/hudson/node_monitors/DiskSpaceMonitor/help_ja.html b/core/src/main/resources/hudson/node_monitors/DiskSpaceMonitor/help_ja.html index b5ff164a74c0..5cdbf0b5b61c 100644 --- a/core/src/main/resources/hudson/node_monitors/DiskSpaceMonitor/help_ja.html +++ b/core/src/main/resources/hudson/node_monitors/DiskSpaceMonitor/help_ja.html @@ -1,6 +1,6 @@

          - 各エージェントの$JENKINS_HOMEの利用可能なディスク容量を監視します。もし閾値を下回ったらそのエージェントはオフラインになります。 + 各エージェントの$JENKINS_HOMEの利用可能なディスク容量を監視します。もし閾値を下回ったらそのエージェントはオフラインになります。

          このディレクトリでビルドが実行されるので、いっぱいになったらビルドはすべて失敗します。 -

          \ No newline at end of file +
          diff --git a/core/src/main/resources/hudson/node_monitors/Messages_pt.properties b/core/src/main/resources/hudson/node_monitors/Messages_pt.properties deleted file mode 100644 index f19690280c01..000000000000 --- a/core/src/main/resources/hudson/node_monitors/Messages_pt.properties +++ /dev/null @@ -1,34 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributers -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -ClockMonitor.DisplayName=Diferen\u00e7a de tempo -ResponseTimeMonitor.TimeOut=Time out da tentativa {0} -AbstractNodeMonitorDescriptor.NoDataYet=Sem informa\u00e7\u00e3o -TemporarySpaceMonitor.DisplayName=Espa\u00e7o de \u00e1rea tempor\u00e1ria -DiskSpaceMonitor.MarkedOnline=Colocar {0} online novamente se existir espa\u00e7o em disco suficiente -ResponseTimeMonitor.DisplayName=Tempo de resposta -DiskSpaceMonitor.MarkedOffline=Deixar {0} temporariamente offline devido \u00e0 falta de espa\u00e7o em disco -DiskSpaceMonitor.DisplayName=Espa\u00e7o em disco livre -SwapSpaceMonitor.DisplayName=Espa\u00e7o de swap livre -ArchitectureMonitor.DisplayName=Arquitetura -ResponseTimeMonitor.MarkedOffline=Deixar {0} offline porque n\u00e3o est\u00e1 respondendo -DiskSpaceMonitorDescriptor.DiskSpace.FreeSpaceTooLow=Espa\u00e7o em disco est\u00e1 acabando, apenas {0}Gb livre em {1}. diff --git a/core/src/main/resources/hudson/node_monitors/Messages_pt_BR.properties b/core/src/main/resources/hudson/node_monitors/Messages_pt_BR.properties index ee3fe556069e..45ba60c78c5d 100644 --- a/core/src/main/resources/hudson/node_monitors/Messages_pt_BR.properties +++ b/core/src/main/resources/hudson/node_monitors/Messages_pt_BR.properties @@ -21,23 +21,16 @@ # THE SOFTWARE. ArchitectureMonitor.DisplayName=Arquitetura -ClockMonitor.DisplayName=Diferen\u00e7a de tempo -DiskSpaceMonitor.DisplayName=Espa\u00e7o livre em disco -# Time out for last {0} try -ResponseTimeMonitor.TimeOut=Time out desde a \u00faltima {0} tentativa -# Free Temp Space -TemporarySpaceMonitor.DisplayName=Espa\u00e7o tempor\u00e1rio dispon\u00edvel -# Response Time +ClockMonitor.DisplayName=Diferen\u00E7a de tempo +DiskSpaceMonitor.DisplayName=Espa\u00E7o livre em disco +ResponseTimeMonitor.TimeOut=Time out desde a \u00FAltima {0} tentativa +TemporarySpaceMonitor.DisplayName=Espa\u00E7o tempor\u00E1rio dispon\u00EDvel ResponseTimeMonitor.DisplayName=Tempo de resposta -# Making {0} offline temporarily due to the lack of disk space -DiskSpaceMonitor.MarkedOffline=Temporariamente indispon\u00edvel por falta de espa\u00e7o em disco -# Free Swap Space -SwapSpaceMonitor.DisplayName=Espa\u00e7o de swap livre -# Making {0} offline temporarily because it is not responding -ResponseTimeMonitor.MarkedOffline= Indispon\u00edvel temporariamente por que n\u00e3o est\u00e1 respondendo -# Not yet +DiskSpaceMonitor.MarkedOffline=Temporariamente indispon\u00EDvel por falta de espa\u00E7o em disco +SwapSpaceMonitor.DisplayName=Espa\u00E7o de troca livre +ResponseTimeMonitor.MarkedOffline= Indispon\u00EDvel temporariamente por que n\u00E3o est\u00E1 respondendo AbstractNodeMonitorDescriptor.NoDataYet=Nada ainda -# Putting {0} back online as there is enough disk space again -DiskSpaceMonitor.MarkedOnline=Retornando {0} para online pois h\u00e1 espa\u00e7o em disco suficiente novamente -# Disk space is too low. Only {0}GB left. -DiskSpaceMonitorDescriptor.DiskSpace.FreeSpaceTooLow=Pouco espa\u00e7o em disco. Somente {0}GB dispon\u00edvel em {1}. +DiskSpaceMonitor.MarkedOnline=Retornando {0} como ativo pois h\u00E1 espa\u00E7o em disco suficiente novamente +DiskSpaceMonitorDescriptor.DiskSpace.FreeSpaceTooLow=Pouco espa\u00E7o em disco. Somente {0}GB dispon\u00EDvel em {1}. +MonitorMarkedNodeOffline.DisplayName=N\u00F3 marcado como fora de servi\u00E7o devido a verifica\u00E7\u00E3o de sa\u00FAde +DiskSpaceMonitorDescriptor.DiskSpace.FreeSpace={0}GB restantes em {1}. diff --git a/core/src/main/resources/hudson/node_monitors/MonitorMarkedNodeOffline/description.jelly b/core/src/main/resources/hudson/node_monitors/MonitorMarkedNodeOffline/description.jelly new file mode 100644 index 000000000000..bb405e931933 --- /dev/null +++ b/core/src/main/resources/hudson/node_monitors/MonitorMarkedNodeOffline/description.jelly @@ -0,0 +1,4 @@ + + + ${%blurb} + diff --git a/core/src/main/resources/hudson/node_monitors/MonitorMarkedNodeOffline/description.properties b/core/src/main/resources/hudson/node_monitors/MonitorMarkedNodeOffline/description.properties new file mode 100644 index 000000000000..ed703833bd7e --- /dev/null +++ b/core/src/main/resources/hudson/node_monitors/MonitorMarkedNodeOffline/description.properties @@ -0,0 +1 @@ +blurb = Whenever a resource monitor marks a node offline, this warning is shown to inform administrators about it. diff --git a/core/src/main/resources/hudson/node_monitors/MonitorMarkedNodeOffline/description_pt_BR.properties b/core/src/main/resources/hudson/node_monitors/MonitorMarkedNodeOffline/description_pt_BR.properties new file mode 100644 index 000000000000..c5828e70220f --- /dev/null +++ b/core/src/main/resources/hudson/node_monitors/MonitorMarkedNodeOffline/description_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +blurb=Sempre que um monitor de recursos marca um n\u00F3 como fora de servi\u00E7o, este aviso \u00E9 mostrado para informar os administradores sobre. diff --git a/core/src/main/resources/hudson/node_monitors/MonitorMarkedNodeOffline/message_pt.properties b/core/src/main/resources/hudson/node_monitors/MonitorMarkedNodeOffline/message_pt.properties deleted file mode 100644 index 91e4c21a6bdc..000000000000 --- a/core/src/main/resources/hudson/node_monitors/MonitorMarkedNodeOffline/message_pt.properties +++ /dev/null @@ -1,24 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributers -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Dismiss=Dispensar - diff --git a/core/src/main/resources/hudson/node_monitors/MonitorMarkedNodeOffline/message_pt_BR.properties b/core/src/main/resources/hudson/node_monitors/MonitorMarkedNodeOffline/message_pt_BR.properties index 81af812fd234..9bc16aa60885 100644 --- a/core/src/main/resources/hudson/node_monitors/MonitorMarkedNodeOffline/message_pt_BR.properties +++ b/core/src/main/resources/hudson/node_monitors/MonitorMarkedNodeOffline/message_pt_BR.properties @@ -20,4 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Dismiss= +Dismiss=Dispensar +blurb=O Jenkins colocou alguns agentes fora de servi\u00E7o porque as m\u00E9tricas chaves de sa\u00FAde deles ficaram abaixo do limite. \ + Se voc\u00EA n\u00E3o quiser que o Jenkins fa\u00E7a isso \ + mude a configura\u00E7\u00E3o diff --git a/core/src/main/resources/hudson/node_monitors/ResponseTimeMonitor/Data/cause_pt.properties b/core/src/main/resources/hudson/node_monitors/ResponseTimeMonitor/Data/cause_pt.properties deleted file mode 100644 index fffde62f1adb..000000000000 --- a/core/src/main/resources/hudson/node_monitors/ResponseTimeMonitor/Data/cause_pt.properties +++ /dev/null @@ -1,23 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributers -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Ping\ response\ time\ is\ too\ long\ or\ timed\ out.=O tempo de resposta do ping est\u00e1 muito alto ou deu time out diff --git a/core/src/main/resources/hudson/node_monitors/ResponseTimeMonitor/help.html b/core/src/main/resources/hudson/node_monitors/ResponseTimeMonitor/help.html index 5a6f27a4125a..977072ab4b0b 100644 --- a/core/src/main/resources/hudson/node_monitors/ResponseTimeMonitor/help.html +++ b/core/src/main/resources/hudson/node_monitors/ResponseTimeMonitor/help.html @@ -1,9 +1,9 @@
          - This monitors the round trip network response time from the master to the agent, and if it + This monitors the round trip network response time from the controller to the agent, and if it goes above a threshold repeatedly, it marks the agent offline.

          This is useful for detecting unresponsive agents, or other network problems that clog the - communication channel. More specifically, the master sends a no-op command to the agent, + communication channel. More specifically, the controller sends a no-op command to the agent, and checks the time it takes to get back the result of this no-op command.

          \ No newline at end of file diff --git a/core/src/main/resources/hudson/node_monitors/SwapSpaceMonitor/help_ja.html b/core/src/main/resources/hudson/node_monitors/SwapSpaceMonitor/help_ja.html index 20829b9a074a..f2163336f035 100644 --- a/core/src/main/resources/hudson/node_monitors/SwapSpaceMonitor/help_ja.html +++ b/core/src/main/resources/hudson/node_monitors/SwapSpaceMonitor/help_ja.html @@ -11,12 +11,12 @@ Windowsはページファイルサイズを自動的に拡張できるので、値にあまり意味はありません。
        • - Linuxでのこの値は、/proc/meminfoから取得します。 + Linuxでのこの値は、/proc/meminfoから取得します。
        • - 他のUnixシステムでのこの値は、topコマンドの実行結果から取得します。 + 他のUnixシステムでのこの値は、topコマンドの実行結果から取得します。

        もし、この値が報告されないOSがあれば、改善できるように連絡してください。 -

        \ No newline at end of file + diff --git a/core/src/main/resources/hudson/node_monitors/TemporarySpaceMonitor/help.html b/core/src/main/resources/hudson/node_monitors/TemporarySpaceMonitor/help.html index d285370f917a..dd61d898f389 100644 --- a/core/src/main/resources/hudson/node_monitors/TemporarySpaceMonitor/help.html +++ b/core/src/main/resources/hudson/node_monitors/TemporarySpaceMonitor/help.html @@ -8,6 +8,6 @@

        More specifically, it checks the available disk space of a partition - that includes directory designated by the java.io.tmpdir system property. - To check where this directory is on a given agent, go to ${rootURL}/computer/SLAVENAME/systemInfo. - \ No newline at end of file + that includes directory designated by the java.io.tmpdir system property. + To check where this directory is on a given agent, go to ${rootURL}/computer/AGENTNAME/systemInfo. + diff --git a/core/src/main/resources/hudson/node_monitors/TemporarySpaceMonitor/help_bg.html b/core/src/main/resources/hudson/node_monitors/TemporarySpaceMonitor/help_bg.html index 861a5d3e98e5..04aa1d317e9a 100644 --- a/core/src/main/resources/hudson/node_monitors/TemporarySpaceMonitor/help_bg.html +++ b/core/src/main/resources/hudson/node_monitors/TemporarySpaceMonitor/help_bg.html @@ -10,7 +10,7 @@

        По-специално, проверката се извършва на файловата система, която съдържа - директорията указвана от системното свойство „java.io.tmpdir“. + директорията указвана от системното свойство „java.io.tmpdir“. За да проверите къде тя се намира на определена машина, прегледайте файла - „${rootURL}/computer/SLAVENAME/systemInfo“. + „${rootURL}/computer/AGENTNAME/systemInfo“. diff --git a/core/src/main/resources/hudson/node_monitors/TemporarySpaceMonitor/help_it.html b/core/src/main/resources/hudson/node_monitors/TemporarySpaceMonitor/help_it.html index bb1faf6bef95..42ddb1fe91ba 100644 --- a/core/src/main/resources/hudson/node_monitors/TemporarySpaceMonitor/help_it.html +++ b/core/src/main/resources/hudson/node_monitors/TemporarySpaceMonitor/help_it.html @@ -11,7 +11,7 @@

        Più nello specifico, questo modulo controlla lo spazio su disco disponibile della partizione che include la directory a cui punta la proprietà di - sistema java.io.tmpdir. Per verificare il percorso di questa + sistema java.io.tmpdir. Per verificare il percorso di questa directory su un determinato agente, aprire - ${rootURL}/computer/NOMEAGENTE/systemInfo. + ${rootURL}/computer/NOMEAGENTE/systemInfo. diff --git a/core/src/main/resources/hudson/node_monitors/TemporarySpaceMonitor/help_ja.html b/core/src/main/resources/hudson/node_monitors/TemporarySpaceMonitor/help_ja.html index 9654d171ef81..e431210ac258 100644 --- a/core/src/main/resources/hudson/node_monitors/TemporarySpaceMonitor/help_ja.html +++ b/core/src/main/resources/hudson/node_monitors/TemporarySpaceMonitor/help_ja.html @@ -6,6 +6,6 @@ 利用可能な容量がなければ正しく動作しない可能性があります。

        - もっと具体的に言うと、システムプロパティjava.io.tmpdirで指定されたディレクトリを含むパーティションの利用可能なディスク容量をチェックします。 - エージェントでのこのディレクトリが何であるかチェックするには、${rootURL}/computer/SLAVENAME/systemInfoを参照してください。 - \ No newline at end of file + もっと具体的に言うと、システムプロパティjava.io.tmpdirで指定されたディレクトリを含むパーティションの利用可能なディスク容量をチェックします。 + エージェントでのこのディレクトリが何であるかチェックするには、${rootURL}/computer/AGENTNAME/systemInfoを参照してください。 + diff --git a/core/src/main/resources/hudson/scm/AbstractScmTagAction/inProgress_pt.properties b/core/src/main/resources/hudson/scm/AbstractScmTagAction/inProgress_pt.properties deleted file mode 100644 index 373b183aec58..000000000000 --- a/core/src/main/resources/hudson/scm/AbstractScmTagAction/inProgress_pt.properties +++ /dev/null @@ -1,23 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributers -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Tagging\ is\ in\ progress\:=Tagging em processamento diff --git a/core/src/main/resources/hudson/scm/EmptyChangeLogSet/digest_ar.properties b/core/src/main/resources/hudson/scm/EmptyChangeLogSet/digest_ar.properties deleted file mode 100644 index 14b6cf7476f3..000000000000 --- a/core/src/main/resources/hudson/scm/EmptyChangeLogSet/digest_ar.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -No\ changes.=\u0644\u0627 \u062A\u063A\u064A\u064A\u0631\u0627\u062A. diff --git a/core/src/main/resources/hudson/scm/EmptyChangeLogSet/digest_pt.properties b/core/src/main/resources/hudson/scm/EmptyChangeLogSet/digest_pt.properties deleted file mode 100644 index 57832d1c49a1..000000000000 --- a/core/src/main/resources/hudson/scm/EmptyChangeLogSet/digest_pt.properties +++ /dev/null @@ -1,23 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributers -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -No\ changes.=Sem mudan\u00e7as. diff --git a/core/src/main/resources/hudson/scm/Messages_pt.properties b/core/src/main/resources/hudson/scm/Messages_pt.properties deleted file mode 100644 index ea6081b823f2..000000000000 --- a/core/src/main/resources/hudson/scm/Messages_pt.properties +++ /dev/null @@ -1,26 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributers -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -SCM.Permissions.Title=SCM -SCM.TagPermission.Description=Essa permiss\u00e3o deixa usu\u00e1rios criar uma nova tag no reposit\u00f3rio do c\u00f3digo fonte para um determinado build. -NullSCM.DisplayName=Nenhum - diff --git a/core/src/main/resources/hudson/scm/SCM/project-changes_ar.properties b/core/src/main/resources/hudson/scm/SCM/project-changes_ar.properties deleted file mode 100644 index f7605bc25dd7..000000000000 --- a/core/src/main/resources/hudson/scm/SCM/project-changes_ar.properties +++ /dev/null @@ -1,4 +0,0 @@ -# This file is under the MIT License by authors - -No\ builds.=\u0644\u0627\u064A\u0648\u062C\u062F \u0623\u064A \u0628\u0646\u0627\u0621. -No\ changes\ in\ any\ of\ the\ builds.=\u0644\u0627\u064A\u0648\u062C\u062F \u0623\u064A \u062A\u063A\u064A\u064A\u0631\u0627\u062A \u0641\u064A \u0623\u064A \u0628\u0646\u0627\u0621. diff --git a/core/src/main/resources/hudson/scm/SCM/project-changes_pt.properties b/core/src/main/resources/hudson/scm/SCM/project-changes_pt.properties deleted file mode 100644 index b36db66c2976..000000000000 --- a/core/src/main/resources/hudson/scm/SCM/project-changes_pt.properties +++ /dev/null @@ -1,25 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributers -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -No\ builds.=Sem builds. -No\ changes\ in\ any\ of\ the\ builds.=Sem mudan\u00e7as em nenhum dos builds. -detail=detalhe diff --git a/core/src/main/resources/hudson/search/Messages_pt.properties b/core/src/main/resources/hudson/search/Messages_pt.properties deleted file mode 100644 index 1e7c8e35b48b..000000000000 --- a/core/src/main/resources/hudson/search/Messages_pt.properties +++ /dev/null @@ -1,24 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributers -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -UserSearchProperty.DisplayName=Defini\u00e7\u00e3o para pesquisa - diff --git a/core/src/main/resources/hudson/search/Search/search-failed_pt.properties b/core/src/main/resources/hudson/search/Search/search-failed_pt.properties deleted file mode 100644 index 47f147878d80..000000000000 --- a/core/src/main/resources/hudson/search/Search/search-failed_pt.properties +++ /dev/null @@ -1,25 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributers -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Nothing\ seems\ to\ match.=N\u00e3o foi encontrado nenhum correspondente. -Search\ for=Buscar por - diff --git a/core/src/main/resources/hudson/search/UserSearchProperty/config_pt.properties b/core/src/main/resources/hudson/search/UserSearchProperty/config_pt.properties deleted file mode 100644 index 8aa1843a89f6..000000000000 --- a/core/src/main/resources/hudson/search/UserSearchProperty/config_pt.properties +++ /dev/null @@ -1,26 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributers -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Case-sensitivity=Diferenciar mai\u00fasculas/min\u00fasculas -Insensitive\ search\ tool=Busca sem diferenciar mai\u00fasculas/min\u00fasculas - - diff --git a/core/src/main/resources/hudson/security/FullControlOnceLoggedInAuthorizationStrategy/config_pt_BR.properties b/core/src/main/resources/hudson/security/FullControlOnceLoggedInAuthorizationStrategy/config_pt_BR.properties new file mode 100644 index 000000000000..f601e56b9de1 --- /dev/null +++ b/core/src/main/resources/hudson/security/FullControlOnceLoggedInAuthorizationStrategy/config_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Allow\ anonymous\ read\ access=Permite\ acesso\ de\ leitura\ de\ forma\ an\u00F4nima diff --git a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-useSecurity.html b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-useSecurity.html index 6ededf98ffde..6a4fb22e65bc 100644 --- a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-useSecurity.html +++ b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-useSecurity.html @@ -11,5 +11,5 @@

        For more information about security and Jenkins, see - this document. + this document. diff --git a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-useSecurity_bg.html b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-useSecurity_bg.html index c65978000f7b..77956bb58864 100644 --- a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-useSecurity_bg.html +++ b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-useSecurity_bg.html @@ -10,5 +10,5 @@

        За повече информация за сигурността и Jenkins вижте - документацията в уикито. + документацията в уикито. diff --git a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-useSecurity_de.html b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-useSecurity_de.html index 80c921f2d132..4ea1ff7dee04 100644 --- a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-useSecurity_de.html +++ b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-useSecurity_de.html @@ -6,7 +6,7 @@

        Die Konfiguration von Benutzerkonten ist anhängig vom Webcontainer, den Sie einsetzen. Tomcat verwendet beispielsweise standardmäßig die Datei - $TOMCAT_HOME/conf/tomcat-users.xml. + $TOMCAT_HOME/conf/tomcat-users.xml.

        Wenn Sie Jenkins im Intranet (oder in einer vertrauenswürdigen Umgebung) einsetzen, @@ -20,5 +20,5 @@

        Weitere Informationen zum Thema "Sicherheit und Jenkins" finden Sie - hier. + hier. diff --git a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-useSecurity_fr.html b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-useSecurity_fr.html index ab0092207d30..1d6cee26d041 100644 --- a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-useSecurity_fr.html +++ b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-useSecurity_fr.html @@ -4,7 +4,7 @@ lancer un nouveau build (utiliser le lien "login" en haut à droite de cette page). La configuration des comptes utilisateurs est spécifique au conteneur web que vous utilisez. Par exemple, par défaut, Tomcat utilise - $TOMCAT_HOME/conf/tomcat-users.xml). + $TOMCAT_HOME/conf/tomcat-users.xml).

        Si vous utilisez Jenkins sur un intranet (ou d'autres environnements "de confiance"), @@ -18,5 +18,5 @@

        Pour plus d'informations sur la sécurité dans Jenkins, voir - ce document. + ce document. diff --git a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-useSecurity_it.html b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-useSecurity_it.html index a2eff0b5329d..3816dbdf4097 100644 --- a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-useSecurity_it.html +++ b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-useSecurity_it.html @@ -14,5 +14,5 @@

        Per ulteriori informazioni sulla sicurezza e su Jenkins, si veda - questo documento. + questo documento. diff --git a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-useSecurity_ja.html b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-useSecurity_ja.html index 2b1d388bf7f5..073a4897bc29 100644 --- a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-useSecurity_ja.html +++ b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-useSecurity_ja.html @@ -2,7 +2,7 @@ 有効にすると,構成を変えたりビルドを実行するには,"管理者(admin)"権限でログインしなければなりません (ページの右上にログイン用のリンクがあります)。 ユーザアカウントは,使用しているWebコンテナに設定します(たとえば Tomcatの場合,デフォルトでは, - $TOMCAT_HOME/conf/tomcat-users.xmlに設定します)。 + $TOMCAT_HOME/conf/tomcat-users.xmlに設定します)。

        もし Jenkins をイントラネット(または信頼された環境)で使うのであれば、このチェックボックスはOFFにするのが望ましいです。 @@ -12,5 +12,5 @@ 有効でないままJenkinsのプロセスを起動すると、Jenkinsはハックされてしまいます。

        Jenkins のセキュリティの詳細については, - このドキュメントを参照してください。 + このドキュメントを参照してください。 diff --git a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-useSecurity_pt_BR.html b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-useSecurity_pt_BR.html index 59d6eef5d058..7fda16017186 100644 --- a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-useSecurity_pt_BR.html +++ b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-useSecurity_pt_BR.html @@ -3,7 +3,7 @@ antes de mudar a configuração ou executar uma nova construção (procure pelo link "login" no canto superior direito da página). A configuração de contas de usuários é específica para o contêiner web que você está usando. - (Por exemplo, no Tomcat, por padrão, ele procura por $TOMCAT_HOME/conf/tomcat-users.xml) + (Por exemplo, no Tomcat, por padrão, ele procura por $TOMCAT_HOME/conf/tomcat-users.xml)

        Se você está usando o Jenkins em uma intranet (ou outro ambiente "confiável"), é geralmente @@ -16,5 +16,5 @@

        Para mais informações sobre segurança e Jenkins, veja - este documento. + este documento. diff --git a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-useSecurity_ru.html b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-useSecurity_ru.html index e068efd717d5..28184825eb0d 100644 --- a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-useSecurity_ru.html +++ b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-useSecurity_ru.html @@ -4,7 +4,7 @@ ссылку "Вход" в правом верхнем углу страницы). Настройка учетных записей пользователей зависит от контейнера, который вы используете для запуска Jenkins. (Например, в Tomcat, по-умолчанию, используется файл - $TOMCAT_HOME/conf/tomcat-users.xml) + $TOMCAT_HOME/conf/tomcat-users.xml)

        Если вы используете Jenkins в локальной сети (или другом "защищенном" окружении), обычно @@ -18,5 +18,5 @@

        Для получения дополнительной информации о безопасности в Jenkins, прочтите - этот документ. + этот документ. diff --git a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-useSecurity_tr.html b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-useSecurity_tr.html index 70a68be87f10..49123a314a54 100644 --- a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-useSecurity_tr.html +++ b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-useSecurity_tr.html @@ -3,7 +3,7 @@ başlatmak için "admin" rolüne sahip bir kullanıcı ve şifre ile giriş yapmanız gerekir. (Sayfanın sağ-üst kısmında "giriş" linkini bulabilirsiniz) Kullanıcı hesaplarının konfigürasyonu, kullandığınız web container'a özeldir. (Mesela, Tomcat kullanıyorsanız, - $TOMCAT_HOME/conf/tomcat-users.xml dosyası dikkate alınır) + $TOMCAT_HOME/conf/tomcat-users.xml dosyası dikkate alınır)

        Jenkins'i intranet (veya başka "güvenilir" bir ortamda) içerisinde kullanıyorsanız, bu kutucuğu @@ -15,6 +15,6 @@ düşünürseniz, güvenlik ayarı olamayan bir Jenkins, hacklenmenin kesin bir yoludur.

        - Güvenlik ile ilgili daha fazla bilgiyi bu dokümanda + Güvenlik ile ilgili daha fazla bilgiyi bu dokümanda bulabilirsiniz. diff --git a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-useSecurity_zh_TW.html b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-useSecurity_zh_TW.html index 290ec69bbd73..ea68cdf86665 100644 --- a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-useSecurity_zh_TW.html +++ b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-useSecurity_zh_TW.html @@ -2,7 +2,7 @@ 啟用後,要用具備 "admin" 角色的使用者帳號及密碼登入才能修改設定或是執行新的建置 (請看頁面右上角的 "登入" 連結)。 使用者帳號設定取決於您使用的 Web Container - (以 Tomcat 來說,預設會放在 $TOMCAT_HOME/conf/tomcat-users.xml)。 + (以 Tomcat 來說,預設會放在 $TOMCAT_HOME/conf/tomcat-users.xml)。

        如果您在內網或是其他「信任」的環境中使用 Jenkins,一般不會勾選這個項目。 @@ -13,6 +13,6 @@ Jenkins 會啟動處理序,所以不安全的 Jenkins 肯定是被駭的好路子。

        - 參考這份文件, + 參考這份文件, 可以看到更多有關安全性及 Jenkins 的資訊。 diff --git a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index.groovy b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index.groovy index a8e92c4791df..492a7b250e43 100644 --- a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index.groovy +++ b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index.groovy @@ -12,16 +12,16 @@ def l=namespace(lib.LayoutTagLib) def st=namespace("jelly:stapler") l.layout(permission:app.SYSTEM_READ, title:my.displayName, cssclass:request.getParameter('decorate')) { + l.app_bar(title: my.displayName) + l.main_panel { - h1 { - l.icon(class: 'icon-secure icon-xlg') - text(my.displayName) - } set("readOnlyMode", !app.hasPermission(app.ADMINISTER)) p() - div(class:"behavior-loading", _("LOADING")) - f.form(method:"post",name:"config",action:"configure") { + div(class:"behavior-loading") { + l.spinner(text: _("LOADING")) + } + f.form(method:"post",name:"config",action:"configure", class: "jenkins-form") { set("instance",my) set("descriptor", my.descriptor) @@ -30,12 +30,8 @@ l.layout(permission:app.SYSTEM_READ, title:my.displayName, cssclass:request.getP f.checkbox(title:_("Disable remember me"), field: "disableRememberMe") } - div(style:"width:100%") { - f.dropdownDescriptorSelector(title:_("Security Realm"), field: 'securityRealm', descriptors: h.filterDescriptors(app, SecurityRealm.all())) - } - } + f.dropdownDescriptorSelector(title:_("Security Realm"), field: 'securityRealm', descriptors: h.filterDescriptors(app, SecurityRealm.all())) - div(style:"width:100%") { f.dropdownDescriptorSelector(title:_("Authorization"), field: 'authorizationStrategy', descriptors: h.filterDescriptors(app, AuthorizationStrategy.all())) } diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/_entryFormPage/resources.css b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/_entryFormPage/resources.css index 18e07446425e..00657b82588f 100644 --- a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/_entryFormPage/resources.css +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/_entryFormPage/resources.css @@ -1,4 +1,4 @@ -input { +.form-content input { /* match width with captcha image */ width:200px; } diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/_entryForm_pt_BR.properties b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/_entryForm_pt_BR.properties index dd7b02f7978c..63c24a6aa234 100644 --- a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/_entryForm_pt_BR.properties +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/_entryForm_pt_BR.properties @@ -21,9 +21,9 @@ # THE SOFTWARE. Password=Senha -Username=Nome de usu\u00e1rio +Username=Nome de usu\u00E1rio Enter\ text\ as\ shown=Digite o texto como mostrado Full\ name=Nome completo Confirm\ password=Confirmar a senha -E-mail\ address=Endere\u00e7o de e-mail -Sign\ up=Registrar +E-mail\ address=Endere\u00E7o de e-mail +captcha=captcha diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/firstUser_zh_TW.properties b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/firstUser_zh_TW.properties index 1f1ed5cb812d..8b2aac6cff7a 100644 --- a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/firstUser_zh_TW.properties +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/firstUser_zh_TW.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2013, Chunghwa Telecom Co., Ltd., Pei-Tang Huang +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Create\ First\ Admin\ User=\u5efa\u7acb\u7b2c\u4e00\u500b\u7cfb\u7d71\u7ba1\u7406\u54e1\u5e33\u865f +Create\ First\ Admin\ User=\u5efa\u7acb\u7b2c\u4e00\u4f4d\u7ba1\u7406\u54e1\u4f7f\u7528\u8005 diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/index.jelly b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/index.jelly index 8a5fde08fe56..f0aca5eeae99 100644 --- a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/index.jelly +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/index.jelly @@ -27,29 +27,58 @@ THE SOFTWARE. -

        ${%Users}

        -

        ${%blurb}

        - - - - - - - +
        +
        +

        + ${%Users} +

        +
        +
        +

        ${%blurb}

        + +
        - ${%User ID}${%Name} -
        + - - - - + + + - + + + + + + + + + + + +
        ${user.id}${user} - - - - - + ${%User ID}${%Name} +
        +
        + +
        +
        + ${user.id} + + ${user.fullName} + +
        + + + +
        +
        + +
        + + + +
        +
        +
        diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/index_pt_BR.properties b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/index_pt_BR.properties index b1c1c835ab32..cb44009c1157 100644 --- a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/index_pt_BR.properties +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/index_pt_BR.properties @@ -21,7 +21,6 @@ # THE SOFTWARE. Name=Nome -User\ Id=Identifica\u00e7\u00e3o do usu\u00e1rio -Users=Usu\u00e1rios -blurb=Esses usu\u00e1rios podem entrar no Jenkins. Este \u00e9 um sub-conjunto desta lista, que tamb\u00e9m cont\u00e9m os usu\u00e1rios criados de forma autom\u00e1tica ao executarem algum commit nos projetos que o Jenkins tem acesso. - +Users=Usu\u00E1rios +blurb=Esses usu\u00E1rios podem entrar no Jenkins. Este \u00E9 um sub-conjunto desta lista, que tamb\u00E9m cont\u00E9m os usu\u00E1rios criados de forma autom\u00E1tica ao executarem alguma confirma\u00E7\u00E3o nos projetos que o Jenkins tem acesso. +User\ ID=Identifica\u00E7\u00E3o do usu\u00E1rio diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/loginLink_ar.properties b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/loginLink_ar.properties deleted file mode 100644 index 51855c12fb34..000000000000 --- a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/loginLink_ar.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -sign\ up=\u0627\u0634\u062A\u0631\u0627\u0643 diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/sidepanel.jelly b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/sidepanel.jelly index 8e3c84edcc1d..a48380643e7d 100644 --- a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/sidepanel.jelly +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/sidepanel.jelly @@ -28,8 +28,9 @@ THE SOFTWARE. - - + + + diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/sidepanel_pt_BR.properties b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/sidepanel_pt_BR.properties index 2ad0eb9c92c7..d7c175a0bb67 100644 --- a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/sidepanel_pt_BR.properties +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/sidepanel_pt_BR.properties @@ -22,4 +22,5 @@ Back\ to\ Dashboard=Voltar ao painel principal Manage\ Jenkins=Gerenciar o Jenkins -Create\ User=Criar usu\u00e1rio +Create\ User=Criar usu\u00E1rio +Users=Usu\u00E1rios diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/sidepanel_zh_TW.properties b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/sidepanel_zh_TW.properties index 5f53f63e616f..f1a152920de4 100644 --- a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/sidepanel_zh_TW.properties +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/sidepanel_zh_TW.properties @@ -22,5 +22,6 @@ # THE SOFTWARE. Create\ User=\u5efa\u7acb\u4f7f\u7528\u8005 -Back\ to\ Dashboard=\u56DE\u5230(\u9996\u9801)\u5100\u8868\u677F +Back\ to\ Dashboard=\u8fd4\u56de\u8cc7\u8a0a\u4e3b\u9801 Manage\ Jenkins=\u7ba1\u7406 Jenkins +Users=\u4f7f\u7528\u8005 diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signup_pt_BR.properties b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signup_pt_BR.properties index 8bbb2c78eb33..6ae43a167244 100644 --- a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signup_pt_BR.properties +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signup_pt_BR.properties @@ -1,17 +1,18 @@ # The MIT License -# -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Reginaldo L. Russinholi, Cleiber Silva -# +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number +# of other of contributors +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: -# +# # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. -# +# # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -20,4 +21,20 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Sign\ up=Inscrever +Enter\ text\ as\ shown=Entre\ com\ texto\ conforme\ mostrado +Create\ account=Criar\ conta +Weak=Fraca +Create\ an\ account!\ [Jenkins]=Criar\ uma\ conta!\ [Jenkins] +Strength=For\u00E7a +Strong=Forte +please\ sign\ in.=Por\ favor\ d\u00EA\ entrada. +Show=Mostrar +Moderate=Moderada +Create\ an\ account!=Criar\ uma\ conta! +Username=Nome do usu\u00E1rio +Full\ name=Nome\ completo +A\ strong\ password\ is\ a\ long\ password\ that''s\ unique\ for\ every\ site.\ Try\ using\ a\ phrase\ with\ 5-6\ words\ for\ the\ best\ security.=Uma\ senha\ forte\ \u00E9\ uma\ senha\ longa\ que\ seja\ \u00FAnica\ para\ cada\ s\u00EDtio.\ Tente usar\ uma\ frase\ com\ 5\ a\ 6\ palavras\ para\ melhor\ seguran\u00E7a. +Poor=Fraca +Password=Senha +Email=Email +If\ you\ already\ have\ a\ Jenkins\ account,=Voc\u00EA\ j\u00E1\ tem\ uma\ conta\ no\ Jenkins, diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signup_zh_TW.properties b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signup_zh_TW.properties index 4050e0e167f1..39ccee0a6519 100644 --- a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signup_zh_TW.properties +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signup_zh_TW.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2013, Chunghwa Telecom Co., Ltd., Pei-Tang Huang +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,20 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Sign\ up=\u8a3b\u518a +A\ strong\ password\ is\ a\ long\ password\ that's\ unique\ for\ every\ site.\ Try\ using\ a\ phrase\ with\ 5-6\ words\ for\ the\ best\ security.=\u5f37\u5065\u7684\u5bc6\u78bc\u64c1\u6709\u8f03\u591a\u5b57\u5143\u4e14\u5728\u4e0d\u540c\u7cfb\u7d71\u4f7f\u7528\u7368\u7279\u7684\u5bc6\u78bc\u3002\u8acb\u8a66\u8457\u4f7f\u7528\u5305\u542b 5~6 \u500b\u55ae\u5b57\u7684\u53e5\u5b50\u4ee5\u7372\u5f97\u6700\u4f73\u5b89\u5168\u6027\u3002 +If\ you\ already\ have\ a\ Jenkins\ account,=\u5982\u679c\u60a8\u6709 Jenkins \u5e33\u6236\u4e86\uff0c +Create\ an\ account\!\ [Jenkins]=\u5efa\u7acb\u65b0\u5e33\u6236\! [Jenkins] +Strength=\u5f37\u5ea6 +please\ sign\ in.=\u8acb\u767b\u5165\u3002 +Show=\u986f\u793a +Username=\u5e33\u865f +Create\ an\ account\!=\u5efa\u7acb\u65b0\u5e33\u6236\! +Enter\ text\ as\ shown=\u8f38\u5165\u986f\u793a\u7684\u6587\u5b57 +Weak=\u5f31 +Moderate=\u4e2d +Poor=\u5dee +Create\ account=\u5efa\u7acb\u5e33\u6236 +Email=\u96fb\u5b50\u4fe1\u7bb1 +Strong=\u5f37 +Password=\u5bc6\u78bc +Full\ name=\u5168\u540d diff --git a/core/src/main/resources/hudson/security/LegacySecurityRealm/config.groovy b/core/src/main/resources/hudson/security/LegacySecurityRealm/config.groovy index 9c017edda7d4..1d0d2eb4d9cb 100644 --- a/core/src/main/resources/hudson/security/LegacySecurityRealm/config.groovy +++ b/core/src/main/resources/hudson/security/LegacySecurityRealm/config.groovy @@ -7,7 +7,9 @@ import jenkins.model.Jenkins def f = namespace(lib.FormTagLib) f.entry(title: _('Unprotected URLs')) { - p(_('blurb')) + p(class: "jenkins-form-description") { + _('blurb') + } ul { for (def action : Jenkins.get().getActions().sort { x, y -> x.getUrlName() <=> y.getUrlName() }) { if (action instanceof UnprotectedRootAction) { diff --git a/core/src/main/resources/hudson/security/Messages.properties b/core/src/main/resources/hudson/security/Messages.properties index 00d301a9ac4f..c49320ba2d23 100644 --- a/core/src/main/resources/hudson/security/Messages.properties +++ b/core/src/main/resources/hudson/security/Messages.properties @@ -32,7 +32,7 @@ HudsonPrivateSecurityRealm.Details.PasswordError=\ The confirmed password is not the same as the one entered. \ Please make sure to type the same password twice. HudsonPrivateSecurityRealm.ManageUserLinks.DisplayName=Manage Users -HudsonPrivateSecurityRealm.ManageUserLinks.Description=Create/delete/modify users that can log in to this Jenkins +HudsonPrivateSecurityRealm.ManageUserLinks.Description=Create/delete/modify users that can log in to this Jenkins. HudsonPrivateSecurityRealm.CreateAccount.TextNotMatchWordInImage=Text didn''t match the word shown in the image HudsonPrivateSecurityRealm.CreateAccount.PasswordNotMatch=Password didn''t match diff --git a/core/src/main/resources/hudson/security/Messages_pt_BR.properties b/core/src/main/resources/hudson/security/Messages_pt_BR.properties index d1c6223d86a7..6a28fc40efce 100644 --- a/core/src/main/resources/hudson/security/Messages_pt_BR.properties +++ b/core/src/main/resources/hudson/security/Messages_pt_BR.properties @@ -19,42 +19,30 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -GlobalSecurityConfiguration.DisplayName=Configurar seguran\u00e7a global -GlobalSecurityConfiguration.Description=Fa\u00e7a a seguran\u00e7a no Jenkins; defina quem pode usar/acessar o sistema. -HudsonPrivateSecurityRealm.WouldYouLikeToSignUp=O {0} {1} \u00e9 novo no Jenkins. Voc\u00ea deseja se cadastrar ? +GlobalSecurityConfiguration.DisplayName=Configurar seguran\u00E7a global +GlobalSecurityConfiguration.Description=Fa\u00E7a a seguran\u00E7a no Jenkins; defina quem pode usar/acessar o sistema. +HudsonPrivateSecurityRealm.WouldYouLikeToSignUp=O {0} {1} \u00E9 novo no Jenkins. Voc\u00EA deseja se cadastrar? LegacyAuthorizationStrategy.DisplayName=Modo legado - HudsonPrivateSecurityRealm.Details.DisplayName=Senha -HudsonPrivateSecurityRealm.Details.PasswordError=A senha confirmada n\u00e3o \u00e9 igual \u00e0 senha informada. Por favor assegure-se de digitar a mesma senha duas vezes. - -UserDetailsServiceProxy.UnableToQuery=N\u00e3o foi poss\u00edvel buscar informa\u00e7\u00f5es do usu\u00e1rio\: {0} - -# not in use +HudsonPrivateSecurityRealm.Details.PasswordError=A senha confirmada n\u00E3o \u00E9 igual \u00E0 senha informada. Por favor assegure-se de digitar a mesma senha duas vezes. +UserDetailsServiceProxy.UnableToQuery=N\u00E3o foi poss\u00EDvel buscar informa\u00E7\u00F5es do usu\u00E1rio\: {0} Permission.Permissions.Title=N/A -# Logged-in users can do anything -FullControlOnceLoggedInAuthorizationStrategy.DisplayName=Usu\u00e1rios logados conseguem fazer qualquer coisa -# Anyone can do anything +FullControlOnceLoggedInAuthorizationStrategy.DisplayName=Usu\u00E1rios que deram entrada conseguem fazer qualquer coisa AuthorizationStrategy.DisplayName=Qualquer um pode fazer qualquer coisa -# {0} is missing the {1} permission -AccessDeniedException2.MissingPermission= {0} est\u00e1 faltando a permiss\u00e3o {1} -# Manage Users -HudsonPrivateSecurityRealm.ManageUserLinks.DisplayName=Gerenciar usu\u00e1rios -# Delegate to servlet container -LegacySecurityRealm.Displayname=Delegar para o servlet container -# Jenkins''s own user database +AccessDeniedException2.MissingPermission= {0} est\u00E1 faltando a permiss\u00E3o {1} +HudsonPrivateSecurityRealm.ManageUserLinks.DisplayName=Gerenciar usu\u00E1rios +LegacySecurityRealm.Displayname=Delegar para o conteiner de servlet HudsonPrivateSecurityRealm.DisplayName=Base de dados interna do Jenkins -# Create/delete/modify users that can log in to this Jenkins -HudsonPrivateSecurityRealm.ManageUserLinks.Description=Criar/remover/modificar usu\u00e1rios que entram no Jenkins -# User name is required -HudsonPrivateSecurityRealm.CreateAccount.UserNameRequired=O nome do usu\u00e1rio \u00e9 obrigat\u00f3rio -# User name is already taken -HudsonPrivateSecurityRealm.CreateAccount.UserNameAlreadyTaken=O nome de usu\u00e1rio \u00e9 foi utilizado -# Password is required -HudsonPrivateSecurityRealm.CreateAccount.PasswordRequired=A senha \u00e9 obrigat\u00f3ria -# Password didn't match -HudsonPrivateSecurityRealm.CreateAccount.PasswordNotMatch=A senha n\u00e3o confere -# Text didn't match the word shown in the image -HudsonPrivateSecurityRealm.CreateAccount.TextNotMatchWordInImage=O texto n\u00e3o confere com o exibido na imagem -# Invalid e-mail address -HudsonPrivateSecurityRealm.CreateAccount.InvalidEmailAddress=Endere\u00e7o de e-mail inv\u00e1lido +HudsonPrivateSecurityRealm.ManageUserLinks.Description=Criar/remover/modificar usu\u00E1rios que entram no Jenkins +HudsonPrivateSecurityRealm.CreateAccount.UserNameRequired=O nome do usu\u00E1rio \u00E9 obrigat\u00F3rio +HudsonPrivateSecurityRealm.CreateAccount.UserNameAlreadyTaken=O nome de usu\u00E1rio \u00E9 foi utilizado +HudsonPrivateSecurityRealm.CreateAccount.PasswordRequired=A senha \u00E9 obrigat\u00F3ria +HudsonPrivateSecurityRealm.CreateAccount.PasswordNotMatch=A senha n\u00E3o confere +HudsonPrivateSecurityRealm.CreateAccount.TextNotMatchWordInImage=O texto n\u00E3o confere com o exibido na imagem +HudsonPrivateSecurityRealm.CreateAccount.InvalidEmailAddress=Endere\u00E7o de e-mail inv\u00E1lido +HudsonPrivateSecurityRealm.SignupWarning=Com inscri\u00E7\u00E3o habilitada qualquer pessoa na sua rede pode se tornar um usu\u00E1rio autenticado. \u00C9 recomendado neste caso minimizar as permiss\u00F5es concedidas a qualquer usu\u00E1rio autenticado. +NoneSecurityRealm.DisplayName=Nenhum +AccessDeniedException.MissingPermissions={0} tem uma permiss\u00E3o faltando, uma da {1} \u00E9 requerida +HudsonPrivateSecurityRealm.CreateAccount.UserNameInvalidCharacters=O nome do usu\u00E1rio pode conter apenas caracteres alfanum\u00E9ricos, sublinhado e h\u00EDfen +HudsonPrivateSecurityRealm.CreateAccount.UserNameInvalidCharactersCustom=Nome do usu\u00E1rio precisa combinar com a seguinte express\u00E3o: {0} diff --git a/core/src/main/resources/hudson/security/SecurityRealm/loginLink_ar.properties b/core/src/main/resources/hudson/security/SecurityRealm/loginLink_ar.properties deleted file mode 100644 index e95ee05a9f0e..000000000000 --- a/core/src/main/resources/hudson/security/SecurityRealm/loginLink_ar.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -login=\u062A\u0633\u062C\u064A\u0644 \u0627\u0644\u062F\u062E\u0648\u0644 diff --git a/core/src/main/resources/hudson/security/SecurityRealm/signup_pt_BR.properties b/core/src/main/resources/hudson/security/SecurityRealm/signup_pt_BR.properties new file mode 100644 index 000000000000..c39feff52474 --- /dev/null +++ b/core/src/main/resources/hudson/security/SecurityRealm/signup_pt_BR.properties @@ -0,0 +1,25 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Sign\ up=Fazer\ o\ cadastro +This\ is\ not\ supported\ in\ the\ current\ configuration.=Isto n\u00E3o \u00E9 suportado na configura\u00E7\u00E3o atual. +Signup\ not\ supported=Fazer\ o\ cadastro\ n\u00E3o\ suportado diff --git a/core/src/main/resources/hudson/security/SecurityRealm/signup_zh_TW.properties b/core/src/main/resources/hudson/security/SecurityRealm/signup_zh_TW.properties new file mode 100644 index 000000000000..84408cb13310 --- /dev/null +++ b/core/src/main/resources/hudson/security/SecurityRealm/signup_zh_TW.properties @@ -0,0 +1,25 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Sign\ up=\u8a3b\u518a +Signup\ not\ supported=\u4e0d\u63d0\u4f9b\u8a3b\u518a +This\ is\ not\ supported\ in\ the\ current\ configuration.=\u76ee\u524d\u7684\u8a2d\u5b9a\u4e0d\u63d0\u4f9b\u6b64\u529f\u80fd\u3002 diff --git a/core/src/main/resources/hudson/security/csrf/CrumbFilter/retry.jelly b/core/src/main/resources/hudson/security/csrf/CrumbFilter/retry.jelly index 70e615b78e4d..93e573b66763 100644 --- a/core/src/main/resources/hudson/security/csrf/CrumbFilter/retry.jelly +++ b/core/src/main/resources/hudson/security/csrf/CrumbFilter/retry.jelly @@ -32,7 +32,7 @@ THE SOFTWARE.

        ${%blurb}

        -

        ${requestURL}

        +

        ${requestURL}

        ${%warning}

        diff --git a/core/src/main/resources/hudson/security/csrf/CrumbFilter/retry_pt_BR.properties b/core/src/main/resources/hudson/security/csrf/CrumbFilter/retry_pt_BR.properties new file mode 100644 index 000000000000..e99f61f976da --- /dev/null +++ b/core/src/main/resources/hudson/security/csrf/CrumbFilter/retry_pt_BR.properties @@ -0,0 +1,29 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Retry\ using\ POST=Retentativa\ usando\ POST +blurb=A URL que voc\u00EA est\u00E1 tentando acessar exige que requisi\u00E7\u00F5es sejam enviadas usando POST (como uma submiss\u00E3o de formul\u00E1rio). \ +O bot\u00E3o abaixo permite que voc\u00EA tente novamente acessando esta URL com POST. \ +URL sendo acessada: +This\ URL\ requires\ POST=Esta\ URL\ requer\ HTTP\ POST +warning=Se voc\u00EA chegou \u00E0 partir de uma fonte n\u00E3o-confi\u00E1vel, por favor proceda com cautela. +Method\ Not\ Allowed=M\u00E9todo\ n\u00E3o\ permitido diff --git a/core/src/main/resources/hudson/security/csrf/GlobalCrumbIssuerConfiguration/help-csrf.html b/core/src/main/resources/hudson/security/csrf/GlobalCrumbIssuerConfiguration/help-csrf.html index a7e28cc8e2b6..aa7e7e3da286 100644 --- a/core/src/main/resources/hudson/security/csrf/GlobalCrumbIssuerConfiguration/help-csrf.html +++ b/core/src/main/resources/hudson/security/csrf/GlobalCrumbIssuerConfiguration/help-csrf.html @@ -14,5 +14,5 @@
      • If you are accessing Jenkins through a reverse proxy, it may strip the CSRF HTTP header, resulting in some protected actions failing.

      - More information about CSRF exploits can be found here. + More information about CSRF exploits can be found here. diff --git a/core/src/main/resources/hudson/security/csrf/GlobalCrumbIssuerConfiguration/help-csrf_bg.html b/core/src/main/resources/hudson/security/csrf/GlobalCrumbIssuerConfiguration/help-csrf_bg.html index 98f0e00ec505..9187dea50e06 100644 --- a/core/src/main/resources/hudson/security/csrf/GlobalCrumbIssuerConfiguration/help-csrf_bg.html +++ b/core/src/main/resources/hudson/security/csrf/GlobalCrumbIssuerConfiguration/help-csrf_bg.html @@ -20,5 +20,5 @@

    Повече информация за заявките с фалшив произход (CSRF) има - тук. + тук. diff --git a/core/src/main/resources/hudson/security/csrf/GlobalCrumbIssuerConfiguration/help-csrf_de.html b/core/src/main/resources/hudson/security/csrf/GlobalCrumbIssuerConfiguration/help-csrf_de.html index ed9520d69f16..6163b2c352b6 100644 --- a/core/src/main/resources/hudson/security/csrf/GlobalCrumbIssuerConfiguration/help-csrf_de.html +++ b/core/src/main/resources/hudson/security/csrf/GlobalCrumbIssuerConfiguration/help-csrf_de.html @@ -10,5 +10,5 @@ und Aufrufe der Remote-API.

    - Mehr über CSRF-Angriffe finden Sie hier. + Mehr über CSRF-Angriffe finden Sie hier. diff --git a/core/src/main/resources/hudson/security/csrf/GlobalCrumbIssuerConfiguration/help-csrf_it.html b/core/src/main/resources/hudson/security/csrf/GlobalCrumbIssuerConfiguration/help-csrf_it.html index 5d434891f23e..609b059c9aec 100644 --- a/core/src/main/resources/hudson/security/csrf/GlobalCrumbIssuerConfiguration/help-csrf_it.html +++ b/core/src/main/resources/hudson/security/csrf/GlobalCrumbIssuerConfiguration/help-csrf_it.html @@ -23,5 +23,5 @@

    È possibile reperire ulteriori informazioni sugli exploit CSRF - qui. + qui. diff --git a/core/src/main/resources/hudson/security/csrf/GlobalCrumbIssuerConfiguration/help-csrf_ja.html b/core/src/main/resources/hudson/security/csrf/GlobalCrumbIssuerConfiguration/help-csrf_ja.html index 11a67adb694c..d79200a977a8 100644 --- a/core/src/main/resources/hudson/security/csrf/GlobalCrumbIssuerConfiguration/help-csrf_ja.html +++ b/core/src/main/resources/hudson/security/csrf/GlobalCrumbIssuerConfiguration/help-csrf_ja.html @@ -5,5 +5,5 @@ このオプションを有効にすると、Jenkinsサーバでの変更を伴うリクエストについて、ノンス(使い捨ての乱数)や"crumb"をチェックします。 フォームの実行やリモートAPIの呼び出しでも同様です。

    - CSRFについての詳細は、ここを参照してください。 + CSRFについての詳細は、ここを参照してください。 diff --git a/core/src/main/resources/hudson/security/csrf/GlobalCrumbIssuerConfiguration/help-csrf_zh_TW.html b/core/src/main/resources/hudson/security/csrf/GlobalCrumbIssuerConfiguration/help-csrf_zh_TW.html index c43a29127b83..8c0851877f9a 100644 --- a/core/src/main/resources/hudson/security/csrf/GlobalCrumbIssuerConfiguration/help-csrf_zh_TW.html +++ b/core/src/main/resources/hudson/security/csrf/GlobalCrumbIssuerConfiguration/help-csrf_zh_TW.html @@ -5,5 +5,5 @@ 啟動這個選項後,Jenkins 會檢查任何可能修改 Jenkins 伺服器設定的要求,看看產生的 Nonce 值 (或叫做 "Crumb") 是否正確。 這類要求包含表單送出,以及呼叫遠端 API。

    - 您可以在這裡找到更多有關 CSRF 入侵的資訊。 + 您可以在這裡找到更多有關 CSRF 入侵的資訊。 diff --git a/core/src/main/resources/hudson/slaves/Cloud/index_pt_BR.properties b/core/src/main/resources/hudson/slaves/Cloud/index_pt_BR.properties new file mode 100644 index 000000000000..f4ec0a6e137e --- /dev/null +++ b/core/src/main/resources/hudson/slaves/Cloud/index_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Cloud=Nuvem diff --git a/core/src/main/resources/hudson/slaves/ComputerLauncher/main_pt_BR.properties b/core/src/main/resources/hudson/slaves/ComputerLauncher/main_pt_BR.properties index 4fc0b8c1b0a4..881e96845ff9 100644 --- a/core/src/main/resources/hudson/slaves/ComputerLauncher/main_pt_BR.properties +++ b/core/src/main/resources/hudson/slaves/ComputerLauncher/main_pt_BR.properties @@ -21,5 +21,7 @@ # THE SOFTWARE. # This node is being launched. -launchingDescription=Este n\u00f3 est\u00e1 sendo lan\u00e7ado -See\ log\ for\ more\ details=Veja o log para mais detalhes +launchingDescription=Este n\u00F3 est\u00E1 sendo lan\u00E7ado +See\ log\ for\ more\ details=Veja o registro de atividades para mais detalhes +Relaunch\ agent=Lan\u00E7ar\ o\ agente\ novamente +Launch\ agent=Lan\u00E7ar\ o\ agente diff --git a/core/src/main/resources/hudson/slaves/DumbSlave/configure-entries_pt_BR.properties b/core/src/main/resources/hudson/slaves/DumbSlave/configure-entries_pt_BR.properties index 599f9f565eb4..3c7a69a39c7f 100644 --- a/core/src/main/resources/hudson/slaves/DumbSlave/configure-entries_pt_BR.properties +++ b/core/src/main/resources/hudson/slaves/DumbSlave/configure-entries_pt_BR.properties @@ -21,9 +21,9 @@ # THE SOFTWARE. Description=Descri\u00E7\u00E3o -\#\ of\ executors=N\ufffdmero de executores -Remote\ root\ directory=Diret\u00F3rio root remoto +Remote\ root\ directory=Diret\u00F3rio raiz remoto Labels=R\u00F3tulos Launch\ method=M\u00E9todo de lan\u00E7amento Availability=Disponibilidade Node\ Properties=Propriedades dos n\u00D3S +Number\ of\ executors=N\u00FAmero\ de\ executores diff --git a/core/src/main/resources/hudson/slaves/DumbSlave/newInstanceDetail_pt_BR.properties b/core/src/main/resources/hudson/slaves/DumbSlave/newInstanceDetail_pt_BR.properties new file mode 100644 index 000000000000..62fae3b247c7 --- /dev/null +++ b/core/src/main/resources/hudson/slaves/DumbSlave/newInstanceDetail_pt_BR.properties @@ -0,0 +1,26 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +detail=Adiciona um agente simples e permanente no Jenkins. Isto \u00E9 chamado de "permanente" porque o Jenkins n\u00E3o prove \ +uma integra\u00E7\u00E3o de alto n\u00EDvel com estes agentes, como provisionamento din\u00E2mico. \ +Selecione este tipo se nenhum outro for aplic\u00E1vel — por exemplo, quando voc\u00EA estiver adicionando \ +um computador f\u00EDsico, m\u00E1quinhas virtuais gerenciadas fora do Jenkins, etc. diff --git a/core/src/main/resources/hudson/slaves/JNLPLauncher/config_pt_BR.properties b/core/src/main/resources/hudson/slaves/JNLPLauncher/config_pt_BR.properties index 51cc60c25154..89efc02556bb 100644 --- a/core/src/main/resources/hudson/slaves/JNLPLauncher/config_pt_BR.properties +++ b/core/src/main/resources/hudson/slaves/JNLPLauncher/config_pt_BR.properties @@ -22,3 +22,5 @@ Tunnel\ connection\ through=T\u00FAnel conecta atrav\u00E9s JVM\ options=Op\u00E7\u00F5es da JVM +Enable\ work\ directory=Habilitar\ diret\u00F3rio\ de\ trabalho +Use\ WebSocket=Usar\ um\ websocket diff --git a/core/src/main/resources/hudson/slaves/JNLPLauncher/help-vmargs.html b/core/src/main/resources/hudson/slaves/JNLPLauncher/help-vmargs.html index 085afd948211..2a398539e66e 100644 --- a/core/src/main/resources/hudson/slaves/JNLPLauncher/help-vmargs.html +++ b/core/src/main/resources/hudson/slaves/JNLPLauncher/help-vmargs.html @@ -1,5 +1,5 @@

    If the agent JVM should be launched with additional VM arguments, such as "-Xmx256m", specify those here. List of all the options are available - here. + here.
    \ No newline at end of file diff --git a/core/src/main/resources/hudson/slaves/JNLPLauncher/help-vmargs_bg.html b/core/src/main/resources/hudson/slaves/JNLPLauncher/help-vmargs_bg.html index 26e7fed59cfa..551c5cbb746b 100644 --- a/core/src/main/resources/hudson/slaves/JNLPLauncher/help-vmargs_bg.html +++ b/core/src/main/resources/hudson/slaves/JNLPLauncher/help-vmargs_bg.html @@ -2,5 +2,5 @@ При необходимост тук попълнете допълнителните аргументи за стартирането на виртуалната машина на Java на подчинените компютри като „-Xmx256m“. Погледнете документацията за - пълния списък. + пълния списък. diff --git a/core/src/main/resources/hudson/slaves/JNLPLauncher/help-vmargs_fr.html b/core/src/main/resources/hudson/slaves/JNLPLauncher/help-vmargs_fr.html index ca49c4f101c7..ef2647a6259d 100644 --- a/core/src/main/resources/hudson/slaves/JNLPLauncher/help-vmargs_fr.html +++ b/core/src/main/resources/hudson/slaves/JNLPLauncher/help-vmargs_fr.html @@ -1,5 +1,5 @@
    Si la JVM agent doit être lancée avec des arguments supplémentaires, comme "-Xmx256m", indiquez-les ici. La liste de toutes options disponibles est disponible - ici. + ici.
    \ No newline at end of file diff --git a/core/src/main/resources/hudson/slaves/JNLPLauncher/help-vmargs_it.html b/core/src/main/resources/hudson/slaves/JNLPLauncher/help-vmargs_it.html index 4b2295e04a74..9dcbbe93bb20 100644 --- a/core/src/main/resources/hudson/slaves/JNLPLauncher/help-vmargs_it.html +++ b/core/src/main/resources/hudson/slaves/JNLPLauncher/help-vmargs_it.html @@ -2,5 +2,5 @@ Se la JVM dell'agente deve essere avviata con argomenti VM aggiuntivi, come "-Xmx256m", specificarli qui. Un elenco con tutte le opzioni è disponibile - qui. + qui. diff --git a/core/src/main/resources/hudson/slaves/JNLPLauncher/help-vmargs_ja.html b/core/src/main/resources/hudson/slaves/JNLPLauncher/help-vmargs_ja.html index 39239b68cd98..3356babf6f98 100644 --- a/core/src/main/resources/hudson/slaves/JNLPLauncher/help-vmargs_ja.html +++ b/core/src/main/resources/hudson/slaves/JNLPLauncher/help-vmargs_ja.html @@ -1,4 +1,4 @@
    エージェントのJVMに"-Xmx256m"のようなオプションをつけて起動する必要があるなら、ここで指定します。 - 利用可能なオプションの一覧を参照してください。 + 利用可能なオプションの一覧を参照してください。
    \ No newline at end of file diff --git a/core/src/main/resources/hudson/slaves/JNLPLauncher/help-webSocket.html b/core/src/main/resources/hudson/slaves/JNLPLauncher/help-webSocket.html index 90f5c28f9077..35c5bdadabfe 100644 --- a/core/src/main/resources/hudson/slaves/JNLPLauncher/help-webSocket.html +++ b/core/src/main/resources/hudson/slaves/JNLPLauncher/help-webSocket.html @@ -1,4 +1,4 @@
    Use WebSocket to connect to the Jenkins master rather than the TCP port. - See JEP-222 for background. + See JEP-222 for background.
    diff --git a/core/src/main/resources/hudson/slaves/JNLPLauncher/help-webSocket_it.html b/core/src/main/resources/hudson/slaves/JNLPLauncher/help-webSocket_it.html index 3809613d7be4..3a44359ce951 100644 --- a/core/src/main/resources/hudson/slaves/JNLPLauncher/help-webSocket_it.html +++ b/core/src/main/resources/hudson/slaves/JNLPLauncher/help-webSocket_it.html @@ -1,5 +1,5 @@
    Utilizza WebSocket per connettersi al master Jenkins anziché una porta - TCP. Si veda JEP-222 per il + TCP. Si veda JEP-222 per il contesto.
    diff --git a/core/src/main/resources/hudson/slaves/JNLPLauncher/help.properties b/core/src/main/resources/hudson/slaves/JNLPLauncher/help.properties index a14577f0f2d7..d49d20b0ed01 100644 --- a/core/src/main/resources/hudson/slaves/JNLPLauncher/help.properties +++ b/core/src/main/resources/hudson/slaves/JNLPLauncher/help.properties @@ -21,14 +21,14 @@ # THE SOFTWARE. blurb=\ - Allows an agent to be connected to the Jenkins master whenever it is ready.
    \ + Allows an agent to be connected to the Jenkins controller whenever it is ready.
    \ In one mode, Java Web Start is used. \ In this case, a JNLP file must be opened on the agent machine, \ - which will establish a TCP connection to the Jenkins master. \ + which will establish a TCP connection to the Jenkins controller. \ (Other launch methods use a JNLP file but not Java Web Start, or do not use a JNLP file at all.)
    \ - This means that the agent need not be reachable from the master; \ - the agent just needs to be able to reach the master. \ + This means that the agent need not be reachable from the controller; \ + the agent just needs to be able to reach the controller. \ If you have enabled security via the Configure Global Security page, \ - you can customize the port on which the Jenkins master will listen for incoming agent connections.
    \ + you can customize the port on which the Jenkins controller will listen for incoming agent connections.
    \ By default, the agent will launch a GUI, but it is also possible to run \ an agent without a GUI, for example as a Windows service. diff --git a/core/src/main/resources/hudson/slaves/JNLPLauncher/help_es.properties b/core/src/main/resources/hudson/slaves/JNLPLauncher/help_es.properties index 26aee9fd3a1f..0f7743712438 100644 --- a/core/src/main/resources/hudson/slaves/JNLPLauncher/help_es.properties +++ b/core/src/main/resources/hudson/slaves/JNLPLauncher/help_es.properties @@ -20,7 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -blurb=Arranca un agente haciendo uso de JNLP.\ +blurb=Arranca un agente haciendo uso de JNLP.\ De modo que el agente inicia la ejecucin, por lo que los agentes no necesitan una IP accesible desde el master. \ Incluso es posible arrancar una ejecucin sin GUI, como puede ser un servicio Windows. diff --git a/core/src/main/resources/hudson/slaves/JNLPLauncher/help_pt_BR.properties b/core/src/main/resources/hudson/slaves/JNLPLauncher/help_pt_BR.properties new file mode 100644 index 000000000000..b0d6de667e78 --- /dev/null +++ b/core/src/main/resources/hudson/slaves/JNLPLauncher/help_pt_BR.properties @@ -0,0 +1,34 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +blurb=\ + Permite que um agente seja conectado ao Jenkins controller sempre que estiver pronto.
    \ + Neste modo o Java Web Start \u00E9 utilizado. \ + Neste caso, um arquivo JNLP precisa ser aberto no agente de m\u00E1quina, \ + que ir\u00E1 estabelecer uma conex\u00E3o TCP com o Jenkins controller \ + (outros m\u00E9todos de lan\u00E7amento usam o arquivo JNLP mas n\u00E3o o Java Web start, ou n\u00E3o usam o JNLP de qualquer forma).
    \ + Isto significa que o agente n\u00E3o precisa ser alcan\u00E7\u00E1vel pelo controller, \ + ele precisa apenas conseguir alcan\u00E7ar o controller. \ + Se voc\u00EA tiver seguran\u00E7a habilitada via a p\u00E1gina Configurar seguran\u00E7a global, \ + voc\u00EA pode customizar a porta em que o Jenkins controller ir\u00E1 escutar por conex\u00F5es de entrada do agente.
    \ + Por padr\u00E3o, o agente ir\u00E1 lan\u00E7ar uma GUI, mas tamb\u00E9m \u00E9 poss\u00EDvel executar \ + o agente sem a GUI, como um servi\u00E7o do Windows, por exemplo. diff --git a/core/src/main/resources/hudson/slaves/JNLPLauncher/main.jelly b/core/src/main/resources/hudson/slaves/JNLPLauncher/main.jelly index 3cade5dd6add..468192e4be7b 100644 --- a/core/src/main/resources/hudson/slaves/JNLPLauncher/main.jelly +++ b/core/src/main/resources/hudson/slaves/JNLPLauncher/main.jelly @@ -37,27 +37,16 @@ THE SOFTWARE. ${%Connect agent to Jenkins one of these ways:}

      - - -
    • -

      - - ${%launch agent} - - ${%Launch agent from browser} -

      -
    • -
      - -
    • -

      - - ${%Java Web Start is not available for the JVM version running Jenkins} - -

      -
    • -
      -
      + +
    • +

      + + ${%launch agent} + + ${%Launch agent from browser} +

      +
    • +
    • diff --git a/core/src/main/resources/hudson/slaves/JNLPLauncher/main_it.properties b/core/src/main/resources/hudson/slaves/JNLPLauncher/main_it.properties index e89eb6e7b88f..f1aa1b04e977 100644 --- a/core/src/main/resources/hudson/slaves/JNLPLauncher/main_it.properties +++ b/core/src/main/resources/hudson/slaves/JNLPLauncher/main_it.properties @@ -26,9 +26,6 @@ configure.link.text=Vai alla schermata di configurazione della sicurezza e \ modificala Connect\ agent\ to\ Jenkins\ one\ of\ these\ ways\:=Connettere l''agente a \ Jenkins in uno di questi modi: -Java\ Web\ Start\ is\ not\ available\ for\ the\ JVM\ version\ running\ Jenkins=\ - Java Web Start non disponibile per la versione della JVM su cui in \ - esecuzione Jenkins. launch\ agent=avvia l''agente Launch\ agent\ from\ browser=Avvia l''agente dal browser Or\ if\ the\ agent\ is\ headless\:=O se l''agente senza interfaccia grafica: diff --git a/core/src/main/resources/hudson/slaves/JNLPLauncher/main_pt_BR.properties b/core/src/main/resources/hudson/slaves/JNLPLauncher/main_pt_BR.properties index d5538a43a9a0..60a58aef6466 100644 --- a/core/src/main/resources/hudson/slaves/JNLPLauncher/main_pt_BR.properties +++ b/core/src/main/resources/hudson/slaves/JNLPLauncher/main_pt_BR.properties @@ -20,9 +20,12 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -launch\ agent=Lan\u00e7ar agente -# The TCP port for the JNLP agents is disabled. -slaveAgentPort.disabled=Porta TCP para JNLP est\u00e1 desativada -Connected\ via\ JNLP\ agent.=Conectado via JNLP agente. -# Go to security configuration screen and change it -configure.link.text=V\u00e1 para a p\u00e1gina de configura\u00e7\u00e3o de seguran\u00e7a para alterar +launch\ agent=Lan\u00E7ar agente +slaveAgentPort.disabled=Porta TCP para JNLP est\u00E1 desativada +configure.link.text=V\u00E1 para a p\u00E1gina de configura\u00E7\u00E3o de seguran\u00E7a para alterar +Or\ if\ the\ agent\ is\ headless\:=Ou\ se\ o\ agente\ for\ do\ tipo\ sem\ interface\ gr\u00E1fica +Agent\ is\ connected.=O\ agente\ est\u00E1\ conectado. +Run\ from\ agent\ command\ line,\ with\ the\ secret\ stored\ in\ a\ file\:=Executar\ da\ linha\ de\ comando\ do\ agente\ com\ um\ segredo\ armazenado\ em\ um\ arquivo\: +Launch\ agent\ from\ browser=Lan\u00E7ar\ um\ agente\ de\ um\ navegador +Connect\ agent\ to\ Jenkins\ one\ of\ these\ ways\:=Conectar\ o\ agente\ com\ o\ Jenkins\ usando\ uma\ das\ seguintes\ maneiras\: +Run\ from\ agent\ command\ line\:=Executar\ da\ linha\ de\ comando\ do\ agente\: diff --git a/core/src/main/resources/hudson/slaves/Messages.properties b/core/src/main/resources/hudson/slaves/Messages.properties index e767585075b0..bf2dd8dc8fe5 100644 --- a/core/src/main/resources/hudson/slaves/Messages.properties +++ b/core/src/main/resources/hudson/slaves/Messages.properties @@ -23,7 +23,7 @@ RetentionStrategy.Always.displayName=Keep this agent online as much as possible RetentionStrategy.Demand.displayName=Bring this agent online when in demand, and take offline when idle RetentionStrategy.Demand.OfflineIdle=Offline because computer was idle; it will be relaunched when needed. -JNLPLauncher.displayName=Launch agent by connecting it to the master +JNLPLauncher.displayName=Launch agent by connecting it to the controller ComputerLauncher.unexpectedError=Unexpected error in launching an agent. This is probably a bug in Jenkins ComputerLauncher.abortedLaunch=Launching agent process aborted. ConnectionActivityMonitor.OfflineCause=Repeated ping attempts failed diff --git a/core/src/main/resources/hudson/slaves/Messages_pt_BR.properties b/core/src/main/resources/hudson/slaves/Messages_pt_BR.properties index f0e4108f33f6..e95d12197de6 100644 --- a/core/src/main/resources/hudson/slaves/Messages_pt_BR.properties +++ b/core/src/main/resources/hudson/slaves/Messages_pt_BR.properties @@ -20,25 +20,23 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -# No launch command specified -# Offline because computer was idle; it will be relaunched when needed. -RetentionStrategy.Demand.OfflineIdle=Offline porque o computador estava ocioso; ser\u00e1 relan\u00e7ado quando necess\u00e1rio. -# Repeated ping attempts failed +RetentionStrategy.Demand.OfflineIdle=Fora de servi\u00E7o porque o computador estava ocioso; ser\u00E1 relan\u00E7ado quando necess\u00E1rio. ConnectionActivityMonitor.OfflineCause=Repetidos comandos PING falharam -# Disconnected by {0}{1} SlaveComputer.DisconnectedBy=Desconectado por {0}{1} -# Computer has finished its scheduled uptime SimpleScheduledRetentionStrategy.FinishedUpTime=O computador terminou o seu tempo de atividade programada -NodeProvisioner.EmptyString= -# Environment variables -EnvironmentVariablesNodeProperty.displayName=Vari\u00e1veis de ambiente -# Java version {0} was found but 1.6 or later is needed. -ComputerLauncher.NoJavaFound=A vers\u00e3o {0} do Java foi encontrada, mas a vers\u00e3o 1.6 ou mais nova \u00e9 necess\u00e1ria. -# Couldn\u2019t figure out the Java version of {0} -ComputerLauncher.UknownJavaVersion=N\u00e3o foi poss\u00edvel detectar a vers\u00e3o do Java de {0} -# Name is mandatory -NodeDescripter.CheckName.Mandatory=O nome \u00e9 obrigat\u00f3rio -# {0} -version returned {1}. +EnvironmentVariablesNodeProperty.displayName=Vari\u00E1veis de ambiente +ComputerLauncher.NoJavaFound=A vers\u00E3o {0} do Java foi encontrada, mas a vers\u00E3o 1.6 ou mais nova \u00E9 necess\u00E1ria. ComputerLauncher.JavaVersionResult={0} -version retornou {1}. -# Connection was broken: {0} -OfflineCause.connection_was_broken_=A conex\u00e3o foi interrompida: {0} +OfflineCause.connection_was_broken_=A conex\u00E3o foi interrompida: {0} +ComputerLauncher.abortedLaunch=O processo de lan\u00E7amento do agente foi abortado. +NodeProvisioner.EmptyString=NodeProvisioner.EmptyString +ComputerLauncher.UnknownJavaVersion=N\u00E3o foi poss\u00EDvel definir a vers\u00E3o do Java {0} +RetentionStrategy.Demand.displayName=Ative este agente sob demanda e coloque-o fora de servi\u00E7o quando inativo +NodeDescriptor.CheckName.Mandatory=O nome \u00E9 mandat\u00F3rio +SimpleScheduledRetentionStrategy.displayName=Ative este agente de acordo com um agendamento +OfflineCause.LaunchFailed=O agente est\u00E1 fora de servi\u00E7o porque o Jenkins falhou ao tentar lan\u00E7ar um processo de agente. +ComputerLauncher.unexpectedError=Ocorreu um erro inesperado ao lan\u00E7ar um agente. Isto \u00E9 provavelmente um bug no Jenkins. +DumbSlave.displayName=Agente permanente +RetentionStrategy.Always.displayName=Mantenha este agente em servi\u00E7o o m\u00E1ximo poss\u00EDvel +JNLPLauncher.displayName=Lan\u00E7ar um agente conectando-o ao controlador +Cloud.ProvisionPermission.Description=Provisionar novos n\u00F3s diff --git a/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config.jelly b/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config.jelly deleted file mode 100644 index d6c1c24f5f5e..000000000000 --- a/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config.jelly +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - diff --git a/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config_bg.properties b/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config_bg.properties deleted file mode 100644 index 9ef3fbe7059a..000000000000 --- a/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config_bg.properties +++ /dev/null @@ -1,26 +0,0 @@ -# The MIT License -# -# Bulgarian translation: Copyright (c) 2016, Alexander Shopov -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Startup\ Schedule=\ - \u0420\u0430\u0437\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0437\u0430 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435 -Shutdown\ Schedule=\ - \u0420\u0430\u0437\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0437\u0430 \u0441\u043f\u0438\u0440\u0430\u043d\u0435 diff --git a/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config_da.properties b/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config_da.properties deleted file mode 100644 index a88ffdb3706e..000000000000 --- a/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config_da.properties +++ /dev/null @@ -1,24 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc. Kohsuke Kawaguchi. Knud Poulsen. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Shutdown\ Schedule=Nedlukningstidsplan -Startup\ Schedule=Opstartstidsplan diff --git a/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config_de.properties b/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config_de.properties deleted file mode 100644 index 0a8d74393b39..000000000000 --- a/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config_de.properties +++ /dev/null @@ -1,24 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Simon Wiest -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Startup\ Schedule=Anschaltzeitplan -Shutdown\ Schedule=Abschaltzeitplan diff --git a/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config_es.properties b/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config_es.properties deleted file mode 100644 index 5149904d5daf..000000000000 --- a/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config_es.properties +++ /dev/null @@ -1,24 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Startup\ Schedule=Arranque programado -Shutdown\ Schedule=Apagado programado diff --git a/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config_fr.properties b/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config_fr.properties deleted file mode 100644 index 4ddc92cffb5e..000000000000 --- a/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config_fr.properties +++ /dev/null @@ -1,24 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Eric Lefevre-Ardant -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Startup\ Schedule=Heure de dmarrage -Shutdown\ Schedule=Heure d''arrt diff --git a/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config_it.properties b/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config_it.properties deleted file mode 100644 index 7dabe222c16d..000000000000 --- a/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config_it.properties +++ /dev/null @@ -1,25 +0,0 @@ -# The MIT License -# -# Italian localization plugin for Jenkins -# Copyright 2020 Alessandro Menti -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Shutdown\ Schedule=Pianificazione spegnimento -Startup\ Schedule=Pianificazione avvio diff --git a/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config_ja.properties b/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config_ja.properties deleted file mode 100644 index 1aa99d158d00..000000000000 --- a/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config_ja.properties +++ /dev/null @@ -1,24 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc., Seiji Sogabe -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Startup\ Schedule=\u8D77\u52D5\u30B9\u30B1\u30B8\u30E5\u30FC\u30EB -Shutdown\ Schedule=\u505C\u6B62\u30B9\u30B1\u30B8\u30E5\u30FC\u30EB diff --git a/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config_pt_BR.properties b/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config_pt_BR.properties deleted file mode 100644 index ce75096f0da2..000000000000 --- a/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config_pt_BR.properties +++ /dev/null @@ -1,24 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Reginaldo L. Russinholi, Cleiber Silva, Fernando Boaglio -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Startup\ Schedule=Agenda de inicializa\u00e7\u00e3o -Shutdown\ Schedule=Agenda de desligamento diff --git a/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config_ru.properties b/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config_ru.properties deleted file mode 100644 index 5518fca281fa..000000000000 --- a/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config_ru.properties +++ /dev/null @@ -1,24 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Mike Salnikov -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Startup\ Schedule=\u0420\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u043e\u0432 -Shutdown\ Schedule=\u0420\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043e\u043a diff --git a/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config_sr.properties b/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config_sr.properties deleted file mode 100644 index b95c745f05ae..000000000000 --- a/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config_sr.properties +++ /dev/null @@ -1,4 +0,0 @@ -# This file is under the MIT License by authors - -Startup\ Schedule=\u0420\u0430\u0441\u043F\u043E\u0440\u0435\u0434 \u043F\u043E\u043A\u0440\u0435\u0442\u0430\u045A\u0430 -Shutdown\ Schedule=\u0420\u0430\u0441\u043F\u043E\u0440\u0435\u0434 \u0433\u0430\u0448\u0435\u045A\u0430 diff --git a/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config_tr.properties b/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config_tr.properties deleted file mode 100644 index 7671772ab509..000000000000 --- a/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config_tr.properties +++ /dev/null @@ -1,24 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Oguz Dag -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Startup\ Schedule=Ac\u0131l\u0131\u015f Plan\u0131 -Shutdown\ Schedule=Kapan\u0131\u015f Plan\u0131 diff --git a/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config_zh_TW.properties b/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config_zh_TW.properties deleted file mode 100644 index a2c3fb381e72..000000000000 --- a/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config_zh_TW.properties +++ /dev/null @@ -1,24 +0,0 @@ -# The MIT License -# -# Copyright (c) 2013, Chunghwa Telecom Co., Ltd., Pei-Tang Huang -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Startup\ Schedule=\u555f\u52d5\u6392\u7a0b -Shutdown\ Schedule=\u505c\u6b62\u6392\u7a0b diff --git a/core/src/main/resources/hudson/slaves/SlaveComputer/jenkins-agent.jnlp.jelly b/core/src/main/resources/hudson/slaves/SlaveComputer/jenkins-agent.jnlp.jelly index c350a36b8c5b..22b7a562448e 100644 --- a/core/src/main/resources/hudson/slaves/SlaveComputer/jenkins-agent.jnlp.jelly +++ b/core/src/main/resources/hudson/slaves/SlaveComputer/jenkins-agent.jnlp.jelly @@ -28,10 +28,10 @@ THE SOFTWARE. - + diff --git a/core/src/main/resources/hudson/slaves/SlaveComputer/log.jelly b/core/src/main/resources/hudson/slaves/SlaveComputer/log.jelly index e2f20376b1c8..6fb706fd701f 100644 --- a/core/src/main/resources/hudson/slaves/SlaveComputer/log.jelly +++ b/core/src/main/resources/hudson/slaves/SlaveComputer/log.jelly @@ -29,7 +29,7 @@ THE SOFTWARE.
             
      - +
      - - - + title="${%Trigger only if build is stable}" id="threshold-SUCCESS" value="SUCCESS"/> - - + title="${%Trigger even if the build is unstable}" id="threshold-UNSTABLE" value="UNSTABLE"/> - + title="${%Trigger even if the build fails}" id="threshold-FAILURE" value="FAILURE"/> diff --git a/core/src/main/resources/hudson/tasks/Fingerprinter/FingerprintAction/index.jelly b/core/src/main/resources/hudson/tasks/Fingerprinter/FingerprintAction/index.jelly index d1da90669f20..72d28f5ceaf0 100644 --- a/core/src/main/resources/hudson/tasks/Fingerprinter/FingerprintAction/index.jelly +++ b/core/src/main/resources/hudson/tasks/Fingerprinter/FingerprintAction/index.jelly @@ -36,18 +36,20 @@ THE SOFTWARE. ${%Recorded Fingerprints} - - - - - - +
      ${%File}${%Original owner}${%Age}
      + + + + + + + +
      ${%File}${%Original owner}${%Age}
      - - ${e.key} + + ${e.key} diff --git a/core/src/main/resources/hudson/tasks/Fingerprinter/FingerprintAction/index_pt_BR.properties b/core/src/main/resources/hudson/tasks/Fingerprinter/FingerprintAction/index_pt_BR.properties index 3ef4c38fb094..e1f7e83efb86 100644 --- a/core/src/main/resources/hudson/tasks/Fingerprinter/FingerprintAction/index_pt_BR.properties +++ b/core/src/main/resources/hudson/tasks/Fingerprinter/FingerprintAction/index_pt_BR.properties @@ -24,6 +24,5 @@ Recorded\ Fingerprints=Fingerprints gravados File=Arquivo Original\ owner=Propriet\u00e1rio original Age=Idade -more\ details=mais detalhes this\ build=Esta builds outside\ Jenkins=fora do Jenkins diff --git a/core/src/main/resources/hudson/tasks/Fingerprinter/config_pt_BR.properties b/core/src/main/resources/hudson/tasks/Fingerprinter/config_pt_BR.properties index 4805efc8a530..46c89bab8e73 100644 --- a/core/src/main/resources/hudson/tasks/Fingerprinter/config_pt_BR.properties +++ b/core/src/main/resources/hudson/tasks/Fingerprinter/config_pt_BR.properties @@ -21,3 +21,6 @@ # THE SOFTWARE. Files\ to\ fingerprint=Arquivos para gerar assinatura +caseSensitive=Tratar padr\u00F5es de inclus\u00E3o e exclus\u00E3o como sens\u00EDveis a caixa alta/baixa +Excludes=Exclui +defaultExcludes=Usar exclus\u00F5es padr\u00E3o diff --git a/core/src/main/resources/hudson/tasks/Fingerprinter/help-excludes_it.html b/core/src/main/resources/hudson/tasks/Fingerprinter/help-excludes_it.html index 80ab471901e9..ab3702263245 100644 --- a/core/src/main/resources/hudson/tasks/Fingerprinter/help-excludes_it.html +++ b/core/src/main/resources/hudson/tasks/Fingerprinter/help-excludes_it.html @@ -1,5 +1,5 @@
      - Specificare facoltativamente il pattern 'excludes', + Specificare facoltativamente il pattern 'excludes', ad esempio "pippo/pluto/**/*". Un file corrispondente a questa maschera non sarà archiviato anche nel caso in cui corrisponda alla maschera specificata nella sezione "File di cui rilevare le impronte digitali". diff --git a/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets.html b/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets.html index ec2d670afde8..364cb69bb747 100644 --- a/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets.html +++ b/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets.html @@ -1,5 +1,5 @@
      Can use wildcards like module/dist/**/*.zip - (see the @includes of Ant fileset for the exact format). + (see the @includes of Ant fileset for the exact format). The base directory is the workspace.
      diff --git a/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets_bg.html b/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets_bg.html index 5db7e7bed12f..80c8b16c4aae 100644 --- a/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets_bg.html +++ b/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets_bg.html @@ -1,7 +1,7 @@
      Можете да използвате шаблонни знаци като module/dist/**/*.zip (за точния формат погледнете секцията за - @includes от + @includes от ръководството на Ant). Основната директория е работното пространството.
      diff --git a/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets_de.html b/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets_de.html index 9becf777f6d0..4aa7673e812b 100644 --- a/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets_de.html +++ b/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets_de.html @@ -1,6 +1,6 @@
      Es sind reguläre Ausdrücke wie z.B. 'module/dist/**/*.zip' erlaubt. - Das genaue Format können Sie der + Das genaue Format können Sie der Spezifikation für @includes eines Ant-Filesets entnehmen. Das Ausgangsverzeichnis ist der Arbeitsbereich.
      diff --git a/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets_es.html b/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets_es.html index 16965cb0e66f..1bb91e2d9eac 100644 --- a/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets_es.html +++ b/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets_es.html @@ -1,6 +1,6 @@
      Se pueden usar comodines como 'module/dist/**/*.zip'. - Echa un vistazo al + Echa un vistazo al atributo @includes de la etiqueta fileset de Ant para conocer el formato exacto. El directorio base es el workspace.
      diff --git a/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets_fr.html b/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets_fr.html index 80db23a98b62..579074b62b15 100644 --- a/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets_fr.html +++ b/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets_fr.html @@ -1,5 +1,5 @@
      Les wildcards du type 'module/dist/**/*.zip' sont autorisés. - Voir le format exact des @includes des filesets Ants. + Voir le format exact des @includes des filesets Ants. Le répertoire de base est le répertoire de travail (workspace).
      diff --git a/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets_it.html b/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets_it.html index 52e943ba4485..2e6c02b6d733 100644 --- a/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets_it.html +++ b/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets_it.html @@ -1,5 +1,5 @@
      È possibile utilizzare caratteri jolly come modulo/dist/**/*.zip - (si veda la direttiva @includes dei fileset di Ant per il formato esatto). + (si veda la direttiva @includes dei fileset di Ant per il formato esatto). La directory di base è lo spazio di lavoro.
      diff --git a/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets_ja.html b/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets_ja.html index 2650acfaba72..ea1103453e49 100644 --- a/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets_ja.html +++ b/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets_ja.html @@ -1,3 +1,3 @@
      - 記録したいファイルのパターンをAnt fileset includes属性の書式で(ベースディレクトリはワークスペースルート)。例:module/dist/**/*.zip + 記録したいファイルのパターンをAnt fileset includes属性の書式で(ベースディレクトリはワークスペースルート)。例:module/dist/**/*.zip
      diff --git a/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets_nl.html b/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets_nl.html index aa6be339f6b0..3c1ed02491e2 100644 --- a/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets_nl.html +++ b/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets_nl.html @@ -1,6 +1,6 @@
      Je kunt jokerkarakters zoals in 'module/dist/**/*.zip' gebruiken. - Zie de @includes mogelijkheid van Ant bestandsbundels voor het correcte + Zie de @includes mogelijkheid van Ant bestandsbundels voor het correcte formaat. De basisfolder is de werkplaats.
      diff --git a/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets_pt_BR.html b/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets_pt_BR.html index 815753d97d25..09cde5b86dcf 100644 --- a/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets_pt_BR.html +++ b/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets_pt_BR.html @@ -1,5 +1,5 @@
      Pode usar caracteres coringas como em 'module/dist/**/*.zip'. - Veja o Fileset @includes do Ant para o formato exato. + Veja o Fileset @includes do Ant para o formato exato. O diret�rio base � o workspace.
      diff --git a/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets_ru.html b/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets_ru.html index 8054371a3e0f..81480ccf735d 100644 --- a/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets_ru.html +++ b/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets_ru.html @@ -1,6 +1,6 @@
      Вы можете использовать шаблоны, например, 'module/dist/**/*.zip'. - Подробнее смотрите + Подробнее смотрите @includes для наборов файлов Ant. Базовой директорией для шаблонов является рабочая директория.
      diff --git a/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets_zh_TW.html b/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets_zh_TW.html index 73889f3da11a..e5c76e5da261 100644 --- a/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets_zh_TW.html +++ b/core/src/main/resources/hudson/tasks/Fingerprinter/help-targets_zh_TW.html @@ -1,5 +1,5 @@
      可以像 "module/dist/**/*.zip" 這樣使用萬用字元。 - 確切格式可以參考 Ant fileset 的 @includes。 + 確切格式可以參考 Ant fileset 的 @includes。 工作目錄就是工作區目錄
      diff --git a/core/src/main/resources/hudson/tasks/Fingerprinter/help.html b/core/src/main/resources/hudson/tasks/Fingerprinter/help.html index cdbcdd57c89b..f48134850802 100644 --- a/core/src/main/resources/hudson/tasks/Fingerprinter/help.html +++ b/core/src/main/resources/hudson/tasks/Fingerprinter/help.html @@ -5,17 +5,17 @@
      • - I have foo.jar on my HDD but which build number of FOO did it come from? + I have foo.jar on my HDD but which build number of FOO did it come from?
      • - My BAR project depends on foo.jar from the FOO project. + My BAR project depends on foo.jar from the FOO project.
        • - Which build of foo.jar is used in BAR #51? + Which build of foo.jar is used in BAR #51?
        • - Which build of BAR contains my bug fix to foo.jar #32? + Which build of BAR contains my bug fix to foo.jar #32?
      @@ -26,6 +26,6 @@ is used) need to use this and record fingerprints.

      - See this document + See this document for more details.

      diff --git a/core/src/main/resources/hudson/tasks/Fingerprinter/help_bg.html b/core/src/main/resources/hudson/tasks/Fingerprinter/help_bg.html index c4a834bad6cb..fff280a98121 100644 --- a/core/src/main/resources/hudson/tasks/Fingerprinter/help_bg.html +++ b/core/src/main/resources/hudson/tasks/Fingerprinter/help_bg.html @@ -6,19 +6,19 @@
      • - На диска ми има файл foo.jar, но от кое точно изграждане идва? + На диска ми има файл foo.jar, но от кое точно изграждане идва?
      • - Ако проектът BAR зависи от файла foo.jar, който е от проекта FOO: + Ако проектът BAR зависи от файла foo.jar, който е от проекта FOO:
        • - От кое изграждане идва версията на foo.jar, която се ползва в + От кое изграждане идва версията на foo.jar, която се ползва в изграждане на №51 на BAR?
        • Кое изграждане на BAR ще ползва поправката на грешката, която е включена - в изграждане №32 на foo.jar? + в изграждане №32 на foo.jar?
      @@ -30,5 +30,5 @@

      За повече информация вижте - документацията. + документацията. diff --git a/core/src/main/resources/hudson/tasks/Fingerprinter/help_de.html b/core/src/main/resources/hudson/tasks/Fingerprinter/help_de.html index a138d3e21db5..8639b9919f33 100644 --- a/core/src/main/resources/hudson/tasks/Fingerprinter/help_de.html +++ b/core/src/main/resources/hudson/tasks/Fingerprinter/help_de.html @@ -5,19 +5,19 @@ Jenkins bauen, können Sie dadurch schnell Antworten finden auf Fragen wie:

      • - Ich habe foo.jar auf meiner Festplatte - aber aus welchem Build + Ich habe foo.jar auf meiner Festplatte - aber aus welchem Build des Projekts FOO stammt es?
      • - Mein Projekt BAR hängt von foo.jar des Projekts FOO ab. + Mein Projekt BAR hängt von foo.jar des Projekts FOO ab.
        • - Welcher Build von foo.jar wurde in BAR #51 verwendet? + Welcher Build von foo.jar wurde in BAR #51 verwendet?
        • Welcher Build von BAR beinhaltet meine Fehlerkorrektur für - foo.jar #32? + foo.jar #32?
      @@ -27,5 +27,5 @@ Projekt, in dem eine Datei produziert wird, sondern alle Projekte, welche die Datei verwenden) diese Funktion verwenden und Fingerabdrücke aufzeichnen.

      - Weitere Informationen (auf Englisch) + Weitere Informationen (auf Englisch) diff --git a/core/src/main/resources/hudson/tasks/Fingerprinter/help_fr.html b/core/src/main/resources/hudson/tasks/Fingerprinter/help_fr.html index ab9fadd30716..affa9475373a 100644 --- a/core/src/main/resources/hudson/tasks/Fingerprinter/help_fr.html +++ b/core/src/main/resources/hudson/tasks/Fingerprinter/help_fr.html @@ -8,19 +8,19 @@

      • - J'ai toto.jar sur mon disque dur, mais de quel numéro de + J'ai toto.jar sur mon disque dur, mais de quel numéro de build provient-il?
      • - Mon projet TITI dépend de toto.jar du projet TOTO. + Mon projet TITI dépend de toto.jar du projet TOTO.
        • - Quel build de toto.jar est utilisé dans TUTU #51? + Quel build de toto.jar est utilisé dans TUTU #51?
        • Quel build de TATA contient ma correction de bug reporté sur - toto.jar #32? + toto.jar #32?
      @@ -33,6 +33,6 @@

      Voir - ce document + ce document pour plus de details. diff --git a/core/src/main/resources/hudson/tasks/Fingerprinter/help_it.html b/core/src/main/resources/hudson/tasks/Fingerprinter/help_it.html index 006e1c62621a..40155152ca99 100644 --- a/core/src/main/resources/hudson/tasks/Fingerprinter/help_it.html +++ b/core/src/main/resources/hudson/tasks/Fingerprinter/help_it.html @@ -6,17 +6,17 @@

      • - Ho pippo.jar salvato su disco, ma da quale compilazione di PIPPO proviene? + Ho pippo.jar salvato su disco, ma da quale compilazione di PIPPO proviene?
      • - Il progetto PLUTO dipende da pippo.jar proveniente dal progetto PIPPO. + Il progetto PLUTO dipende da pippo.jar proveniente dal progetto PIPPO.
        • - Quale compilazione di pippo.jar è utilizzata nella compilazione 51 di PLUTO? + Quale compilazione di pippo.jar è utilizzata nella compilazione 51 di PLUTO?
        • - Quale compilazione di PLUTO contiene la correzione che ho introdotto nella compilazione 32 di pippo.jar? + Quale compilazione di PLUTO contiene la correzione che ho introdotto nella compilazione 32 di pippo.jar?
      @@ -27,6 +27,6 @@ il file) devono utilizzarla e registrare le impronte digitali.

      - Si veda questo documento + Si veda questo documento per ulteriori dettagli. diff --git a/core/src/main/resources/hudson/tasks/Fingerprinter/help_ja.html b/core/src/main/resources/hudson/tasks/Fingerprinter/help_ja.html index 373c21c411dd..663cab2fbc13 100644 --- a/core/src/main/resources/hudson/tasks/Fingerprinter/help_ja.html +++ b/core/src/main/resources/hudson/tasks/Fingerprinter/help_ja.html @@ -6,17 +6,17 @@ すばやく解決する事ができます。

      • - ハードディスクにある foo.jar は,FOOプロジェクトのどのビルド番号で作られたのか? + ハードディスクにある foo.jar は,FOOプロジェクトのどのビルド番号で作られたのか?
      • - BARプロジェクトが,FOOプロジェクトの foo.jar に依存している場合 + BARプロジェクトが,FOOプロジェクトの foo.jar に依存している場合
        • - BAR プロジェクトのビルド #51 で使われている foo.jarのビルドはどれか? + BAR プロジェクトのビルド #51 で使われている foo.jarのビルドはどれか?
        • - #32でバグフィックスした foo.jar を含んでいる BARプロジェクトのビルド はどれか? + #32でバグフィックスした foo.jar を含んでいる BARプロジェクトのビルド はどれか?
      @@ -26,7 +26,7 @@ ファイルを利用するプロジェクト)すべてで,ファイル指紋を記録する必要があります。

      より詳しくは - このドキュメントを + このドキュメントを 参照してください。 diff --git a/core/src/main/resources/hudson/tasks/Fingerprinter/help_pt_BR.html b/core/src/main/resources/hudson/tasks/Fingerprinter/help_pt_BR.html index 5c113191f7be..3509624b3e90 100644 --- a/core/src/main/resources/hudson/tasks/Fingerprinter/help_pt_BR.html +++ b/core/src/main/resources/hudson/tasks/Fingerprinter/help_pt_BR.html @@ -5,17 +5,17 @@

      • - Eu tenho um foo.jar no meu HD mas qual o número da construção de FOO que gerou ele? + Eu tenho um foo.jar no meu HD mas qual o número da construção de FOO que gerou ele?
      • - Meu projeto BAR depende de foo.jar do projeto FOO. + Meu projeto BAR depende de foo.jar do projeto FOO.
        • - Qual construção de foo.jar é usada na construção de BAR número 51? + Qual construção de foo.jar é usada na construção de BAR número 51?
        • - Qual construção de BAR contém minha correção de bug para o foo.jar de número 32? + Qual construção de BAR contém minha correção de bug para o foo.jar de número 32?
      @@ -26,6 +26,6 @@ é usado) necessitam usar isto e gravar os fingerprints.

      - Veja esta documentação + Veja esta documentação para mais detalhes. diff --git a/core/src/main/resources/hudson/tasks/Fingerprinter/help_ru.html b/core/src/main/resources/hudson/tasks/Fingerprinter/help_ru.html index 057832d20c67..925d55507f68 100644 --- a/core/src/main/resources/hudson/tasks/Fingerprinter/help_ru.html +++ b/core/src/main/resources/hudson/tasks/Fingerprinter/help_ru.html @@ -5,17 +5,17 @@

      • - У меня есть foo.jar на диске, но каков его номер сборки в проекте FOO? + У меня есть foo.jar на диске, но каков его номер сборки в проекте FOO?
      • - Проект BAR зависит от foo.jar из проекта FOO. + Проект BAR зависит от foo.jar из проекта FOO.
        • - Какой номер сборки foo.jar использован в BAR #51? + Какой номер сборки foo.jar использован в BAR #51?
        • - Какая сборка BAR содержит мой багфикс из foo.jar сборки #32? + Какая сборка BAR содержит мой багфикс из foo.jar сборки #32?
      @@ -26,6 +26,6 @@ должны также включить эту опцию и сохранять свои отпечатки.

      - Прочтите этот документ + Прочтите этот документ если вы хотите узнать больше. diff --git a/core/src/main/resources/hudson/tasks/Fingerprinter/help_tr.html b/core/src/main/resources/hudson/tasks/Fingerprinter/help_tr.html index 36e010f00d42..5c411940db78 100644 --- a/core/src/main/resources/hudson/tasks/Fingerprinter/help_tr.html +++ b/core/src/main/resources/hudson/tasks/Fingerprinter/help_tr.html @@ -5,17 +5,17 @@

      • - Sabit diskimde foo.jar dosyam var, fakat FOO projesinin hangi sürüm numarasında üretildi? + Sabit diskimde foo.jar dosyam var, fakat FOO projesinin hangi sürüm numarasında üretildi?
      • - BAR projesi FOO projesinin foo.jar dosyasına bağımlıdır. + BAR projesi FOO projesinin foo.jar dosyasına bağımlıdır.
        • - BAR'ın 51 numaralı sürümünde foo.jar'ın hangi yapılandırması kullanıldı. + BAR'ın 51 numaralı sürümünde foo.jar'ın hangi yapılandırması kullanıldı.
        • - Hangi BAR projesi, foo.jar'ın 32 numaralı sürümüne uyguladığım çözümü içerir? + Hangi BAR projesi, foo.jar'ın 32 numaralı sürümüne uyguladığım çözümü içerir?
      @@ -25,5 +25,5 @@ aynı zamanda bu dosyayı kullanan projelerin de) bunu kullanması ve parmakizlerini kaydetmesi gereklidir.

      - Daha fazla bilgi için lütfen tıklayın + Daha fazla bilgi için lütfen tıklayın diff --git a/core/src/main/resources/hudson/tasks/Fingerprinter/help_zh_TW.html b/core/src/main/resources/hudson/tasks/Fingerprinter/help_zh_TW.html index b38287df9e3c..26dd3875c0e5 100644 --- a/core/src/main/resources/hudson/tasks/Fingerprinter/help_zh_TW.html +++ b/core/src/main/resources/hudson/tasks/Fingerprinter/help_zh_TW.html @@ -24,5 +24,5 @@ 都要開啟指紋記錄功能。

      - 詳情請參考這份文件。 + 詳情請參考這份文件。 diff --git a/core/src/main/resources/hudson/tasks/Maven/config.jelly b/core/src/main/resources/hudson/tasks/Maven/config.jelly index 7653f18a03ae..1e54cdbf628b 100644 --- a/core/src/main/resources/hudson/tasks/Maven/config.jelly +++ b/core/src/main/resources/hudson/tasks/Maven/config.jelly @@ -26,7 +26,7 @@ THE SOFTWARE. - ${inst.name} diff --git a/core/src/main/resources/hudson/tasks/Maven/config_pt_BR.properties b/core/src/main/resources/hudson/tasks/Maven/config_pt_BR.properties index fc63e3c60d6c..7bbdd0ea1b98 100644 --- a/core/src/main/resources/hudson/tasks/Maven/config_pt_BR.properties +++ b/core/src/main/resources/hudson/tasks/Maven/config_pt_BR.properties @@ -20,12 +20,13 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Maven\ Version=Vers\u00e3o do Maven -Default=Padr\u00e3o +Maven\ Version=Vers\u00E3o do Maven +Default=Padr\u00E3o Goals=Goals POM=POM Properties=Propriedades -Use\ private\ Maven\ repository=Use reposit\u00f3rio privado Maven -JVM\ Options=Op\u00e7\u00f5es JVM -Settings\ file=Arquivos de configura\u00e7\u00f5es -Global\ Settings\ file=Arquivos de configura\u00e7\u00f5es globais +Use\ private\ Maven\ repository=Use reposit\u00F3rio privado Maven +JVM\ Options=Op\u00E7\u00F5es JVM +Settings\ file=Arquivos de configura\u00E7\u00F5es +Global\ Settings\ file=Arquivos de configura\u00E7\u00F5es globais +Inject\ build\ variables=Injetar vari\u00E1veis de constru\u00E7\u00E3o diff --git a/core/src/main/resources/hudson/tasks/Maven/help-injectBuildVariables.html b/core/src/main/resources/hudson/tasks/Maven/help-injectBuildVariables.html index 6bf14bbfb235..b36371b2ce83 100644 --- a/core/src/main/resources/hudson/tasks/Maven/help-injectBuildVariables.html +++ b/core/src/main/resources/hudson/tasks/Maven/help-injectBuildVariables.html @@ -1,5 +1,5 @@

      Pass all build variables into maven process in form of java properties. This is seldom needed as Jenkins provides it as environment variables anyway. Preferred way to access Jenkins build variables is to explicitly map it to property in - Properties section (MY_VAR=${MY_VAR}). + Properties section (MY_VAR=${MY_VAR}).
      diff --git a/core/src/main/resources/hudson/tasks/Maven/help-injectBuildVariables_bg.html b/core/src/main/resources/hudson/tasks/Maven/help-injectBuildVariables_bg.html index 6852f46ae4c9..b51de2cdc96d 100644 --- a/core/src/main/resources/hudson/tasks/Maven/help-injectBuildVariables_bg.html +++ b/core/src/main/resources/hudson/tasks/Maven/help-injectBuildVariables_bg.html @@ -2,5 +2,5 @@ Подаване на всички променливи от изграждането към процеса на maven като свойства на Java. Рядко има нужда от това, защото променливите така или иначе са изнесени към средата. Предпочитаният начин за достъп до тях е изрично подаване на отделните променливи от - изграждането като свойства на Java в раздела Свойства (MY_VAR=${MY_VAR}). + изграждането като свойства на Java в раздела Свойства (MY_VAR=${MY_VAR}). diff --git a/core/src/main/resources/hudson/tasks/Maven/help-injectBuildVariables_it.html b/core/src/main/resources/hudson/tasks/Maven/help-injectBuildVariables_it.html index c3e482d2f9c3..f8d4b09dbe82 100644 --- a/core/src/main/resources/hudson/tasks/Maven/help-injectBuildVariables_it.html +++ b/core/src/main/resources/hudson/tasks/Maven/help-injectBuildVariables_it.html @@ -4,5 +4,5 @@ comunque sotto forma di variabili d'ambiente. La modalità preferita di accesso alle variabili di compilazione di Jenkins è la loro mappatura in proprietà specificate nella sezione Proprietà - (VARIABILE=${VARIABILE}). + (VARIABILE=${VARIABILE}). diff --git a/core/src/main/resources/hudson/tasks/Maven/help-properties.html b/core/src/main/resources/hudson/tasks/Maven/help-properties.html index 6c8b8b69aa94..cb607eb5f45b 100644 --- a/core/src/main/resources/hudson/tasks/Maven/help-properties.html +++ b/core/src/main/resources/hudson/tasks/Maven/help-properties.html @@ -4,5 +4,5 @@ name1=value1 name2=value2 - These are passed to Maven like "-Dname1=value1 -Dname2=value2" + These are passed to Maven like "-Dname1=value1 -Dname2=value2" diff --git a/core/src/main/resources/hudson/tasks/Maven/help-properties_bg.html b/core/src/main/resources/hudson/tasks/Maven/help-properties_bg.html index 9087244e82da..3e1a7e9ab4f2 100644 --- a/core/src/main/resources/hudson/tasks/Maven/help-properties_bg.html +++ b/core/src/main/resources/hudson/tasks/Maven/help-properties_bg.html @@ -5,5 +5,5 @@ име1=стойност1 име2=стойност2 - Те се подават към Maven като „-Dиме1=стойност1 -Dиме2=стойност2“ + Те се подават към Maven като „-Dиме1=стойност1 -Dиме2=стойност2“ diff --git a/core/src/main/resources/hudson/tasks/Maven/help-properties_de.html b/core/src/main/resources/hudson/tasks/Maven/help-properties_de.html index e2c68de2c5fd..7c824f1cf911 100644 --- a/core/src/main/resources/hudson/tasks/Maven/help-properties_de.html +++ b/core/src/main/resources/hudson/tasks/Maven/help-properties_de.html @@ -6,5 +6,5 @@ name2=value2 - Diese Eigenschaften werden an Maven wie "-Dname1=value1 -Dname2=value2" weitergegeben. + Diese Eigenschaften werden an Maven wie "-Dname1=value1 -Dname2=value2" weitergegeben. diff --git a/core/src/main/resources/hudson/tasks/Maven/help-properties_fr.html b/core/src/main/resources/hudson/tasks/Maven/help-properties_fr.html index 82518c15afec..e65cc49d3f5a 100644 --- a/core/src/main/resources/hudson/tasks/Maven/help-properties_fr.html +++ b/core/src/main/resources/hudson/tasks/Maven/help-properties_fr.html @@ -4,5 +4,5 @@ nom1=valeur1 nom2=valeur2 - Ces propriétés sont passées à Maven ainsi: "-Dnom1=valeur1 -Dnom2=valeur2" + Ces propriétés sont passées à Maven ainsi: "-Dnom1=valeur1 -Dnom2=valeur2" diff --git a/core/src/main/resources/hudson/tasks/Maven/help-properties_it.html b/core/src/main/resources/hudson/tasks/Maven/help-properties_it.html index 01dccf3f2dfd..91442c8de8e7 100644 --- a/core/src/main/resources/hudson/tasks/Maven/help-properties_it.html +++ b/core/src/main/resources/hudson/tasks/Maven/help-properties_it.html @@ -5,5 +5,5 @@ nome1=valore1 nome2=valore2 - Queste sono fornite a Maven come segue: "-Dnome1=valore1 -Dnome2=valore2" + Queste sono fornite a Maven come segue: "-Dnome1=valore1 -Dnome2=valore2" diff --git a/core/src/main/resources/hudson/tasks/Maven/help-properties_ja.html b/core/src/main/resources/hudson/tasks/Maven/help-properties_ja.html index 19ce50c31bb1..d0020fb449f3 100644 --- a/core/src/main/resources/hudson/tasks/Maven/help-properties_ja.html +++ b/core/src/main/resources/hudson/tasks/Maven/help-properties_ja.html @@ -4,5 +4,5 @@ name1=value1 name2=value2 - これらのプロパティは、Mavenに"-Dname1=value1 -Dname2=value2"のように渡されます。 + これらのプロパティは、Mavenに"-Dname1=value1 -Dname2=value2"のように渡されます。 diff --git a/core/src/main/resources/hudson/tasks/Maven/help-settings.html b/core/src/main/resources/hudson/tasks/Maven/help-settings.html index f60c52eb7ee1..216e07a559cd 100644 --- a/core/src/main/resources/hudson/tasks/Maven/help-settings.html +++ b/core/src/main/resources/hudson/tasks/Maven/help-settings.html @@ -16,5 +16,5 @@ referred to as user settings. If both files exists, their contents gets merged, with the user-specific settings.xml being dominant.

      - see also: settings.xml reference + see also: settings.xml reference \ No newline at end of file diff --git a/core/src/main/resources/hudson/tasks/Maven/help-settings_bg.html b/core/src/main/resources/hudson/tasks/Maven/help-settings_bg.html index d7068029ea73..f0fdc5000aac 100644 --- a/core/src/main/resources/hudson/tasks/Maven/help-settings_bg.html +++ b/core/src/main/resources/hudson/tasks/Maven/help-settings_bg.html @@ -15,6 +15,6 @@ Първото е мястото на глобалните настройки, а второто са настройките за отделен потребител. Ако и двата файла съществуват, те се четат и сливат, като потребителските настройки са с приоритет.

      - За повече информация вижте settings.xml + За повече информация вижте settings.xml документацията. diff --git a/core/src/main/resources/hudson/tasks/Maven/help-settings_it.html b/core/src/main/resources/hudson/tasks/Maven/help-settings_it.html index 2728c5a4a35a..40a907467bcc 100644 --- a/core/src/main/resources/hudson/tasks/Maven/help-settings_it.html +++ b/core/src/main/resources/hudson/tasks/Maven/help-settings_it.html @@ -1,5 +1,5 @@

      - L'elemento settings nel file settings.xml contiene + L'elemento settings nel file settings.xml contiene degli elementi utilizzati per definire valori che configurano l'esecuzione di Maven in vari modi, come accade per il file pom.xml, ma non dovrebbe essere incorporato in un progetto specifico o distribuito @@ -21,5 +21,5 @@ uniti e prevarranno le impostazioni del file settings.xml dell'utente.

      - Si veda anche: Informazioni di riferimento settings.xml + Si veda anche: Informazioni di riferimento settings.xml

      diff --git a/core/src/main/resources/hudson/tasks/Maven/help-settings_zh_TW.html b/core/src/main/resources/hudson/tasks/Maven/help-settings_zh_TW.html index a46db3f653a3..523dac44e517 100644 --- a/core/src/main/resources/hudson/tasks/Maven/help-settings_zh_TW.html +++ b/core/src/main/resources/hudson/tasks/Maven/help-settings_zh_TW.html @@ -13,5 +13,5 @@ 第一個 settings.xml 也叫做全域設定,後面那個叫做使用者設定。 兩者同時存在時,內容會合併,但以使用者自定的 settings.xml 為準。

      - 請參考: settings.xml 參考資料 + 請參考: settings.xml 參考資料 \ No newline at end of file diff --git a/core/src/main/resources/hudson/tasks/Maven/help.properties b/core/src/main/resources/hudson/tasks/Maven/help.properties index dc0bc391ebff..bfc03679c5e0 100644 --- a/core/src/main/resources/hudson/tasks/Maven/help.properties +++ b/core/src/main/resources/hudson/tasks/Maven/help.properties @@ -1,9 +1,9 @@ para1=For projects that use Maven as the build system. This causes Jenkins to invoke \ - Maven with the given goals and options. A non-zero exit code from Maven makes Jenkins \ - mark the build as a failure. Some Maven versions have a bug where it doesn''t return \ - the exit code correctly. -para2=Jenkins passes various environment \ - variables to Maven, which you can access from Maven as "${env.VARIABLENAME}". + Maven with the given goals and options. A non-zero exit code from Maven makes Jenkins \ + mark the build as a failure. Some Maven versions have a bug where it doesn''t return \ + the exit code correctly. +para2=Jenkins passes various environment \ + variables to Maven, which you can access from Maven as "${env.VARIABLENAME}". para3=The same variables can be used in command-line arguments (as if you are invoking \ - this from shell). For example, you can specify \ - -DresultsFile=\${WORKSPACE}/\${BUILD_TAG}.results.txt + this from shell). For example, you can specify \ + -DresultsFile=\${WORKSPACE}/\${BUILD_TAG}.results.txt diff --git a/core/src/main/resources/hudson/tasks/Maven/help_bg.properties b/core/src/main/resources/hudson/tasks/Maven/help_bg.properties index 2d4ca93eaf99..2bb99c9d0164 100644 --- a/core/src/main/resources/hudson/tasks/Maven/help_bg.properties +++ b/core/src/main/resources/hudson/tasks/Maven/help_bg.properties @@ -20,12 +20,12 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -# Jenkins passes various environment \ +# Jenkins passes various environment \ # variables to Maven, which you can access from Maven as "${env.VARIABLENAME}". para2=\ - Jenkins \u043f\u0440\u0435\u0434\u0430\u0432\u0430 \u043d\u044f\u043a\u043e\u0438 \u043f\u0440\u043e\u043c\u0435\u043d\u043b\u0438\u0432\u0438 \u043d\u0430\ + Jenkins \u043f\u0440\u0435\u0434\u0430\u0432\u0430 \u043d\u044f\u043a\u043e\u0438 \u043f\u0440\u043e\u043c\u0435\u043d\u043b\u0438\u0432\u0438 \u043d\u0430\ \u0441\u0440\u0435\u0434\u0430\u0442\u0430 \u043a\u044a\u043c Maven. \u0422\u0435 \u043c\u043e\u0433\u0430\u0442 \u0434\u0430 \u0431\u044a\u0434\u0430\u0442 \u0434\u043e\u0441\u0442\u044a\u043f\u0435\u043d\u0438 \u043e\u0442 Maven \u0447\u0440\u0435\u0437\ - \u201e${env.VARIABLENAME}\u201c. + \u201e${env.VARIABLENAME}\u201c. # For projects that use Maven as the build system. This causes Jenkins to invoke \ # Maven with the given goals and options. A non-zero exit code from Maven makes Jenkins \ @@ -38,8 +38,8 @@ para1=\ \u0434\u0435\u0444\u0435\u043a\u0442, \u043f\u0440\u0438 \u043a\u043e\u0439\u0442\u043e \u0438\u0437\u0445\u043e\u0434\u043d\u0438\u044f\u0442 \u043a\u043e\u0434 \u043d\u0435 \u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0435\u043d. # The same variables can be used in command-line arguments (as if you are invoking \ # this from shell). For example, you can specify \ -# -DresultsFile=\${WORKSPACE}/\${BUILD_TAG}.results.txt +# -DresultsFile=\${WORKSPACE}/\${BUILD_TAG}.results.txt para3=\ \u0421\u044a\u0449\u0438\u0442\u0435 \u043f\u0440\u043e\u043c\u0435\u043d\u043b\u0438\u0432\u0438 \u043c\u043e\u0433\u0430\u0442 \u0434\u0430 \u0441\u0435 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u0442 \u043a\u0430\u0442\u043e \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0438 \u043d\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u0438\u044f \u0440\u0435\u0434, \u0432\u0441\u0435\ \u0435\u0434\u043d\u043e \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u0442\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u0430\u0442\u0430 \u0434\u0438\u0440\u0435\u043a\u0442\u043d\u043e \u043f\u0440\u0435\u0437 \u043e\u0431\u0432\u0438\u0432\u043a\u0430\u0442\u0430. \u041d\u0430\u043f\u0440. \u043c\u043e\u0436\u0435 \u0434\u0430 \u0443\u043a\u0430\u0436\u0435\u0442\u0435:\ - -DresultsFile=\${WORKSPACE}/\${BUILD_TAG}.results.txt + -DresultsFile=\${WORKSPACE}/\${BUILD_TAG}.results.txt diff --git a/core/src/main/resources/hudson/tasks/Maven/help_de.properties b/core/src/main/resources/hudson/tasks/Maven/help_de.properties index 485743f89ec7..a28b544b7769 100644 --- a/core/src/main/resources/hudson/tasks/Maven/help_de.properties +++ b/core/src/main/resources/hudson/tasks/Maven/help_de.properties @@ -3,8 +3,8 @@ para1=F\u00fcr Projekte, die Maven als Build-System benutzen. Dies veranlasst Je ungleich 0 bewirkt, dass Jenkins den Build als Fehlschlag markiert. \ Manche Versionen von Maven beinhalten einen Fehler, durch den der Ergebniscode \ nicht immer korrekt zur\u00fcckgeliefert wird. -para2=Jenkins \u00fcbergibt \ - zahlreiche Umgebungsvariablen an Maven, auf die Sie innerhalb Mavens mittels $'{'env.VARIABLENAME} zugreifen k\u00f6nnen. +para2=Jenkins \u00fcbergibt \ + zahlreiche Umgebungsvariablen an Maven, auf die Sie innerhalb Mavens mittels $'{'env.VARIABLENAME} zugreifen k\u00f6nnen. para3=Die gleichen Umgebungsvariablen k\u00f6nnen in Kommandozeilenargumenten verwendet werden (genauso als ob Sie \ Kommandos in einer Shell ausf\u00fchren w\u00fcrden), wie beispielsweise \ - -DresultsFile=$'{'WORKSPACE}/$'{'BUILD_TAG}.results.txt + -DresultsFile=$'{'WORKSPACE}/$'{'BUILD_TAG}.results.txt diff --git a/core/src/main/resources/hudson/tasks/Maven/help_fr.properties b/core/src/main/resources/hudson/tasks/Maven/help_fr.properties index df6a27d4dde7..51f16bce6ffd 100644 --- a/core/src/main/resources/hudson/tasks/Maven/help_fr.properties +++ b/core/src/main/resources/hudson/tasks/Maven/help_fr.properties @@ -4,9 +4,9 @@ para1=Pour les projets qui utilisent Maven comme outil de build. \ \u00eatre marqu\u00e9 comme un \u00e9chec. \ Certaines versions de Maven ont un bug qui ne permet pas le retour correct \ d''un code de sortie. -para2=Jenkins passe \ +para2=Jenkins passe \ certaines variables d''environment \u00e0 Maven, auxquelles vous pouvez \ acc\u00e9der \u00e0 l''aide de "$'{'env.NOMDEVARIABLE}". para3=Les m\u00eames variables peuvent \u00eatre utilis\u00e9es comme des arguments de ligne \ de commande, comme si vous faisiez une invocation \u00e0 partir d''un Shell. \ - Par exemple, vous pouvez sp\u00e9cifier -DresultsFile=$'{'WORKSPACE}/$'{'BUILD_TAG}.results.txt + Par exemple, vous pouvez sp\u00e9cifier -DresultsFile=$'{'WORKSPACE}/$'{'BUILD_TAG}.results.txt diff --git a/core/src/main/resources/hudson/tasks/Maven/help_it.properties b/core/src/main/resources/hudson/tasks/Maven/help_it.properties index 05a71ed26b66..96e790891f09 100644 --- a/core/src/main/resources/hudson/tasks/Maven/help_it.properties +++ b/core/src/main/resources/hudson/tasks/Maven/help_it.properties @@ -27,9 +27,9 @@ para1=Per i progetti che utilizzano Maven come sistema di compilazione. \ Jenkins contrassegni la compilazione come non riuscita. Alcune versioni di \ Maven hanno un bug per cui il codice di uscita non viene restituito \ correttamente. -para2=Jenkins fornisce a Maven \ +para2=Jenkins fornisce a Maven \ svariate variabili d''ambiente, a cui si pu accedere da Maven con la \ sintassi "${env.NOMEVARIABILE}". para3=Le stesse variabili possono essere utilizzate negli argomenti da riga \ di comando (come se lo si invocasse da una shell). Ad esempio, possibile \ - specificare -DresultsFile=\${WORKSPACE}/\${BUILD_TAG}.results.txt + specificare -DresultsFile=\${WORKSPACE}/\${BUILD_TAG}.results.txt diff --git a/core/src/main/resources/hudson/tasks/Maven/help_ja.properties b/core/src/main/resources/hudson/tasks/Maven/help_ja.properties index 1bf10a16ad79..ea7361127ffc 100644 --- a/core/src/main/resources/hudson/tasks/Maven/help_ja.properties +++ b/core/src/main/resources/hudson/tasks/Maven/help_ja.properties @@ -2,7 +2,7 @@ para1=\u30d3\u30eb\u30c9\u30b7\u30b9\u30c6\u30e0\u3068\u3057\u3066Maven\u3092\u4 Jenkins\u306f\u3001\u4e0e\u3048\u3089\u308c\u305f\u30b4\u30fc\u30eb\u3068\u30aa\u30d7\u30b7\u30e7\u30f3\u3068\u3068\u3082\u306bMaven\u3092\u8d77\u52d5\u3057\u307e\u3059\u3002\ Maven\u304c0\u3067\u306a\u3044\u7d42\u4e86\u30b3\u30fc\u30c9\u3092\u8fd4\u3059\u3068\u3001Jenkins\u306f\u30d3\u30eb\u30c9\u304c\u5931\u6557\u3057\u305f\u3068\u5224\u65ad\u3057\u307e\u3059\u3002\ Maven\u306e\u3042\u308b\u30d0\u30fc\u30b8\u30e7\u30f3\u306f\u3001\u7d42\u4e86\u30b3\u30fc\u30c9\u3092\u9069\u5207\u306b\u8fd4\u3055\u306a\u3044\u30d0\u30b0\u304c\u3042\u308a\u307e\u3059\u3002 -para2=Jenkins\u306f\u3001\ +para2=Jenkins\u306f\u3001\ \u5229\u7528\u53ef\u80fd\u306a\u74b0\u5883\u5909\u6570 \u3092Maven\u306b\u6e21\u3057\u307e\u3059\u3002Maven\u3067\u306f"$'{'env.VARIABLENAME}"\u3068\u3057\u3066\u53c2\u7167\u3067\u304d\u307e\u3059\u3002 para3=\u540c\u3058\u5909\u6570\u3092\u3001\u30b3\u30de\u30f3\u30c9\u30e9\u30a4\u30f3\u306e\u5f15\u6570\u3067\u4f7f\u7528\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059(\u30b7\u30a7\u30eb\u304b\u3089\u8d77\u52d5\u3057\u3066\u3044\u308b\u304b\u306e\u3088\u3046\u306b)\u3002\ - \u4f8b\u3048\u3070\u3001-DresultsFile=$'{'WORKSPACE}/$'{'BUILD_TAG}.results.txt\u306e\u3088\u3046\u306b\u6307\u5b9a\u3067\u304d\u307e\u3059\u3002 + \u4f8b\u3048\u3070\u3001-DresultsFile=$'{'WORKSPACE}/$'{'BUILD_TAG}.results.txt\u306e\u3088\u3046\u306b\u6307\u5b9a\u3067\u304d\u307e\u3059\u3002 diff --git a/core/src/main/resources/hudson/tasks/Maven/help_pt_BR.properties b/core/src/main/resources/hudson/tasks/Maven/help_pt_BR.properties index 02023c459b57..7e6d02f89e02 100644 --- a/core/src/main/resources/hudson/tasks/Maven/help_pt_BR.properties +++ b/core/src/main/resources/hudson/tasks/Maven/help_pt_BR.properties @@ -2,7 +2,7 @@ para1=Para projetos que usam Maven como sistema de construção. Isto fa invocar o Maven com os objetivos e opções informadas. Um código de saída \ diferente de zero vindo do Maven faz com que o Jenkins marque a construção como uma falha. \ Algumas versões do Maven têm um bug onde ele não retorna o código de saída corretamente. -para2=O Jenkins passa \ +para2=O Jenkins passa \ várias variáveis de ambiente para o Maven, que você pode acessar do Maven como "$'{'env.VARIABLENAME}". para3=As mesmas variáveis podem ser usadas como argumentos na linha de comando (como se você fosse invocar do shell). \ - Por exemplo, você pode especificar -DresultsFile=$'{'WORKSPACE}/$'{'BUILD_TAG}.resultados.txt + Por exemplo, você pode especificar -DresultsFile=$'{'WORKSPACE}/$'{'BUILD_TAG}.resultados.txt diff --git a/core/src/main/resources/hudson/tasks/Maven/help_ru.properties b/core/src/main/resources/hudson/tasks/Maven/help_ru.properties index 240e24fa11cd..8df59fb70eae 100644 --- a/core/src/main/resources/hudson/tasks/Maven/help_ru.properties +++ b/core/src/main/resources/hudson/tasks/Maven/help_ru.properties @@ -2,9 +2,9 @@ para1=\u0414\u043b\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432, \u043 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c Maven \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0446\u0435\u043b\u044f\u043c\u0438 \u0438 \u043e\u043f\u0446\u0438\u044f\u043c\u0438. \u0415\u0441\u043b\u0438 Maven \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442 \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 \ \u043d\u0435\u043d\u0443\u043b\u0435\u0432\u044b\u043c \u043a\u043e\u0434\u043e\u043c, \u0441\u0431\u043e\u0440\u043a\u0430 \u0431\u0443\u0434\u0435\u0442 \u0441\u0447\u0438\u0442\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u043e\u0432\u0430\u043b\u0438\u0432\u0448\u0435\u0439\u0441\u044f. \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0435\u0440\u0441\u0438\u0438 Maven \ \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u043e\u0448\u0438\u0431\u043a\u0443, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044f \u043d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u043a\u043e\u0434 \u043f\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0438. -para2=Jenkins \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442 \ +para2=Jenkins \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442 \ \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0432 Maven, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e\ \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 Maven "$'{'env.VARIABLENAME}". para3=\u042d\u0442\u0438 \u0436\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438 \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0435 (\u0435c\u043b\u0438 \u0432\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0435 \ Maven \u0438\u0437 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f shell). \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0443\u043a\u0430\u0437\u0430\u0442\u044c \ - -DresultsFile=$'{'WORKSPACE}/$'{'BUILD_TAG}.results.txt. + -DresultsFile=$'{'WORKSPACE}/$'{'BUILD_TAG}.results.txt. diff --git a/core/src/main/resources/hudson/tasks/Maven/help_sr.properties b/core/src/main/resources/hudson/tasks/Maven/help_sr.properties index c1657bcbbf13..5143cfed80a1 100644 --- a/core/src/main/resources/hudson/tasks/Maven/help_sr.properties +++ b/core/src/main/resources/hudson/tasks/Maven/help_sr.properties @@ -1,6 +1,6 @@ # This file is under the MIT License by authors para1=\u0417\u0430 \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0435 \u043A\u043E\u0458\u0438 \u043A\u043E\u0440\u0438\u0441\u0442\u0435 \u0441\u0438\u0441\u0442\u0435\u043C \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 Maven. \u041E\u0432\u043E \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0435 \u045B\u0435 \u0443\u043A\u0430\u0437\u0430\u0442\u0438 \u0434\u0430 Jenkins \u043A\u043E\u0440\u0438\u0441\u0442\u0438 Maven \u0441\u0430 \u0434\u0430\u0442\u0438\u043C \u0446\u0438\u0459\u0435\u0432\u0438\u043C\u0430 \u0438 \u043E\u043F\u0446\u0438\u0458\u0430\u043C\u0430. \u0410\u043A\u043E Maven \u0437\u0430\u0432\u0440\u0448\u0438 \u0441\u0430 \u043D\u0435\u043D\u0443\u043B\u043D\u0438\u043C \u043A\u043E\u0434\u043E\u043C, \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u045B\u0435 \u0441\u0435 \u0441\u043C\u0430\u0442\u0440\u0430\u0442\u0438 \u043D\u0435\u0443\u0441\u043F\u0435\u043D\u043E\u0433. \u041C\u0435\u0452\u0443\u0442\u0438\u043C \u043D\u0435\u043A\u0435 \u0432\u0435\u0440\u0437\u0438\u0458\u0435 Maven \u0438\u043C\u0430\u0458\u0443 \u0433\u0440\u0435\u0448\u043A\u0443 \u043A\u043E\u0458\u0430 \u0432\u0440\u0430\u045B\u0430 \u043F\u043E\u0433\u0440\u0435\u0448\u0430\u043D \u043A\u043E\u0434 \u043F\u043E \u0437\u0430\u0432\u0440\u0448\u0435\u0442\u043A\u0443. -para2=Jenkins \u043F\u0440\u0435\u043D\u0435\u0441\u0435 \ +para2=Jenkins \u043F\u0440\u0435\u043D\u0435\u0441\u0435 \ \u0440\u0430\u0437\u043D\u0430 \u043F\u0440\u043E\u043C\u0435\u043D\u0459\u0438\u0432\u0430 Maven-\u0443, \u043A\u043E\u0458\u0430 \u0441\u0443 \u0434\u043E\u0441\u0442\u0443\u043F\u043D\u0430 \u043F\u043E \u0448\u0430\u0431\u043B\u043E\u043D\u0443 "$'{'env.VARIABLENAME}". para3=\u0422\u0435 \u0438\u0441\u0442\u0435 \u043F\u0440\u043E\u043C\u0435\u043D\u0459\u0438\u0432\u0435 \u043C\u043E\u0433\u0443 \u0441\u0435 \u043A\u043E\u0440\u0438\u0441\u0442\u0438 \u043F\u0440\u0435\u043A\u043E \u043A\u043E\u043C\u0430\u043D\u0434\u043D\u0435 \u043B\u0438\u043D\u0438\u0458\u0435 (\u0430\u043A\u043E \u043F\u043E\u0437\u043E\u0432\u0435\u0442\u0435 Maven \u0441\u0430 \u043A\u043E\u043C\u0430\u043D\u0434\u043D\u0435 \u043B\u0438\u043D\u0438\u0458\u0435). \u041D\u0430 \u043F\u0440\u0438\u043C\u0435\u0440, \u043C\u043E\u0436\u0435\u0442\u0435 \u0434\u0430 \u043E\u0434\u0440\u0435\u0434\u0438\u0442\u0435 diff --git a/core/src/main/resources/hudson/tasks/Maven/help_tr.properties b/core/src/main/resources/hudson/tasks/Maven/help_tr.properties index 874306e43be7..60d98bd9290f 100644 --- a/core/src/main/resources/hudson/tasks/Maven/help_tr.properties +++ b/core/src/main/resources/hudson/tasks/Maven/help_tr.properties @@ -2,7 +2,7 @@ para1=Yapılandırma sistemi olarak Maven kullanan projeler için ku içerisinde, Maven''ı, verilen hedefler ve seçenekler ile çalıştırabilirsiniz. Maven''dan gelen \ 0 olmayan(non-zero) çıkış kodu, yapılandırmayı başarısız olarak ilan eder. \ Bazı Maven versiyonlarında çıkış kodunun düzgün dönememesi gibi bir bug vardır. -para2=Jenkins \ +para2=Jenkins \ çeşitli ortam değişkinlerini Maven''a aktarır, bunlara Maven içerisinden "$'{'env.VARIABLENAME}" ile ulaşabilirsiniz. para3=Aynı değişkenleri komut satırında parametre olarak kullanabilirsiniz (bunu shell''den çağırıyorsanız) \ - Mesela, -DresultsFile=$'{'WORKSPACE}/$'{'BUILD_TAG}.results.txt şeklinde belirleyebilirsiniz + Mesela, -DresultsFile=$'{'WORKSPACE}/$'{'BUILD_TAG}.results.txt şeklinde belirleyebilirsiniz diff --git a/core/src/main/resources/hudson/tasks/Maven/help_zh_TW.properties b/core/src/main/resources/hudson/tasks/Maven/help_zh_TW.properties index 2517d53dd71e..ca26a30baa10 100644 --- a/core/src/main/resources/hudson/tasks/Maven/help_zh_TW.properties +++ b/core/src/main/resources/hudson/tasks/Maven/help_zh_TW.properties @@ -1,7 +1,7 @@ para1=\u9069\u7528\u4ee5 Maven \u5efa\u7f6e\u7684\u5c08\u6848\uff0c\u8b93 Jenkins \u4f7f\u7528\u6307\u5b9a\u7684 Goal \u53ca\u9078\u9805\u53eb\u7528 Maven\u3002\ Jenkins \u6703\u5c07 Maven \u4efb\u4f55\u975e 0 \u7684\u7d50\u675f\u4ee3\u78bc\u90fd\u8996\u70ba\u5efa\u7f6e\u5931\u6557\u3002\ \u67d0\u4e9b\u7248\u672c\u7684 Maven \u6709 Bug\uff0c\u4e0d\u6703\u56de\u50b3\u6b63\u78ba\u7684\u7d50\u675f\u4ee3\u78bc\u3002 -para2=Jenkins \u50b3\u9001\u591a\u500b\u74b0\u5883\u8b8a\u6578\u7d66 \ +para2=Jenkins \u50b3\u9001\u591a\u500b\u74b0\u5883\u8b8a\u6578\u7d66 \ Maven\uff0c\u60a8\u53ef\u4ee5\u5728 Maven \u88e1\u7528 "$'{'env.VARIABLENAME}" \u4f86\u53d6\u5f97\u8b8a\u6578\u503c\u3002 para3=\u540c\u6a23\u7684\u8b8a\u6578\u4e5f\u53ef\u4ee5\u7528\u5728\u547d\u4ee4\u5217\u53c3\u6578\u88e1 (\u5047\u8a2d\u60a8\u662f\u5f9e Shell \u53eb\u7528)\u3002\ \u4f8b\u5982: -DresultsFile=$'{'WORKSPACE}/$'{'BUILD_TAG}.results.txt\u3002 diff --git a/core/src/main/resources/hudson/tasks/Messages_de.properties b/core/src/main/resources/hudson/tasks/Messages_de.properties index 78921f78f179..35d192dadd78 100644 --- a/core/src/main/resources/hudson/tasks/Messages_de.properties +++ b/core/src/main/resources/hudson/tasks/Messages_de.properties @@ -30,7 +30,7 @@ Ant.ProjectConfigNeeded=Eventuell m\u00FCssen Sie f\u00FCr das Projekt noch eine ArtifactArchiver.ARCHIVING_ARTIFACTS=Archiviere Artefakte ArtifactArchiver.DisplayName=Artefakte archivieren -ArtifactArchiver.NoIncludes=Es sind keine Artefakte zur Archivierung konfiguriert.\n\u00DCberpr\u00FCfen Sie, ob in den Einstellungen ein Dateisuchmuster angegeben ist.\nWenn Sie alle Dateien archivieren m\u00F6chten, geben Sie ** an. +ArtifactArchiver.NoIncludes=Es sind keine Artefakte zur Archivierung konfiguriert.\n\u00DCberpr\u00FCfen Sie, ob in den Einstellungen ein Dateisuchmuster angegeben ist.\nWenn Sie alle Dateien archivieren m\u00F6chten, geben Sie ** an. ArtifactArchiver.NoMatchFound=Keine Artefakte gefunden, die mit dem Dateisuchmuster \u201E{0}\u201C \u00FCbereinstimmen. Ein Konfigurationsfehler? ArtifactArchiver.SkipBecauseOnlyIfSuccessful=Archivierung wird \u00FCbersprungen, da der Build nicht erfolgreich ist. diff --git a/core/src/main/resources/hudson/tasks/Messages_pt_BR.properties b/core/src/main/resources/hudson/tasks/Messages_pt_BR.properties index bd20ca67afc9..3802812838d1 100644 --- a/core/src/main/resources/hudson/tasks/Messages_pt_BR.properties +++ b/core/src/main/resources/hudson/tasks/Messages_pt_BR.properties @@ -21,29 +21,24 @@ # THE SOFTWARE. Ant.DisplayName=Chamar Ant -Ant.ExecFailed=Execu\u00e7\u00e3o de comando falhou. -Ant.GlobalConfigNeeded= \u00c9 necess\u00e1rio configurar onde sua instala\u00e7\u00e3o do Ant est\u00e1. -Ant.NotADirectory={0} n\u00e3o \u00e9 um diret\u00f3rio -Ant.NotAntDirectory={0} n\u00e3o parece ser um diret\u00f3rio Ant -Ant.ProjectConfigNeeded= \u00c9 necess\u00e1rio configurar a job para escolher uma de suas instala\u00e7\u00f5es do Ant. - +Ant.ExecFailed=Execu\u00E7\u00E3o de comando falhou. +Ant.GlobalConfigNeeded= \u00C9 necess\u00E1rio configurar onde o Ant est\u00E1 instalado. +Ant.NotADirectory={0} n\u00E3o \u00E9 um diret\u00F3rio +Ant.NotAntDirectory={0} n\u00E3o parece ser um diret\u00F3rio do Ant +Ant.ProjectConfigNeeded= \u00C9 necess\u00E1rio configurar a job para escolher uma de suas instala\u00E7\u00F5es do Ant. ArtifactArchiver.DisplayName=Arquivar os artefatos -ArtifactArchiver.NoIncludes=Nenhum artefato est\u00e1 configurado para arquivamento.\n \u00c9 necess\u00e1rio informar o padr\u00e3o de arquivo, volte para a configura\u00e7\u00e3o e especifique-o.\nSe necessitar arquivar todos os arquivos do workspace, por favor especifique "**" -ArtifactArchiver.NoMatchFound=Nenhum artefato encontrado casa com o padr\u00e3o de arquivo "{0}". Erro de configura\u00e7\u00e3o? - +ArtifactArchiver.NoIncludes=Nenhum artefato est\u00E1 configurado para arquivamento.\n \u00C9 necess\u00E1rio informar o padr\u00E3o de arquivo, volte para a configura\u00E7\u00E3o e especifique-o.\nSe necessitar arquivar todos os arquivos do workspace, por favor especifique "**" +ArtifactArchiver.NoMatchFound=Nenhum artefato encontrado casa com o padr\u00E3o de arquivo "{0}". Erro de configura\u00E7\u00E3o? BatchFile.DisplayName=Executar no comando do Windows - -BuildTrigger.Disabled={0} est\u00e1 desabilitado. A trigger foi pulada +BuildTrigger.Disabled={0} est\u00E1 desabilitado. O gatilho foi ignorado BuildTrigger.DisplayName=Construir outros projetos -BuildTrigger.InQueue={0} j\u00e1 est\u00e3o na fila -BuildTrigger.NoSuchProject=N\u00e3o existe tal projeto ''{0}''. Voc\u00ea quis dizer ''{1}''? -BuildTrigger.NotBuildable={0} n\u00e3o pode ser constru\u00eddo -BuildTrigger.Triggering=Disparando um novo build de {0} - -CommandInterpreter.CommandFailed=execu\u00e7\u00e3o de comando falhou -CommandInterpreter.UnableToDelete=N\u00e3o foi poss\u00edvel apagar o arquivo de script {0} -CommandInterpreter.UnableToProduceScript=N\u00e3o foi poss\u00edvel produzir um arquivo de script - +BuildTrigger.InQueue={0} j\u00E1 est\u00E3o na fila +BuildTrigger.NoSuchProject=N\u00E3o existe tal projeto ''{0}''. Voc\u00EA quis dizer ''{1}''? +BuildTrigger.NotBuildable={0} n\u00E3o pode ser constru\u00EDdo +BuildTrigger.Triggering=Disparando uma nova constru\u00E7\u00E3o de {0} +CommandInterpreter.CommandFailed=execu\u00E7\u00E3o de comando falhou +CommandInterpreter.UnableToDelete=N\u00E3o foi poss\u00EDvel apagar o arquivo de script {0} +CommandInterpreter.UnableToProduceScript=N\u00E3o foi poss\u00EDvel produzir um arquivo de script Fingerprinter.Aborted=Abortado Fingerprinter.Action.DisplayName=Ver fingerprints Fingerprinter.DigestFailed=Falhou ao computar resumo para {0} @@ -51,31 +46,26 @@ Fingerprinter.DisplayName=Gravar fingerprints de arquivos para trilhar o uso Fingerprinter.Failed=Falhou ao gravar fingerprints Fingerprinter.FailedFor=Falhou ao gravar fingerprint para {0} Fingerprinter.Recording=Gravando fingerprints - JavadocArchiver.DisplayName=Publicar Javadoc JavadocArchiver.DisplayName.Generic=Documento JavadocArchiver.DisplayName.Javadoc=Javadoc TestJavadocArchiver.DisplayName.Javadoc=Test Javadoc JavadocArchiver.Publishing=Publicando Javadoc JavadocArchiver.UnableToCopy=Incapaz de copiar Javadoc de {0} para {1} - -Maven.DisplayName=Chamar alvos Maven de alto n\u00edvel -Maven.ExecFailed=execu\u00e7\u00e3o de comando falhou -Maven.NotMavenDirectory={0} n\u00e3o parece ser um diret\u00f3rio Maven -Maven.NoExecutable=N\u00e3o pode encontrar nenhum execut\u00e1vel em {0} - +Maven.DisplayName=Chamar alvos Maven de alto n\u00EDvel +Maven.ExecFailed=execu\u00E7\u00E3o de comando falhou +Maven.NotMavenDirectory={0} n\u00E3o parece ser um diret\u00F3rio Maven +Maven.NoExecutable=N\u00E3o pode encontrar nenhum execut\u00E1vel em {0} Shell.DisplayName=Executar shell -# Cannot find executable from the choosen Ant installation "{0}" -Ant.ExecutableNotFound=N\u00e3o pode ser executado pela instala\u00e7\u00e3o ANT "{0}" -# Archiving artifacts +Ant.ExecutableNotFound=N\u00E3o pode ser executado pela instala\u00E7\u00E3o ANT "{0}" ArtifactArchiver.ARCHIVING_ARTIFACTS=Arquivando artefatos -# Install from Apache InstallFromApache=Instalar a partir do Apache -# No javadoc found in {0}: {1} -JavadocArchiver.NoMatchFound=Nenhum javadoc encontrado {0}: {1} -# Skipped archiving because build is not successful -ArtifactArchiver.SkipBecauseOnlyIfSuccessful=Arquivamento ignorado devido ao t\u00e9rmino do build sem sucesso -# No project specified +JavadocArchiver.NoMatchFound=Nenhum javadoc encontrado {0}: {1} +ArtifactArchiver.SkipBecauseOnlyIfSuccessful=Arquivamento ignorado devido ao t\u00E9rmino sem sucesso da constru\u00E7\u00E3o BuildTrigger.NoProjectSpecified=Nenhum projeto especificado -# You have no permission to build {0} -BuildTrigger.you_have_no_permission_to_build_=Voc\u00ea n\u00e3o tem permiss\u00e3o para construir {0} +BuildTrigger.you_have_no_permission_to_build_=Voc\u00EA n\u00E3o tem permiss\u00E3o para construir {0} +BatchFile.invalid_exit_code_range=Valor de n\u00EDvel de erro inv\u00E1lido: {0}. Verifique a se\u00E7\u00E3o de ajuda +Shell.invalid_exit_code_zero=C\u00F3digo de sa\u00EDda igual a zero \u00E9 ignorado ne n\u00E3o torna a constru\u00E7\u00E3o inst\u00E1vel +BuildTrigger.ok_ancestor_is_null=Ancestral/contexto desconhecido: o projeto especificado n\u00E3o pode ser validado +BatchFile.invalid_exit_code_zero=ERRORLEVEL igual a zero \u00E9 ignorado e n\u00E3o torna a constru\u00E7\u00E3o inst\u00E1vel +Shell.invalid_exit_code_range=C\u00F3digo de sa\u00EDda inv\u00E1lido: {0}. Verifique a se\u00E7\u00E3o de ajuda diff --git a/core/src/main/resources/hudson/tasks/Shell/config.properties b/core/src/main/resources/hudson/tasks/Shell/config.properties index 5a69c4dc7c2e..3f974495e379 100644 --- a/core/src/main/resources/hudson/tasks/Shell/config.properties +++ b/core/src/main/resources/hudson/tasks/Shell/config.properties @@ -20,6 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -description=See the list of available environment variables +description=See the list of available environment variables filterRules=Environment filters addFilterRule=Add environment filter diff --git a/core/src/main/resources/hudson/tasks/Shell/config_da.properties b/core/src/main/resources/hudson/tasks/Shell/config_da.properties index 069dd34ffbc3..5c6e32b4c9ba 100644 --- a/core/src/main/resources/hudson/tasks/Shell/config_da.properties +++ b/core/src/main/resources/hudson/tasks/Shell/config_da.properties @@ -21,4 +21,4 @@ # THE SOFTWARE. Command=Kommando -description=Se listen af tilg\u00e6ngelige milj\u00f8variable +description=Se listen af tilg\u00e6ngelige milj\u00f8variable diff --git a/core/src/main/resources/hudson/tasks/Shell/config_de.properties b/core/src/main/resources/hudson/tasks/Shell/config_de.properties index e0c7c64ee391..3cbba51ddd99 100644 --- a/core/src/main/resources/hudson/tasks/Shell/config_de.properties +++ b/core/src/main/resources/hudson/tasks/Shell/config_de.properties @@ -21,4 +21,4 @@ # THE SOFTWARE. Command=Befehl -description=Liste der verfgbaren Umgebungsvariablen +description=Liste der verfügbaren Umgebungsvariablen diff --git a/core/src/main/resources/hudson/tasks/Shell/config_es.properties b/core/src/main/resources/hudson/tasks/Shell/config_es.properties index 56919def3dd6..c4a36655db86 100644 --- a/core/src/main/resources/hudson/tasks/Shell/config_es.properties +++ b/core/src/main/resources/hudson/tasks/Shell/config_es.properties @@ -20,5 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -description=Visualizar la lista de variables de entorno disponibles +description=Visualizar la lista de variables de entorno disponibles Command=Comando diff --git a/core/src/main/resources/hudson/tasks/Shell/config_fr.properties b/core/src/main/resources/hudson/tasks/Shell/config_fr.properties index 3eb953d0a445..0564a2312d57 100644 --- a/core/src/main/resources/hudson/tasks/Shell/config_fr.properties +++ b/core/src/main/resources/hudson/tasks/Shell/config_fr.properties @@ -21,4 +21,4 @@ # THE SOFTWARE. Command=Commande -description=Voir la liste des variables d''environnement disponibles +description=Voir la liste des variables d''environnement disponibles diff --git a/core/src/main/resources/hudson/tasks/Shell/config_it.properties b/core/src/main/resources/hudson/tasks/Shell/config_it.properties index 6580cf0dca12..efe696fdea7e 100644 --- a/core/src/main/resources/hudson/tasks/Shell/config_it.properties +++ b/core/src/main/resources/hudson/tasks/Shell/config_it.properties @@ -22,7 +22,7 @@ # THE SOFTWARE. Command=Comando -description=Si veda l''elenco delle \ +description=Si veda l''elenco delle \ variabili d''ambiente disponibili Exit\ code\ to\ set\ build\ unstable=Codice d''uscita richiesto per \ contrassegnare la compilazione come instabile diff --git a/core/src/main/resources/hudson/tasks/Shell/config_ja.properties b/core/src/main/resources/hudson/tasks/Shell/config_ja.properties index c36e9c47426a..c64a4e166290 100644 --- a/core/src/main/resources/hudson/tasks/Shell/config_ja.properties +++ b/core/src/main/resources/hudson/tasks/Shell/config_ja.properties @@ -21,4 +21,4 @@ # THE SOFTWARE. Command=\u30b7\u30a7\u30eb\u30b9\u30af\u30ea\u30d7\u30c8 -description=\u30d3\u30eb\u30c9\u304b\u3089\u5229\u7528\u53ef\u80fd\u306a\u74b0\u5883\u5909\u6570\u306e\u4e00\u89a7 +description=\u30d3\u30eb\u30c9\u304b\u3089\u5229\u7528\u53ef\u80fd\u306a\u74b0\u5883\u5909\u6570\u306e\u4e00\u89a7 diff --git a/core/src/main/resources/hudson/tasks/Shell/config_nl.properties b/core/src/main/resources/hudson/tasks/Shell/config_nl.properties index 7dccd1c84552..896093a19694 100644 --- a/core/src/main/resources/hudson/tasks/Shell/config_nl.properties +++ b/core/src/main/resources/hudson/tasks/Shell/config_nl.properties @@ -21,4 +21,4 @@ # THE SOFTWARE. Command=Commando -description=Zie de lijst van beschikbare omgevingsparameters. +description=Zie de lijst van beschikbare omgevingsparameters. diff --git a/core/src/main/resources/hudson/tasks/Shell/config_pt_BR.properties b/core/src/main/resources/hudson/tasks/Shell/config_pt_BR.properties index 795ea26b235b..db679e4fdfd5 100644 --- a/core/src/main/resources/hudson/tasks/Shell/config_pt_BR.properties +++ b/core/src/main/resources/hudson/tasks/Shell/config_pt_BR.properties @@ -21,4 +21,4 @@ # THE SOFTWARE. Command=Comando -description=Veja a lista de vari\u00e1veis de ambiente dispon\u00edveis +description=Veja a lista de vari\u00e1veis de ambiente dispon\u00edveis diff --git a/core/src/main/resources/hudson/tasks/Shell/config_ru.properties b/core/src/main/resources/hudson/tasks/Shell/config_ru.properties index a461942bacf1..329a720f6d31 100644 --- a/core/src/main/resources/hudson/tasks/Shell/config_ru.properties +++ b/core/src/main/resources/hudson/tasks/Shell/config_ru.properties @@ -21,4 +21,4 @@ # THE SOFTWARE. Command=\u041a\u043e\u043c\u0430\u043d\u0434\u0430 -description=\u0441\u043f\u0438\u0441\u043e\u043a \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f +description=\u0441\u043f\u0438\u0441\u043e\u043a \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f diff --git a/core/src/main/resources/hudson/tasks/Shell/config_sr.properties b/core/src/main/resources/hudson/tasks/Shell/config_sr.properties index e94472cd0e9a..c0b492c1c5f1 100644 --- a/core/src/main/resources/hudson/tasks/Shell/config_sr.properties +++ b/core/src/main/resources/hudson/tasks/Shell/config_sr.properties @@ -1,4 +1,4 @@ # This file is under the MIT License by authors -description=\u041F\u0440\u0435\u0433\u043B\u0435\u0434\u0430\u0458\u0442\u0435 \u0441\u043F\u0438\u0441\u0430\u043A \u043F\u0440\u043E\u043C\u0435\u043D\u0459\u0438\u0432\u0430 +description=\u041F\u0440\u0435\u0433\u043B\u0435\u0434\u0430\u0458\u0442\u0435 \u0441\u043F\u0438\u0441\u0430\u043A \u043F\u0440\u043E\u043C\u0435\u043D\u0459\u0438\u0432\u0430 Command=\u041A\u043E\u043C\u0430\u043D\u0434\u0430 diff --git a/core/src/main/resources/hudson/tasks/Shell/config_tr.properties b/core/src/main/resources/hudson/tasks/Shell/config_tr.properties index 54501683bc39..0c3c1db76783 100644 --- a/core/src/main/resources/hudson/tasks/Shell/config_tr.properties +++ b/core/src/main/resources/hudson/tasks/Shell/config_tr.properties @@ -20,5 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -description=T\u00fcm ortam de\u011fi\u015fkenlerini grmek iin t\u0131klay\u0131n\u0131z +description=T\u00fcm ortam de\u011fi\u015fkenlerini grmek iin t\u0131klay\u0131n\u0131z Command=Komut diff --git a/core/src/main/resources/hudson/tasks/Shell/config_zh_TW.properties b/core/src/main/resources/hudson/tasks/Shell/config_zh_TW.properties index 55bcbbb3b1e7..09cf41134316 100644 --- a/core/src/main/resources/hudson/tasks/Shell/config_zh_TW.properties +++ b/core/src/main/resources/hudson/tasks/Shell/config_zh_TW.properties @@ -22,4 +22,4 @@ # THE SOFTWARE. Command=\u6307\u4ee4 -description=\u53ef\u4ee5\u53c3\u8003\u53ef\u7528\u74b0\u5883\u8b8a\u6578\u6e05\u55ae +description=\u53ef\u4ee5\u53c3\u8003\u53ef\u7528\u74b0\u5883\u8b8a\u6578\u6e05\u55ae diff --git a/core/src/main/resources/hudson/tasks/Shell/help-shell.html b/core/src/main/resources/hudson/tasks/Shell/help-shell.html index 92ebf77339ee..b83343f6f458 100644 --- a/core/src/main/resources/hudson/tasks/Shell/help-shell.html +++ b/core/src/main/resources/hudson/tasks/Shell/help-shell.html @@ -1,5 +1,5 @@

      Normally you should just leave this field empty and let Jenkins pick up the right shell executable. - If your sh (Windows) or /bin/sh binary exists outside your PATH, however, + If your sh (Windows) or /bin/sh binary exists outside your PATH, however, specify the absolute path to the shell executable. -
      \ No newline at end of file + diff --git a/core/src/main/resources/hudson/tasks/Shell/help-shell_bg.html b/core/src/main/resources/hudson/tasks/Shell/help-shell_bg.html index db9993009d58..4586273f7823 100644 --- a/core/src/main/resources/hudson/tasks/Shell/help-shell_bg.html +++ b/core/src/main/resources/hudson/tasks/Shell/help-shell_bg.html @@ -1,5 +1,5 @@
      Обикновено това поле трябва да е празно, а Jenkins сам ще подбере правилния интерпретатор. - Ако обаче sh (под Windows) или /bin/sh е извън пътя сочен от PATH, + Ако обаче sh (под Windows) или /bin/sh е извън пътя сочен от PATH, тук ще трябва да зададете пътя към изпълнимия файл на интерпретатора.
      diff --git a/core/src/main/resources/hudson/tasks/Shell/help-shell_de.html b/core/src/main/resources/hudson/tasks/Shell/help-shell_de.html index 785bea75eddf..495ab2d69990 100644 --- a/core/src/main/resources/hudson/tasks/Shell/help-shell_de.html +++ b/core/src/main/resources/hudson/tasks/Shell/help-shell_de.html @@ -1,6 +1,6 @@
      Im Regelfall sollten Sie dieses Feld leerlassen und Jenkins die richtige Shell-Installation - wählen lassen. Falls Ihre sh (Windows) oder /bin/sh Kommandozeilenanwendung - nicht über die PATH Umgebungsvariable gefunden werden kann, geben Sie den absoluten Pfad - zur sh Kommandozeilenanwendung an. -
      \ No newline at end of file + wählen lassen. Falls Ihre sh (Windows) oder /bin/sh Kommandozeilenanwendung + nicht über die PATH Umgebungsvariable gefunden werden kann, geben Sie den absoluten Pfad + zur sh Kommandozeilenanwendung an. + diff --git a/core/src/main/resources/hudson/tasks/Shell/help-shell_fr.html b/core/src/main/resources/hudson/tasks/Shell/help-shell_fr.html index 9f5e5155db97..faf53c672c45 100644 --- a/core/src/main/resources/hudson/tasks/Shell/help-shell_fr.html +++ b/core/src/main/resources/hudson/tasks/Shell/help-shell_fr.html @@ -1,6 +1,6 @@
      En général, ce champ peut rester vide pour laisser Jenkins choisir le bon sh. - Néanmoins, si votre binaire sh (Windows) ou /bin/sh est placé hors de votre - PATH, spécifiez le chemin absolu vers l'exécutable sh. -
      \ No newline at end of file + Néanmoins, si votre binaire sh (Windows) ou /bin/sh est placé hors de votre + PATH, spécifiez le chemin absolu vers l'exécutable sh. + diff --git a/core/src/main/resources/hudson/tasks/Shell/help-shell_it.html b/core/src/main/resources/hudson/tasks/Shell/help-shell_it.html index 0344f949ab10..0c8c60449929 100644 --- a/core/src/main/resources/hudson/tasks/Shell/help-shell_it.html +++ b/core/src/main/resources/hudson/tasks/Shell/help-shell_it.html @@ -1,6 +1,6 @@
      Normalmente si dovrebbe lasciare questo campo vuoto e far sì che Jenkins - scelga l'eseguibile shell corretto. Ciò nonostante, se i binari sh - (su Windows) o /bin/sh sono al di fuori del proprio PATH, + scelga l'eseguibile shell corretto. Ciò nonostante, se i binari sh + (su Windows) o /bin/sh sono al di fuori del proprio PATH, specificare il percorso assoluto all'eseguibile shell.
      diff --git a/core/src/main/resources/hudson/tasks/Shell/help-shell_ja.html b/core/src/main/resources/hudson/tasks/Shell/help-shell_ja.html index e9dd76773e8d..e57aae6ac793 100644 --- a/core/src/main/resources/hudson/tasks/Shell/help-shell_ja.html +++ b/core/src/main/resources/hudson/tasks/Shell/help-shell_ja.html @@ -1,4 +1,4 @@
      通常、この項目を空欄のままにしてJenkinsに正しいシェルを検出させます。 - もし、sh(Windows)や/bin/shPATHに含まれていない場合、シェルの絶対パスを指定します。 + もし、sh(Windows)や/bin/shPATHに含まれていない場合、シェルの絶対パスを指定します。
      diff --git a/core/src/main/resources/hudson/tasks/Shell/help-shell_nl.html b/core/src/main/resources/hudson/tasks/Shell/help-shell_nl.html index 93812b80ed39..3dd30fd2b345 100644 --- a/core/src/main/resources/hudson/tasks/Shell/help-shell_nl.html +++ b/core/src/main/resources/hudson/tasks/Shell/help-shell_nl.html @@ -1,5 +1,5 @@
      Normaal dient u dit veld leeg te laten. Jenkins pikt dan zelf het juiste shell programma op. -Indien het sh (Windows) of /bin/sh programma dat u wenst te gebruiken echter buiten het -PATH ligt, dan kunt u hier het absolute pad naar uw shell programma invullen. -
      \ No newline at end of file +Indien het sh (Windows) of /bin/sh programma dat u wenst te gebruiken echter buiten het +PATH ligt, dan kunt u hier het absolute pad naar uw shell programma invullen. + diff --git a/core/src/main/resources/hudson/tasks/Shell/help-shell_pt_BR.html b/core/src/main/resources/hudson/tasks/Shell/help-shell_pt_BR.html index e0cb58d54928..1aff49d4b7b9 100644 --- a/core/src/main/resources/hudson/tasks/Shell/help-shell_pt_BR.html +++ b/core/src/main/resources/hudson/tasks/Shell/help-shell_pt_BR.html @@ -1,5 +1,5 @@
      Normalmente você deveria apenas deixar este campo vazio e deixar que o Jenkins escolha o sh correto. - Se seu binário sh (Windows) ou /bin/sh está fora de seu PATH, entretanto, especifique o caminho + Se seu binário sh (Windows) ou /bin/sh está fora de seu PATH, entretanto, especifique o caminho absoluto para o executável sh.
      diff --git a/core/src/main/resources/hudson/tasks/Shell/help.html b/core/src/main/resources/hudson/tasks/Shell/help.html index 338006fc3630..0ab3beb6f295 100644 --- a/core/src/main/resources/hudson/tasks/Shell/help.html +++ b/core/src/main/resources/hudson/tasks/Shell/help.html @@ -1,17 +1,17 @@
      - Runs a shell script (defaults to sh, but this is configurable) for building the project. + Runs a shell script (defaults to sh, but this is configurable) for building the project. The script will be run with the workspace as the current directory. Type in the contents of your shell - script. If your shell script has no header line like #!/bin/sh —, then the shell configured + script. If your shell script has no header line like #!/bin/sh —, then the shell configured system-wide will be used, but you can also use the header line to write script in another language - (like #!/bin/perl) or control the options that shell uses. + (like #!/bin/perl) or control the options that shell uses.

      By default, the shell will be invoked with the "-ex" option. So all of the commands are printed before being executed, and the build is considered a failure if any of the commands exits with a non-zero exit code. Again, add the - #!/bin/... line to change this behavior. + #!/bin/... line to change this behavior.

      As a best practice, try not to put a long shell script in here. Instead, consider adding the shell script - in SCM and simply call that shell script from Jenkins (via bash -ex myscript.sh or something like that), + in SCM and simply call that shell script from Jenkins (via bash -ex myscript.sh or something like that), so that you can track changes in your shell script.

      diff --git a/core/src/main/resources/hudson/tasks/Shell/help_bg.html b/core/src/main/resources/hudson/tasks/Shell/help_bg.html index 11ef4eb73522..3eba4b7ab8ad 100644 --- a/core/src/main/resources/hudson/tasks/Shell/help_bg.html +++ b/core/src/main/resources/hudson/tasks/Shell/help_bg.html @@ -1,19 +1,19 @@
      - Изпълнение на скрипт чрез интерпретатор за изграждането на проект (стандартно е sh, + Изпълнение на скрипт чрез интерпретатор за изграждането на проект (стандартно е sh, но може да се настрои). Текущата директория за изпълнението на скрипта е директорията на работното пространство. Попълнете тук съдържанието на скрипта. Ако в началото му - липсва заглавен ред от вида: #!/bin/sh, ще се използва системният интерпретатор. - Ако в началото на скрипта има ред от вида: #!/bin/perl, ще можете да използвате + липсва заглавен ред от вида: #!/bin/sh, ще се използва системният интерпретатор. + Ако в началото на скрипта има ред от вида: #!/bin/perl, ще можете да използвате произволен интерпретатор и ще можете изрично да задавате с какви опции ще се стартира.

      - Стандартно интерпретаторът се извиква с опцията -ex. Така всички команди се + Стандартно интерпретаторът се извиква с опцията -ex. Така всички команди се отпечатват преди изпълнение, а изграждането се счита за неуспешно, ако някоя от - командите завърши с код, различен от 0. Може да промените това поведение, - като зададете начален ред за указване на интерпретатора като #!/bin/…. + командите завърши с код, различен от 0. Може да промените това поведение, + като зададете начален ред за указване на интерпретатора като #!/bin/….

      Добра практика е да не задавате голям скрипт тук. По-добре е да го сложите в системата - за контрол на версиите, а тук просто да го извикате чрез bash -ex myscript.sh + за контрол на версиите, а тук просто да го извикате чрез bash -ex myscript.sh или нещо подобно. Така ще може да следите промените в скрипта.

      diff --git a/core/src/main/resources/hudson/tasks/Shell/help_de.html b/core/src/main/resources/hudson/tasks/Shell/help_de.html index 5bef177eb4e4..b7821f63136d 100644 --- a/core/src/main/resources/hudson/tasks/Shell/help_de.html +++ b/core/src/main/resources/hudson/tasks/Shell/help_de.html @@ -1,14 +1,14 @@
      Führt ein Shell-Skript aus, um das Projekt zu bauen (Vorgabewert für die Shell ist - sh, aber dies ist konfigurierbar). Das Skript wird im Arbeitsbereich + sh, aber dies ist konfigurierbar). Das Skript wird im Arbeitsbereich als aktuelles Verzeichnis ausgeführt. Geben Sie den Inhalt Ihres Shell-Skriptes direkt in die Textbox ein, jedoch ohne die Kopfzeile - #!/bin/sh — diese wird von Jenkins, entsprechend der + #!/bin/sh — diese wird von Jenkins, entsprechend der systemweiten Konfiguration, hinzugefügt.

      Die Shell wird mit der Option - -ex ausgeführt. Dadurch werden alle Kommandos ausgegeben, bevor sie + -ex ausgeführt. Dadurch werden alle Kommandos ausgegeben, bevor sie ausgeführt werden. Der Build gilt als fehlgeschlagen, wenn einer der Kommandos in der Befehlszeile einen Ergebniscode ungleich 0 liefert.

      diff --git a/core/src/main/resources/hudson/tasks/Shell/help_fr.html b/core/src/main/resources/hudson/tasks/Shell/help_fr.html index 109ebce63a99..5460bb3eccdd 100644 --- a/core/src/main/resources/hudson/tasks/Shell/help_fr.html +++ b/core/src/main/resources/hudson/tasks/Shell/help_fr.html @@ -1,16 +1,16 @@
      - Lance un script Shell (par défaut à l'aide de sh, mais cela est configurable) pour construire le projet. + Lance un script Shell (par défaut à l'aide de sh, mais cela est configurable) pour construire le projet. Le script sera lancé avec le workspace comme répertoire courant. - Entrez le contenu de votre script shell. Si votre script n'a pas de ligne de titre du type #!/bin/sh, + Entrez le contenu de votre script shell. Si votre script n'a pas de ligne de titre du type #!/bin/sh, alors le shell configuré pour l'ensemble du système sera utilisé. Si votre script contient une telle ligne, vous pourrez utiliser un autre langage de script - (comme #!/bin/perl) ou contrôler les options que le shell utilise. + (comme #!/bin/perl) ou contrôler les options que le shell utilise.

      Par défaut, le shell sera invoqué avec l'option "-ex". Par conséquent, toutes les commandes seront affichées avant d'être exécutées et le build sera considéré en èchec si l'une de ces commandes renvoie un code de retour différent de zéro. - Encore une fois, vous pouvez ajouter la ligne #!/bin/... pour modifier ce comportement. + Encore une fois, vous pouvez ajouter la ligne #!/bin/... pour modifier ce comportement.

      Une bonne pratique est de ne pas mettre un long script ici. A la place, pensez à ajouter le script shell diff --git a/core/src/main/resources/hudson/tasks/Shell/help_it.html b/core/src/main/resources/hudson/tasks/Shell/help_it.html index ddb583774be3..629e1010e8fe 100644 --- a/core/src/main/resources/hudson/tasks/Shell/help_it.html +++ b/core/src/main/resources/hudson/tasks/Shell/help_it.html @@ -1,12 +1,12 @@

      - Esegue uno script shell (per impostazione predefinita sh, ma il + Esegue uno script shell (per impostazione predefinita sh, ma il parametro è configurabile) per compilare il progetto. Lo script sarà eseguito impostando la directory dello spazio di lavoro come directory corrente. Immettere i contenuti dello script shell. Se lo script shell non - ha una riga di intestazione come #!/bin/sh, sarà utilizzata la + ha una riga di intestazione come #!/bin/sh, sarà utilizzata la shell configurata a livello di sistema, ma è anche possibile utilizzare la riga di intestazione per scrivere lo script in un altro linguaggio (ad - esempio #!/bin/perl) o per controllare le opzioni utilizzate dalla + esempio #!/bin/perl) o per controllare le opzioni utilizzate dalla shell.

      @@ -14,12 +14,12 @@ questo modo tutti i comandi saranno stampati prima di essere eseguiti e la compilazione sarà considerata non riuscita se uno qualunque dei comandi esce con un codice di uscita diverso da zero. Ancora una volta, si aggiunga la - riga #!/bin/... per modificare questo comportamento. + riga #!/bin/... per modificare questo comportamento.

      Come procedura consigliata, non si tenti di immettere uno script shell corposo qui. Si consideri piuttosto l'aggiunta dello script shell al sistema di gestione del codice sorgente, quindi semplicemente lo si richiami da - Jenkins (tramite bash -ex mioscript.sh o un'invocazione simile), + Jenkins (tramite bash -ex mioscript.sh o un'invocazione simile), in modo da poter tracciare le modifiche al proprio script shell.

      diff --git a/core/src/main/resources/hudson/tasks/Shell/help_ja.html b/core/src/main/resources/hudson/tasks/Shell/help_ja.html index 645e9751a8a3..0b91f5857cc6 100644 --- a/core/src/main/resources/hudson/tasks/Shell/help_ja.html +++ b/core/src/main/resources/hudson/tasks/Shell/help_ja.html @@ -1,12 +1,12 @@ 
      - プロジェクトのビルドに、シェルスクリプト(デフォルトはshですが、設定可能です)を起動します。 + プロジェクトのビルドに、シェルスクリプト(デフォルトはshですが、設定可能です)を起動します。 シェルスクリプトは、ワークスペースをカレントディレクトリとして起動します。 - シェルスクリプトを記述してください。もし、#!/bin/shのようなヘッダがなければ、システムの設定で設定したシェルを使用しますが、 - ヘッダを使用して、(#!/bin/perlのように)他の言語を使用したスクリプトを書いたり、シェルのオプションを制御できます。 + シェルスクリプトを記述してください。もし、#!/bin/shのようなヘッダがなければ、システムの設定で設定したシェルを使用しますが、 + ヘッダを使用して、(#!/bin/perlのように)他の言語を使用したスクリプトを書いたり、シェルのオプションを制御できます。

      デフォルトで、シェルは"-ex"オプションを付けて起動され、実行前に全てのコマンドが表示されます。 - そして、0以外の終了コードで終了した場合、ビルドが失敗したと判断します。これを変更するには、#!/bin/...を追加します。 + そして、0以外の終了コードで終了した場合、ビルドが失敗したと判断します。これを変更するには、#!/bin/...を追加します。

      ベストプラクティスとして、ここに長いシェルを記述しようとはしないで、代わりに、 diff --git a/core/src/main/resources/hudson/tasks/Shell/help_pt_BR.html b/core/src/main/resources/hudson/tasks/Shell/help_pt_BR.html index cf5967321f1e..05ca71bdb135 100644 --- a/core/src/main/resources/hudson/tasks/Shell/help_pt_BR.html +++ b/core/src/main/resources/hudson/tasks/Shell/help_pt_BR.html @@ -1,7 +1,7 @@

      - Executa um script de shell (o padrão é o sh, mas isto é configurável) para construir o projeto. + Executa um script de shell (o padrão é o sh, mas isto é configurável) para construir o projeto. O script será executado com o workspace como diretório atual. Informe no conteúdo de seu - script, mas sem um cabeçalho como #!/bin/sh — que é adicionado pelo Jenkins, onde + script, mas sem um cabeçalho como #!/bin/sh — que é adicionado pelo Jenkins, onde o caminho do shell está configurado globalmente.

      diff --git a/core/src/main/resources/hudson/tasks/Shell/help_ru.html b/core/src/main/resources/hudson/tasks/Shell/help_ru.html index 7058cef60722..c8784e8f59bb 100644 --- a/core/src/main/resources/hudson/tasks/Shell/help_ru.html +++ b/core/src/main/resources/hudson/tasks/Shell/help_ru.html @@ -1,7 +1,7 @@ 

      - Выполняет запуск сценария оболочки (по-умолчанию, sh, но это настраивается) для + Выполняет запуск сценария оболочки (по-умолчанию, sh, но это настраивается) для сборки проекта. Сценарий будет запущен в сборочной директории проекта. Вы можете вставить - в это поле содержимое вашего сценария, убрав заголовок #!/bin/sh, он будет добавлен + в это поле содержимое вашего сценария, убрав заголовок #!/bin/sh, он будет добавлен автоматически в зависимости от глобальных настроек.

      diff --git a/core/src/main/resources/hudson/tasks/Shell/help_tr.html b/core/src/main/resources/hudson/tasks/Shell/help_tr.html index d0c8bc4f3e01..52281e506c9c 100644 --- a/core/src/main/resources/hudson/tasks/Shell/help_tr.html +++ b/core/src/main/resources/hudson/tasks/Shell/help_tr.html @@ -1,9 +1,9 @@

      - Projeyi yapılandırmak için shell scripti (varsayılan sh'dır, fakat değiştirilebilir) çalıştırır. + Projeyi yapılandırmak için shell scripti (varsayılan sh'dır, fakat değiştirilebilir) çalıştırır. Script, bulunduğu dizin, çalışma alanı olacak şekilde çalışır. - Eğer shell scriptinizin başında #!/bin/sh satırı yoksa, sistem seviyesinde ayarlanan shell kullanılacaktır. - Fakat yinede, başlık satırını, başka programlama dilinde shell yazmak (#!/bin/perl gibi) veya shell'in + Eğer shell scriptinizin başında #!/bin/sh satırı yoksa, sistem seviyesinde ayarlanan shell kullanılacaktır. + Fakat yinede, başlık satırını, başka programlama dilinde shell yazmak (#!/bin/perl gibi) veya shell'in kullandıgı seçenekleri kontrol etmek için kullanabilirsiniz. Shell "-ex" seçeneği ile çağırılır. Böylece tüm komutlar çalışmadan önce ekrana yazılır ve komutlardan herhangi diff --git a/core/src/main/resources/hudson/tasks/Shell/help_zh_TW.html b/core/src/main/resources/hudson/tasks/Shell/help_zh_TW.html index 03c1f036fdec..df0c8441b013 100644 --- a/core/src/main/resources/hudson/tasks/Shell/help_zh_TW.html +++ b/core/src/main/resources/hudson/tasks/Shell/help_zh_TW.html @@ -1,6 +1,6 @@
      執行 Shell Script (預設使用 sh,不過可以設定) 建置專案,該 Script 會在工作區目錄中執行。 - 輸入您 Shell Script 的內容,如果您的 Shell Script 沒有 #!/bin/sh 這類標頭,就會使用系統設定的 Shell 執行。 + 輸入您 Shell Script 的內容,如果您的 Shell Script 沒有 #!/bin/sh 這類標頭,就會使用系統設定的 Shell 執行。 您也可以使用標頭指定撰寫別種語言的 Script (例如 #!/bin/perl) 或是控制 Shell 使用的選項。

      @@ -10,6 +10,6 @@

      前人血淚的教訓指出: 千萬不要把複雜的 Shell Script 放在這裡。 - 應該把 Shell Script 放到 SCM 裡,再由 Jenkins 單純的呼叫它 (透過 bash -ex myscript.sh 之類的)。 + 應該把 Shell Script 放到 SCM 裡,再由 Jenkins 單純的呼叫它 (透過 bash -ex myscript.sh 之類的)。 這樣您也可以追溯 Shell Script 的版本異動。

      diff --git a/core/src/main/resources/hudson/tools/Messages.properties b/core/src/main/resources/hudson/tools/Messages.properties index 5eeb9f12f03a..ab80fbb894be 100644 --- a/core/src/main/resources/hudson/tools/Messages.properties +++ b/core/src/main/resources/hudson/tools/Messages.properties @@ -30,5 +30,5 @@ ZipExtractionInstaller.bad_connection=Server rejected connection. ZipExtractionInstaller.malformed_url=Malformed URL. ZipExtractionInstaller.could_not_connect=Could not connect to URL. InstallSourceProperty.DescriptorImpl.displayName=Install automatically -ToolDescriptor.NotADirectory={0} is not a directory on the Jenkins master (but perhaps it exists on some agents) +ToolDescriptor.NotADirectory={0} is not a directory on the Jenkins controller (but perhaps it exists on some agents) CannotBeInstalled=Installer "{0}" cannot be used to install "{1}" on the node "{2}" diff --git a/core/src/main/resources/hudson/tools/Messages_pt_BR.properties b/core/src/main/resources/hudson/tools/Messages_pt_BR.properties index ea3c2cf28028..5b5f188dbbb6 100644 --- a/core/src/main/resources/hudson/tools/Messages_pt_BR.properties +++ b/core/src/main/resources/hudson/tools/Messages_pt_BR.properties @@ -20,24 +20,15 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -# Extract *.zip/*.tar.gz ZipExtractionInstaller.DescriptorImpl.displayName=Extrair *.zip/*.tar.gz -# Could not connect to URL. -ZipExtractionInstaller.could_not_connect=N\u00e3o foi poss\u00edvel pode conectar \u00e0 URL -# Tool Locations +ZipExtractionInstaller.could_not_connect=N\u00E3o foi poss\u00EDvel pode conectar \u00E0 URL ToolLocationNodeProperty.displayName=Ferramentas locais -# Must provide a command to run. -CommandInstaller.no_command=Forne\u00e7a um comando para ser executado -# Server rejected connection. -ZipExtractionInstaller.bad_connection=Conex\u00e3o rejeitada pelo servidor -# Run Command +CommandInstaller.no_command=Forne\u00E7a um comando para ser executado +ZipExtractionInstaller.bad_connection=Conex\u00E3o rejeitada pelo servidor CommandInstaller.DescriptorImpl.displayName=Executar comando -# Install automatically InstallSourceProperty.DescriptorImpl.displayName=Instalar automaticamente -# Malformed URL. -ZipExtractionInstaller.malformed_url=URL n\u00e3o reconhecida. -# Must provide a tool home directory. -CommandInstaller.no_toolHome=\u00c9 necess\u00e1rio fornecer um diret\u00f3rio home para a ferramenta. -# Run Batch Command -BatchCommandInstaller.DescriptorImpl.displayName=Executar comando em lotes - +ZipExtractionInstaller.malformed_url=URL n\u00E3o reconhecida. +CommandInstaller.no_toolHome=\u00C9 necess\u00E1rio fornecer um diret\u00F3rio home para a ferramenta. +BatchCommandInstaller.DescriptorImpl.displayName=Executar comando em lote +ToolDescriptor.NotADirectory={0} n\u00E3o \u00E9 um diret\u00F3rio no controlador do Jenkins (mas tavlez ele exista para alguns agentes) +CannotBeInstalled=O instalador "{0}" n\u00E3o pode ser utilizado para instalar "{1}" no n\u00F3 "{2}" diff --git a/core/src/main/resources/hudson/tools/Messages_zh_TW.properties b/core/src/main/resources/hudson/tools/Messages_zh_TW.properties index 10156f9d77d2..bee9970f63d0 100644 --- a/core/src/main/resources/hudson/tools/Messages_zh_TW.properties +++ b/core/src/main/resources/hudson/tools/Messages_zh_TW.properties @@ -21,11 +21,14 @@ # THE SOFTWARE. ToolLocationNodeProperty.displayName=\u5de5\u5177\u4f4d\u7f6e -CommandInstaller.DescriptorImpl.displayName=\u57f7\u884c\u6307\u4ee4 +CommandInstaller.DescriptorImpl.displayName=\u57f7\u884c Shell \u6307\u4ee4 CommandInstaller.no_command=\u5fc5\u9808\u63d0\u4f9b\u6307\u4ee4\u624d\u80fd\u57f7\u884c\u3002 CommandInstaller.no_toolHome=\u5fc5\u9808\u63d0\u4f9b\u5de5\u5177\u4e3b\u76ee\u9304\u3002 +BatchCommandInstaller.DescriptorImpl.displayName=\u57f7\u884c\u6279\u6b21\u6307\u4ee4 ZipExtractionInstaller.DescriptorImpl.displayName=\u89e3\u58d3\u7e2e *.zip/*.tar.gz ZipExtractionInstaller.bad_connection=\u9023\u7dda\u88ab\u4f3a\u670d\u5668\u62d2\u7d55\u3002 ZipExtractionInstaller.malformed_url=URL \u4e0d\u6b63\u78ba\u3002 ZipExtractionInstaller.could_not_connect=\u9023\u4e0d\u5230 URL\u3002 InstallSourceProperty.DescriptorImpl.displayName=\u81ea\u52d5\u5b89\u88dd +ToolDescriptor.NotADirectory={0} \u4e0d\u662f Jenkins Controller \u4e0a\u7684\u76ee\u9304\uff08\u4f46\u5b83\u53ef\u80fd\u5b58\u5728\u65bc\u67d0\u4e9b Agent \u4e0a\uff09 +CannotBeInstalled=\u7121\u6cd5\u4f7f\u7528\u5b89\u88dd\u7a0b\u5f0f\u300c{0}\u300d\u4f86\u5b89\u88dd\u300c{1}\u300d\u5230\u7bc0\u9ede\u300c{2}\u300d diff --git a/core/src/main/resources/hudson/tools/ToolLocationNodeProperty/config.jelly b/core/src/main/resources/hudson/tools/ToolLocationNodeProperty/config.jelly index 4f8a57463196..5a38fbd626e1 100644 --- a/core/src/main/resources/hudson/tools/ToolLocationNodeProperty/config.jelly +++ b/core/src/main/resources/hudson/tools/ToolLocationNodeProperty/config.jelly @@ -28,7 +28,7 @@ - (${toolDescriptor.displayName}) ${toolInstallation.name} diff --git a/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help-url.html b/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help-url.html index 9637265029d9..f22666f2191b 100644 --- a/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help-url.html +++ b/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help-url.html @@ -3,5 +3,5 @@ Should be either a ZIP or a GZip-compressed TAR file. The timestamp on the server will be compared to the local version (if any) so you can publish updates easily. - The URL must be accessible from the Jenkins master but need not be accessible from agents. + The URL must be accessible from the Jenkins controller but need not be accessible from agents. diff --git a/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help.html b/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help.html index de90c2eaa1d8..d36d72d8c181 100644 --- a/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help.html +++ b/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help.html @@ -1,6 +1,5 @@
      Downloads a tool archive and installs it within Jenkins's working directory. - Example: http://apache.promopeddler.com/ant/binaries/apache-ant-1.7.1-bin.zip - (or whatever mirror is closest to your server) - and specify a subdir of apache-ant-1.7.1. + Example: https://downloads.apache.org/ant/binaries/apache-ant-1.10.12-bin.zip + and specify a subdir of apache-ant-1.10.12.
      diff --git a/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help_bg.html b/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help_bg.html index 7e10b81bca44..5885e35c97fe 100644 --- a/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help_bg.html +++ b/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help_bg.html @@ -1,6 +1,5 @@ -
      Изтегляне на архив с програма и инсталирането ѝ в работната директория на Jenkins. - Примерно: http://apache.promopeddler.com/ant/binaries/apache-ant-1.7.1-bin.zip - (или друг сървър-огледало, който е по-близо или бърз) и укажете поддиректория на - apache-ant-1.7.1. + Примерно: https://downloads.apache.org/ant/binaries/apache-ant-1.10.12-bin.zip + и укажете поддиректория на apache-ant-1.10.12.
      diff --git a/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help_de.html b/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help_de.html index 164576bdcc9a..3b0c19163a28 100644 --- a/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help_de.html +++ b/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help_de.html @@ -1,7 +1,6 @@
      Lädt ein Hilfsprogramm als gepacktes Archiv herunter und installiert es innerhalb des Jenkins-Arbeitsverzeichnisses. - Beispiel: http://apache.promopeddler.com/ant/binaries/apache-ant-1.7.1-bin.zip - (oder ein Spiegelserver, der näher zu Ihrem Jenkins-Server liegt) mit der Angabe eines - Unterverzeichnisses von apache-ant-1.7.1. + Beispiel: https://downloads.apache.org/ant/binaries/apache-ant-1.10.12-bin.zip + mit der Angabe eines Unterverzeichnisses von apache-ant-1.10.12.
      diff --git a/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help_it.html b/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help_it.html index 727280351212..f55d1370d4c4 100644 --- a/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help_it.html +++ b/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help_it.html @@ -1,7 +1,6 @@
      Scarica un archivio contenente uno strumento e lo installa all'interno della directory di lavoro di Jenkins. Ad esempio: - http://apache.promopeddler.com/ant/binaries/apache-ant-1.7.1-bin.zip - (o il mirror più vicino al proprio server) e si specifichi una - sottodirectory di apache-ant-1.7.1. + https://downloads.apache.org/ant/binaries/apache-ant-1.10.12-bin.zip + e si specifichi una sottodirectory di apache-ant-1.10.12.
      diff --git a/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help_ja.html b/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help_ja.html index abf95e5f7009..9b80732de1f2 100644 --- a/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help_ja.html +++ b/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help_ja.html @@ -1,6 +1,5 @@
      ツールのアーカイブをダウンロードして、Jenkinsのワークディレクトリにインストールします。 - 例えば: http://apache.promopeddler.com/ant/binaries/apache-ant-1.7.1-bin.zip - (もしくは、あなたのサーバーに一番近いミラーサイト) - そして、サブディレクトリにapache-ant-1.7.1を指定します。 + 例えば: https://downloads.apache.org/ant/binaries/apache-ant-1.10.12-bin.zip + そして、サブディレクトリにapache-ant-1.10.12を指定します。
      diff --git a/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help_zh_TW.html b/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help_zh_TW.html index 0844a8985639..95af127631f2 100644 --- a/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help_zh_TW.html +++ b/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help_zh_TW.html @@ -1,5 +1,5 @@
      下載工具壓縮檔,並安裝到 Jenkins 工作目錄中。 - 例如: http://apache.promopeddler.com/ant/binaries/apache-ant-1.7.1-bin.zip - (或是其他離您伺服器進的鏡像站) 並指定子目錄 apache-ant-1.7.1。 + 例如: https://downloads.apache.org/ant/binaries/apache-ant-1.10.12-bin.zip + 並指定子目錄 apache-ant-1.10.12
      diff --git a/core/src/main/resources/hudson/triggers/Messages_pt_BR.properties b/core/src/main/resources/hudson/triggers/Messages_pt_BR.properties index 400d651fa58b..82572c8fca9a 100644 --- a/core/src/main/resources/hudson/triggers/Messages_pt_BR.properties +++ b/core/src/main/resources/hudson/triggers/Messages_pt_BR.properties @@ -21,19 +21,18 @@ # THE SOFTWARE. SCMTrigger.DisplayName=Consultar periodicamente o SCM -SCMTrigger.getDisplayName={0} Log de consulta peri\u00f3dica +SCMTrigger.getDisplayName={0} Sondagem de registro de atividades TimerTrigger.DisplayName=Construir periodicamente -# Initializing timer for triggers -Trigger.init=Inicializando temporizador para os triggers -# Started by an SCM change -SCMTrigger.SCMTriggerCause.ShortDescription=Iniciado por uma mudan\u00e7a no SCM -# Started by timer +Trigger.init=Inicializando temporizador para os gatilhos +SCMTrigger.SCMTriggerCause.ShortDescription=Iniciado por uma mudan\u00E7a no SCM TimerTrigger.TimerTriggerCause.ShortDescription=Iniciado pelo temporizador -# Would last have run at {0}; would next run at {1}. -TimerTrigger.would_last_have_run_at_would_next_run_at=Deveria ter executado em {0}; dever\u00e1 executar novamente em {1}. -# You appear to be missing whitespace between * and *. -TimerTrigger.MissingWhitespace=Aparentemente est\u00e1 faltando um espa\u00e7o em branco entre * e *. -# No schedules so will never run -TimerTrigger.no_schedules_so_will_never_run=Nenhum agendamente portando nunca executar\u00e1 -# Polling Log -SCMTrigger.BuildAction.DisplayName=Registro de verifica\u00e7\u00f5es +TimerTrigger.would_last_have_run_at_would_next_run_at=Deveria ter executado em {0}; dever\u00E1 executar novamente em {1}. +TimerTrigger.MissingWhitespace=Aparentemente est\u00E1 faltando um espa\u00E7o em branco entre * e *. +TimerTrigger.no_schedules_so_will_never_run=Nunca executar\u00E1 pois n\u00E3o tem nenhum agendamento +SCMTrigger.BuildAction.DisplayName=Sondagem de registro de atividades +SCMTrigger.no_schedules_hooks=N\u00E3o h\u00E1 nenhum agendamento portanto executar\u00E1 somente atr\u00E1ves de mudan\u00E7as no SCM se disparado por um ganho de p\u00F3s-confirma\u00E7\u00E3o +SCMTrigger.no_schedules_no_hooks=Ganchos de p\u00F3s-confirma\u00E7\u00E3o est\u00E3o ignorados e nenhum agendamento existe, portanto nunca executar\u00E1 devido a altera\u00E7\u00F5es no SCM +SlowTriggerAdminMonitor.DisplayName=Monitor de gatilhos do Cron +TimerTrigger.the_specified_cron_tab_is_rare_or_impossible=Este agendamento funcionar\u00E1 somente em datas de baixa ocorr\u00EAncia (como 29 de fevereiro, por exemplo) ou \ + nunca (31 de junho, por exemplo) portanto este job s\u00F3 ser\u00E1 disparado raramente ou mesmo nunca. +SCMTrigger.AdministrativeMonitorImpl.DisplayName=Excesso de sondagens paralelas no SCM diff --git a/core/src/main/resources/hudson/triggers/SCMTrigger/AdministrativeMonitorImpl/description.jelly b/core/src/main/resources/hudson/triggers/SCMTrigger/AdministrativeMonitorImpl/description.jelly new file mode 100644 index 000000000000..bb405e931933 --- /dev/null +++ b/core/src/main/resources/hudson/triggers/SCMTrigger/AdministrativeMonitorImpl/description.jelly @@ -0,0 +1,4 @@ + + + ${%blurb} + diff --git a/core/src/main/resources/hudson/triggers/SCMTrigger/AdministrativeMonitorImpl/description.properties b/core/src/main/resources/hudson/triggers/SCMTrigger/AdministrativeMonitorImpl/description.properties new file mode 100644 index 000000000000..79330e8548d5 --- /dev/null +++ b/core/src/main/resources/hudson/triggers/SCMTrigger/AdministrativeMonitorImpl/description.properties @@ -0,0 +1 @@ +blurb = If there are more SCM polling activities scheduled than Jenkins can handle in parallel, this informs administrators about the problem and provides diagnostic information. diff --git a/core/src/main/resources/hudson/triggers/SCMTrigger/AdministrativeMonitorImpl/description_pt_BR.properties b/core/src/main/resources/hudson/triggers/SCMTrigger/AdministrativeMonitorImpl/description_pt_BR.properties new file mode 100644 index 000000000000..957fd3be5d4e --- /dev/null +++ b/core/src/main/resources/hudson/triggers/SCMTrigger/AdministrativeMonitorImpl/description_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +blurb=Se houverem mais atividades agendadads de sondagens do SCM que o Jenkins possa executar em paralelo, isto informa administradores sobre o problema e prov\u00EA informa\u00E7\u00F5es de diagn\u00F3sticos. diff --git a/core/src/main/resources/hudson/triggers/SCMTrigger/BuildAction/index.jelly b/core/src/main/resources/hudson/triggers/SCMTrigger/BuildAction/index.jelly index 545c19b6ca79..e05ffc91d005 100644 --- a/core/src/main/resources/hudson/triggers/SCMTrigger/BuildAction/index.jelly +++ b/core/src/main/resources/hudson/triggers/SCMTrigger/BuildAction/index.jelly @@ -31,14 +31,8 @@ THE SOFTWARE.

      ${%Polling Log}

      - - - ${%View as plain text} - - -

      ${%blurb}

      - +
               
               ${it.writePollingLogTo(0,output)}
      diff --git a/core/src/main/resources/hudson/triggers/SCMTrigger/BuildAction/index_fr.properties b/core/src/main/resources/hudson/triggers/SCMTrigger/BuildAction/index_fr.properties
      index 8f0d3e034aed..6f74dfeb3062 100644
      --- a/core/src/main/resources/hudson/triggers/SCMTrigger/BuildAction/index_fr.properties
      +++ b/core/src/main/resources/hudson/triggers/SCMTrigger/BuildAction/index_fr.properties
      @@ -21,5 +21,5 @@
       # THE SOFTWARE.
       
       Polling\ Log=Journal de d\u00E9clenchement
      -View\ as\ plain\ text=Voir en texte
      +View\ as\ plain\ text=Voir en texte brut
       blurb=Cette page affiche le journal de ce qui a d\u00E9clench\u00E9 cette construction.
      diff --git a/core/src/main/resources/hudson/triggers/SCMTrigger/help.html b/core/src/main/resources/hudson/triggers/SCMTrigger/help.html
      index f4243eb26fbc..0b85e09d28b7 100644
      --- a/core/src/main/resources/hudson/triggers/SCMTrigger/help.html
      +++ b/core/src/main/resources/hudson/triggers/SCMTrigger/help.html
      @@ -5,5 +5,5 @@
         Note that this is going to be an expensive operation for CVS, as every polling
         requires Jenkins to scan the entire workspace and verify it with the server.
         Consider setting up a "push" trigger to avoid this overhead, as described in
      -  this document
      +  this document
       
      diff --git a/core/src/main/resources/hudson/triggers/SCMTrigger/help_bg.html b/core/src/main/resources/hudson/triggers/SCMTrigger/help_bg.html
      index 785ad9f9f9a2..3714874fe5e1 100644
      --- a/core/src/main/resources/hudson/triggers/SCMTrigger/help_bg.html
      +++ b/core/src/main/resources/hudson/triggers/SCMTrigger/help_bg.html
      @@ -6,5 +6,5 @@
         обходи цялото работно пространство и да го синхронизира със сървъра.
         По-добре е с помощта на автоматично действие от страна на CVS да известявате
         Jenkins за промени.  За повече информация погледнете
      -  документацията.
      +  документацията.
       
      diff --git a/core/src/main/resources/hudson/triggers/SCMTrigger/help_de.html b/core/src/main/resources/hudson/triggers/SCMTrigger/help_de.html
      index ec159cbc7a9d..898019c59e7a 100644
      --- a/core/src/main/resources/hudson/triggers/SCMTrigger/help_de.html
      +++ b/core/src/main/resources/hudson/triggers/SCMTrigger/help_de.html
      @@ -7,6 +7,6 @@
         ressourcenintensive Operation darstellt, da Jenkins bei jeder Abfrage den 
         kompletten Arbeitsbereich überprüfen und mit dem CVS-Server abgleichen muss.
         Ziehen Sie daher alternativ einen "Push"-Auslöser in Betracht, wie er in 
      -  diesem Dokument beschrieben
      +  diesem Dokument beschrieben
         wird.
       
      diff --git a/core/src/main/resources/hudson/triggers/SCMTrigger/help_fr.html b/core/src/main/resources/hudson/triggers/SCMTrigger/help_fr.html
      index 0804b0992ec9..c5770ad49f05 100644
      --- a/core/src/main/resources/hudson/triggers/SCMTrigger/help_fr.html
      +++ b/core/src/main/resources/hudson/triggers/SCMTrigger/help_fr.html
      @@ -8,5 +8,5 @@
         workspace et le comparer avec le serveur.
         Envisagez d'utiliser un trigger de type 'push' pour éviter cette 
         surcharge, comme décrit dans
      -  ce document.
      +  ce document.
       
      diff --git a/core/src/main/resources/hudson/triggers/SCMTrigger/help_it.html b/core/src/main/resources/hudson/triggers/SCMTrigger/help_it.html
      index aa78f01a84e3..0abb0be58265 100644
      --- a/core/src/main/resources/hudson/triggers/SCMTrigger/help_it.html
      +++ b/core/src/main/resources/hudson/triggers/SCMTrigger/help_it.html
      @@ -7,6 +7,6 @@
         operazione di polling richiede a Jenkins di scansionare tutto lo spazio di
         lavoro e di verificarlo con il server. Si prenda in considerazione
         l'impostazione di un trigger "push" per evitare quest'onere, come descritto
      -  in questo
      +  in questo
         documento.
       
      diff --git a/core/src/main/resources/hudson/triggers/SCMTrigger/help_ja.html b/core/src/main/resources/hudson/triggers/SCMTrigger/help_ja.html
      index 6e94ae93ca99..9df6bb6a4e24 100644
      --- a/core/src/main/resources/hudson/triggers/SCMTrigger/help_ja.html
      +++ b/core/src/main/resources/hudson/triggers/SCMTrigger/help_ja.html
      @@ -5,6 +5,6 @@
         ポーリング毎に、Jenkinsはワークスペースをスキャンしてサーバーと検証する必要があるので、
         CVSにとって負荷の高い操作ということに注意してください。
         このオーバーヘッドを避けるために、
      -  このドキュメントにあるように、
      +  このドキュメントにあるように、
         "push"トリガーの設定を検討してください。
       
      diff --git a/core/src/main/resources/hudson/triggers/SCMTrigger/help_pt_BR.html b/core/src/main/resources/hudson/triggers/SCMTrigger/help_pt_BR.html
      index 9de5639081ad..8ea027342632 100644
      --- a/core/src/main/resources/hudson/triggers/SCMTrigger/help_pt_BR.html
      +++ b/core/src/main/resources/hudson/triggers/SCMTrigger/help_pt_BR.html
      @@ -5,5 +5,5 @@
         Note que isto vai ser uma operação custosa para o CVS, como toda consulta
         requer que o Jenkins examine o workspace inteiro e verifique-o com o servidor.
         Considere configurar um disparador de construção periódico ("Construir periodicamente") para evitar esta sobrecarga, como descrito
      -  nesta documentação
      +  nesta documentação
       
      diff --git a/core/src/main/resources/hudson/triggers/SCMTrigger/help_ru.html b/core/src/main/resources/hudson/triggers/SCMTrigger/help_ru.html
      index 459ed73f0c0b..39a804fecee0 100644
      --- a/core/src/main/resources/hudson/triggers/SCMTrigger/help_ru.html
      +++ b/core/src/main/resources/hudson/triggers/SCMTrigger/help_ru.html
      @@ -6,5 +6,5 @@
         на SCM, так как каждый опрос представляет собой сканирование сборочной директории и 
         сверка содержимого с данными на сервере. Лучшим вариантом будет настройка 
         вашей SCM на инициацию сборки при внесении в неё изменений, как описано
      -  в этом документе.
      +  в этом документе.
       
      diff --git a/core/src/main/resources/hudson/triggers/SCMTrigger/help_tr.html b/core/src/main/resources/hudson/triggers/SCMTrigger/help_tr.html
      index eba539be5e27..6c28b7cf9d01 100644
      --- a/core/src/main/resources/hudson/triggers/SCMTrigger/help_tr.html
      +++ b/core/src/main/resources/hudson/triggers/SCMTrigger/help_tr.html
      @@ -4,6 +4,6 @@
         

      Unutmayın, bu işlem CVS için biraz yüklü olacaktır, çünkü her kontrolde Jenkins tüm çalışma alanını tarayacak ve bunu CVS sunucusu ile karşılaştıracaktır. - Bunun yerine bu dokümanda anlatıldığı gibi + Bunun yerine bu dokümanda anlatıldığı gibi "push" tetikleyicisini ayarlayın. diff --git a/core/src/main/resources/hudson/triggers/SCMTrigger/help_zh_TW.html b/core/src/main/resources/hudson/triggers/SCMTrigger/help_zh_TW.html index 75edc639e210..6c65125f2c1c 100644 --- a/core/src/main/resources/hudson/triggers/SCMTrigger/help_zh_TW.html +++ b/core/src/main/resources/hudson/triggers/SCMTrigger/help_zh_TW.html @@ -3,6 +3,6 @@

      請注意,這對 CVS 而言代價很高,每次輪詢 Jenkins 都要掃描整個工作區,並與伺服器比對。 - 建議參考這份文件設定 + 建議參考這份文件設定 "push" 觸發程序,避免額外負擔。 diff --git a/core/src/main/resources/hudson/triggers/SlowTriggerAdminMonitor/description.jelly b/core/src/main/resources/hudson/triggers/SlowTriggerAdminMonitor/description.jelly new file mode 100644 index 000000000000..bb405e931933 --- /dev/null +++ b/core/src/main/resources/hudson/triggers/SlowTriggerAdminMonitor/description.jelly @@ -0,0 +1,4 @@ + + + ${%blurb} + diff --git a/core/src/main/resources/hudson/triggers/SlowTriggerAdminMonitor/description.properties b/core/src/main/resources/hudson/triggers/SlowTriggerAdminMonitor/description.properties new file mode 100644 index 000000000000..0b16a7b1baca --- /dev/null +++ b/core/src/main/resources/hudson/triggers/SlowTriggerAdminMonitor/description.properties @@ -0,0 +1 @@ +blurb = This warns administrators that triggers are not firing on schedule, typically because some plugins perform additional actions (like network access) during trigger processing. diff --git a/core/src/main/resources/hudson/triggers/SlowTriggerAdminMonitor/description_pt_BR.properties b/core/src/main/resources/hudson/triggers/SlowTriggerAdminMonitor/description_pt_BR.properties new file mode 100644 index 000000000000..3a9277e0c16e --- /dev/null +++ b/core/src/main/resources/hudson/triggers/SlowTriggerAdminMonitor/description_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +blurb=Isto avisa administradores que gatilhos n\u00E3o est\u00E3o disparando conforme o agendamento, tipicamente porque algumas extens\u00F5es executam a\u00E7\u00F5es adicionais (como acesso a rede) durante o processamento do gatilho. diff --git a/core/src/main/resources/hudson/triggers/SlowTriggerAdminMonitor/message.groovy b/core/src/main/resources/hudson/triggers/SlowTriggerAdminMonitor/message.groovy index e29c4a89854c..7aeb0f43e5ce 100644 --- a/core/src/main/resources/hudson/triggers/SlowTriggerAdminMonitor/message.groovy +++ b/core/src/main/resources/hudson/triggers/SlowTriggerAdminMonitor/message.groovy @@ -1,6 +1,9 @@ package hudson.triggers.SlowTriggerAdminMonitor +import hudson.Util import hudson.triggers.SlowTriggerAdminMonitor +import jenkins.model.Jenkins +import org.apache.commons.jelly.tags.fmt.FmtTagLibrary SlowTriggerAdminMonitor tam = my @@ -10,26 +13,30 @@ dl { input(name: "clear", type: "submit", value: _("Dismiss"), class: "submit-button primary") } - text(_("Warning messages for cron triggers")) + text(_("blurb")) - style(""" - #cron-triggers-warning-table th { - text-align: left; - } - """) - - table(class: "pane sortable bigtable", width: "100%", id: "cron-triggers-warning-table") { + table(class: "pane sortable bigtable", width: "100%") { tr { th(_("Trigger")) - th(_("Time")) - th(_("Message")) + th(_("Most Recent Occurrence")) + th(_("Most Recently Occurring Job")) + th(_("Duration")) } tam.errors.each { trigger, val -> + def job = Jenkins.get().getItemByFullName(val.fullJobName) + tr { - td(trigger) - td(val.time) - td(val.msg) + td(Jenkins.get().getDescriptorByType(val.trigger).getDisplayName()) + td(val.getTimeString()) + if (job == null) { + td(val.fullJobName) + } else { + td { + a(job.getFullDisplayName(), href: job.getUrl(), class: 'model-link') + } + } + td(Util.getTimeSpanString(val.duration)) } } } diff --git a/core/src/main/resources/hudson/triggers/SlowTriggerAdminMonitor/message.properties b/core/src/main/resources/hudson/triggers/SlowTriggerAdminMonitor/message.properties new file mode 100644 index 000000000000..acaf949819c3 --- /dev/null +++ b/core/src/main/resources/hudson/triggers/SlowTriggerAdminMonitor/message.properties @@ -0,0 +1,3 @@ +blurb = The following triggers took a long time to process. \ + This is usually caused by networking issues or high load on the Jenkins controller. \ + As a result, other triggers could be delayed and scheduled tasks may not have started at the expected time. diff --git a/core/src/main/resources/hudson/triggers/SlowTriggerAdminMonitor/message_it.properties b/core/src/main/resources/hudson/triggers/SlowTriggerAdminMonitor/message_it.properties deleted file mode 100644 index 6a3fe01ab9d6..000000000000 --- a/core/src/main/resources/hudson/triggers/SlowTriggerAdminMonitor/message_it.properties +++ /dev/null @@ -1,28 +0,0 @@ -# The MIT License -# -# Italian localization plugin for Jenkins -# Copyright 2020 Alessandro Menti -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Dismiss=Nascondi -Message=Messaggio -Time=Data e ora -Trigger=Trigger -Warning\ messages\ for\ cron\ triggers=Messaggio d''avviso per i trigger cron diff --git a/core/src/main/resources/hudson/triggers/TimerTrigger/help.html b/core/src/main/resources/hudson/triggers/TimerTrigger/help.html index 2cfdb20b5c44..03fa53f40e59 100644 --- a/core/src/main/resources/hudson/triggers/TimerTrigger/help.html +++ b/core/src/main/resources/hudson/triggers/TimerTrigger/help.html @@ -1,5 +1,5 @@

      - Provides a cron-like feature + Provides a cron-like feature to periodically execute this project.

      @@ -11,7 +11,7 @@ this feature. However, the point of continuous integration is to start a build as soon as a change is made, to provide a quick feedback to the change. To do that you need to - hook up SCM change notification to Jenkins. + hook up SCM change notification to Jenkins.

      So, before using this feature, stop and ask yourself if this is really what you want. diff --git a/core/src/main/resources/hudson/triggers/TimerTrigger/help_bg.html b/core/src/main/resources/hudson/triggers/TimerTrigger/help_bg.html index 810cb0d90ff1..f28073ae3f4e 100644 --- a/core/src/main/resources/hudson/triggers/TimerTrigger/help_bg.html +++ b/core/src/main/resources/hudson/triggers/TimerTrigger/help_bg.html @@ -1,6 +1,6 @@

      Възможност за периодично изпълнение на този проект на база време, - подобно но програмата cron. + подобно но програмата cron.

      Това дава възможност да ползвате Jenkins като заместител на cron. @@ -12,7 +12,7 @@ употреба на тази възможност. Идеята обаче е друга — при непрекъснатото изграждане трябва да се реагира с появата на всяка промяна, за да се получи възможно най-скоро обратна връзка. Това се постига с - автоматични + автоматични известия от системата за контрол на версиите към Jenkins.

      diff --git a/core/src/main/resources/hudson/triggers/TimerTrigger/help_de.html b/core/src/main/resources/hudson/triggers/TimerTrigger/help_de.html index 446b3928a27a..c4ba27215850 100644 --- a/core/src/main/resources/hudson/triggers/TimerTrigger/help_de.html +++ b/core/src/main/resources/hudson/triggers/TimerTrigger/help_de.html @@ -1,6 +1,6 @@

      Erlaubt eine Ausführung des Projekts in regelmäßigen Zeitintervallen, ähnlich - dem Cron-Befehl. + dem Cron-Befehl.

      Dieses Merkmal ist hauptsächlich als Cron-Ersatz gedacht und ist @@ -12,7 +12,7 @@ kontinuierlichen Integration liegt jedoch darin, einen neuen Build zu starten, sobald eine Änderung im Code vorgenommen wurde, um möglichst schnell eine Rückmeldung zu bekommen. Dazu müssen sie eine - Änderungsabfrage (SCM change + Änderungsabfrage (SCM change notification) in Jenkins einrichten.

      diff --git a/core/src/main/resources/hudson/triggers/TimerTrigger/help_fr.html b/core/src/main/resources/hudson/triggers/TimerTrigger/help_fr.html index 80ae28b35cff..539776a666ea 100644 --- a/core/src/main/resources/hudson/triggers/TimerTrigger/help_fr.html +++ b/core/src/main/resources/hudson/triggers/TimerTrigger/help_fr.html @@ -1,6 +1,6 @@ 

      Fournit une fonctionnalité de type - cron + cron afin d'exécuter le projet périodiquement.

      @@ -15,7 +15,7 @@ chaque changement dans la base de code, afin de donner un retour rapide sur ce changement. Pour cela, vous devez - associer la notification des changements de l'outil de gestion de version à Jenkins.. + associer la notification des changements de l'outil de gestion de version à Jenkins..

      Donc, avant d'utiliser cette fonctionnalité, demandez-vous si c'est bien diff --git a/core/src/main/resources/hudson/triggers/TimerTrigger/help_it.html b/core/src/main/resources/hudson/triggers/TimerTrigger/help_it.html index 523c5a2d17e2..9e9b46f4028e 100644 --- a/core/src/main/resources/hudson/triggers/TimerTrigger/help_it.html +++ b/core/src/main/resources/hudson/triggers/TimerTrigger/help_it.html @@ -1,5 +1,5 @@

      - Fornisce una funzionalità simile a cron + Fornisce una funzionalità simile a cron per eseguire periodicamente questo progetto.

      @@ -13,7 +13,7 @@ della continuous integration, tuttavia, è quello di avviare una compilazione non appena si introduce una modifica, per fornire rapidamente un feedback in merito. Per farlo è necessario - integrare le + integrare le notifiche delle modifiche apportate nel sistema di gestione del codice sorgente in Jenkins. diff --git a/core/src/main/resources/hudson/triggers/TimerTrigger/help_ja.html b/core/src/main/resources/hudson/triggers/TimerTrigger/help_ja.html index a11c40031bb7..7d117cf6abba 100644 --- a/core/src/main/resources/hudson/triggers/TimerTrigger/help_ja.html +++ b/core/src/main/resources/hudson/triggers/TimerTrigger/help_ja.html @@ -1,5 +1,5 @@

      - このプロジェクトを定期的に実行するクーロンのような機能を提供します。 + このプロジェクトを定期的に実行するクーロンのような機能を提供します。

      この機能は、クーロンの代替品としてJenkinsを使用するのが第一なので、 @@ -10,7 +10,7 @@ この機能を使用します。しかしながら、継続的インテグレーションのポイントは、 変更したらすぐにビルドを開始し、変更へのフィードバックをすばやくすることです。 そうするには、 - SCMの変更通知をJenkinsに中継する必要があります。 + SCMの変更通知をJenkinsに中継する必要があります。

      上記の通り、この機能を使用する前に、この機能が本当にあなたが必要とするものなのか、 diff --git a/core/src/main/resources/hudson/triggers/TimerTrigger/help_pt_BR.html b/core/src/main/resources/hudson/triggers/TimerTrigger/help_pt_BR.html index 9c8cc68dba74..23ea6fb2d525 100644 --- a/core/src/main/resources/hudson/triggers/TimerTrigger/help_pt_BR.html +++ b/core/src/main/resources/hudson/triggers/TimerTrigger/help_pt_BR.html @@ -1,5 +1,5 @@

      - Fornece uma funcionalidade ao estilo do cron + Fornece uma funcionalidade ao estilo do cron para periodicamente executar este projeto.

      @@ -11,7 +11,7 @@ usam esta funcionalidade. Porém, o ponto principal da integração contínua é iniciar uma construção tão logo uma mudança seja feita, para fornecer um feedback rápido sobre a mudança. Para fazer isto você precisa - ligar a notificação de mudança do SCM ao Jenkins.. + ligar a notificação de mudança do SCM ao Jenkins..

      Assim, antes de usar esta funcionalidade, pare e pergunte a si mesmo se isto é o que realmente você quer. diff --git a/core/src/main/resources/hudson/triggers/TimerTrigger/help_ru.html b/core/src/main/resources/hudson/triggers/TimerTrigger/help_ru.html index 28e0eece9b8f..3a3a32bdf711 100644 --- a/core/src/main/resources/hudson/triggers/TimerTrigger/help_ru.html +++ b/core/src/main/resources/hudson/triggers/TimerTrigger/help_ru.html @@ -1,5 +1,5 @@

      - �।��⠢��� cron-like �㭪樮���쭮��� + �।��⠢��� cron-like �㭪樮���쭮��� ��� 㪠����� �ᯨᠭ�� ᡮப �஥��.

      @@ -14,7 +14,7 @@ ࠧࠡ��稪��. �⮡� ��������� Jenkins �뫮 ������ ⠪��, ����ன� - �����饭�� �� ��஭� SCM. + �����饭�� �� ��஭� SCM.

      ��������, ��। ⥬ ��� �ᯮ�짮���� ��� �㭪��, ��⠭������ � ���� ᥡ�, diff --git a/core/src/main/resources/hudson/triggers/TimerTrigger/help_tr.html b/core/src/main/resources/hudson/triggers/TimerTrigger/help_tr.html index 3dfa2fbb6b9b..00193471c65f 100644 --- a/core/src/main/resources/hudson/triggers/TimerTrigger/help_tr.html +++ b/core/src/main/resources/hudson/triggers/TimerTrigger/help_tr.html @@ -1,5 +1,5 @@

      - Bu özellik, projeyi periyodik olarak cron + Bu özellik, projeyi periyodik olarak cron gibi çalıştırabilmeyi sağlar.

      @@ -10,7 +10,7 @@ planlanabilir. Bu özellik de bu amaç için kullanılabilse de, sürekli entegrasyonun asıl noktasının herhangi bir değişiklik olur olmaz yapılandırmanın başlatılması olduğu ve bu değişikliğe ait geri bildirimin çabucak verilmesi gerektiği unutulmamalıdır. - Bunun için SCM değişikliklerini Jenkins'e bildirecek mekanizmanın + Bunun için SCM değişikliklerini Jenkins'e bildirecek mekanizmanın ayarlanması gerekir.

      Yani, bu özelliği kullanmadan önce yapmak istediğinizin bu yöntem ile mi yapılması gerektiğini sorgulayın. diff --git a/core/src/main/resources/hudson/triggers/TimerTrigger/help_zh_TW.html b/core/src/main/resources/hudson/triggers/TimerTrigger/help_zh_TW.html index 0809ad1abb34..11dc9ee2fe34 100644 --- a/core/src/main/resources/hudson/triggers/TimerTrigger/help_zh_TW.html +++ b/core/src/main/resources/hudson/triggers/TimerTrigger/help_zh_TW.html @@ -1,12 +1,12 @@

      - 提供類似 cron 的功能,定期執行專案。 + 提供類似 cron 的功能,定期執行專案。

      這個功能主要是讓 Jenkins 取代 cron,而且持續建置軟體專案並不是理想選項。 大家第一次接觸持續整合 (Continuous Integration; CI) 時,常會有 Nightly 或 Weekly 建置的刻板印象,認為就該用這個功能為建置挑個良辰吉時。 但是,CI 的中心思想是個仁...不是啦,CI 的中心思想是在異動後盡快建置,讓大家馬上就能知道這次變更所造成的影響。 - 要達到這個目的,可以讓 SCM 在異動後主動通知 Jenkins。 + 要達到這個目的,可以讓 SCM 在異動後主動通知 Jenkins

      所以,在使用這個功能前,先停下來問問自己: 「我到底想要幹嘛?」 diff --git a/core/src/main/resources/hudson/util/AWTProblem/index.properties b/core/src/main/resources/hudson/util/AWTProblem/index.properties index 817ba2c967c4..44c5b087d5c3 100644 --- a/core/src/main/resources/hudson/util/AWTProblem/index.properties +++ b/core/src/main/resources/hudson/util/AWTProblem/index.properties @@ -20,4 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -errorMessage=AWT is not properly configured on this server. Perhaps you need to run your container with "-Djava.awt.headless=true"? See also: https://jenkins.io/redirect/troubleshooting/java.awt.headless +errorMessage=AWT is not properly configured on this server. Perhaps you need to run your container with "-Djava.awt.headless=true"? See also: https://www.jenkins.io/redirect/troubleshooting/java.awt.headless diff --git a/core/src/main/resources/hudson/util/AWTProblem/index_bg.properties b/core/src/main/resources/hudson/util/AWTProblem/index_bg.properties index 650a6df3fae7..1a6f5d854ae4 100644 --- a/core/src/main/resources/hudson/util/AWTProblem/index_bg.properties +++ b/core/src/main/resources/hudson/util/AWTProblem/index_bg.properties @@ -20,10 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -# AWT is not properly configured on this server. Perhaps you need to run your container with "-Djava.awt.headless=true"? See also: https://jenkins.io/redirect/troubleshooting/java.awt.headless +# AWT is not properly configured on this server. Perhaps you need to run your container with "-Djava.awt.headless=true"? See also: https://www.jenkins.io/redirect/troubleshooting/java.awt.headless errorMessage=\ AWT \u043d\u0435 \u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d \u043f\u0440\u0430\u0432\u0438\u043b\u043d\u043e \u043d\u0430 \u0442\u043e\u0437\u0438 \u0441\u044a\u0440\u0432\u044a\u0440. \u0412\u0435\u0440\u043e\u044f\u0442\u043d\u043e \u0442\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u0442\u0435\ \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u0441 \u201e-Djava.awt.headless=true\u201c. \u0412\u0438\u0436\u0442\u0435 \u0438:\ - https://jenkins.io/redirect/troubleshooting/java.awt.headless + https://www.jenkins.io/redirect/troubleshooting/java.awt.headless Error=\ \u0413\u0440\u0435\u0448\u043a\u0430 diff --git a/core/src/main/resources/hudson/util/AWTProblem/index_de.properties b/core/src/main/resources/hudson/util/AWTProblem/index_de.properties index 250307f6ba2a..65b967413c6b 100644 --- a/core/src/main/resources/hudson/util/AWTProblem/index_de.properties +++ b/core/src/main/resources/hudson/util/AWTProblem/index_de.properties @@ -1,4 +1,4 @@ Error=Fehler errorMessage=\ AWT ist auf diesem Server nicht vollstndig konfiguriert. Eventuell \ - sollten Sie Ihren Servlet-Container mit der Option -Djava.awt.headless=true starten. + sollten Sie Ihren Servlet-Container mit der Option -Djava.awt.headless=true starten. diff --git a/core/src/main/resources/hudson/util/AWTProblem/index_it.properties b/core/src/main/resources/hudson/util/AWTProblem/index_it.properties index a7b38f41ccc9..253564d75aee 100644 --- a/core/src/main/resources/hudson/util/AWTProblem/index_it.properties +++ b/core/src/main/resources/hudson/util/AWTProblem/index_it.properties @@ -24,4 +24,4 @@ Error=Errore errorMessage=AWT non configurato correttamente su questo server. Forse \ necessario eseguire il container con l''opzione "-Djava.awt.headless=true"? \ - Si veda anche https://jenkins.io/redirect/troubleshooting/java.awt.headless + Si veda anche https://www.jenkins.io/redirect/troubleshooting/java.awt.headless diff --git a/core/src/main/resources/hudson/util/AWTProblem/index_sr.properties b/core/src/main/resources/hudson/util/AWTProblem/index_sr.properties index 41e88a682a43..6ded26b78921 100644 --- a/core/src/main/resources/hudson/util/AWTProblem/index_sr.properties +++ b/core/src/main/resources/hudson/util/AWTProblem/index_sr.properties @@ -1,4 +1,4 @@ # This file is under the MIT License by authors Error=\u0413\u0440\u0435\u0448\u043A\u0430 -errorMessage=AWT \u043D\u0438\u0458\u0435 \u043F\u0440\u0430\u0432\u0438\u043B\u043D\u043E \u043F\u043E\u0441\u0442\u0430\u0432\u0459\u0435\u043D\u043E \u043D\u0430 \u043E\u0432\u043E\u0458 \u043C\u0430\u0448\u0438\u043D\u0438. \u041C\u043E\u0436\u0434\u0430 \u0431\u0438 \u0442\u0440\u0435\u0431\u0430\u043B\u0438 \u043F\u043E\u0447\u0435\u0442\u0438 \u043A\u043E\u043D\u0442\u0435\u0458\u043D\u0435\u0440\u0435 \u0441\u0430 \u043E\u043F\u0446\u0438\u0458\u043E\u043C "-Djava.awt.headless=true"? \u0418\u0441\u0442\u043E \u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0430\u0458\u0442\u0435: https://jenkins.io/redirect/troubleshooting/java.awt.headless +errorMessage=AWT \u043D\u0438\u0458\u0435 \u043F\u0440\u0430\u0432\u0438\u043B\u043D\u043E \u043F\u043E\u0441\u0442\u0430\u0432\u0459\u0435\u043D\u043E \u043D\u0430 \u043E\u0432\u043E\u0458 \u043C\u0430\u0448\u0438\u043D\u0438. \u041C\u043E\u0436\u0434\u0430 \u0431\u0438 \u0442\u0440\u0435\u0431\u0430\u043B\u0438 \u043F\u043E\u0447\u0435\u0442\u0438 \u043A\u043E\u043D\u0442\u0435\u0458\u043D\u0435\u0440\u0435 \u0441\u0430 \u043E\u043F\u0446\u0438\u0458\u043E\u043C "-Djava.awt.headless=true"? \u0418\u0441\u0442\u043E \u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0430\u0458\u0442\u0435: https://www.jenkins.io/redirect/troubleshooting/java.awt.headless diff --git a/core/src/main/resources/hudson/util/HudsonIsLoading/index_pt_BR.properties b/core/src/main/resources/hudson/util/HudsonIsLoading/index_pt_BR.properties index ffc66362be31..195fb332118b 100644 --- a/core/src/main/resources/hudson/util/HudsonIsLoading/index_pt_BR.properties +++ b/core/src/main/resources/hudson/util/HudsonIsLoading/index_pt_BR.properties @@ -21,4 +21,5 @@ # THE SOFTWARE. Please\ wait\ while\ Jenkins\ is\ getting\ ready\ to\ work=Por favor aguarde enquanto o Jenkins se prepara para trabalhar -Your\ browser\ will\ reload\ automatically\ when\ Jenkins\ is\ ready.=Seu browser recarregar\u00e1 automaticamente quando o Jenkins estiver pronto. +Your\ browser\ will\ reload\ automatically\ when\ Jenkins\ is\ ready.=Seu navegador recarregar\u00E1 automaticamente quando o Jenkins estiver pronto. +Starting\ Jenkins=Iniciando\ o\ Jenkins diff --git a/core/src/main/resources/hudson/util/HudsonIsRestarting/index_pt_BR.properties b/core/src/main/resources/hudson/util/HudsonIsRestarting/index_pt_BR.properties index 68c3c234d3a4..8921a9391488 100644 --- a/core/src/main/resources/hudson/util/HudsonIsRestarting/index_pt_BR.properties +++ b/core/src/main/resources/hudson/util/HudsonIsRestarting/index_pt_BR.properties @@ -20,5 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Please\ wait\ while\ Jenkins\ is\ restarting=Por favor aguarde enquanto o Jenkins est\u00e1 reiniciando -Your\ browser\ will\ reload\ automatically\ when\ Jenkins\ is\ ready.=Seu browser recarregar\u00e1 automaticamente quando o Jenkins estiver pronto. +Please\ wait\ while\ Jenkins\ is\ restarting=Por favor aguarde enquanto o Jenkins est\u00E1 reiniciando +Your\ browser\ will\ reload\ automatically\ when\ Jenkins\ is\ ready.=Seu navegador recarregar\u00E1 automaticamente quando o Jenkins estiver pronto. +Restarting\ Jenkins=Reiniciando\ o\ Jenkins diff --git a/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index.properties b/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index.properties index bcfc48cfbb5a..287da73bef33 100644 --- a/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index.properties +++ b/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index.properties @@ -24,5 +24,5 @@ errorMessage=\ We detected that your servlet container is loading an older version of Ant by itself, \ thereby preventing Jenkins from loading its own newer copy. \ (Ant classes are loaded from {0})
      \ - Perhaps can you override Ant in your container by copying one from Jenkins\u2019s WEB-INF/lib, \ + Perhaps can you override Ant in your container by copying one from Jenkins\u2019s WEB-INF/lib, \ or can you set up the classloader delegation to child-first so that Jenkins sees its own copy first? diff --git a/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_bg.properties b/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_bg.properties index d030ed8413d8..458663336907 100644 --- a/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_bg.properties +++ b/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_bg.properties @@ -24,14 +24,14 @@ # We detected that your servlet container is loading an older version of Ant by itself, \ # thereby preventing Jenkins from loading its own newer copy. \ # (Ant classes are loaded from {0})
      \ -# Perhaps can you override Ant in your container by copying one from Jenkins\u2019s WEB-INF/lib, \ +# Perhaps can you override Ant in your container by copying one from Jenkins\u2019s WEB-INF/lib, \ # or can you set up the classloader delegation to child-first so that Jenkins sees its own copy first? errorMessage=\ \u0418\u0437\u0433\u043b\u0435\u0436\u0434\u0430, \u0447\u0435 \u0432\u0430\u0448\u0438\u044f\u0442 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0438 \u0437\u0430 \u0441\u044a\u0440\u0432\u043b\u0435\u0442\u0438 \u0437\u0430\u0440\u0435\u0436\u0434\u0430 \u0441\u0442\u0430\u0440\u0430 \u0432\u0435\u0440\u0441\u0438\u044f \u043d\u0430 Ant, \u0430 \u0442\u043e\u0432\u0430\ \u043f\u0440\u0435\u0447\u0438 \u043d\u0430 Jenkins \u0434\u0430 \u0437\u0430\u0440\u0435\u0434\u0438 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u0430\u0442\u0430 \u0441\u0438 \u0432\u0435\u0440\u0441\u0438\u044f. (\u041a\u043b\u0430\u0441\u043e\u0432\u0435\u0442\u0435 \u043d\u0430 Ant \u0432 \u043c\u043e\u043c\u0435\u043d\u0442\u0430\ \u0441\u0430 \u0437\u0430\u0440\u0435\u0434\u0435\u043d\u0438 \u043e\u0442 \u201e{0}\u201c)
      \ \u0415\u0434\u0438\u043d \u043e\u0442 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0438\u0442\u0435 \u0435 \u0434\u0430 \u043f\u0440\u0438\u043f\u043e\u043a\u0440\u0438\u0435\u0442\u0435 \u0432\u0435\u0440\u0441\u0438\u044f\u0442\u0430 \u043d\u0430 Ant \u043d\u0430 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430, \u043a\u0430\u0442\u043e\ - \u043a\u043e\u043f\u0438\u0440\u0430\u0442\u0435 \u0442\u0430\u0437\u0438 \u043d\u0430 Jenkins \u043e\u0442WEB-INF/lib. \u0414\u0440\u0443\u0433\u0430 \u0432\u044a\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442 \u0435 \u0434\u0430\ + \u043a\u043e\u043f\u0438\u0440\u0430\u0442\u0435 \u0442\u0430\u0437\u0438 \u043d\u0430 Jenkins \u043e\u0442WEB-INF/lib. \u0414\u0440\u0443\u0433\u0430 \u0432\u044a\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442 \u0435 \u0434\u0430\ \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u0435 \u0438\u043b\u0438 \u043f\u0440\u0435\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0438\u0440\u0430\u0442\u0435 \u0437\u0430\u0440\u0435\u0436\u0434\u0430\u043d\u0435\u0442\u043e \u043d\u0430 \u043a\u043b\u0430\u0441\u043e\u0432\u0435, \u0442\u0430\u043a\u0430 \u0447\u0435 \u0441 \u043f\u0440\u0435\u0434\u0438\u043c\u0441\u0442\u0432\u043e \u0434\u0430\ \u0441\u0435 \u043f\u043e\u043b\u0437\u0432\u0430 \u043a\u043e\u043f\u0438\u0435\u0442\u043e \u043d\u0430 Jenkins. Error=\ diff --git a/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_da.properties b/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_da.properties index 38de136597b2..3e89e495c2ea 100644 --- a/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_da.properties +++ b/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_da.properties @@ -22,6 +22,6 @@ errorMessage=Din servlet container indl\u00e6ser en \u00e6ldre version af Ant, hvilket forhindrer Jenkins \ i at indl\u00e6se sin egen nyere Ant version. \ (Ant klasser indl\u00e6ses fra {0})
      \ -M\u00e5ske kan du tilsides\u00e6tte Antversionen i din container ved at kopiere Ant fra Jenkins''s WEB-INF/lib, \ +M\u00e5ske kan du tilsides\u00e6tte Antversionen i din container ved at kopiere Ant fra Jenkins''s WEB-INF/lib, \ eller du kan eventuelt s\u00e6tte classloader delegation til child-first, s\u00e5 Jenkins ser sin egen kopi f\u00f8rst? Error=Fejl diff --git a/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_de.properties b/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_de.properties index 27d2269f2bbe..44f74ff221d7 100644 --- a/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_de.properties +++ b/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_de.properties @@ -26,5 +26,5 @@ errorMessage=\ Jenkins daran, seine eigene, neuere Version zu verwenden \ (Ant Klassen werden aus {0} geladen).
      \ Eventuell k\u00F6nnen Sie die Ant-Version Ihres Servlet-Containers mit einer Version aus \ - Jenkins' WEB-INF/lib-Verzeichnis \u00FCberschreiben oder die Classloader-Delegation \ + Jenkins' WEB-INF/lib-Verzeichnis \u00FCberschreiben oder die Classloader-Delegation \ auf den Modus \u201EKinder zuerst (child first)\u201C umstellen, so dass Jenkins seine Version zuerst findet? diff --git a/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_es.properties b/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_es.properties index 4f3715608df8..ec82ba551940 100644 --- a/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_es.properties +++ b/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_es.properties @@ -23,7 +23,7 @@ errorMessage=\ Se ha detectado que tu ''contenedor de servlets'' utiliza una versin antigua de Ant,\ (Ant se est cargando desde {0})
      \ - Es posible que puedas configurar tu contenedor para usar una nueva version de ant, ponindola en el directorio WEB-INF/lib, \ + Es posible que puedas configurar tu contenedor para usar una nueva version de ant, ponindola en el directorio WEB-INF/lib, \ o modificar el orden de carga de clases configurando como child-first. Error=Error diff --git a/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_fr.properties b/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_fr.properties index 14dd9773f3b0..3e23daae3ff9 100644 --- a/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_fr.properties +++ b/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_fr.properties @@ -27,7 +27,7 @@ errorMessage=\ propre copie de Ant, plus rcente. \ (les classes de Ant sont charges partir de {0})
      \ Peut-tre pouvez-vous surcharger Ant dans votre conteneur en \ - copiant un exemplaire partir du rpertoire WEB-INF/lib de \ + copiant un exemplaire partir du rpertoire WEB-INF/lib de \ Jenkins? Ou tentez de positionner la dlgation classloader en child-first \ afin que Jenkins puisse voir sa propre copie d''abord. diff --git a/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_it.properties b/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_it.properties index 3cdce005fbd4..acdc8fa4c308 100644 --- a/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_it.properties +++ b/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_it.properties @@ -27,6 +27,6 @@ errorMessage=Jenkins ha rilevato che il container servlet sta caricando \ Jenkins di caricare la propria copia pi recente. (Le classi Ant sono \ caricate da {0}).
      \ Forse possibile eseguire l''override della versione di Ant nel container \ - copiandone una dalla directory WEB-INF/lib di Jenkins, oppure \ + copiandone una dalla directory WEB-INF/lib di Jenkins, oppure \ possibile impostare la delega del classloader a "prima i figli" in modo \ tale che Jenkins rilevi prima la propria copia? diff --git a/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_ja.properties b/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_ja.properties index f5560aaa1bff..bbc490a1400d 100644 --- a/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_ja.properties +++ b/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_ja.properties @@ -25,5 +25,5 @@ errorMessage=\ \u30B5\u30FC\u30D6\u30EC\u30C3\u30C8\u30B3\u30F3\u30C6\u30CA\u30FC\u304C\u63D0\u4F9B\u3059\u308B\u53E4\u3044\u30D0\u30FC\u30B8\u30E7\u30F3\u306EAnt\u3092\u30ED\u30FC\u30C9\u3057\u3066\u3044\u308B\u3088\u3046\u3067\u3059\u3002\ \u305D\u306E\u7D50\u679C\u3001Jenkins\u306E\u65B0\u3057\u3044\u30D0\u30FC\u30B8\u30E7\u30F3\u306EAnt\u3092\u30ED\u30FC\u30C9\u3067\u304D\u307E\u305B\u3093\u3002\ (Ant\u3092{0}\u304B\u3089\u30ED\u30FC\u30C9\u3057\u3066\u3044\u307E\u3059\u3002)
      \ - Jenkins\u306EWEB-INF/lin\u306EAnt\u3067\u30B3\u30F3\u30C6\u30CA\u30FC\u306EAnt\u3092\u4E0A\u66F8\u304D\u3059\u308B\u304B\u3001\ + Jenkins\u306EWEB-INF/lin\u306EAnt\u3067\u30B3\u30F3\u30C6\u30CA\u30FC\u306EAnt\u3092\u4E0A\u66F8\u304D\u3059\u308B\u304B\u3001\ Jenkins\u306EAnt\u3092\u6700\u521D\u306B\u30ED\u30FC\u30C9\u3067\u304D\u308B\u3088\u3046\u306B\u3001\u30AF\u30E9\u30B9\u30ED\u30FC\u30C0\u30FC\u3092\u5909\u66F4\u3057\u3066\u304F\u3060\u3055\u3044\u3002 diff --git a/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_nl.properties b/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_nl.properties index 0289fb79d1cf..b1fd420b81d0 100644 --- a/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_nl.properties +++ b/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_nl.properties @@ -26,7 +26,7 @@ errorMessage=\ Hierdoor kan Jenkins zijn eigen recentere versie van Ant niet \ laden. (Uw Ant klassen worden vanuit volgend pad geladen : {0})\ Misschien kunt u een andere versie van Ant in uw container laden \ -door de bibliotheek uit de WEB-INF/lib folder van Jenkins\ +door de bibliotheek uit de WEB-INF/lib folder van Jenkins\ te kopiren? Of misschien kunt u de 'delegation classloader' configureren\ in 'child first' modus, zodanig dat Jenkins zijn eigen versie rst \ kan laden. diff --git a/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_pt_BR.properties b/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_pt_BR.properties index 5ad17ae8352e..6d4a4fb27b5c 100644 --- a/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_pt_BR.properties +++ b/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_pt_BR.properties @@ -25,6 +25,6 @@ errorMessage=\ N\u00f3s detectamos que seu container de servlet est\u00e1 carregando uma vers\u00e3o antiga do Ant, \ e com isso evitando que o Jenkins carregue sua pr\u00f3pria c\u00f3pia mais recente. \ (classes Ant s\u00e3o carregadas de {0})
      \ - Talvez voc\u00ea possa sobrecarregar o Ant em seu container copiando uma vers\u00e3o do diret\u00f3rio WEB-INF/lib do Jenkins, \ + Talvez voc\u00ea possa sobrecarregar o Ant em seu container copiando uma vers\u00e3o do diret\u00f3rio WEB-INF/lib do Jenkins, \ ou voc\u00ea possa configurar a delega\u00e7\u00e3o do Classloader para first-child tal que o Jenkins veja sua pr\u00f3pria c\u00f3pia primeiro? diff --git a/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_tr.properties b/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_tr.properties index 82603e686f29..fdcc2ffdd7a5 100644 --- a/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_tr.properties +++ b/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_tr.properties @@ -24,6 +24,6 @@ errorMessage=\ Jenkins''in \u00fczerinde y\u00fcr\u00fct\u00fcld\u00fc\u011f\u00fc servlet container''\u0131n eski bir Ant versiyonu y\u00fckledi\u011fi tespit edildi,\ bu da Jenkins''in kendi, daha yeni kopyas\u0131n\u0131 y\u00fcklemesini engelliyor.\ (Ant s\u0131n\u0131flar\u0131 {0} i\u00e7erisinden y\u00fckleniyor}
      \ - Container i\u00e7erisindeki kopyay\u0131 Jenkins''in WEB-INF/lib dizinindeki ile ezmeniz gerekebilir,\ + Container i\u00e7erisindeki kopyay\u0131 Jenkins''in WEB-INF/lib dizinindeki ile ezmeniz gerekebilir,\ veya classloader''\u0131 delegasyonunu Jenkins''e vererek, Jenkins''in kendi kopyas\u0131n\u0131 y\u00fcklemesini sa\u011flayabilirsiniz. Error=Hata diff --git a/core/src/main/resources/hudson/util/IncompatibleVMDetected/index.properties b/core/src/main/resources/hudson/util/IncompatibleVMDetected/index.properties index 6abcaf9ef33a..cb904322d9aa 100644 --- a/core/src/main/resources/hudson/util/IncompatibleVMDetected/index.properties +++ b/core/src/main/resources/hudson/util/IncompatibleVMDetected/index.properties @@ -23,4 +23,4 @@ errorMessage=\ We detected that your JVM is not supported by Jenkins. \ This is due to the limitation is one of the libraries that Jenkins uses, namely XStream. \ - See this FAQ for more details. + See this FAQ for more details. diff --git a/core/src/main/resources/hudson/util/IncompatibleVMDetected/index_bg.properties b/core/src/main/resources/hudson/util/IncompatibleVMDetected/index_bg.properties index 870a017c5dd2..3850810fedd2 100644 --- a/core/src/main/resources/hudson/util/IncompatibleVMDetected/index_bg.properties +++ b/core/src/main/resources/hudson/util/IncompatibleVMDetected/index_bg.properties @@ -33,12 +33,12 @@ OS\ Name=\ # \ # We detected that your JVM is not supported by Jenkins. \ # This is due to the limitation is one of the libraries that Jenkins uses, namely XStream. \ -# See this FAQ for more details. +# See this FAQ for more details. errorMessage=\ \u0412\u0430\u0448\u0430\u0442\u0430 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u043d\u0430\u0442\u0430 \u043c\u0430\u0448\u0438\u043d\u0430 \u0437\u0430 Java \u043d\u0435 \u0441\u0435 \u043f\u043e\u0434\u0434\u044a\u0440\u0436\u0430 \u043e\u0442 Jenkins. \u0422\u043e\u0432\u0430 \u0435\ \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u0432 \u0435\u0434\u043d\u0430 \u043e\u0442 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438\u0442\u0435, \u043a\u043e\u0438\u0442\u043e Jenkins \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430 \u2014 XStream. \u0417\u0430\ \u043f\u043e\u0432\u0435\u0447\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043f\u0440\u0435\u0433\u043b\u0435\u0434\u0430\u0439\u0442\u0435\ - \u043e\u0442\u0433\u043e\u0432\u043e\u0440\u0438\u0442\u0435 \u043d\u0430 \u0447\u0435\u0441\u0442\u043e \u0437\u0430\u0434\u0430\u0432\u0430\u043d\u0438\u0442\u0435\ + \u043e\u0442\u0433\u043e\u0432\u043e\u0440\u0438\u0442\u0435 \u043d\u0430 \u0447\u0435\u0441\u0442\u043e \u0437\u0430\u0434\u0430\u0432\u0430\u043d\u0438\u0442\u0435\ \u0432\u044a\u043f\u0440\u043e\u0441\u0438 \u0437\u0430 XStream. Version=\ \u0412\u0435\u0440\u0441\u0438\u044f diff --git a/core/src/main/resources/hudson/util/IncompatibleVMDetected/index_de.properties b/core/src/main/resources/hudson/util/IncompatibleVMDetected/index_de.properties index 5b55c0c15ebf..e21183d21645 100644 --- a/core/src/main/resources/hudson/util/IncompatibleVMDetected/index_de.properties +++ b/core/src/main/resources/hudson/util/IncompatibleVMDetected/index_de.properties @@ -30,4 +30,4 @@ errorMessage=\ Die gefundene Java Virtual Machine (JVM) wird von Jenkins nicht untersttzt. \ Jenkins ist auf die Bibliothek XStream angewiesen, welche aber nicht mit der \ gefundenen JVM funktioniert. \ - Mehr dazu... + Mehr dazu... diff --git a/core/src/main/resources/hudson/util/IncompatibleVMDetected/index_es.properties b/core/src/main/resources/hudson/util/IncompatibleVMDetected/index_es.properties index 2b820813429d..0ad5b97211cd 100644 --- a/core/src/main/resources/hudson/util/IncompatibleVMDetected/index_es.properties +++ b/core/src/main/resources/hudson/util/IncompatibleVMDetected/index_es.properties @@ -22,7 +22,7 @@ errorMessage=\ Se ha detectado que tu versin de java no est soportada por Jenkins.\ - Echa un vistazo a esta FAQ para mas detalles. + Echa un vistazo a esta FAQ para mas detalles. Error=Error VM\ Name=Nombre de la mquina virtual Version=Versin diff --git a/core/src/main/resources/hudson/util/IncompatibleVMDetected/index_it.properties b/core/src/main/resources/hudson/util/IncompatibleVMDetected/index_it.properties index da9d7196e0ff..923e46f460ab 100644 --- a/core/src/main/resources/hudson/util/IncompatibleVMDetected/index_it.properties +++ b/core/src/main/resources/hudson/util/IncompatibleVMDetected/index_it.properties @@ -26,7 +26,7 @@ Error=Errore errorMessage=Jenkins ha rilevato che la JVM in uso non supportata da \ Jenkins. Ci dovuto alla limitazione introdotta da una libreria \ utilizzata da Jenkins, ossia XStream. Si veda \ - questa domanda frequente \ + questa domanda frequente \ per ulteriori dettagli. OS\ Name=Nome sistema operativo Vendor=Fornitore diff --git a/core/src/main/resources/hudson/util/IncompatibleVMDetected/index_ja.properties b/core/src/main/resources/hudson/util/IncompatibleVMDetected/index_ja.properties index 71bedd523d84..c68e40bb5cc8 100644 --- a/core/src/main/resources/hudson/util/IncompatibleVMDetected/index_ja.properties +++ b/core/src/main/resources/hudson/util/IncompatibleVMDetected/index_ja.properties @@ -24,7 +24,7 @@ Error=\u30A8\u30E9\u30FC errorMessage=\ Jenkins\u304C\u30B5\u30DD\u30FC\u30C8\u3057\u3066\u3044\u306A\u3044JVM\u304C\u4F7F\u308F\u308C\u3066\u3044\u308B\u3088\u3046\u3067\u3059\u3002\ \u3053\u306E\u5236\u9650\u306F\u3001Jenkins\u304C\u4F7F\u7528\u3057\u3066\u3044\u308BXStream\u306B\u3088\u308B\u3082\u306E\u3067\u3059\u3002\ - \u8A73\u7D30\u306F\u3001\u3053\u306EFAQ\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002 + \u8A73\u7D30\u306F\u3001\u3053\u306EFAQ\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002 Detected\ JVM=JVM Vendor=\u30D9\u30F3\u30C0\u30FC Version=\u30D0\u30FC\u30B8\u30E7\u30F3 diff --git a/core/src/main/resources/hudson/util/IncompatibleVMDetected/index_pt_BR.properties b/core/src/main/resources/hudson/util/IncompatibleVMDetected/index_pt_BR.properties index 6dd7cd3ce2a5..e0629c213a61 100644 --- a/core/src/main/resources/hudson/util/IncompatibleVMDetected/index_pt_BR.properties +++ b/core/src/main/resources/hudson/util/IncompatibleVMDetected/index_pt_BR.properties @@ -25,10 +25,10 @@ Detected\ JVM=JVM detectada # \ # We detected that your JVM is not supported by Jenkins. \ # This is due to the limitation is one of the libraries that Jenkins uses, namely XStream. \ -# See this FAQ for more details. +# See this FAQ for more details. errorMessage=N\u00f3s detectamos que o Jenkins n\u00e3o suporta sua JVM. \ Isto se d\u00e1 devido a uma limita\u00e7\u00e3o na biblioteca do Huson, chamada XStream. \ - Veja essa FAQ para mais detalhes. + Veja essa FAQ para mais detalhes. Version=Vers\u00e3o Vendor=Fornecedor Error=Erro diff --git a/core/src/main/resources/hudson/util/IncompatibleVMDetected/index_sr.properties b/core/src/main/resources/hudson/util/IncompatibleVMDetected/index_sr.properties index c969814074ec..10c8830baf72 100644 --- a/core/src/main/resources/hudson/util/IncompatibleVMDetected/index_sr.properties +++ b/core/src/main/resources/hudson/util/IncompatibleVMDetected/index_sr.properties @@ -2,7 +2,7 @@ Error=\u0413\u0440\u0435\u0448\u043A\u0430 errorMessage=Jenkins \u0458\u0435 \u043F\u0440\u043E\u043D\u0430\u0448\u0430\u043E \u0434\u0430 \u0432\u0430\u0448\u0430 JVM \u043D\u0438\u0458\u0435 \u043F\u043E\u0434\u0440\u0436\u0430\u043D\u0430, \u0437\u0431\u043E\u0433 \u043D\u0435\u043A\u0438\u0445 \u0431\u0438\u0431\u043B\u0438\u043E\u0442\u0435\u043A\u0430 \u043E\u0434 \u043A\u043E\u0458\u0435 Jenkins \u0437\u0430\u0432\u0438\u0441\u0438.\ -\u041F\u0440\u0435\u0433\u043B\u0435\u0434\u0430\u0458\u0442\u0435 this FAQ \u0433\u0434\u0435 \u0438\u043C\u0430 \u0432\u0438\u043F\u0435 \u0434\u0435\u0442\u0430\u0459\u0430. +\u041F\u0440\u0435\u0433\u043B\u0435\u0434\u0430\u0458\u0442\u0435 this FAQ \u0433\u0434\u0435 \u0438\u043C\u0430 \u0432\u0438\u043F\u0435 \u0434\u0435\u0442\u0430\u0459\u0430. Detected\ JVM= Vendor=\u041F\u0440\u043E\u0438\u0437\u0432\u043E\u0452\u0430\u0447 Version=\u0412\u0435\u0440\u0437\u0438\u0458\u0430 diff --git a/core/src/main/resources/hudson/util/IncompatibleVMDetected/index_zh_TW.properties b/core/src/main/resources/hudson/util/IncompatibleVMDetected/index_zh_TW.properties index 5ed9dfc4f68d..2eeaf69bf5a5 100644 --- a/core/src/main/resources/hudson/util/IncompatibleVMDetected/index_zh_TW.properties +++ b/core/src/main/resources/hudson/util/IncompatibleVMDetected/index_zh_TW.properties @@ -24,7 +24,7 @@ Error=\u932f\u8aa4 errorMessage=\ Jenkins \u4e0d\u652f\u63f4\u60a8\u7684 JVM\u3002\ \u9019\u662f Jenkins \u4f7f\u7528\u5230\u7684 XStream \u51fd\u5f0f\u5eab\u7684\u9650\u5236\u3002\ - \u8a73\u7d30\u8cc7\u6599\u8acb\u53c3\u8003 XStream \u7684 FAQ\u3002 + \u8a73\u7d30\u8cc7\u6599\u8acb\u53c3\u8003 XStream \u7684 FAQ\u3002 Detected\ JVM=\u5075\u6e2c\u5230\u7684 JVM Vendor=\u4f9b\u61c9\u5546 Version=\u7248\u672c diff --git a/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index.properties b/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index.properties index 4a5267880447..0e1fa3d13b0b 100644 --- a/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index.properties +++ b/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index.properties @@ -29,5 +29,5 @@ errorMessage.1=\ way to fix the problem is simply to turn the security manager off. errorMessage.2=\ For how to turn off security manager in your container, refer to \ - \ + \ Container-specific documentations of Jenkins. diff --git a/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index_bg.properties b/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index_bg.properties index 8a316a5158b1..3ba151508ef2 100644 --- a/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index_bg.properties +++ b/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index_bg.properties @@ -21,12 +21,12 @@ # THE SOFTWARE. # For how to turn off security manager in your container, refer to \ -# \ +# \ # Container-specific documentations of Jenkins. errorMessage.2=\ \u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043a\u0430\u043a \u0434\u0430 \u0441\u043f\u0440\u0435\u0442\u0435 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u0442\u043e \u043d\u0430 \u0441\u0438\u0433\u0443\u0440\u043d\u043e\u0441\u0442\u0442\u0430 (security manager) \u043d\u0430\ \u0432\u0430\u0448\u0438\u044f \u0443\u0435\u0431 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0438\u043c\u0430 \u0432\ - \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f\u0442\u0430\ + \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f\u0442\u0430\ \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u0447\u043d\u0430 \u0437\u0430 \u043e\u0442\u0434\u0435\u043b\u043d\u0438\u0442\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0438 \u0437\u0430 \u0441\u044a\u0440\u0432\u043b\u0435\u0442\u0438. # \ # We detected that Jenkins does not have sufficient permission to run, \ diff --git a/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index_de.properties b/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index_de.properties index 2e701993d076..e516bcd8d2e2 100644 --- a/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index_de.properties +++ b/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index_de.properties @@ -28,5 +28,5 @@ errorMessage.1=\ zuteilen. Falls nicht, ist es am einfachsten, den Security Manager abzuschalten. errorMessage.2=\ Wie Sie den Security Manager Ihres Servlet-Containers abschalten, entnehmen Sie \ - der containerspezifischen \ + der containerspezifischen \ Jenkins-Dokumentation. diff --git a/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index_es.properties b/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index_es.properties index ec945dcc8675..b44366ba59b0 100644 --- a/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index_es.properties +++ b/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index_es.properties @@ -24,7 +24,7 @@ errorMessage.1=\ Se ha detectado que Jenkins no tiene suficientes permisos para ejecutarse. \ Probablemente pueda ser que el ''security manager'' de tu contenedor de ''servlet'' est activado. errorMessage.2=\ - Echa un vistazo a \ + Echa un vistazo a \ Container-specific documentations para saber cmo desactivar esta restriccin. Error=Error diff --git a/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index_it.properties b/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index_it.properties index e81c6858e693..7ac989885992 100644 --- a/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index_it.properties +++ b/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index_it.properties @@ -31,5 +31,5 @@ errorMessage.1=Jenkins ha rilevato di non disporre dei privilegi sufficienti \ problema semplicemente disattivare il gestore della sicurezza. errorMessage.2=Per le istruzioni sulla disabilitazione del gestore della \ sicurezza all''interno del proprio container, si faccia riferimento alla \ - \ + \ documentazione specifica dei vari container di Jenkins. diff --git a/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index_ja.properties b/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index_ja.properties index ae3a8711670e..a6549ae7458b 100644 --- a/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index_ja.properties +++ b/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index_ja.properties @@ -29,5 +29,5 @@ errorMessage.1=\ \u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u30DE\u30CD\u30FC\u30B8\u30E3\u30FC\u3092\u7121\u52B9\u306B\u3057\u3066\u3057\u307E\u3046\u306E\u304C\u4E00\u756A\u7C21\u5358\u3067\u3059\u3002 errorMessage.2=\ \u4F7F\u7528\u3057\u3066\u3044\u308B\u30B3\u30F3\u30C6\u30CA\u30FC\u3067\u306E\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u30DE\u30CD\u30FC\u30B8\u30E3\u30FC\u306E\u7121\u52B9\u5316\u306E\u65B9\u6CD5 \u306B\u3064\u3044\u3066\u306F\u3001\ - \ + \ Container-specific documentations\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002 diff --git a/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index_pt_BR.properties b/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index_pt_BR.properties index 82059ee24818..7f2b2373eb6f 100644 --- a/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index_pt_BR.properties +++ b/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index_pt_BR.properties @@ -34,7 +34,7 @@ de seguran\u00e7a, poder\u00e1 desativ\u00e1-lo. Error=Erro # \ # For how to turn off security manager in your container, refer to \ -# \ +# \ # Container-specific documentations of Jenkins. errorMessage.2=Para desativar o gerenciador de seguran\u00e7a, \ Documenta\u00e7\u00e3o especifica sobre containers do Jenkins diff --git a/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index_sr.properties b/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index_sr.properties index 011f3bd6120f..8ef2cee78a4e 100644 --- a/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index_sr.properties +++ b/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index_sr.properties @@ -3,6 +3,6 @@ Error=\u0413\u0440\u0435\u0448\u043A\u0430 errorMessage.1=Jenkins je \u043E\u0442\u043A\u0440\u0438o \u0434\u0430 \u043D\u0435\u043C\u0430 \u043E\u0432\u043B\u0430\u0448\u045B\u0435\u045A\u0435 \u0434\u0430 \u0441\u0435 \u0438\u0437\u0432\u0440\u0448\u0430\u0432\u0430, \u0435\u0432\u0438\u0434\u0435\u043D\u0442\u0438\u0440\u0430\u043D\u043E \u043F\u0440\u0430\u0442\u0435\u045B\u043E\u0458 \u0442\u0440\u0430\u0441\u0438 \u0441\u0442\u0435\u043A\u043E\u043C. \u0412\u0435\u0440\u043E\u0432\u0430\u0442\u043D\u043E \u0458\u0435 \u0437\u0431\u043E\u0433 \u043D\u0435\u043A\u043E\u0433 \u043D\u0430\u0434\u0437\u043E\u0440\u043D\u043E\u0433 \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u0430, \u043A\u043E\u0458\u0438 \u0431\u0438 \u0442\u0440\u0435\u0431\u043E \u0434\u0430 \u0441\u0435 \u043F\u043E\u0434\u0435\u0441\u0438 \u0438\u043B\u0438 \u0438\u0441\u043A\u0459\u0443\u0447\u0438. errorMessage.2=\u0423\u043F\u0443\u0441\u0442\u0432\u043E \u043A\u0430\u043A\u043E \u0443\u0433\u0430\u0441\u0438\u0442\u0438 security manager \u0443 \u0432\u0430\u0448\u0435\u043C \u043A\u043E\u043D\u0442\u0435\u0458\u043D\u0435\u0440\u0443 \u0441\u0435 \u043D\u0430\u043B\u0430\u0437\u0438 \u0443 \u0447\u043B\u0430\u043D\u043A\u0443 \ - \ + \ \u0414\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430\u0446\u0438\u0458\u0430 \u043A\u043E\u043D\u0442\u0435\u0458\u043D\u0435\u0440\u0430 \u0443 Jenkins-\u0443. de= diff --git a/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index_zh_TW.properties b/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index_zh_TW.properties index dd369fb349d6..79fd5d109600 100644 --- a/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index_zh_TW.properties +++ b/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index_zh_TW.properties @@ -28,5 +28,5 @@ errorMessage.1=\ \u8981\u662f\u60a8\u9023 Security Manager \u662f\u4ec0\u9ebc\u90fd\u4e0d\u77e5\u9053\uff0c\u6700\u7c21\u55ae\u7684\u8655\u7406\u65b9\u6cd5\u5c31\u662f\u628a\u5b83\u95dc\u6389\u3002 errorMessage.2=\ \u95dc\u9589\u60a8 Container \u7684 Security Manager \u7684\u65b9\u6cd5\u53ef\u4ee5\u53c3\u8003 Jenkins \u7684 \ - \ + \ Container \u76f8\u95dc\u6587\u4ef6\u3002 diff --git a/core/src/main/resources/hudson/util/JNADoublyLoaded/index.jelly b/core/src/main/resources/hudson/util/JNADoublyLoaded/index.jelly deleted file mode 100644 index 933c57f94001..000000000000 --- a/core/src/main/resources/hudson/util/JNADoublyLoaded/index.jelly +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - -

      ${%Failed to load JNA}

      -

      ${%blurb}

      -
      ${it.stackTraceString}
      - - - diff --git a/core/src/main/resources/hudson/util/JNADoublyLoaded/index.properties b/core/src/main/resources/hudson/util/JNADoublyLoaded/index.properties deleted file mode 100644 index cf8fe45ca348..000000000000 --- a/core/src/main/resources/hudson/util/JNADoublyLoaded/index.properties +++ /dev/null @@ -1,24 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -blurb=Another instance of JNA is already loaded in another classloader, thereby making it impossible for Jenkins \ - to load its own copy. See Wiki for more details. diff --git a/core/src/main/resources/hudson/util/JNADoublyLoaded/index_bg.properties b/core/src/main/resources/hudson/util/JNADoublyLoaded/index_bg.properties deleted file mode 100644 index 58ec93527524..000000000000 --- a/core/src/main/resources/hudson/util/JNADoublyLoaded/index_bg.properties +++ /dev/null @@ -1,31 +0,0 @@ -# The MIT License -# -# Bulgarian translation: Copyright (c) 2016, 2017, Alexander Shopov -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Failed\ to\ load\ JNA=\ - JNA \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u0437\u0430\u0440\u0435\u0434\u0438 -# Another instance of JNA is already loaded in another classloader, thereby making it impossible for Jenkins \ -# to load its own copy. See Wiki for more details. -blurb=\ - JNA \u0432\u0435\u0447\u0435 \u0435 \u0437\u0430\u0440\u0435\u0434\u0435\u043d \u043e\u0442 \u0434\u0440\u0443\u0433 \u043a\u043b\u0430\u0441 \u0437\u0430 \u0437\u0430\u0440\u0435\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u043a\u043b\u0430\u0441\u043e\u0432\u0435 \u0438 Jenkins \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430\ - \u0437\u0430\u0440\u0435\u0434\u0438 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u0430\u0442\u0430 \u0441\u0438 \u0432\u0435\u0440\u0441\u0438\u044f \u043d\u0430 JNA. \u0417\u0430 \u043f\u043e\u0432\u0435\u0447\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \ - \u043f\u0440\u0435\u0433\u043b\u0435\u0434\u0430\u0439\u0442\u0435 \u0443\u0438\u043a\u0438\u0442\u043e. diff --git a/core/src/main/resources/hudson/util/JNADoublyLoaded/index_da.properties b/core/src/main/resources/hudson/util/JNADoublyLoaded/index_da.properties deleted file mode 100644 index 233d05d629e2..000000000000 --- a/core/src/main/resources/hudson/util/JNADoublyLoaded/index_da.properties +++ /dev/null @@ -1,24 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc. Kohsuke Kawaguchi. Knud Poulsen. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -blurb=En anden instans af JNA er allerede indl\u00e6st i en anden classloader, dermed er det umuligt for Jenkins -Failed\ to\ load\ JNA=Kunne ikke indl\u00e6se JNA diff --git a/core/src/main/resources/hudson/util/JNADoublyLoaded/index_de.properties b/core/src/main/resources/hudson/util/JNADoublyLoaded/index_de.properties deleted file mode 100644 index c043e4f426af..000000000000 --- a/core/src/main/resources/hudson/util/JNADoublyLoaded/index_de.properties +++ /dev/null @@ -1,28 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Simon Wiest -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Failed\ to\ load\ JNA=Java Native Access (JNA) konnte nicht geladen werden -blurb=\ - Eine JNA-Instanz wurde bereits von einem anderen Classloader geladen. \ - Dies hindert Jenkins daran, seine eigene JNA-Instanz zu laden. \ - Mehr... - diff --git a/core/src/main/resources/hudson/util/JNADoublyLoaded/index_es.properties b/core/src/main/resources/hudson/util/JNADoublyLoaded/index_es.properties deleted file mode 100644 index f04bc938f6ee..000000000000 --- a/core/src/main/resources/hudson/util/JNADoublyLoaded/index_es.properties +++ /dev/null @@ -1,25 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -blurb=Otra instancia de JNA est en ejecucin, echa un vistazo a esta \ - pagina para ver mas detalles. -Failed\ to\ load\ JNA=Fallo al cargar JNA diff --git a/core/src/main/resources/hudson/util/JNADoublyLoaded/index_it.properties b/core/src/main/resources/hudson/util/JNADoublyLoaded/index_it.properties deleted file mode 100644 index 6ccfb9a2d401..000000000000 --- a/core/src/main/resources/hudson/util/JNADoublyLoaded/index_it.properties +++ /dev/null @@ -1,29 +0,0 @@ -# The MIT License -# -# Italian localization plugin for Jenkins -# Copyright 2020 Alessandro Menti -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -blurb=Un''altra istanza di JNA gi caricata in un altro classloader, il che \ - fa s che il caricamento della propria copia da parte di Jenkins sia \ - impossibile. \ - Si \ - veda il wiki per ulteriori dettagli. -Failed\ to\ load\ JNA=Caricamento di JNA non riuscito diff --git a/core/src/main/resources/hudson/util/JNADoublyLoaded/index_ja.properties b/core/src/main/resources/hudson/util/JNADoublyLoaded/index_ja.properties deleted file mode 100644 index fb66f542ea68..000000000000 --- a/core/src/main/resources/hudson/util/JNADoublyLoaded/index_ja.properties +++ /dev/null @@ -1,25 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Seiji Sogabe -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Failed\ to\ load\ JNA=Java Native Access (JNA) \u306E\u30ED\u30FC\u30C9\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002 -blurb=\u5225\u306E\u30AF\u30E9\u30B9\u30ED\u30FC\u30C0\u30FC\u304CJNA\u306E\u30A4\u30F3\u30B9\u30BF\u30F3\u30B9\u3092\u65E2\u306B\u30ED\u30FC\u30C9\u3057\u3066\u3044\u307E\u3059\u3002\u305D\u306E\u305F\u3081\u3001Jenkins\u304C\u30ED\u30FC\u30C9\u3059\u308B\u3053\u3068\u304C\u3067\u304D\u307E\u305B\u3093\u3002\ - \u8A73\u7D30\u306F\u3001Wiki\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002 diff --git a/core/src/main/resources/hudson/util/JNADoublyLoaded/index_pt_BR.properties b/core/src/main/resources/hudson/util/JNADoublyLoaded/index_pt_BR.properties deleted file mode 100644 index 8238947faa20..000000000000 --- a/core/src/main/resources/hudson/util/JNADoublyLoaded/index_pt_BR.properties +++ /dev/null @@ -1,27 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc., Cleiber Silva, Fernando Boaglio -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Failed\ to\ load\ JNA= -# Another instance of JNA is already loaded in another classloader, thereby making it impossible for Jenkins \ -# to load its own copy. See Wiki for more details. -blurb=Outra inst\u00e2ncia do JNA j\u00e1 est\u00e1 carregada em outro Classloader, impossibilitando ao Jenkins \ - diff --git a/core/src/main/resources/hudson/util/JNADoublyLoaded/index_sr.properties b/core/src/main/resources/hudson/util/JNADoublyLoaded/index_sr.properties deleted file mode 100644 index 89c5a8befb81..000000000000 --- a/core/src/main/resources/hudson/util/JNADoublyLoaded/index_sr.properties +++ /dev/null @@ -1,4 +0,0 @@ -# This file is under the MIT License by authors - -Failed\ to\ load\ JNA=\u041D\u0438\u0458\u0435 \u043C\u043E\u0433\u043B\u043E \u0443\u0447\u0438\u0442\u0430\u0442\u0438 JNA -blurb=\u0414\u0440\u0443\u0433\u0430 \u0438\u043D\u0441\u0442\u0430\u043D\u0446\u0430 JNA \u0458\u0435 \u0432\u0435\u045B \u0443\u0447\u0438\u0442\u0430\u043D\u0430 \u0443 classloader, \u043F\u043E\u0442\u043E\u043C Jenkins \u043D\u0435\u043C\u043E\u0436\u0435 \u0443\u0447\u0438\u0442\u0430\u0442\u0438 \u0441\u0432\u043E\u0458\u0443 \u043A\u043E\u043F\u0438\u0458\u0443. \u041F\u0440\u0435\u0433\u043B\u0435\u0434\u0430\u0458\u0442\u0435 \u0412\u0438\u043A\u0438 \u0437\u0430 \u0432\u0438\u0448\u0435 \u0434\u0435\u0442\u0430\u0459\u0430. diff --git a/core/src/main/resources/hudson/util/JNADoublyLoaded/index_zh_TW.properties b/core/src/main/resources/hudson/util/JNADoublyLoaded/index_zh_TW.properties deleted file mode 100644 index 9d12da7613fd..000000000000 --- a/core/src/main/resources/hudson/util/JNADoublyLoaded/index_zh_TW.properties +++ /dev/null @@ -1,26 +0,0 @@ -# The MIT License -# -# Copyright (c) 2013, Chunghwa Telecom Co., Ltd., Pei-Tang Huang -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Failed\ to\ load\ JNA=JNA \u8f09\u5165\u5931\u6557 -blurb=\ - \u5df2\u7d93\u6709\u5176\u4ed6 ClassLoader \u8f09\u5165\u4e86 JNA\uff0cJenkins \u56e0\u6b64\u7121\u6cd5\u8f09\u5165\u81ea\u5df1\u7684\u7248\u672c\u3002\ - \u8acb\u53c3\u8003 Wiki \u4e0a\u7684\u8a73\u7d30\u8cc7\u6599\u3002 diff --git a/core/src/main/resources/hudson/util/Messages_pt_BR.properties b/core/src/main/resources/hudson/util/Messages_pt_BR.properties index 15041e9fda10..ca93ac2c6892 100644 --- a/core/src/main/resources/hudson/util/Messages_pt_BR.properties +++ b/core/src/main/resources/hudson/util/Messages_pt_BR.properties @@ -20,19 +20,20 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -# Failed to check ClockDifference.Failed=Falha na checagem -# \ ahead -ClockDifference.Ahead={0} \u00e0 frente -# In sync +ClockDifference.Ahead={0} \u00E0 frente ClockDifference.InSync=Em sincronia -# \ behind -ClockDifference.Behind={0} atr\u00e1s -# (show details) +ClockDifference.Behind={0} atr\u00E1s FormValidation.Error.Details=(mostrar detahes) -# Saved HttpResponses.Saved=Salvo -# Did not manage to validate {0} (may be too slow) -FormFieldValidator.did_not_manage_to_validate_may_be_too_sl=N\u00e3o conseguiu validar {0} (pode ser muito lento) -# Required -FormValidation.ValidateRequired=Obrigat\u00f3rio +FormFieldValidator.did_not_manage_to_validate_may_be_too_sl=N\u00E3o conseguiu validar {0} (pode ser muito lento) +FormValidation.ValidateRequired=Obrigat\u00F3rio +Retrier.Attempt=Tentativa #{0} para tomar a a\u00E7\u00E3o {1} +Retrier.Success=Tomou a a\u00E7\u00E3o {0} com sucesso na tentativa #{1} +Retrier.NoSuccess=Tentou a a\u00E7\u00E3o {0} por {1} vez(es) sem sucesso +Retrier.ExceptionFailed=A tentativa #{0} para tomar a a\u00E7\u00E3o {1} falhou com a seguinte exce\u00E7\u00E3o permitida: +Retrier.Interruption=As tentivas de tomar a a\u00E7\u00E3o {0} tem sido interrompidas +Retrier.ExceptionThrown=A tentativa #{0} para tomar a a\u00E7\u00E3o {1} lan\u00E7ou uma exce\u00E7\u00E3o n\u00E3o permitida, lan\u00E7ando novamente +Retrier.AttemptFailed=A tentativa #{0} para tomar a a\u00E7\u00E3o {1} falhou +Retrier.Sleeping=Aguardando por {0} milisegundos antes de uma nova tentativa para a\u00E7\u00E3o {1} +Retrier.CallingListener=Chamando o ouvinte da exce\u00E7\u00E3o permitida ''{0}'' na tentativa #{1} para tomar a a\u00E7\u00E3o {2} diff --git a/core/src/main/resources/hudson/util/NoHomeDir/index.properties b/core/src/main/resources/hudson/util/NoHomeDir/index.properties index c54b6adbcc22..0cce4771c4dc 100644 --- a/core/src/main/resources/hudson/util/NoHomeDir/index.properties +++ b/core/src/main/resources/hudson/util/NoHomeDir/index.properties @@ -23,8 +23,8 @@ errorMessage.1=\ Unable to create the home directory \u2018{0}\u2019. This is most likely a permission problem. errorMessage.2=\ - To change the home directory, use JENKINS_HOME environment variable or set the \ - JENKINS_HOME system property. \ - See Container-specific documentation \ + To change the home directory, use JENKINS_HOME environment variable or set the \ + JENKINS_HOME system property. \ + See Container-specific documentation \ for more details of how to do this. diff --git a/core/src/main/resources/hudson/util/NoHomeDir/index_bg.properties b/core/src/main/resources/hudson/util/NoHomeDir/index_bg.properties index 290dcb28c673..7d4351b9e6f9 100644 --- a/core/src/main/resources/hudson/util/NoHomeDir/index_bg.properties +++ b/core/src/main/resources/hudson/util/NoHomeDir/index_bg.properties @@ -26,15 +26,15 @@ errorMessage.1=\ \u0414\u043e\u043c\u0430\u0448\u043d\u0430\u0442\u0430 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u201e{0}\u201c \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0431\u044a\u0434\u0435 \u0441\u044a\u0437\u0434\u0430\u0434\u0435\u043d\u0430. \u041d\u0430\u0439-\u0447\u0435\u0441\u0442\u0430\u0442\u0430 \u043f\u0440\u0438\u0447\u0438\u043d\u0430 \u0441\u0430\ \u043f\u0440\u0430\u0432\u0430\u0442\u0430 \u0437\u0430 \u0434\u043e\u0441\u0442\u044a\u043f \u0434\u043e \u0444\u0430\u0439\u043b\u043e\u0432\u0435\u0442\u0435. # \ -# To change the home directory, use JENKINS_HOME environment variable or set the \ -# JENKINS_HOME system property. \ -# See Container-specific documentation \ +# To change the home directory, use JENKINS_HOME environment variable or set the \ +# JENKINS_HOME system property. \ +# See Container-specific documentation \ # for more details of how to do this. errorMessage.2=\ \u041c\u043e\u0436\u0435 \u0434\u0430 \u0441\u043c\u0435\u043d\u0438\u0442\u0435 \u0434\u043e\u043c\u0430\u0448\u043d\u0430\u0442\u0430 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u0447\u0440\u0435\u0437 \u043f\u0440\u043e\u043c\u0435\u043d\u043b\u0438\u0432\u0430\u0442\u0430 \u043d\u0430 \u0441\u0440\u0435\u0434\u0430\u0442\u0430\ - JENKINS_HOME \u0438\u043b\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u043e\u0442\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u0441\u044a\u0441 \u0441\u044a\u0449\u043e\u0442\u043e \u0438\u043c\u0435.\ + JENKINS_HOME \u0438\u043b\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u043e\u0442\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u0441\u044a\u0441 \u0441\u044a\u0449\u043e\u0442\u043e \u0438\u043c\u0435.\ \u0417\u0430 \u043f\u043e\u0432\u0435\u0447\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043a\u0430\u043a \u0441\u0435 \u043f\u0440\u0430\u0432\u0438 \u0442\u043e\u0432\u0430, \u043f\u0440\u0435\u0433\u043b\u0435\u0434\u0430\u0439\u0442\u0435\ - \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f\u0442\u0430\ + \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f\u0442\u0430\ \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u0447\u043d\u0430 \u0437\u0430 \u043e\u0442\u0434\u0435\u043b\u043d\u0438\u0442\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0438 \u0437\u0430 \u0441\u044a\u0440\u0432\u043b\u0435\u0442\u0438. Error=\ \u0413\u0440\u0435\u0448\u043a\u0430 diff --git a/core/src/main/resources/hudson/util/NoHomeDir/index_da.properties b/core/src/main/resources/hudson/util/NoHomeDir/index_da.properties index 480533cc5050..4cc836f95818 100644 --- a/core/src/main/resources/hudson/util/NoHomeDir/index_da.properties +++ b/core/src/main/resources/hudson/util/NoHomeDir/index_da.properties @@ -20,7 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -errorMessage.2=For at \u00e6ndre Jenkins''s hjemmedirektorie benyttes JENKINS_HOME milj\u00f8variablen \ -eller s\u00e6t JENKINS_HOME systemegenskaben. +errorMessage.2=For at \u00e6ndre Jenkins''s hjemmedirektorie benyttes JENKINS_HOME milj\u00f8variablen \ +eller s\u00e6t JENKINS_HOME systemegenskaben. errorMessage.1=Ikke i stand til at oprette hjemmedirektoriet ''{0}''. Dette er h\u00f8jst sandsynligt et rettighedproblem. Error=Fejl diff --git a/core/src/main/resources/hudson/util/NoHomeDir/index_de.properties b/core/src/main/resources/hudson/util/NoHomeDir/index_de.properties index 055a854e3555..b89646ada77e 100644 --- a/core/src/main/resources/hudson/util/NoHomeDir/index_de.properties +++ b/core/src/main/resources/hudson/util/NoHomeDir/index_de.properties @@ -25,8 +25,8 @@ errorMessage.1=\ Das Stammverzeichnis \u201E{0}\u201C konnte nicht angelegt werden. In den meisten Fllen ist \ dies ein Dateirechte-Problem. errorMessage.2=\ - Um das Stammverzeichnis zu ndern, verwenden Sie die Umgebungsvariable JENKINS_HOME \ - oder die Java-Systemeigenschaft JENKINS_HOME. Weitere Details entnehmen Sie \ - der containerspezifischen \ + Um das Stammverzeichnis zu ndern, verwenden Sie die Umgebungsvariable JENKINS_HOME \ + oder die Java-Systemeigenschaft JENKINS_HOME. Weitere Details entnehmen Sie \ + der containerspezifischen \ Jenkins-Dokumentation. diff --git a/core/src/main/resources/hudson/util/NoHomeDir/index_es.properties b/core/src/main/resources/hudson/util/NoHomeDir/index_es.properties index 2cdd09a469d5..46cd6c3a150a 100644 --- a/core/src/main/resources/hudson/util/NoHomeDir/index_es.properties +++ b/core/src/main/resources/hudson/util/NoHomeDir/index_es.properties @@ -23,7 +23,7 @@ errorMessage.1=\ No fu posible crear el directorio principal ''{0}''. Normalmente es un problema de permisos. errorMessage.2=\ - Para cambiar el directorio principal usa la variable de entorno JENKINS_HOME \ - Tienes mas detalles de cmo hacerlo en: Container-specific documentation + Para cambiar el directorio principal usa la variable de entorno JENKINS_HOME \ + Tienes mas detalles de cmo hacerlo en: Container-specific documentation Error=Error diff --git a/core/src/main/resources/hudson/util/NoHomeDir/index_it.properties b/core/src/main/resources/hudson/util/NoHomeDir/index_it.properties index dce711728fc6..1a9b75f4273d 100644 --- a/core/src/main/resources/hudson/util/NoHomeDir/index_it.properties +++ b/core/src/main/resources/hudson/util/NoHomeDir/index_it.properties @@ -25,8 +25,8 @@ Error=Errore errorMessage.1=Impossibile creare la directory home "{0}". Questo molto \ probabilmente un problema di permessi. errorMessage.2=Per modificare la directory home, utilizzare la variabile \ - d''ambiente JENKINS_HOME o impostare la propriet di sistema \ - JENKINS_HOME. Si veda la \ - documentazione \ + d''ambiente JENKINS_HOME o impostare la propriet di sistema \ + JENKINS_HOME. Si veda la \ + documentazione \ specifica dei container per ulteriori dettagli su come eseguire \ quest''operazione. diff --git a/core/src/main/resources/hudson/util/NoHomeDir/index_ja.properties b/core/src/main/resources/hudson/util/NoHomeDir/index_ja.properties index 9a4622cb1c32..dd21d0913d97 100644 --- a/core/src/main/resources/hudson/util/NoHomeDir/index_ja.properties +++ b/core/src/main/resources/hudson/util/NoHomeDir/index_ja.properties @@ -24,9 +24,9 @@ Error=\u30A8\u30E9\u30FC errorMessage.1=\ \u30DB\u30FC\u30E0\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA ''{0}'' \u3092\u4F5C\u6210\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u304A\u305D\u3089\u304F\u30D1\u30FC\u30DF\u30C3\u30B7\u30E7\u30F3\u306E\u554F\u984C\u3067\u3059\u3002 errorMessage.2=\ - \u30DB\u30FC\u30E0\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3092\u5909\u66F4\u3059\u308B\u306B\u306F\u3001\u74B0\u5883\u5909\u6570\u306EJENKINS_HOME\u304B\u3001\u30B7\u30B9\u30C6\u30E0\u30D7\u30ED\u30D1\u30C6\u30A3\u306E \ - JENKINS_HOME\u3092\u8A2D\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002\ - \u8A2D\u5B9A\u65B9\u6CD5\u306B\u3064\u3044\u3066\u306F\u3001Container-specific documentation \ + \u30DB\u30FC\u30E0\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3092\u5909\u66F4\u3059\u308B\u306B\u306F\u3001\u74B0\u5883\u5909\u6570\u306EJENKINS_HOME\u304B\u3001\u30B7\u30B9\u30C6\u30E0\u30D7\u30ED\u30D1\u30C6\u30A3\u306E \ + JENKINS_HOME\u3092\u8A2D\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002\ + \u8A2D\u5B9A\u65B9\u6CD5\u306B\u3064\u3044\u3066\u306F\u3001Container-specific documentation \ \u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002 diff --git a/core/src/main/resources/hudson/util/NoHomeDir/index_pt_BR.properties b/core/src/main/resources/hudson/util/NoHomeDir/index_pt_BR.properties index ea8295abc9c8..e079d2d7afe0 100644 --- a/core/src/main/resources/hudson/util/NoHomeDir/index_pt_BR.properties +++ b/core/src/main/resources/hudson/util/NoHomeDir/index_pt_BR.properties @@ -23,10 +23,10 @@ Error=Erro # Unable to create the home directory \u2018{0}\u2019. This is most likely a permission problem. errorMessage.1=N\u00e3o foi poss\u00edvel criar o diret\u00f3rio principal "{0}". Provavelmente um por problema de permiss\u00e3o. -# To change the home directory, use JENKINS_HOME environment variable or set the \ -# JENKINS_HOME system property. \ -# See Container-specific documentation \ +# To change the home directory, use JENKINS_HOME environment variable or set the \ +# JENKINS_HOME system property. \ +# See Container-specific documentation \ # for more details of how to do this. -errorMessage.2= Para mudar o diret\u00f3rio principal, use a vari\u00e1vel de ambiente JENKINS_HOME \ - Veja a documenta\u00e7\u00e3o especifica para o servidor \ +errorMessage.2= Para mudar o diret\u00f3rio principal, use a vari\u00e1vel de ambiente JENKINS_HOME \ + Veja a documenta\u00e7\u00e3o especifica para o servidor \ para mais detalhes de como fazer isto. diff --git a/core/src/main/resources/hudson/util/NoHomeDir/index_sr.properties b/core/src/main/resources/hudson/util/NoHomeDir/index_sr.properties index 6297d8414acb..d34f3267dfac 100644 --- a/core/src/main/resources/hudson/util/NoHomeDir/index_sr.properties +++ b/core/src/main/resources/hudson/util/NoHomeDir/index_sr.properties @@ -3,7 +3,7 @@ Error=\u0413\u0440\u0435\u0448\u043A\u0430 errorMessage.1=\u041D\u0438\u0458\u0435 \u043C\u043E\u0433\u0443\u045B\u0435 \u043A\u0440\u0435\u0438\u0440\u0430\u0442\u0438 \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0458\u0443\u043C \u2018{0}\u2019, \u0432\u0435\u0440\u043E\u0432\u0430\u0442\u043D\u043E \u0437\u0431\u043E\u0433 \u043D\u0435\u0434\u043E\u0441\u0442\u0430\u0442\u043A\u0430 \u043F\u0440\u0430\u0432\u0430. errorMessage.2=\ - \u0414\u0430 \u043F\u0440\u043E\u043C\u0435\u043D\u0438\u0442\u0435 \u0433\u043B\u0430\u0432\u043D\u0438 \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0458\u0443\u043C, \u043A\u043E\u0440\u0438\u0441\u0442\u0438\u0442\u0435 JENKINS_HOME \u043F\u0440\u043E\u043C\u0435\u043D\u0459\u0438\u0432\u0443 \u0438\u043B\u0438 \ - JENKINS_HOME \u0441\u0438\u0441\u0442\u0435\u043C\u0441\u043A\u0443 \u043F\u043E\u0441\u0442\u0430\u0432\u043A\u0443. \ - \u041F\u0440\u043E\u0447\u0438\u0442\u0430\u0458\u0442\u0435 \u0414\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430\u0446\u0438\u0458\u0443 \u043E \u043A\u043E\u043D\u0442\u0435\u0458\u043D\u0435\u0440\u0438\u043C\u0430 \ + \u0414\u0430 \u043F\u0440\u043E\u043C\u0435\u043D\u0438\u0442\u0435 \u0433\u043B\u0430\u0432\u043D\u0438 \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0458\u0443\u043C, \u043A\u043E\u0440\u0438\u0441\u0442\u0438\u0442\u0435 JENKINS_HOME \u043F\u0440\u043E\u043C\u0435\u043D\u0459\u0438\u0432\u0443 \u0438\u043B\u0438 \ + JENKINS_HOME \u0441\u0438\u0441\u0442\u0435\u043C\u0441\u043A\u0443 \u043F\u043E\u0441\u0442\u0430\u0432\u043A\u0443. \ + \u041F\u0440\u043E\u0447\u0438\u0442\u0430\u0458\u0442\u0435 \u0414\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430\u0446\u0438\u0458\u0443 \u043E \u043A\u043E\u043D\u0442\u0435\u0458\u043D\u0435\u0440\u0438\u043C\u0430 \ \u0437\u0430 \u0458\u043E\u0448 \u0434\u0435\u0442\u0430\u0459\u0430. diff --git a/core/src/main/resources/hudson/util/NoHomeDir/index_zh_TW.properties b/core/src/main/resources/hudson/util/NoHomeDir/index_zh_TW.properties index 9ffa047ddcfc..7546dda3ab11 100644 --- a/core/src/main/resources/hudson/util/NoHomeDir/index_zh_TW.properties +++ b/core/src/main/resources/hudson/util/NoHomeDir/index_zh_TW.properties @@ -26,4 +26,4 @@ errorMessage.1=\ errorMessage.2=\ \u8981\u4fee\u6539\u4e3b\u76ee\u9304\uff0c\u8acb\u8a2d\u5b9a JENKINS_HOME \u74b0\u5883\u8b8a\u6578\u6216 JENKINS_HOME \u7cfb\u7d71\u5c6c\u6027\u3002\ \u8a73\u7d30\u4f5c\u6cd5\u8acb\u53c3\u8003 \ - Container \u76f8\u95dc\u6587\u4ef6\u3002 + Container \u76f8\u95dc\u6587\u4ef6\u3002 diff --git a/core/src/main/resources/hudson/views/BuildButtonColumn/column.jelly b/core/src/main/resources/hudson/views/BuildButtonColumn/column.jelly index f57d537f2e58..4ada9dbac120 100644 --- a/core/src/main/resources/hudson/views/BuildButtonColumn/column.jelly +++ b/core/src/main/resources/hudson/views/BuildButtonColumn/column.jelly @@ -24,32 +24,25 @@ THE SOFTWARE. -
      diff --git a/core/src/main/resources/hudson/views/BuildButtonColumn/columnHeader.jelly b/core/src/main/resources/hudson/views/BuildButtonColumn/columnHeader.jelly index 1d7825c40c12..7da40bad1859 100644 --- a/core/src/main/resources/hudson/views/BuildButtonColumn/columnHeader.jelly +++ b/core/src/main/resources/hudson/views/BuildButtonColumn/columnHeader.jelly @@ -22,8 +22,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --> - - - \ No newline at end of file + + diff --git a/core/src/main/resources/hudson/views/LastDurationColumn/columnHeader_ar.properties b/core/src/main/resources/hudson/views/LastDurationColumn/columnHeader_ar.properties deleted file mode 100644 index a1da739079ec..000000000000 --- a/core/src/main/resources/hudson/views/LastDurationColumn/columnHeader_ar.properties +++ /dev/null @@ -1,23 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Last\ Duration=\u0622\u062E\u0631 \u0645\u062F\u0629 diff --git a/core/src/main/resources/hudson/views/LastDurationColumn/columnHeader_zh_TW.properties b/core/src/main/resources/hudson/views/LastDurationColumn/columnHeader_zh_TW.properties index b30982c81430..fa91636bae0c 100644 --- a/core/src/main/resources/hudson/views/LastDurationColumn/columnHeader_zh_TW.properties +++ b/core/src/main/resources/hudson/views/LastDurationColumn/columnHeader_zh_TW.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Last\ Duration=\u4E0A\u6B21\u5EFA\u7F6E\u82B1\u8CBB\u6642\u9593 +Last\ Duration=\u4e0a\u6b21\u8cbb\u6642 diff --git a/core/src/main/resources/hudson/views/LastDurationColumn/column_ar.properties b/core/src/main/resources/hudson/views/LastDurationColumn/column_ar.properties deleted file mode 100644 index b4ccf5f39841..000000000000 --- a/core/src/main/resources/hudson/views/LastDurationColumn/column_ar.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -N/A=\u063A\u064A\u0631 \u0645\u0648\u062C\u0648\u062F diff --git a/core/src/main/resources/hudson/views/LastFailureColumn/column.jelly b/core/src/main/resources/hudson/views/LastFailureColumn/column.jelly index 43544f10bb35..cfecd8389b02 100644 --- a/core/src/main/resources/hudson/views/LastFailureColumn/column.jelly +++ b/core/src/main/resources/hudson/views/LastFailureColumn/column.jelly @@ -29,7 +29,7 @@ THE SOFTWARE. ${lfBuild.timestampString} - - ${lfBuild.displayName} + ${lfBuild.displayName} ${%N/A} diff --git a/core/src/main/resources/hudson/views/LastFailureColumn/columnHeader_ar.properties b/core/src/main/resources/hudson/views/LastFailureColumn/columnHeader_ar.properties deleted file mode 100644 index d53b9c71ae6f..000000000000 --- a/core/src/main/resources/hudson/views/LastFailureColumn/columnHeader_ar.properties +++ /dev/null @@ -1,23 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Last\ Failure=\u0622\u062E\u0631 \u0641\u0634\u0644 diff --git a/core/src/main/resources/hudson/views/LastFailureColumn/columnHeader_zh_TW.properties b/core/src/main/resources/hudson/views/LastFailureColumn/columnHeader_zh_TW.properties index ed22fe7af336..b7be8bc4fddf 100644 --- a/core/src/main/resources/hudson/views/LastFailureColumn/columnHeader_zh_TW.properties +++ b/core/src/main/resources/hudson/views/LastFailureColumn/columnHeader_zh_TW.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Last\ Failure=\u4E0A\u6B21\u5931\u6557\u6642\u9593 +Last\ Failure=\u4e0a\u6b21\u5931\u6557 diff --git a/core/src/main/resources/hudson/views/LastFailureColumn/column_ar.properties b/core/src/main/resources/hudson/views/LastFailureColumn/column_ar.properties deleted file mode 100644 index 6433cac03e64..000000000000 --- a/core/src/main/resources/hudson/views/LastFailureColumn/column_ar.properties +++ /dev/null @@ -1,23 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -N/A=\u063A\u064A\u0631 \u0645\u0648\u062C\u0648\u062F diff --git a/core/src/main/resources/hudson/views/LastStableColumn/column.jelly b/core/src/main/resources/hudson/views/LastStableColumn/column.jelly index 6700bd42d65e..7bbc2dcc0868 100644 --- a/core/src/main/resources/hudson/views/LastStableColumn/column.jelly +++ b/core/src/main/resources/hudson/views/LastStableColumn/column.jelly @@ -29,7 +29,7 @@ THE SOFTWARE. ${lstBuild.timestampString} - - ${lstBuild.displayName} + ${lstBuild.displayName} ${%N/A} diff --git a/core/src/main/resources/hudson/views/LastStableColumn/columnHeader_zh_TW.properties b/core/src/main/resources/hudson/views/LastStableColumn/columnHeader_zh_TW.properties index 0130a5f55447..44d870e85175 100644 --- a/core/src/main/resources/hudson/views/LastStableColumn/columnHeader_zh_TW.properties +++ b/core/src/main/resources/hudson/views/LastStableColumn/columnHeader_zh_TW.properties @@ -20,4 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Last\ Stable=\u4e0a\u6b21\u7a69\u5b9a\u6642\u9593 +Last\ Stable=\u4e0a\u6b21\u7a69\u5b9a diff --git a/core/src/main/resources/hudson/views/LastStableColumn/column_zh_TW.properties b/core/src/main/resources/hudson/views/LastStableColumn/column_zh_TW.properties index 4b9074325e4e..3b799f647ec8 100644 --- a/core/src/main/resources/hudson/views/LastStableColumn/column_zh_TW.properties +++ b/core/src/main/resources/hudson/views/LastStableColumn/column_zh_TW.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2013, Chunghwa Telecom Co., Ltd., Pei-Tang Huang +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -N/A=N/A +N/A=\u7121 diff --git a/core/src/main/resources/hudson/views/LastSuccessColumn/column.jelly b/core/src/main/resources/hudson/views/LastSuccessColumn/column.jelly index bed1c1363c15..7b951f4a1296 100644 --- a/core/src/main/resources/hudson/views/LastSuccessColumn/column.jelly +++ b/core/src/main/resources/hudson/views/LastSuccessColumn/column.jelly @@ -29,7 +29,7 @@ THE SOFTWARE. ${lsBuild.timestampString} - - ${lsBuild.displayName} + ${lsBuild.displayName} ${%N/A} diff --git a/core/src/main/resources/hudson/views/LastSuccessColumn/columnHeader_ar.properties b/core/src/main/resources/hudson/views/LastSuccessColumn/columnHeader_ar.properties deleted file mode 100644 index 4aee979c2206..000000000000 --- a/core/src/main/resources/hudson/views/LastSuccessColumn/columnHeader_ar.properties +++ /dev/null @@ -1,23 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Last\ Success=\u0622\u062E\u0631 \u0646\u062C\u0627\u062D diff --git a/core/src/main/resources/hudson/views/LastSuccessColumn/columnHeader_zh_TW.properties b/core/src/main/resources/hudson/views/LastSuccessColumn/columnHeader_zh_TW.properties index 97e1b9697410..e8a17066c544 100644 --- a/core/src/main/resources/hudson/views/LastSuccessColumn/columnHeader_zh_TW.properties +++ b/core/src/main/resources/hudson/views/LastSuccessColumn/columnHeader_zh_TW.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Last\ Success=\u4e0a\u6b21\u6210\u529f\u6642\u9593 +Last\ Success=\u4e0a\u6b21\u6210\u529f diff --git a/core/src/main/resources/hudson/views/LastSuccessColumn/column_ar.properties b/core/src/main/resources/hudson/views/LastSuccessColumn/column_ar.properties deleted file mode 100644 index 6433cac03e64..000000000000 --- a/core/src/main/resources/hudson/views/LastSuccessColumn/column_ar.properties +++ /dev/null @@ -1,23 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -N/A=\u063A\u064A\u0631 \u0645\u0648\u062C\u0648\u062F diff --git a/core/src/main/resources/hudson/views/LastSuccessColumn/column_zh_TW.properties b/core/src/main/resources/hudson/views/LastSuccessColumn/column_zh_TW.properties index ccabb0279de4..3b799f647ec8 100644 --- a/core/src/main/resources/hudson/views/LastSuccessColumn/column_zh_TW.properties +++ b/core/src/main/resources/hudson/views/LastSuccessColumn/column_zh_TW.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,3 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. +N/A=\u7121 diff --git a/core/src/main/resources/hudson/views/Messages_pt_BR.properties b/core/src/main/resources/hudson/views/Messages_pt_BR.properties index 963754b4feee..95a75ed3bf25 100644 --- a/core/src/main/resources/hudson/views/Messages_pt_BR.properties +++ b/core/src/main/resources/hudson/views/Messages_pt_BR.properties @@ -21,23 +21,15 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -# Last Duration -LastDurationColumn.DisplayName=\u00daltima dura\u00e7\u00e3o -# Status -StatusColumn.DisplayName=Status -# Build Button -BuildButtonColumn.DisplayName=Bot\u00e3o de builds -# Weather +LastDurationColumn.DisplayName=\u00DAltima dura\u00E7\u00E3o +StatusColumn.DisplayName=Estado +BuildButtonColumn.DisplayName=Bot\u00E3o de constru\u00E7\u00F5es WeatherColumn.DisplayName=Tempo -# Last Success -LastSuccessColumn.DisplayName=\u00daltimo sucesso -# Last Failure -LastFailureColumn.DisplayName=\u00daltima falha -# Last Stable -LastStableColumn.DisplayName=\u00daltimo est\u00e1vel - -DefaultMyViewsTabsBar.DisplayName=Aba com minhas views por padr\u00e3o - -DefaultViewsTabsBar.DisplayName=Aba com as views por padr\u00e3o - +LastSuccessColumn.DisplayName=\u00DAltimo sucesso +LastFailureColumn.DisplayName=\u00DAltima falha +LastStableColumn.DisplayName=\u00DAltimo est\u00E1vel +DefaultMyViewsTabsBar.DisplayName=Aba com as minhas vis\u00F5es por padr\u00E3o +DefaultViewsTabsBar.DisplayName=Aba com as vis\u00F5es por padr\u00E3o JobColumn.DisplayName=Nome +StatusFilter.DisplayName=Filtro de estado +GlobalDefaultViewConfiguration.ViewDoesNotExist=A vis\u00E3o especificada n\u00E3o existe: {0} diff --git a/core/src/main/resources/hudson/views/Messages_zh_TW.properties b/core/src/main/resources/hudson/views/Messages_zh_TW.properties index cbc398c82c09..bfc5a99d5ace 100644 --- a/core/src/main/resources/hudson/views/Messages_zh_TW.properties +++ b/core/src/main/resources/hudson/views/Messages_zh_TW.properties @@ -22,11 +22,14 @@ BuildButtonColumn.DisplayName=\u5efa\u7f6e\u6309\u9215 JobColumn.DisplayName=\u540d\u7a31 -LastDurationColumn.DisplayName=\u4e0a\u6b21\u82b1\u8cbb\u6642\u9593 +LastDurationColumn.DisplayName=\u4e0a\u6b21\u8cbb\u6642 LastFailureColumn.DisplayName=\u4e0a\u6b21\u5931\u6557 LastStableColumn.DisplayName=\u4e0a\u6b21\u7a69\u5b9a LastSuccessColumn.DisplayName=\u4e0a\u6b21\u6210\u529f StatusColumn.DisplayName=\u72c0\u614b WeatherColumn.DisplayName=\u6c23\u8c61 -DefaultViewsTabsBar.DisplayName=\u9810\u8a2d\u8996\u666f\u7d22\u5f15\u6a19\u7c64\u5217 -DefaultMyViewsTabsBar.DisplayName=\u9810\u8a2d\u6211\u7684\u8996\u666f\u7d22\u5f15\u6a19\u7c64\u5217 +DefaultViewsTabsBar.DisplayName=\u9810\u8a2d\u8996\u666f\u9801\u7c64\u5217 +DefaultMyViewsTabsBar.DisplayName=\u9810\u8a2d\u6211\u7684\u8996\u666f\u9801\u7c64\u5217 +StatusFilter.DisplayName=\u72c0\u614b\u7be9\u9078 + +GlobalDefaultViewConfiguration.ViewDoesNotExist=\u6307\u5b9a\u7684\u8996\u666f\u4e0d\u5b58\u5728\: {0} diff --git a/core/src/main/resources/hudson/views/StatusColumn/column.jelly b/core/src/main/resources/hudson/views/StatusColumn/column.jelly index b6a772135675..5297d99809a3 100644 --- a/core/src/main/resources/hudson/views/StatusColumn/column.jelly +++ b/core/src/main/resources/hudson/views/StatusColumn/column.jelly @@ -23,6 +23,6 @@ THE SOFTWARE. --> - - + + \ No newline at end of file diff --git a/core/src/main/resources/hudson/views/StatusColumn/columnHeader.jelly b/core/src/main/resources/hudson/views/StatusColumn/columnHeader.jelly index d33a9422b899..12d2b4bfc2ec 100644 --- a/core/src/main/resources/hudson/views/StatusColumn/columnHeader.jelly +++ b/core/src/main/resources/hudson/views/StatusColumn/columnHeader.jelly @@ -24,5 +24,5 @@ THE SOFTWARE. - + \ No newline at end of file diff --git a/core/src/main/resources/hudson/views/StatusColumn/columnHeader_ar.properties b/core/src/main/resources/hudson/views/StatusColumn/columnHeader_ar.properties deleted file mode 100644 index 0204cee36b0c..000000000000 --- a/core/src/main/resources/hudson/views/StatusColumn/columnHeader_ar.properties +++ /dev/null @@ -1,23 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Status\ of\ the\ last\ build=\u062D\u0627\u0644\u0629 \u0622\u062E\u0631 \u0628\u0646\u0627\u0621 diff --git a/core/src/main/resources/hudson/views/StatusColumn/columnHeader_zh_TW.properties b/core/src/main/resources/hudson/views/StatusColumn/columnHeader_zh_TW.properties index 12bf85ff5d1c..c705d0bd24c8 100644 --- a/core/src/main/resources/hudson/views/StatusColumn/columnHeader_zh_TW.properties +++ b/core/src/main/resources/hudson/views/StatusColumn/columnHeader_zh_TW.properties @@ -22,3 +22,4 @@ # THE SOFTWARE. Status\ of\ the\ last\ build=\u4e0a\u6b21\u5efa\u7f6e\u72c0\u614b +S=S diff --git a/core/src/main/resources/hudson/views/StatusFilter/config.jelly b/core/src/main/resources/hudson/views/StatusFilter/config.jelly index bd4507ab0454..416c63b18b10 100644 --- a/core/src/main/resources/hudson/views/StatusFilter/config.jelly +++ b/core/src/main/resources/hudson/views/StatusFilter/config.jelly @@ -26,7 +26,7 @@ THE SOFTWARE. - ${%Enabled jobs only} ${%Disabled jobs only} diff --git a/core/src/main/resources/hudson/views/StatusFilter/config_pt_BR.properties b/core/src/main/resources/hudson/views/StatusFilter/config_pt_BR.properties new file mode 100644 index 000000000000..3ddcd532c4b0 --- /dev/null +++ b/core/src/main/resources/hudson/views/StatusFilter/config_pt_BR.properties @@ -0,0 +1,25 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Status\ Filter=Filtros\ de\ estado +Disabled\ jobs\ only=Somentes\ jobs\ desabilitados +Enabled\ jobs\ only=Somente\ jobs\ habilitados diff --git a/core/src/main/resources/hudson/views/StatusFilter/config_zh_TW.properties b/core/src/main/resources/hudson/views/StatusFilter/config_zh_TW.properties new file mode 100644 index 000000000000..b84b0a523fc5 --- /dev/null +++ b/core/src/main/resources/hudson/views/StatusFilter/config_zh_TW.properties @@ -0,0 +1,3 @@ +Enabled\ jobs\ only=\u53ea\u986f\u793a\u555f\u7528\u7684\u5de5\u4f5c +Disabled\ jobs\ only=\u53ea\u986f\u793a\u505c\u7528\u7684\u5de5\u4f5c +Status\ Filter=\u72c0\u614b\u7be9\u9078 diff --git a/core/src/main/resources/hudson/views/WeatherColumn/columnHeader.jelly b/core/src/main/resources/hudson/views/WeatherColumn/columnHeader.jelly index fd2224835d68..29af9277804e 100644 --- a/core/src/main/resources/hudson/views/WeatherColumn/columnHeader.jelly +++ b/core/src/main/resources/hudson/views/WeatherColumn/columnHeader.jelly @@ -24,5 +24,7 @@ THE SOFTWARE. - + \ No newline at end of file diff --git a/core/src/main/resources/hudson/views/WeatherColumn/columnHeader_ar.properties b/core/src/main/resources/hudson/views/WeatherColumn/columnHeader_ar.properties deleted file mode 100644 index 052b930f5748..000000000000 --- a/core/src/main/resources/hudson/views/WeatherColumn/columnHeader_ar.properties +++ /dev/null @@ -1,23 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Weather\ report\ showing\ aggregated\ status\ of\ recent\ builds=\u0627\u0644\u062A\u0642\u0631\u064A\u0631 \u0627\u0644\u062C\u0648\u064A \u064A\u0639\u0631\u0636 \u062D\u0627\u0644\u0629 \u0622\u062E\u0631 \u0627\u0644\u0628\u0646\u0627\u0621\u0627\u062A diff --git a/core/src/main/resources/hudson/views/WeatherColumn/columnHeader_pt_BR.properties b/core/src/main/resources/hudson/views/WeatherColumn/columnHeader_pt_BR.properties index 2ab31349a24c..f0c2cf3b03d7 100644 --- a/core/src/main/resources/hudson/views/WeatherColumn/columnHeader_pt_BR.properties +++ b/core/src/main/resources/hudson/views/WeatherColumn/columnHeader_pt_BR.properties @@ -20,5 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Weather\ report\ showing\ aggregated\ status\ of\ recent\ builds=Relat\u00F3rio de clima mostrando o estado consolidado dos builds recentes +Weather\ report\ showing\ aggregated\ status\ of\ recent\ builds=Relat\u00F3rio de clima mostrando o estado consolidado das constru\u00E7\u00F5es recentes W=W diff --git a/core/src/main/resources/hudson/widgets/HistoryWidget/entry.jelly b/core/src/main/resources/hudson/widgets/HistoryWidget/entry.jelly index b690e2084ccc..5ed47248ad6d 100644 --- a/core/src/main/resources/hudson/widgets/HistoryWidget/entry.jelly +++ b/core/src/main/resources/hudson/widgets/HistoryWidget/entry.jelly @@ -40,14 +40,14 @@ THE SOFTWARE.
      - ${build.displayName} + ${build.displayName}
      ${%Took} ${build.durationString} - + ${h.getUserTimeZonePostfix()} diff --git a/core/src/main/resources/hudson/widgets/HistoryWidget/entry_ar.properties b/core/src/main/resources/hudson/widgets/HistoryWidget/entry_ar.properties deleted file mode 100644 index 19d8ca5e83aa..000000000000 --- a/core/src/main/resources/hudson/widgets/HistoryWidget/entry_ar.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -Console\ Output=\u0645\u062E\u0631\u062C\u0627\u062A \u0627\u0644\u0645\u062D\u0631\u0631 diff --git a/core/src/main/resources/hudson/widgets/HistoryWidget/entry_pt.properties b/core/src/main/resources/hudson/widgets/HistoryWidget/entry_pt.properties deleted file mode 100644 index 678eb90bc3ae..000000000000 --- a/core/src/main/resources/hudson/widgets/HistoryWidget/entry_pt.properties +++ /dev/null @@ -1,24 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributers -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Console\ Output=Sa\u00edda do console - diff --git a/core/src/main/resources/hudson/widgets/HistoryWidget/entry_pt_BR.properties b/core/src/main/resources/hudson/widgets/HistoryWidget/entry_pt_BR.properties index 00e1f9b6e8e7..06351b6e4ce3 100644 --- a/core/src/main/resources/hudson/widgets/HistoryWidget/entry_pt_BR.properties +++ b/core/src/main/resources/hudson/widgets/HistoryWidget/entry_pt_BR.properties @@ -21,3 +21,5 @@ # THE SOFTWARE. Console\ Output=Sa\u00EDda de console +confirm=Voc\u00EA tem certeza que quer abortar {0}? +Took=Tomou diff --git a/core/src/main/resources/hudson/widgets/HistoryWidget/entry_zh_TW.properties b/core/src/main/resources/hudson/widgets/HistoryWidget/entry_zh_TW.properties index 72ebd14fc3b5..2044142b0609 100644 --- a/core/src/main/resources/hudson/widgets/HistoryWidget/entry_zh_TW.properties +++ b/core/src/main/resources/hudson/widgets/HistoryWidget/entry_zh_TW.properties @@ -20,4 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Console\ Output=\u4E3B\u63A7\u53F0\u8F38\u51FA +confirm=\u60a8\u78ba\u5b9a\u8981\u4e2d\u6b62 {0} \u55ce\uff1f +Console\ Output=\u4e3b\u63a7\u53f0\u8f38\u51fa +Took=\u8cbb\u6642 diff --git a/core/src/main/resources/hudson/widgets/HistoryWidget/index.jelly b/core/src/main/resources/hudson/widgets/HistoryWidget/index.jelly index ad4d05280f61..08a3143b052d 100644 --- a/core/src/main/resources/hudson/widgets/HistoryWidget/index.jelly +++ b/core/src/main/resources/hudson/widgets/HistoryWidget/index.jelly @@ -24,16 +24,21 @@ THE SOFTWARE. --> - - - - - + +
      + + + + ${it.displayName} + + ${%trend} + +
      @@ -42,84 +47,56 @@ THE SOFTWARE. --> - - Atom feed ${%for all} + + + + Atom feed ${%for all} - + + + Atom feed ${%for failures} -
      +
      - - - +
      +
      + +
      +
      + +
      +
      + +
      - -
      + + - - - - - - - - - - - - + + +
      +
      - + - +
      + diff --git a/core/src/main/resources/jenkins/fingerprints/GlobalFingerprintConfiguration/config.jelly b/core/src/main/resources/jenkins/fingerprints/GlobalFingerprintConfiguration/config.jelly index 916ca936ff71..40a441604b6a 100644 --- a/core/src/main/resources/jenkins/fingerprints/GlobalFingerprintConfiguration/config.jelly +++ b/core/src/main/resources/jenkins/fingerprints/GlobalFingerprintConfiguration/config.jelly @@ -20,8 +20,8 @@ THE SOFTWARE. - - + + diff --git a/core/src/main/resources/jenkins/fingerprints/GlobalFingerprintConfiguration/config_pt_BR.properties b/core/src/main/resources/jenkins/fingerprints/GlobalFingerprintConfiguration/config_pt_BR.properties new file mode 100644 index 000000000000..919d5f66afaa --- /dev/null +++ b/core/src/main/resources/jenkins/fingerprints/GlobalFingerprintConfiguration/config_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Fingerprints=Assinaturas diff --git a/core/src/main/resources/jenkins/fingerprints/GlobalFingerprintConfiguration/config_zh_TW.properties b/core/src/main/resources/jenkins/fingerprints/GlobalFingerprintConfiguration/config_zh_TW.properties new file mode 100644 index 000000000000..d010484bd37c --- /dev/null +++ b/core/src/main/resources/jenkins/fingerprints/GlobalFingerprintConfiguration/config_zh_TW.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Fingerprints=\u6307\u7d0b diff --git a/core/src/main/resources/jenkins/fingerprints/Messages_pt_BR.properties b/core/src/main/resources/jenkins/fingerprints/Messages_pt_BR.properties new file mode 100644 index 000000000000..7793e6170d80 --- /dev/null +++ b/core/src/main/resources/jenkins/fingerprints/Messages_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +FileFingerprintStorage.DisplayName=Armazenamento local de assinaturas diff --git a/core/src/main/resources/jenkins/fingerprints/Messages_zh_TW.properties b/core/src/main/resources/jenkins/fingerprints/Messages_zh_TW.properties new file mode 100644 index 000000000000..cd4734dc653b --- /dev/null +++ b/core/src/main/resources/jenkins/fingerprints/Messages_zh_TW.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2020, Jenkins Project Contributors. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +FileFingerprintStorage.DisplayName = \u672c\u5730\u6307\u7d0b\u5132\u5b58\u5340 diff --git a/core/src/main/resources/jenkins/formelementpath/FormElementPathPageDecorator/footer.jelly b/core/src/main/resources/jenkins/formelementpath/FormElementPathPageDecorator/footer.jelly new file mode 100644 index 000000000000..1b92a93950fe --- /dev/null +++ b/core/src/main/resources/jenkins/formelementpath/FormElementPathPageDecorator/footer.jelly @@ -0,0 +1,6 @@ + + + + + + diff --git a/core/src/main/resources/jenkins/formelementpath/form-element-path.js b/core/src/main/resources/jenkins/formelementpath/form-element-path.js new file mode 100644 index 000000000000..6c512faeea86 --- /dev/null +++ b/core/src/main/resources/jenkins/formelementpath/form-element-path.js @@ -0,0 +1,197 @@ +/** + * Adds a 'path' attribute to form elements in the DOM. + * This is useful for providing stable selectors for UI testing. + * + * Instead of selecting by xpath with something like div/span/input[text() = 'Name'] + * You can use the path attribute: /org-jenkinsci-plugins-workflow-libs-FolderLibraries/libraries/name + */ +document.addEventListener("DOMContentLoaded", function(){ + // most of this is copied from hudson-behaviour.js + function buildFormTree(form) { + form.formDom = {}; // root object + + var doms = []; // DOMs that we added 'formDom' for. + doms.push(form); + + function addProperty(parent, name, value) { + name = shortenName(name); + if (parent[name] != null) { + if (parent[name].push == null) // is this array? + parent[name] = [parent[name]]; + parent[name].push(value); + } else { + parent[name] = value; + } + } + + // find the grouping parent node, which will have @name. + // then return the corresponding object in the map + function findParent(e) { + var p = findFormParent(e, form); + if (p == null) return {}; + + var m = p.formDom; + if (m == null) { + // this is a new grouping node + doms.push(p); + p.formDom = m = {}; + addProperty(findParent(p), p.getAttribute("name"), p); + } + return m; + } + + var jsonElement = null; + + for (var i = 0; i < form.elements.length; i++) { + var e = form.elements[i]; + if (e.name == "json") { + jsonElement = e; + continue; + } + if (e.tagName == "FIELDSET") + continue; + if (e.tagName == "SELECT" && e.multiple) { + addProperty(findParent(e), e.name, e); + continue; + } + + var p; + var type = e.getAttribute("type"); + if (type == null) type = ""; + switch (type.toLowerCase()) { + case "button": + var element + // modern buttons aren't wrapped in spans + if (e.classList.contains('jenkins-button') || e.classList.contains('repeatable-delete')) { + p = findParent(e); + element = e + } else { + p = findParent(e); + element = e.parentNode.parentNode; // YUI's surrounding that has interesting classes + } + var name = null; + ["repeatable-add", "repeatable-delete", "hetero-list-add", "expand-button", "advanced-button", "apply-button", "validate-button"] + .forEach(function (clazz) { + if (element.classList.contains(clazz)) { + name = clazz; + } + }); + if (name == null) { + if (name == null) { + element = element.parentNode.previousSibling; + if (element != null && element.classList && element.classList.contains('repeatable-insertion-point')) { + name = "hetero-list-add"; + } + } + } + if (name != null) { + addProperty(p, name, e); + } + break; + case "submit": + break; + case "checkbox": + case "radio": + p = findParent(e); + if (e.groupingNode) { + e.formDom = {}; + } + addProperty(p, e.name, e); + break; + case "file": + // to support structured form submission with file uploads, + // rename form field names to unique ones, and leave this name mapping information + // in JSON. this behavior is backward incompatible, so only do + // this when + p = findParent(e); + if (e.getAttribute("jsonAware") != null) { + var on = e.getAttribute("originalName"); + if (on != null) { + addProperty(p, on, e); + } else { + addProperty(p, e.name, e); + } + } + break; + // otherwise fall through + default: + p = findParent(e); + addProperty(p, e.name, e); + break; + } + } + + function annotate(e, path) { + e.setAttribute("path", path); + var o = e.formDom || {}; + for (var key in o) { + var v = o[key]; + + function child(v, i) { + var suffix = null; + var newKey = key; + if (v.parentNode.className && v.parentNode.className.indexOf("one-each") > -1 && v.parentNode.className.indexOf("honor-order") > -1) { + suffix = v.getAttribute("descriptorId").split(".").pop() + } else if (v.getAttribute("type") == "radio") { + suffix = v.value + while (newKey.substring(0, 8) == 'removeme') + newKey = newKey.substring(newKey.indexOf('_', 8) + 1); + } else if (v.getAttribute("suffix") != null) { + suffix = v.getAttribute("suffix") + } else { + if (i > 0) + suffix = i; + } + if (suffix == null) suffix = ""; + else suffix = '[' + suffix + ']'; + + annotate(v, path + "/" + newKey + suffix); + } + + if (v instanceof Array) { + var i = 0; + v.forEach(function (v) { + child(v, i++) + }) + } else { + child(v, 0) + } + } + + } + + annotate(form, ""); + + // clean up + for (i = 0; i < doms.length; i++) + doms[i].formDom = null; + + return true; + } + + function applyAll() { + document.querySelectorAll("FORM").forEach(function (e) { + buildFormTree(e); + }) + } + + /* JavaScript sometimes re-arranges the DOM and doesn't call layout callback + * known cases: YUI buttons, CodeMirror. + * We run apply twice to work around this, once immediately so that most cases work and the tests don't need to wait, + * and once to catch the edge cases. + */ + function hardenedApplyAll () { + applyAll(); + + setTimeout(function () { + applyAll(); + }, 1000); + } + + hardenedApplyAll(); + + layoutUpdateCallback.add(hardenedApplyAll) + + // expose this globally so that Selenium can call it + window.recomputeFormElementPath = hardenedApplyAll; +}); diff --git a/core/src/main/resources/jenkins/install/Messages_pt_BR.properties b/core/src/main/resources/jenkins/install/Messages_pt_BR.properties new file mode 100644 index 000000000000..a60a332c39ed --- /dev/null +++ b/core/src/main/resources/jenkins/install/Messages_pt_BR.properties @@ -0,0 +1,26 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +SetupWizard_ConfigureInstance_ValidationErrors=Algumas configura\u00E7\u00F5es s\u00E3o inv\u00E1lidas. Vide as mensagens de erro para detalhes. +SetupWizard_ConfigureInstance_RootUrl_Invalid=A URL \u00E9 inv\u00E1lida, por favor garanta que voc\u00EA est\u00E1 usando http:// ou https:// com um dom\u00EDnio v\u00E1lido. +SetupWizard_ConfigureInstance_RootUrl_Empty=A URL n\u00E3o pode ser vazia. +SetupWizard.DisplayName=Assistente de configura\u00E7\u00E3o. diff --git a/core/src/main/resources/jenkins/install/Messages_zh_TW.properties b/core/src/main/resources/jenkins/install/Messages_zh_TW.properties new file mode 100644 index 000000000000..fde62510d3fa --- /dev/null +++ b/core/src/main/resources/jenkins/install/Messages_zh_TW.properties @@ -0,0 +1,25 @@ +# The MIT License +# +# Copyright 2018 CloudBees, Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +SetupWizard_ConfigureInstance_ValidationErrors=\u67d0\u4e9b\u8a2d\u5b9a\u7121\u6548\u3002\u67e5\u770b\u932f\u8aa4\u8a0a\u606f\u4ee5\u4e86\u89e3\u8a73\u60c5\u3002 +SetupWizard_ConfigureInstance_RootUrl_Empty=URL \u4e0d\u5f97\u70ba\u7a7a +SetupWizard_ConfigureInstance_RootUrl_Invalid=URL \u7121\u6548\uff0c\u8acb\u78ba\u4fdd\u60a8\u4f7f\u7528 http\:// \u6216 https\:// \u548c\u6709\u6548\u7684\u7db2\u57df\u540d\u7a31\u3002 +SetupWizard.DisplayName=\u5b89\u88dd\u7cbe\u9748 diff --git a/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token.properties b/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token.properties index 6e30f8d6b698..d10f5d858f74 100644 --- a/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token.properties +++ b/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token.properties @@ -1,7 +1,7 @@ authenticate-security-token.getting.started=Getting Started authenticate-security-token.unlock.jenkins=Unlock Jenkins jenkins.install.findSecurityTokenMessage=To ensure Jenkins is securely set up by the administrator, \ -a password has been written to the log (not sure where to find it?) and this file on the server:

      {0}

      +a password has been written to the log (not sure where to find it?) and this file on the server:

      {0}

      authenticate-security-token.copy.password=Please copy the password from either location and paste it below. authenticate-security-token.error=ERROR: authenticate-security-token.password.incorrect=The password entered is incorrect, please check the file for the correct password diff --git a/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_bg.properties b/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_bg.properties index 90aea2fa8818..d0a6d55bfcc2 100644 --- a/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_bg.properties +++ b/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_bg.properties @@ -36,11 +36,11 @@ authenticate-security-token.password.incorrect=\ authenticate-security-token.unlock.jenkins=\ \u041e\u0442\u043a\u043b\u044e\u0447\u0432\u0430\u043d\u0435 \u043d\u0430 Jenkins # To ensure Jenkins is securely set up by the administrator, \ -# a password has been written to the log (not sure where to find it?) and this file on the server:

      {0}

      +# a password has been written to the log (not sure where to find it?) and this file on the server:

      {0}

      jenkins.install.findSecurityTokenMessage=\ \u0417\u0430 \u0434\u0430 \u0431\u044a\u0434\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d Jenkins \u043e\u0442 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440, \u0431\u0435 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0430\u043d\u0430 \u043f\u0430\u0440\u043e\u043b\u0430, \u043a\u043e\u044f\u0442\u043e \u0435\ \u0437\u0430\u043f\u0438\u0441\u0430\u043d\u0430 \u0432 \u0436\u0443\u0440\u043d\u0430\u043b\u0430 (\u0430\u043a\u043e \u043d\u0435 \u0437\u043d\u0430\u0435\u0442\u0435 \u043a\u044a\u0434\u0435 \u0435 \u0442\u043e\u0439: \u0432\u0438\u0436\u0442\u0435\ + href="https://www.jenkins.io/redirect/find-jenkins-logs" rel="noopener noreferrer" target="_blank">\u0432\u0438\u0436\u0442\u0435\ \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f\u0442\u0430), \u043a\u0430\u043a\u0442\u043e \u0438 \u0432 \u0442\u043e\u0437\u0438 \u0444\u0430\u0439\u043b \u043d\u0430 \u0441\u044a\u0440\u0432\u044a\u0440\u0430:\ \u201e

      {0}

      \u201c # Getting Started diff --git a/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_de.properties b/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_de.properties index 3459cbf18744..aa734fbb3d67 100644 --- a/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_de.properties +++ b/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_de.properties @@ -27,5 +27,5 @@ authenticate-security-token.copy.password=Bitte kopieren Sie das Passwort von ei authenticate-security-token.unlock.jenkins=Jenkins entsperren authenticate-security-token.continue=Weiter jenkins.install.findSecurityTokenMessage=Um sicher zu stellen, dass Jenkins von einem autorisierten Administrator sicher initialisiert wird, wurde ein zuf\u00E4llig generiertes Passwort in das Log\ - (wo ist das?) und diese Datei auf dem Server geschrieben:

      {0}

      + (wo ist das?) und diese Datei auf dem Server geschrieben:

      {0}

      authenticate-security-token.password.incorrect=Das angegebene Passwort ist nicht korrekt. diff --git a/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_fr.properties b/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_fr.properties index 1aadc46e20f6..369739fc02cb 100644 --- a/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_fr.properties +++ b/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_fr.properties @@ -2,7 +2,7 @@ authenticate-security-token.getting.started=D\u00e9marrage authenticate-security-token.unlock.jenkins=D\u00e9bloquer Jenkins jenkins.install.findSecurityTokenMessage=Pour \u00eatre s\u00fbr que que Jenkins soit configur\u00e9 de fa\u00e7on s\u00e9curis\u00e9e \ par un administrateur, un mot de passe a \u00e9t\u00e9 g\u00e9n\u00e9r\u00e9 dans le fichier de logs \ -(o\u00f9 le trouver) \ +(o\u00f9 le trouver) \ ainsi que dans ce fichier sur le serveur :

      {0}

      authenticate-security-token.copy.password=Veuillez copier le mot de passe depuis un des 2 endroits et le coller \ ci-dessous. diff --git a/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_it.properties b/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_it.properties index fa0bf87bce50..6559c59166c1 100644 --- a/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_it.properties +++ b/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_it.properties @@ -32,6 +32,6 @@ authenticate-security-token.password.incorrect=La password immessa non authenticate-security-token.unlock.jenkins=Sblocca Jenkins jenkins.install.findSecurityTokenMessage=Per assicurarsi che Jenkins venga \ configurato in modo sicuro dall''amministratore, stata scritta una \ - password nel log (non si sicuri di dove trovarla?) e su questo \ file sul server:

      {0}

      diff --git a/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_lt.properties b/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_lt.properties index 27b1941203a9..5045730211f4 100644 --- a/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_lt.properties +++ b/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_lt.properties @@ -1,7 +1,7 @@ authenticate-security-token.getting.started=\u012evadas authenticate-security-token.unlock.jenkins=Atrakinti Jenkins\u0105 jenkins.install.findSecurityTokenMessage=Kad u\u017etikrintum\u0117me kad Jenkins\u0105 saugiai paruo\u0161\u0117 administratorius, \ -slapta\u017eodis buvo \u012fra\u0161ytas \u012f \u017eurnal\u0105 (ne\u017einote, kur j\u012f rasti?) ir \u0161\u012f fail\u0105 serveryje:

      {0}

      +slapta\u017eodis buvo \u012fra\u0161ytas \u012f \u017eurnal\u0105 (ne\u017einote, kur j\u012f rasti?) ir \u0161\u012f fail\u0105 serveryje:

      {0}

      authenticate-security-token.copy.password=Pra\u0161ome nukopijuoti slapta\u017eiod\u012f i\u0161 bet kurios vietos \u012f \u017eemiau esant\u012f lauk\u0105. authenticate-security-token.error=KLAIDA: authenticate-security-token.password.incorrect=\u012evestas neteisingas slapta\u017eodis, pra\u0161ome patikrinti fail\u0105 ir rasti teising\u0105 slapta\u017eod\u012f diff --git a/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_pl.properties b/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_pl.properties index 91e055e3d893..49ec939bffd2 100644 --- a/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_pl.properties +++ b/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_pl.properties @@ -22,7 +22,7 @@ authenticate-security-token.getting.started=Zaczynamy authenticate-security-token.unlock.jenkins=Odblokuj Jenkinsa jenkins.install.findSecurityTokenMessage=Aby zapewni\u0107, \u017Ce Jenkins jest bezpiecznie uruchomiony przez administratora, \ -has\u0142o zosta\u0142o zapisane do pliku log\u00F3w (nie masz pewno\u015Bci, gdzie go znale\u017A\u0107?) oraz w pliku na serwerze:

      {0}

      +has\u0142o zosta\u0142o zapisane do pliku log\u00F3w (nie masz pewno\u015Bci, gdzie go znale\u017A\u0107?) oraz w pliku na serwerze:

      {0}

      authenticate-security-token.copy.password=Skopiuj has\u0142o z jednej z powy\u017Cszych lokalizacji i wklej poni\u017Cej. authenticate-security-token.error=B\u0142\u0105d: authenticate-security-token.password.incorrect=Has\u0142o nie jest poprawne, sprawd\u017A ponownie celem wprowadzenia poprawnego has\u0142a diff --git a/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_pt_BR.properties b/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_pt_BR.properties new file mode 100644 index 000000000000..30019b4d0779 --- /dev/null +++ b/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_pt_BR.properties @@ -0,0 +1,31 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +authenticate-security-token.continue=Continuar +authenticate-security-token.unlock.jenkins=Abrir o Jenkins +authenticate-security-token.password.administrator=Senha do administrador +authenticate-security-token.getting.started=Come\u00E7ando +authenticate-security-token.error=ERRO: +authenticate-security-token.password.incorrect=A senha inserida \u00E9 incorreta, por favor verifique o arquivo pela senha correta +authenticate-security-token.copy.password=Por favor copie a senha de qualquer uma das localiza\u00E7\u00F5es e cole abaixo. +jenkins.install.findSecurityTokenMessage=Para garantir que o Jenkins est\u00E1 configurado de forma segura pelo administrador, \ + uma senha foi escrita no arquivo de registro (n\u00E3o sabe onde encontrar?) e neste arquivo no servidor:

      {0}

      diff --git a/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_sr.properties b/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_sr.properties index 476fb7c972f2..f196ab7d5b41 100644 --- a/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_sr.properties +++ b/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_sr.properties @@ -3,7 +3,7 @@ authenticate-security-token.getting.started=\u041F\u043E\u0447\u0435\u0442\u0430\u043A authenticate-security-token.unlock.jenkins=\u041E\u0442\u043A\u0459\u0443\u0447\u0430\u0458 Jenkins jenkins.install.findSecurityTokenMessage=\u0414\u0430 \u0431\u0443\u0434\u0435 \u0431\u0438\u043E \u043F\u0440\u0438\u0441\u0442\u0443\u043F Jenkins-\u0443 \u043E\u0431\u0435\u0437\u0431\u0435\u0452\u0435\u043D, \ -\u043B\u043E\u0437\u0438\u043D\u043A\u0430 \u0458\u0435 \u0431\u0438\u043B\u0430 \u0438\u0437\u043F\u0438\u0441\u0430\u043D\u0430 \u0436\u0443\u0440\u043D\u0430\u043B\u0443 (\u043D\u0438\u0441\u0442\u0435 \u0441\u0438\u0433\u0443\u0440\u043D\u0438 \u0433\u0434\u0435 \u0441\u0435 \u0442\u043E \u043D\u0430\u043B\u0430\u0437\u0438?) \u0438 \u0443 \u043E\u0432\u043E\u0458 \u0434\u0430\u0442\u043E\u0442\u0435\u0446\u0438 \u043D\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0443:

      {0}

      +\u043B\u043E\u0437\u0438\u043D\u043A\u0430 \u0458\u0435 \u0431\u0438\u043B\u0430 \u0438\u0437\u043F\u0438\u0441\u0430\u043D\u0430 \u0436\u0443\u0440\u043D\u0430\u043B\u0443 (\u043D\u0438\u0441\u0442\u0435 \u0441\u0438\u0433\u0443\u0440\u043D\u0438 \u0433\u0434\u0435 \u0441\u0435 \u0442\u043E \u043D\u0430\u043B\u0430\u0437\u0438?) \u0438 \u0443 \u043E\u0432\u043E\u0458 \u0434\u0430\u0442\u043E\u0442\u0435\u0446\u0438 \u043D\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0443:

      {0}

      authenticate-security-token.copy.password=\u041C\u043E\u043B\u0438\u043C\u043E \u0438\u0441\u043A\u043E\u043F\u0438\u0440\u0430\u0458\u0442\u0435 \u043B\u043E\u0437\u0438\u043D\u043A\u0443 \u0441\u0430 \u0458\u0435\u0434\u043D\u0443 \u043E\u0434 \u0442\u0438\u0445 \u043B\u043E\u043A\u0430\u0446\u0438\u0458\u0430 \u0438 \u0443\u0431\u0430\u0446\u0438\u0458\u0435 \u0443 \u043E\u0434\u0433\u043E\u0432\u0430\u0440\u0443\u0458\u0443\u045B\u0435 \u043F\u043E\u0459\u0435. authenticate-security-token.error=\u0413\u0420\u0415\u0428\u041A\u0410: authenticate-security-token.password.incorrect=\u041D\u0430\u0432\u0435\u0434\u0435\u043D\u0430 \u043B\u043E\u0437\u0438\u043D\u043A\u0430 \u0441\u0435 \u043D\u0435 \u043F\u043E\u043A\u043B\u0430\u043F\u0430, \u043C\u043E\u043B\u0438\u043C\u043E \u0432\u0430\u0441 \u043F\u043E\u0442\u0440\u0430\u0436\u0438\u0442\u0435 \u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0443 \u0437\u0430 \u0442\u0430\u0447\u043D\u0443 \u043B\u043E\u0437\u0438\u043D\u043A\u0443. diff --git a/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_zh_CN.properties b/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_zh_CN.properties index 9e4bcc6de977..c24ce09c5ca2 100644 --- a/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_zh_CN.properties +++ b/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_zh_CN.properties @@ -24,7 +24,7 @@ authenticate-security-token.getting.started=\u5165\u95E8 authenticate-security-token.unlock.jenkins=\u89E3\u9501 Jenkins jenkins.install.findSecurityTokenMessage=\u4E3A\u4E86\u786E\u4FDD\u7BA1\u7406\u5458\u5B89\u5168\u5730\u5B89\u88C5 Jenkins\uFF0C\ -\u5BC6\u7801\u5DF2\u5199\u5165\u5230\u65E5\u5FD7\u4E2D\uFF08\u4E0D\u77E5\u9053\u5728\u54EA\u91CC\uFF1F\uFF09\u8BE5\u6587\u4EF6\u5728\u670D\u52A1\u5668\u4E0A\uFF1A

      {0}

      +\u5BC6\u7801\u5DF2\u5199\u5165\u5230\u65E5\u5FD7\u4E2D\uFF08\u4E0D\u77E5\u9053\u5728\u54EA\u91CC\uFF1F\uFF09\u8BE5\u6587\u4EF6\u5728\u670D\u52A1\u5668\u4E0A\uFF1A

      {0}

      authenticate-security-token.copy.password=\u8BF7\u4ECE\u672C\u5730\u590D\u5236\u5BC6\u7801\u5E76\u7C98\u8D34\u5230\u4E0B\u9762\u3002 authenticate-security-token.error=\u9519\u8BEF\uFF1A authenticate-security-token.password.incorrect=\u8F93\u5165\u7684\u5BC6\u7801\u6709\u8BEF\uFF0C\u8BF7\u68C0\u67E5\u6587\u4EF6\u4EE5\u786E\u8BA4\u5BC6\u7801\u6B63\u786E diff --git a/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_zh_TW.properties b/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_zh_TW.properties new file mode 100644 index 000000000000..b8a469f3124f --- /dev/null +++ b/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_zh_TW.properties @@ -0,0 +1,8 @@ +authenticate-security-token.getting.started=\u958b\u59cb\u4f7f\u7528 +authenticate-security-token.unlock.jenkins=\u89e3\u9396 Jenkins +jenkins.install.findSecurityTokenMessage=\u70ba\u4e86\u78ba\u4fdd Jenkins \u662f\u7531\u7ba1\u7406\u54e1\u5b89\u5168\u5730\u5b89\u88dd\uff0c\u5df2\u5c07\u5bc6\u78bc\u5beb\u5165\u8a18\u9304\u6a94\uff08\u4e0d\u78ba\u5b9a\u5728\u54ea\u88e1\u53ef\u4ee5\u627e\u5230\uff1f\uff09\u6b64\u6a94\u6848\u4f4d\u65bc\u4f3a\u670d\u5668\u4e0a\uff1a

      {0}

      +authenticate-security-token.copy.password=\u8acb\u5f9e\u5176\u4e2d\u4e00\u500b\u4f4d\u7f6e\u8907\u88fd\u5bc6\u78bc\u4e26\u8cbc\u5230\u4e0b\u65b9\u3002 +authenticate-security-token.error=\u932f\u8aa4\: +authenticate-security-token.password.incorrect=\u8f38\u5165\u7684\u5bc6\u78bc\u6709\u8aa4\uff0c\u8acb\u6aa2\u67e5\u8a72\u6a94\u6848\u4ee5\u53d6\u5f97\u6b63\u78ba\u7684\u5bc6\u78bc +authenticate-security-token.password.administrator=\u7ba1\u7406\u54e1\u5bc6\u78bc +authenticate-security-token.continue=\u7e7c\u7e8c diff --git a/core/src/main/resources/jenkins/install/SetupWizard/proxy-configuration_pt_BR.properties b/core/src/main/resources/jenkins/install/SetupWizard/proxy-configuration_pt_BR.properties new file mode 100644 index 000000000000..a31c094ecf05 --- /dev/null +++ b/core/src/main/resources/jenkins/install/SetupWizard/proxy-configuration_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +HTTP\ Proxy\ Configuration=Configura\u00E7\u00E3o do proxy HTTP diff --git a/core/src/main/resources/jenkins/install/SetupWizard/proxy-configuration_zh_TW.properties b/core/src/main/resources/jenkins/install/SetupWizard/proxy-configuration_zh_TW.properties new file mode 100644 index 000000000000..36316c3c5f81 --- /dev/null +++ b/core/src/main/resources/jenkins/install/SetupWizard/proxy-configuration_zh_TW.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +HTTP\ Proxy\ Configuration=HTTP \u4ee3\u7406\u4f3a\u670d\u5668\u8a2d\u5b9a diff --git a/core/src/main/resources/jenkins/install/SetupWizard/setupWizardConfigureInstance_pt_BR.properties b/core/src/main/resources/jenkins/install/SetupWizard/setupWizardConfigureInstance_pt_BR.properties new file mode 100644 index 000000000000..c80144fb26ec --- /dev/null +++ b/core/src/main/resources/jenkins/install/SetupWizard/setupWizardConfigureInstance_pt_BR.properties @@ -0,0 +1,28 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Jenkins\ URL=URL\ do\ Jenkins +jenkinsURL_help=A URL do Jenkins \u00E9 usada para prover a URL ra\u00EDz para links absolutos para v\u00E1rios recursos do Jenkins. \ +Isto significa que este valor \u00E9 requerido para a opera\u00E7\u00E3o apropriada de muitas funcionalidades do Jenkins incluindo notifica\u00E7\u00F5es por e-mail, atualiza\u00E7\u00E3o de estado de PR e a vari\u00E1vel de ambiente BUILD_URL provida pelos passos de constru\u00E7\u00E3o.
      \ +O valor proposto padr\u00E3o mostrado \u00E9 ainda n\u00E3o salvo e \u00E9 gerado da solicita\u00E7\u00E3o atual, se poss\u00EDvel. \ +A melhor pr\u00E1tica \u00E9 configurar este valor para a URL que espera-se que os usu\u00E1rios utilizem. Isto evita confus\u00E3o quando compartilhando ou vendo links. +Instance\ Configuration=Configura\u00E7\u00E3o\ da\ instancia diff --git a/core/src/main/resources/jenkins/install/SetupWizard/setupWizardConfigureInstance_zh_TW.properties b/core/src/main/resources/jenkins/install/SetupWizard/setupWizardConfigureInstance_zh_TW.properties new file mode 100644 index 000000000000..f1514ce5c7da --- /dev/null +++ b/core/src/main/resources/jenkins/install/SetupWizard/setupWizardConfigureInstance_zh_TW.properties @@ -0,0 +1,3 @@ +Instance\ Configuration=\u57f7\u884c\u500b\u9ad4\u8a2d\u5b9a +Jenkins\ URL=Jenkins URL +jenkinsURL_help=Jenkins URL \u662f\u7528\u4f86\u63d0\u4f9b root URL \u7d66\u5404\u7a2e Jenkins \u8cc7\u6e90\u7684\u7d55\u5c0d\u9023\u7d50\u3002\u6b64\u503c\u662f\u8a31\u591a Jenkins \u529f\u80fd\u6b63\u5e38\u904b\u4f5c\u7684\u5fc5\u8981\u689d\u4ef6\uff0c\u5305\u542b\u96fb\u5b50\u90f5\u4ef6\u901a\u77e5\u3001PR \u72c0\u614b\u66f4\u65b0\u3001\u63d0\u4f9b\u7d66\u5efa\u7f6e\u6b65\u9a5f\u7684 BUILD_URL \u74b0\u5883\u8b8a\u6578\u3002
      \u986f\u793a\u7684\u5efa\u8b70\u9810\u8a2d\u503c\u5c1a\u672a\u5132\u5b58\u4e14\u5b83\u662f\u7531\u76ee\u524d\u7684\u8acb\u6c42\u7522\u751f\u7684\u3002\u6700\u597d\u628a\u5b83\u8a2d\u5b9a\u70ba\u4f7f\u7528\u8005\u5c07\u6703\u4f7f\u7528\u7684 URL\uff0c\u9019\u53ef\u907f\u514d\u5206\u4eab\u6216\u6aa2\u8996\u9023\u7d50\u6642\u7522\u751f\u56f0\u60d1\u3002 diff --git a/core/src/main/resources/jenkins/install/SetupWizard/setupWizardFirstUser_pt_BR.properties b/core/src/main/resources/jenkins/install/SetupWizard/setupWizardFirstUser_pt_BR.properties new file mode 100644 index 000000000000..f77df0fc46dd --- /dev/null +++ b/core/src/main/resources/jenkins/install/SetupWizard/setupWizardFirstUser_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Create\ First\ Admin\ User=Criar\ o\ primeiro\ usu\u00E1rio\ administrativo diff --git a/core/src/main/resources/jenkins/install/SetupWizard/setupWizardFirstUser_zh_TW.properties b/core/src/main/resources/jenkins/install/SetupWizard/setupWizardFirstUser_zh_TW.properties new file mode 100644 index 000000000000..db5852f9e806 --- /dev/null +++ b/core/src/main/resources/jenkins/install/SetupWizard/setupWizardFirstUser_zh_TW.properties @@ -0,0 +1 @@ +Create\ First\ Admin\ User=\u5efa\u7acb\u7b2c\u4e00\u4f4d\u7ba1\u7406\u54e1\u4f7f\u7528\u8005 diff --git a/core/src/main/resources/jenkins/install/platform-plugins.json b/core/src/main/resources/jenkins/install/platform-plugins.json index 4347ee0f270d..2f73e4d15bf7 100644 --- a/core/src/main/resources/jenkins/install/platform-plugins.json +++ b/core/src/main/resources/jenkins/install/platform-plugins.json @@ -96,7 +96,6 @@ { "name": "email-ext", "suggested": true }, { "name": "emailext-template" }, { "name": "mailer", "suggested": true }, - { "name": "publish-over-ssh" }, { "name": "ssh" } ] }, diff --git a/core/src/main/resources/jenkins/install/pluginSetupWizard.properties b/core/src/main/resources/jenkins/install/pluginSetupWizard.properties index 0b0ad7e837d1..86fd3f21517f 100644 --- a/core/src/main/resources/jenkins/install/pluginSetupWizard.properties +++ b/core/src/main/resources/jenkins/install/pluginSetupWizard.properties @@ -32,7 +32,7 @@ installWizard_offline_title=Offline installWizard_offline_message=This Jenkins instance appears to be offline. \

      \ For information about installing Jenkins without an internet connection, see the \ -Offline Jenkins Installation Documentation.

      \ +Offline Jenkins Installation Documentation.

      \ You may choose to continue by configuring a proxy or skipping plugin installation. \

      installWizard_error_title=Error @@ -46,7 +46,7 @@ installWizard_installCustom_selectNone=None installWizard_installCustom_selectRecommended=Suggested installWizard_installCustom_selected=Selected installWizard_installCustom_dependenciesPrefix=Dependencies -installWizard_installCustom_pluginListDesc=Note that the full list of plugins is not shown here. Additional plugins can be installed in the Plugin Manager once the initial setup is complete. See the Wiki for more information. +installWizard_installCustom_pluginListDesc=Note that the full list of plugins is not shown here. Additional plugins can be installed in the Plugin Manager once the initial setup is complete. See the documentation for more information. installWizard_goBack=Back installWizard_goInstall=Install installWizard_installing_title=Getting Started @@ -100,12 +100,12 @@ installWizard_upgradePanel_message=Jenkins {0} includes some great new features installWizard_upgradePanel_skipRecommendedPlugins=No thanks installWizard_upgradeComplete_title=Upgrade installWizard_pluginsInstalled_banner=Welcome to Jenkins {0}! -installWizard_upgradeComplete_message=Congratulations! You have upgraded to Jenkins {0}.

      To learn more about its great new features, visit the Jenkins website! +installWizard_upgradeComplete_message=Congratulations! You have upgraded to Jenkins {0}.

      To learn more about its great new features, visit the Jenkins website! installWizard_upgradeSkipped_title=Upgrade installWizard_upgradeSkipped_banner=Features Not Installed installWizard_upgradeSkipped_message=

      Suggested plugins will not be installed.
      \

      You can also install new features from the Plugin Manager, if you change your mind.

      \

      Learn how these new features can improve your Jenkins experience by \ -visiting the homepage.

      +visiting the homepage.

      installWizard_upgrading_title=Installing plugins installWizard_upgradeComplete_finishButtonLabel=Finish diff --git a/core/src/main/resources/jenkins/install/pluginSetupWizard_fr.properties b/core/src/main/resources/jenkins/install/pluginSetupWizard_fr.properties index 9d9f74ad3bdd..847c7993cdd8 100644 --- a/core/src/main/resources/jenkins/install/pluginSetupWizard_fr.properties +++ b/core/src/main/resources/jenkins/install/pluginSetupWizard_fr.properties @@ -11,7 +11,7 @@ installWizard_offline_title=Hors-ligne installWizard_offline_message=Cette instance Jenkins a l\'air d\'\u00eatre hors-ligne. \

      \ Pour des informations relatives \u00e0 l\'installation de Jenkins sans acc\u00e8s Internet, voir la \ -Documentation \ +Documentation \ d'Installation hors-ligne de Jenkins.

      \ Vous pouvez continuer en configurant un serveur proxy ou en passant l\'installation des plugins. \

      @@ -24,9 +24,6 @@ installWizard_installCustom_selectNone=Aucun installWizard_installCustom_selectRecommended=Recommand\u00e9s installWizard_installCustom_selected=S\u00e9lectionn\u00e9s installWizard_installCustom_dependenciesPrefix=D\u00e9pendances -installWizard_installCustom_pluginListDesc=Notez que la liste compl\u00e8te des plugins n\'est pas affich\u00e9e ici. \ -Des plugins additionnels peuvent \u00eatre install\u00e9s depuis le Plugin Manager une fois la \ -configuration initiale termin\u00e9e. Voir le Wiki pour plus d\'informations. installWizard_goBack=Retour installWizard_goInstall=Installer installWizard_installing_title=Installation en cours... diff --git a/core/src/main/resources/jenkins/install/pluginSetupWizard_it.properties b/core/src/main/resources/jenkins/install/pluginSetupWizard_it.properties index 34fa6f2a5f97..fea9125c7255 100644 --- a/core/src/main/resources/jenkins/install/pluginSetupWizard_it.properties +++ b/core/src/main/resources/jenkins/install/pluginSetupWizard_it.properties @@ -60,13 +60,6 @@ installWizard_installComplete_message=L''installazione di Jenkins installWizard_installComplete_restartLabel=Riavvia installWizard_installComplete_title=Attivit iniziali installWizard_installCustom_dependenciesPrefix=Dipendenze -installWizard_installCustom_pluginListDesc=Si noti che qui non viene \ - visualizzato l''elenco completo dei componenti aggiuntivi. possibile \ - installare altri componenti aggiuntivi dal Gestore componenti \ - aggiuntivi una volta che l''installazione iniziale stata \ - completata. \ - \ - Si veda il wiki per ulteriori informazioni. installWizard_installCustom_selectAll=Tutti installWizard_installCustom_selected=Selezionati installWizard_installCustom_selectNone=Nessuno @@ -87,7 +80,7 @@ installWizard_jenkinsVersionTitle=Jenkins installWizard_offline_message=Sembra che quest''istanza di Jenkins non sia in \ linea.

      Per ulteriori informazioni \ sull''installazione di Jenkins senza una connessione a Internet, si veda la \ - \ + \ documentazione sull''installazione non in linea di Jenkins.

      \ possibile continuare se si configura un proxy o se si omette \ l''installazione dei componenti aggiuntivi.

      @@ -111,7 +104,7 @@ installWizard_upgradeComplete_finishButtonLabel=Fine installWizard_upgradeComplete_message=Congratulazioni! L''aggiornamento a \ Jenkins {0} stato completato.

      Per ulteriori informazioni sulle sue \ nuove funzionalit, si visiti il sito Web di Jenkins! + href="https://www.jenkins.io/2.0/">il sito Web di Jenkins! installWizard_upgradeComplete_title=Aggiornamento installWizard_upgradePanel_banner=Benvenuto in Jenkins {0}! installWizard_upgradePanel_message=Jenkins {0} include delle nuove \ @@ -125,7 +118,7 @@ installWizard_upgradeSkipped_message=

      possibile anche installare nuove funzionalit \ dal Gestore componenti aggiuntivi se si cambia idea.

      Scopri come queste nuove funzionalit possano migliorare \ - l''esperienza con Jenkins \ + l''esperienza con Jenkins \ visitandone il sito.

      installWizard_upgradeSkipped_title=Aggiornamento installWizard_upgrading_title=Installazione componenti aggiuntivi in corso diff --git a/core/src/main/resources/jenkins/install/pluginSetupWizard_lt.properties b/core/src/main/resources/jenkins/install/pluginSetupWizard_lt.properties index 4d47f7b45101..337dd6304d46 100644 --- a/core/src/main/resources/jenkins/install/pluginSetupWizard_lt.properties +++ b/core/src/main/resources/jenkins/install/pluginSetupWizard_lt.properties @@ -10,7 +10,7 @@ installWizard_offline_title=Atsijung\u0119s installWizard_offline_message=Pana\u0161u, kad \u0161is Jenkinsas yra atsijung\u0119s. \

      \ Daugiau informacijos apie tai, kaip diegti Jenkins\u0105 neprisijungus prie interneto, ie\u0161kokite \ -Neprijungto Jenkins diegimo dokumentacijoje.

      \ +Neprijungto Jenkins diegimo dokumentacijoje.

      \ Galite nuspr\u0119sti t\u0119sti sukonfig\u016brav\u0119 \u0161liuz\u0105 arba praleisdami pried\u0173 diegim\u0105. \

      installWizard_error_header=\u012evyko klaida @@ -22,7 +22,6 @@ installWizard_installCustom_selectNone=Nieko installWizard_installCustom_selectRecommended=Rekomenduojami installWizard_installCustom_selected=Pa\u017eym\u0117ti installWizard_installCustom_dependenciesPrefix=Priklausomyb\u0117s -installWizard_installCustom_pluginListDesc=Pasteb\u0117tina, kad \u010dia nerodomas pilnas pried\u0173 s\u0105ra\u0161as. Papildomus priedus galite \u012fdiegti Pried\u0173 tvarkykl\u0117je, kai bus baigtas pradinis diegimas. Daugiau informacijos rasite vikyje. installWizard_goBack=Atgal installWizard_goInstall=\u012ediegti installWizard_installing_title=\u012evadas diff --git a/core/src/main/resources/jenkins/install/pluginSetupWizard_pl.properties b/core/src/main/resources/jenkins/install/pluginSetupWizard_pl.properties index 80f07bc809a5..dfdfcc71e388 100644 --- a/core/src/main/resources/jenkins/install/pluginSetupWizard_pl.properties +++ b/core/src/main/resources/jenkins/install/pluginSetupWizard_pl.properties @@ -42,7 +42,6 @@ installWizard_installCustom_selectAll=Wszystkie installWizard_installCustom_selectNone=\u017Badne installWizard_installCustom_selectRecommended=Rekomendowane installWizard_installCustom_selected=Wybrane -installWizard_installCustom_pluginListDesc=Zauwa\u017C, \u017Ce poni\u017Cej nie jest wy\u015Bwietlana pe\u0142na lista wtyczek. Dodatkowe wtyczki mog\u0105 by\u0107 pobrane przez Mened\u017Cera wtyczek, kiedy konfiguracja Jenkinsa zostanie zasko\u0144czona. Sprawd\u017A wi\u0119cej informacji na Wiki. installWizard_goBack=Wr\u00F3\u0107 installWizard_goInstall=Instaluj installWizard_error_connection=Nie uda\u0142o si\u0119 po\u0142\u0105czy\u0107 z Jenkinsem @@ -58,7 +57,7 @@ installWizard_installIncomplete_banner=Wznawianie instalacji installWizard_offline_message=Wygl\u0105da, \u017Ce Jenkins pracuje w trybie offline. \

      \ Aby uzyska\u0107 wi\u0119cej informacji o instalowaniu Jenkinsa bez dost\u0119pu do Internetu, sprawd\u017A \ -Offline Jenkins Installation Documentation.

      \ +Offline Jenkins Installation Documentation.

      \ Mo\u017Cesz kontynuowa\u0107 konfiguruj\u0105c proxy lub pomin\u0105\u0107 instalacje wtyczek.\

      installWizard_configureInstance_title=Konfiguracja instancji diff --git a/core/src/main/resources/jenkins/install/pluginSetupWizard_sr.properties b/core/src/main/resources/jenkins/install/pluginSetupWizard_sr.properties index 40ac6fa11c0f..7a68c49b9d92 100644 --- a/core/src/main/resources/jenkins/install/pluginSetupWizard_sr.properties +++ b/core/src/main/resources/jenkins/install/pluginSetupWizard_sr.properties @@ -8,7 +8,7 @@ installWizard_offline_title=\u0412\u0430\u043D \u043C\u0440\u0435\u0436\u0435 installWizard_offline_message=Jenkins \u0442\u0440\u0435\u043D\u0443\u0442\u043D\u043E \u0440\u0430\u0434\u0438 \u0432\u0430\u043D \u043C\u0440\u0435\u0436\u0435.\

      \ \u0414\u0430 \u0431\u0438 \u0441\u0442\u0435 \u0438\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u043B\u0438 Jenkins \u0431\u0435\u0437 \u0438\u043D\u0442\u0435\u0440\u043D\u0435\u0442 \u0432\u0435\u0437\u043E\u043C, \u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0430\u0458\u0442\u0435 \ -\u0412\u0430\u043D-\u043C\u0440\u0435\u0436\u043D\u0430 Jenkins \u0438\u043D\u0441\u0442\u0430\u043B\u0430\u0446\u0438\u0458\u0430.

      \ +\u0412\u0430\u043D-\u043C\u0440\u0435\u0436\u043D\u0430 Jenkins \u0438\u043D\u0441\u0442\u0430\u043B\u0430\u0446\u0438\u0458\u0430.

      \ \u041C\u043E\u0436\u0435\u0442\u0435 \u043D\u0430\u0441\u0442\u0430\u0432\u0438\u0442\u0438 \u043F\u043E\u0441\u0442\u0430\u0432\u0459\u0430\u0458\u0443\u0447\u0438 proxy \u0438\u043B\u0438 \u043F\u0440\u0435\u0441\u043A\u0430\u043A\u0430\u045A\u0435\u043C \u0438\u043D\u0441\u0442\u0430\u043B\u0430\u0446\u0438\u0458\u0438 \u043C\u043E\u0434\u0443\u043B\u0430. \

      installWizard_error_header=\u0414\u043E\u0448\u043B\u043E \u0458\u0435 \u0434\u043E \u0433\u0440\u0435\u0448\u043A\u0435 @@ -21,7 +21,6 @@ installWizard_installCustom_selectNone=\u041D\u0438\u0448\u0442\u0430 installWizard_installCustom_selectRecommended=\u041F\u0440\u0435\u0434\u043B\u043E\u0436\u0435\u043D\u043E installWizard_installCustom_selected=\u0418\u0437\u0430\u0431\u0440\u0430\u043D\u043E installWizard_installCustom_dependenciesPrefix=\u0417\u0430\u0432\u0438\u0441\u043D\u043E\u0441\u0442\u0438 -installWizard_installCustom_pluginListDesc=\u041A\u043E\u043C\u043F\u043B\u0435\u0442\u0430\u043D \u043D\u0438\u0437 \u043C\u043E\u0434\u0443\u043B\u0430 \u043D\u0438\u0458\u0435 \u043F\u0440\u0438\u043A\u0430\u0437\u0430\u043D\u043E. \u0414\u043E\u0434\u0430\u0442\u043D\u0435 \u043C\u043E\u0434\u0443\u043B\u0435 \u043C\u043E\u0433\u0443 \u0431\u0438\u0442\u0438 \u0438\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u043D\u0438 \u0441\u0430 \u0423\u043F\u0440\u0430\u0432\u0459\u0430\u0447\u0435\u043C \u043C\u043E\u0434\u0443\u043B\u0430. \u041F\u0440\u0435\u0433\u043B\u0435\u0434\u0430\u0458\u0442\u0435 \u0412\u0438\u043A\u0438 \u0437\u0430 \u0432\u0438\u0448\u0435 \u0434\u0435\u0442\u0430\u0459\u0430. installWizard_goBack=\u041D\u0430\u0437\u0430\u0434 installWizard_goInstall=\u0418\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u0458 installWizard_installing_title=\u041F\u043E\u0447\u0435\u0442\u0430\u043A @@ -63,12 +62,12 @@ installWizard_upgradePanel_message=Jenkins {0} \u0438\u043C\u0430 \u043D\u0435\u installWizard_upgradePanel_skipRecommendedPlugins=\u041D\u0435 \u0445\u0432\u0430\u043B\u0430 installWizard_upgradeComplete_title=\u0410\u0436\u0443\u0440\u0438\u0440\u0430\u0458 installWizard_pluginsInstalled_banner=\u0414\u043E\u0431\u0440\u043E\u0434\u043E\u0448\u043B\u0438 \u043D\u0430 Jenkins {0}! -installWizard_upgradeComplete_message=\u0427\u0435\u0441\u0442\u0438\u0442\u0430\u043C\u043E! \u0410\u0436\u0443\u0440\u0438\u0440\u0430\u043B\u0438 \u0441\u0442\u0435 Jenkins \u043D\u0430 \u0432\u0435\u0440\u0437\u0438\u0458\u0443 {0}.

      \u041F\u0440\u043E\u0447\u0438\u0442\u0430\u0458\u0442\u0435 \u0458\u043E\u0448 \u043D\u0430 Jenkins \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0438! +installWizard_upgradeComplete_message=\u0427\u0435\u0441\u0442\u0438\u0442\u0430\u043C\u043E! \u0410\u0436\u0443\u0440\u0438\u0440\u0430\u043B\u0438 \u0441\u0442\u0435 Jenkins \u043D\u0430 \u0432\u0435\u0440\u0437\u0438\u0458\u0443 {0}.

      \u041F\u0440\u043E\u0447\u0438\u0442\u0430\u0458\u0442\u0435 \u0458\u043E\u0448 \u043D\u0430 Jenkins \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0438! installWizard_upgradeSkipped_title=\u0410\u0436\u0443\u0440\u0438\u0440\u0430\u0458 installWizard_upgradeSkipped_banner=\u041E\u0434\u043B\u0438\u043A\u0435 \u043A\u043E\u0458\u0435 \u043D\u0438\u0441\u0443 \u0438\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u043D\u0435 installWizard_upgradeSkipped_message=

      \u043F\u0440\u0435\u0434\u043B\u043E\u0436\u0438\u0435 \u043C\u043E\u0434\u0443\u043B\u0435 \u043D\u0435\u045B\u0435 \u0431\u0438\u0442\u0438 \u0438\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u043D\u0435.
      \

      \u0410\u043A\u043E \u0441\u0442\u0435 \u043F\u0440\u0435\u0434\u043E\u043C\u0438\u0441\u043B\u0438\u0442\u0435, \u043C\u043E\u0436\u0435\u0442\u0435 \u0438\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u0442\u0438 \u043D\u043E\u0432\u0435 \u043C\u043E\u0434\u0443\u043B\u0435 \u0441\u0430 \u0423\u043F\u0440\u0430\u0432\u0459\u0430\u0447\u0435\u043C \u043C\u043E\u0434\u0443\u043B\u0430.

      \

      \u041F\u0440\u043E\u0447\u0438\u0442\u0430\u0458\u0442\u0435 \u043A\u0430\u043A\u043E \u043C\u043E\u0434\u0443\u043B\u0435 \u0443\u0441\u0430\u0432\u0440\u0448\u0430\u0432\u0430\u0458\u0443 Jenkins \ -\u043D\u0430 Jenkins \u0441\u0442\u0430\u043D\u0438\u0446\u0438.

      +\u043D\u0430 Jenkins \u0441\u0442\u0430\u043D\u0438\u0446\u0438.

      installWizard_upgrading_title=\u0418\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u045A\u0435 \u043C\u043E\u0434\u0443\u043B\u0430 installWizard_upgradeComplete_finishButtonLabel=\u0417\u0430\u0432\u0440\u0448\u0438 diff --git a/core/src/main/resources/jenkins/install/pluginSetupWizard_zh_CN.properties b/core/src/main/resources/jenkins/install/pluginSetupWizard_zh_CN.properties index 447017676c54..115ba1786fc6 100644 --- a/core/src/main/resources/jenkins/install/pluginSetupWizard_zh_CN.properties +++ b/core/src/main/resources/jenkins/install/pluginSetupWizard_zh_CN.properties @@ -32,7 +32,7 @@ installWizard_jenkinsVersionTitle=Jenkins installWizard_offline_title=\u79bb\u7ebf installWizard_offline_message=\u8be5Jenkins\u5b9e\u4f8b\u4f3c\u4e4e\u5df2\u79bb\u7ebf\u3002\

      \ -\u53c2\u8003 \u79bb\u7ebfJenkins\u5b89\u88c5\u6587\u6863\u4e86\u89e3\u672a\u63a5\u5165\u4e92\u8054\u7f51\u65f6\u5b89\u88c5Jenkins\u7684\u66f4\u591a\u4fe1\u606f\u3002

      \ +\u53c2\u8003 \u79bb\u7ebfJenkins\u5b89\u88c5\u6587\u6863\u4e86\u89e3\u672a\u63a5\u5165\u4e92\u8054\u7f51\u65f6\u5b89\u88c5Jenkins\u7684\u66f4\u591a\u4fe1\u606f\u3002

      \ \u53ef\u4ee5\u901a\u8fc7\u914d\u7f6e\u4e00\u4e2a\u4ee3\u7406\u6216\u8df3\u8fc7\u63d2\u4ef6\u5b89\u88c5\u6765\u9009\u62e9\u7ee7\u7eed\u3002\

      installWizard_error_header=\u51fa\u73b0\u4e00\u4e2a\u9519\u8bef @@ -45,7 +45,6 @@ installWizard_installCustom_selectNone=\u65e0 installWizard_installCustom_selectRecommended=\u5efa\u8bae installWizard_installCustom_selected=\u5df2\u9009\u62e9 installWizard_installCustom_dependenciesPrefix=\u4f9d\u8d56 -installWizard_installCustom_pluginListDesc=\u6ce8\u610f\uff0c\u8fd9\u91cc\u5e76\u672a\u663e\u793a\u5b8c\u6574\u7684\u63d2\u4ef6\u5217\u8868\u3002\u4e00\u65e6\u521d\u59cb\u5b89\u88c5\u5b8c\u6210\u540e\uff0c\u53ef\u901a\u8fc7\u63d2\u4ef6\u7ba1\u7406\u5668\u5b89\u88c5\u5176\u4ed6\u63d2\u4ef6\u3002\u67e5\u770bwiki\u4e86\u89e3\u66f4\u591a\u3002 installWizard_goBack=\u540e\u9000 installWizard_goInstall=\u5b89\u88c5 installWizard_installing_title=\u65b0\u624b\u5165\u95e8 @@ -98,11 +97,11 @@ installWizard_upgradePanel_message=Jenkins {0} \u5305\u62ec\u4e00\u4e9b\u4e0d\u9 installWizard_upgradePanel_skipRecommendedPlugins=\u4e0d\uff0c\u8c22\u8c22 installWizard_upgradeComplete_title=\u66f4\u65b0 installWizard_pluginsInstalled_banner=\u6b22\u8fce\u4f7f\u7528Jenkins {0} \uff01 -installWizard_upgradeComplete_message=\u606d\u559c\uff01\u4f60\u5df2\u66f4\u65b0\u5230Jenkins {0} \u3002

      \u8bbf\u95eeJenkins\u7f51\u7ad9\u4e86\u89e3\u66f4\u591a\u65b0\u7279\u6027\u7684\u4fe1\u606f\u3002 +installWizard_upgradeComplete_message=\u606d\u559c\uff01\u4f60\u5df2\u66f4\u65b0\u5230Jenkins {0} \u3002

      \u8bbf\u95eeJenkins\u7f51\u7ad9\u4e86\u89e3\u66f4\u591a\u65b0\u7279\u6027\u7684\u4fe1\u606f\u3002 installWizard_upgradeSkipped_title=\u66f4\u65b0 installWizard_upgradeSkipped_banner=\u7279\u6027\u672a\u5b89\u88c5 installWizard_upgradeSkipped_message=

      \u5efa\u8bae\u7684\u63d2\u4ef6\u5c06\u4e0d\u88ab\u5b89\u88c5\u3002
      \

      \u5982\u679c\u4f60\u6539\u53d8\u4e3b\u610f\u4e86\uff0c\u8fd8\u53ef\u4ee5\u4ece\u63d2\u4ef6\u7ba1\u7406\u5668\u5b89\u88c5\u65b0\u7279\u6027\u3002

      \ -

      \u8bbf\u95eeJenkins\u5b98\u7f51\uff0c\u4e86\u89e3\u8fd9\u4e9b\u65b0\u7279\u6027\u5982\u4f55\u63d0\u5347Jenkins\u4f53\u9a8c\u3002

      +

      \u8bbf\u95eeJenkins\u5b98\u7f51\uff0c\u4e86\u89e3\u8fd9\u4e9b\u65b0\u7279\u6027\u5982\u4f55\u63d0\u5347Jenkins\u4f53\u9a8c\u3002

      installWizard_upgrading_title=\u6b63\u5728\u5b89\u88c5\u63d2\u4ef6 installWizard_upgradeComplete_finishButtonLabel=\u5b8c\u6210 diff --git a/core/src/main/resources/jenkins/install/pluginSetupWizard_zh_TW.properties b/core/src/main/resources/jenkins/install/pluginSetupWizard_zh_TW.properties new file mode 100644 index 000000000000..fa2d69024066 --- /dev/null +++ b/core/src/main/resources/jenkins/install/pluginSetupWizard_zh_TW.properties @@ -0,0 +1,96 @@ +# The MIT License +# +# Copyright (c) 2016-2018, Sun Microsystems, Inc., Kohsuke Kawaguchi +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +# +installWizard_welcomePanel_title=\u958b\u59cb\u4f7f\u7528 +installWizard_welcomePanel_banner=\u81ea\u8a02 Jenkins +installWizard_welcomePanel_message=\u5916\u639b\u70ba Jenkins \u64f4\u5145\u984d\u5916\u7684\u529f\u80fd\u4ee5\u6eff\u8db3\u4e0d\u540c\u7684\u9700\u6c42\u3002 +installWizard_welcomePanel_recommendedActionTitle=\u5b89\u88dd\u63a8\u85a6\u7684\u5916\u639b +installWizard_welcomePanel_recommendedActionDetails=\u5b89\u88dd Jenkins \u793e\u7fa4\u8a8d\u70ba\u6700\u6709\u7528\u7684\u5916\u639b\u3002 +installWizard_welcomePanel_customizeActionTitle=\u9078\u64c7\u5916\u639b\u4f86\u5b89\u88dd +installWizard_welcomePanel_customizeActionDetails=\u9078\u64c7\u4e26\u5b89\u88dd\u6700\u9069\u5408\u60a8\u7684\u5916\u639b\u3002 +installWizard_jenkinsVersionTitle=Jenkins +installWizard_offline_title=\u96e2\u7dda +installWizard_offline_message=\u6b64 Jenkins \u57f7\u884c\u500b\u9ad4\u4f3c\u4e4e\u5df2\u96e2\u7dda\u3002

      \u8acb\u53c3\u95b1 Jenkins \u96e2\u7dda\u5b89\u88dd\u6587\u4ef6\u4ee5\u4e86\u89e3\u5982\u4f55\u5728\u6c92\u6709\u7db2\u8def\u9023\u7dda\u6642\u5b89\u88dd Jenkins\u3002

      \u60a8\u53ef\u4ee5\u8a2d\u5b9a\u4ee3\u7406\u4f3a\u670d\u5668\u6216\u8df3\u904e\u5b89\u88dd\u5916\u639b\u4ee5\u7e7c\u7e8c\u3002

      +installWizard_error_title=\u932f\u8aa4 +installWizard_error_header=\u767c\u751f\u932f\u8aa4 +installWizard_error_message=\u5b89\u88dd\u6642\u767c\u751f\u932f\u8aa4\: +installWizard_error_connection=\u7121\u6cd5\u9023\u7dda\u5230 Jenkins +installWizard_error_restartNotSupported=\u4e0d\u652f\u63f4\u91cd\u65b0\u555f\u52d5\uff0c\u8acb\u624b\u52d5\u91cd\u65b0\u555f\u52d5\u6b64\u57f7\u884c\u500b\u9ad4 +installWizard_installCustom_title=\u958b\u59cb\u4f7f\u7528 +installWizard_installCustom_selectAll=\u5168\u9078 +installWizard_installCustom_selectNone=\u53d6\u6d88\u5168\u9078 +installWizard_installCustom_selectRecommended=\u63a8\u85a6 +installWizard_installCustom_selected=\u5df2\u9078\u53d6 +installWizard_installCustom_dependenciesPrefix=\u76f8\u4f9d\u6027 +installWizard_installCustom_pluginListDesc=\u63d0\u9192\u60a8\uff0c\u9019\u88e1\u4e26\u672a\u5217\u51fa\u5b8c\u6574\u7684\u5916\u639b\u6e05\u55ae\u3002\u5b8c\u6210\u521d\u59cb\u5316\u5b89\u88dd\u5f8c\u5373\u53ef\u5728\u5916\u639b\u7e3d\u7ba1\u4e2d\u5b89\u88dd\u984d\u5916\u7684\u5916\u639b\u3002\u67e5\u770b\u6587\u4ef6\u4ee5\u7372\u5f97\u66f4\u591a\u8cc7\u8a0a\u3002 +installWizard_goBack=\u8fd4\u56de +installWizard_goInstall=\u5b89\u88dd +installWizard_installing_title=\u958b\u59cb\u4f7f\u7528 +installWizard_installing_detailsLink=\u8a73\u60c5... +installWizard_installComplete_title=\u958b\u59cb\u4f7f\u7528 +installWizard_installComplete_banner=Jenkins \u5df2\u5c31\u7dd2\uff01 +installWizard_installComplete_bannerRestart=Jenkins \u5373\u5c07\u5c31\u7dd2\uff01 +installWizard_pluginsInstalled_message=\u60a8\u7684\u5916\u639b\u5df2\u5b89\u88dd\u5b8c\u6210\u3002 +installWizard_installComplete_message=\u60a8\u7684 Jenkins \u5df2\u5b89\u88dd\u5b8c\u6210\u3002 +installWizard_installComplete_finishButtonLabel=\u958b\u59cb\u4f7f\u7528 Jenkins +installWizard_installComplete_installComplete_restartRequiredMessage=\u60a8\u7684 Jenkins \u5df2\u5b89\u88dd\u5b8c\u6210\uff0c\u4f46\u67d0\u4e9b\u5916\u639b\u9700\u8981\u91cd\u65b0\u555f\u52d5 Jenkins\u3002 +installWizard_installComplete_installComplete_restartRequiredNotSupportedMessage=\u60a8\u7684 Jenkins \u5df2\u5b89\u88dd\u5b8c\u6210\uff0c\u4f46\u67d0\u4e9b\u5916\u639b\u9700\u8981\u91cd\u65b0\u555f\u52d5 Jenkins\uff0c\u4f46\u770b\u4f86\u6b64\u57f7\u884c\u500b\u9ad4\u4e0d\u652f\u63f4\u81ea\u52d5\u91cd\u65b0\u555f\u52d5\u3002\u73fe\u5728\u8acb\u624b\u52d5\u91cd\u65b0\u555f\u52d5\u60a8\u7684\u57f7\u884c\u500b\u9ad4\u4ee5\u5b8c\u6210\u5b89\u88dd\u3002 +installWizard_installComplete_restartLabel=\u91cd\u65b0\u555f\u52d5 +installWizard_installIncomplete_title=\u7e7c\u7e8c\u5b89\u88dd +installWizard_installIncomplete_banner=\u7e7c\u7e8c\u5b89\u88dd +installWizard_installIncomplete_message=Jenkins \u5728\u5b89\u88dd\u671f\u9593\u91cd\u65b0\u555f\u52d5\uff0c\u800c\u4e14\u4f3c\u4e4e\u672a\u5b89\u88dd\u67d0\u4e9b\u5916\u639b\u3002 +installWizard_installIncomplete_resumeInstallationButtonLabel=\u7e7c\u7e8c +installWizard_saveFirstUser=\u5132\u5b58\u4e26\u7e7c\u7e8c +installWizard_skipFirstUser=\u8df3\u904e\u4e26\u4ee5 admin \u7e7c\u7e8c +installWizard_firstUserSkippedMessage=
      \u60a8\u5df2\u7565\u904e\u8a2d\u5b9a\u7ba1\u7406\u54e1\u4f7f\u7528\u8005\u3002

      \u8acb\u4f7f\u7528\u5e33\u865f\uff1a\u300cadmin\u300d\u548c\u60a8\u9032\u5165\u5b89\u88dd\u7cbe\u9748\u7684\u7ba1\u7406\u54e1\u5bc6\u78bc\u767b\u5165\u3002
      +installWizard_addFirstUser_title=\u958b\u59cb\u4f7f\u7528 + +# instance configuration page +installWizard_configureInstance_title=\u57f7\u884c\u500b\u9ad4\u7d44\u614b +installWizard_saveConfigureInstance=\u5132\u5b58\u4e26\u5b8c\u6210 +installWizard_skipConfigureInstance=\u66ab\u6642\u4e0d\u8981 +installWizard_configureInstanceSkippedMessage=
      \u60a8\u5df2\u7565\u904e\u8a2d\u5b9a Jenkins URL\u3002

      \u60a8\u4e4b\u5f8c\u53ef\u4ee5\u5230\u300c\u7ba1\u7406 Jenkins\u300d\u9801\u9762\u8a2d\u5b9a Jenkins URL\u3002
      + +installWizard_configureProxy_label=\u8a2d\u5b9a\u4ee3\u7406\u4f3a\u670d\u5668 +installWizard_configureProxy_save=\u5132\u5b58\u4e26\u7e7c\u7e8c +installWizard_gettingStarted_title=\u958b\u59cb\u4f7f\u7528 +installWizard_saveSecurity=\u5132\u5b58\u4e26\u7e7c\u7e8c +installWizard_skipPluginInstallations=\u8df3\u904e\u5b89\u88dd\u5916\u639b +installWizard_installIncomplete_dependenciesLabel=\u76f8\u4f9d\u6027 +installWizard_installingConsole_dependencyIndicatorNote=** - \u5fc5\u8981\u7684\u76f8\u4f9d\u6027 +installWizard_websiteLinkLabel=\u7db2\u7ad9 +installWizard_pluginInstallFailure_title=\u5b89\u88dd\u5931\u6557 +installWizard_pluginInstallFailure_message=\u67d0\u4e9b\u5916\u639b\u5b89\u88dd\u5931\u6557\uff0c\u60a8\u53ef\u4ee5\u91cd\u65b0\u5617\u8a66\u5b89\u88dd\u4ed6\u5011\u6216\u7565\u904e\u4e26\u7e7c\u7e8c +installWizard_continue=\u7e7c\u7e8c +installWizard_retry=\u91cd\u8a66 +installWizard_upgradePanel_title=\u5347\u7ea7 +installWizard_upgradePanel_banner=\u6b61\u8fce\u4f7f\u7528 Jenkins {0}\! +installWizard_upgradePanel_message=Jenkins {0} \u5305\u542b\u4e00\u4e9b\u5f88\u68d2\u7684\u65b0\u529f\u80fd\uff0c\u6211\u5011\u8a8d\u70ba\u60a8\u6703\u559c\u6b61\u3002\u5b89\u88dd\u9019\u4e9b\u984d\u5916\u7684\u5916\u639b\u4ee5\u5584\u7528\u4ed6\u5011\u3002 +installWizard_upgradePanel_skipRecommendedPlugins=\u4e0d\u7528\uff0c\u8b1d\u8b1d +installWizard_upgradeComplete_title=\u5347\u7ea7 +installWizard_pluginsInstalled_banner=\u6b61\u8fce\u4f7f\u7528 Jenkins {0}\! +installWizard_upgradeComplete_message=\u606d\u559c\uff01\u60a8\u5df2\u5347\u7d1a\u5230 Jenkins {0}\u3002

      \u9020\u8a2a Jenkins \u7db2\u7ad9\u4ee5\u4e86\u89e3\u66f4\u591a\u65b0\u529f\u80fd\u7684\u8cc7\u8a0a\uff01 +installWizard_upgradeSkipped_title=\u5347\u7ea7 +installWizard_upgradeSkipped_banner=\u529f\u80fd\u672a\u5b89\u88dd +installWizard_upgradeSkipped_message=

      \u4e0d\u6703\u5b89\u88dd\u63a8\u85a6\u7684\u5916\u639b\u3002

      \u5982\u679c\u60a8\u6539\u8b8a\u4e3b\u610f\u4e86\uff0c\u60a8\u53ef\u5f9e\u5916\u639b\u7e3d\u7ba1\u5b89\u88dd\u65b0\u529f\u80fd\u3002

      Learn how these new features can improve your Jenkins experience by \u9020\u8a2a\u9996\u9801\u4ee5\u4e86\u89e3\u9019\u4e9b\u65b0\u529f\u80fd\u5982\u4f55\u63d0\u5347\u60a8\u7684 Jenkins \u4f7f\u7528\u9ad4\u9a57\u3002

      +installWizard_upgrading_title=\u6b63\u5728\u5b89\u88dd\u5916\u639b +installWizard_upgradeComplete_finishButtonLabel=\u5b8c\u6210 diff --git a/core/src/main/resources/jenkins/management/AdministrativeMonitorsApiData/monitorsList_pt_BR.properties b/core/src/main/resources/jenkins/management/AdministrativeMonitorsApiData/monitorsList_pt_BR.properties new file mode 100644 index 000000000000..dce6de3e72bc --- /dev/null +++ b/core/src/main/resources/jenkins/management/AdministrativeMonitorsApiData/monitorsList_pt_BR.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Manage\ Jenkins=Gerenciar o Jenkins +no_active_monitors=Atualmente n\u00E3o h\u00E1 nenhum aviso diff --git a/core/src/main/resources/jenkins/management/AdministrativeMonitorsApiData/monitorsList_zh_TW.properties b/core/src/main/resources/jenkins/management/AdministrativeMonitorsApiData/monitorsList_zh_TW.properties new file mode 100644 index 000000000000..9a889109d7de --- /dev/null +++ b/core/src/main/resources/jenkins/management/AdministrativeMonitorsApiData/monitorsList_zh_TW.properties @@ -0,0 +1,2 @@ +no_active_monitors=\u76ee\u524d\u6c92\u6709\u8b66\u544a +Manage\ Jenkins=\u7ba1\u7406 Jenkins diff --git a/core/src/main/resources/jenkins/management/AdministrativeMonitorsConfiguration/config.groovy b/core/src/main/resources/jenkins/management/AdministrativeMonitorsConfiguration/config.groovy index 6327d38955d6..fb00245ad877 100644 --- a/core/src/main/resources/jenkins/management/AdministrativeMonitorsConfiguration/config.groovy +++ b/core/src/main/resources/jenkins/management/AdministrativeMonitorsConfiguration/config.groovy @@ -32,23 +32,21 @@ st = namespace("jelly:stapler") f.section(title: _("Administrative monitors configuration")) { f.advanced(title: _("Administrative monitors")) { f.entry(title: _("Enabled administrative monitors")) { - p(_("blurb")) - div(width: "100%") { - for (AdministrativeMonitor am : new ArrayList<>(AdministrativeMonitor.all()) - .sort({ o1, o2 -> o1.getDisplayName() <=> o2.getDisplayName() })) { - f.block() { - f.checkbox(name: "administrativeMonitor", - title: am.displayName, - checked: am.enabled, - json: am.id) - if (am.isSecurity()) { - span(style: 'margin-left: 0.5rem', class: 'am-badge', _("Security")) - } + p(class: "jenkins-form-description", _("blurb")) + for (AdministrativeMonitor am : new ArrayList<>(AdministrativeMonitor.all()) + .sort({ o1, o2 -> o1.getDisplayName() <=> o2.getDisplayName() })) { + div(class: "jenkins-checkbox-help-wrapper") { + f.checkbox(name: "administrativeMonitor", + title: am.displayName, + checked: am.enabled, + json: am.id) + if (am.isSecurity()) { + span(style: 'margin-left: 0.5rem', class: 'am-badge', _("Security")) } - div(class: "tr") { - div(class: "setting-description") { - st.include(from: am, page: "description", optional: true) - } + } + div(class: "tr") { + div(class: "jenkins-checkbox__description") { + st.include(from: am, page: "description", optional: true) } } } diff --git a/core/src/main/resources/jenkins/management/AdministrativeMonitorsConfiguration/config_zh_TW.properties b/core/src/main/resources/jenkins/management/AdministrativeMonitorsConfiguration/config_zh_TW.properties new file mode 100644 index 000000000000..8a727a0e6056 --- /dev/null +++ b/core/src/main/resources/jenkins/management/AdministrativeMonitorsConfiguration/config_zh_TW.properties @@ -0,0 +1 @@ +blurb = \u7ba1\u7406\u76e3\u8996\u5668\u662f\u986f\u793a\u7d66 Jenkins \u7ba1\u7406\u54e1\u6709\u95dc\u6b64 Jenkins \u57f7\u884c\u500b\u9ad4\u72c0\u614b\u7684\u8b66\u544a\u3002\u4e00\u822c\u5f37\u70c8\u5efa\u8b70\u555f\u7528\u6240\u6709\u7ba1\u7406\u76e3\u8996\u5668\uff0c\u82e5\u60a8\u4e26\u4e0d\u5728\u610f\u67d0\u4e9b\u8b66\u544a\uff0c\u5728\u9019\u88e1\u53d6\u6d88\u9078\u53d6\u4ee5\u96b1\u85cf\u5b83\u5011\u3002 diff --git a/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/footer_pt_BR.properties b/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/footer_pt_BR.properties new file mode 100644 index 000000000000..7f0eda281b6b --- /dev/null +++ b/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/footer_pt_BR.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +tooltip=Existem {0} monitores administrativos ativos. +tooltipSec=Existem {0} monitores administrativos de seguran\u00E7a ativos. diff --git a/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/footer_zh_TW.properties b/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/footer_zh_TW.properties new file mode 100644 index 000000000000..98f919d0e54b --- /dev/null +++ b/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/footer_zh_TW.properties @@ -0,0 +1,2 @@ +tooltip=\u6709 {0} \u500b\u555f\u7528\u4e2d\u7684\u7ba1\u7406\u76e3\u8996\u5668\u3002 +tooltipSec=\u6709 {0} \u500b\u555f\u7528\u4e2d\u7684\u5b89\u5168\u6027\u7ba1\u7406\u76e3\u8996\u5668\u3002 diff --git a/core/src/main/resources/jenkins/management/AsynchronousAdministrativeMonitor/log.groovy b/core/src/main/resources/jenkins/management/AsynchronousAdministrativeMonitor/log.groovy index b9c4b5a92970..2afa31b94162 100644 --- a/core/src/main/resources/jenkins/management/AsynchronousAdministrativeMonitor/log.groovy +++ b/core/src/main/resources/jenkins/management/AsynchronousAdministrativeMonitor/log.groovy @@ -33,7 +33,7 @@ l.layout { if (my.isFixingActive()) { pre(id: "out") div(id: "spinner") { - img(src: "${imagesURL}/spinner.gif", alt: "") + l.progessAnimation() } t.progressiveText(spinner: "spinner", href: "logText/progressiveHtml", idref: "out") } else { diff --git a/core/src/main/resources/jenkins/management/Messages_bg.properties b/core/src/main/resources/jenkins/management/Messages_bg.properties index 22a399bbfda4..6ce72696078f 100644 --- a/core/src/main/resources/jenkins/management/Messages_bg.properties +++ b/core/src/main/resources/jenkins/management/Messages_bg.properties @@ -45,7 +45,7 @@ SystemInfoLink.Description=\ SystemLogLink.DisplayName=\ \u0421\u0438\u0441\u0442\u0435\u043c\u0435\u043d \u0436\u0443\u0440\u043d\u0430\u043b SystemLogLink.Description=\ - \u0412 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u0438\u044f \u0436\u0443\u0440\u043d\u0430\u043b \u0441\u0435 \u0437\u0430\u043f\u0438\u0441\u0432\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f\u0442\u0430 \u043e\u0442 java.util.logging \u0437\u0430\ + \u0412 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u0438\u044f \u0436\u0443\u0440\u043d\u0430\u043b \u0441\u0435 \u0437\u0430\u043f\u0438\u0441\u0432\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f\u0442\u0430 \u043e\u0442 java.util.logging \u0437\u0430\ Jenkins. StatisticsLink.DisplayName=\ diff --git a/core/src/main/resources/jenkins/management/Messages_cs.properties b/core/src/main/resources/jenkins/management/Messages_cs.properties index 475906a05b27..72b929c0497f 100644 --- a/core/src/main/resources/jenkins/management/Messages_cs.properties +++ b/core/src/main/resources/jenkins/management/Messages_cs.properties @@ -37,5 +37,5 @@ ReloadLink.DisplayName=Znovu nahr\u00E1t konfiguraci z disku ConsoleLink.DisplayName=Konzole ShutdownLink.Description=P\u0159estane spou\u0161t\u011Bt nov\u00E9 buildy, aby mohl b\u00FDt syst\u00E9m pozd\u011Bji bezpe\u010Dn\u011B vypnut. SystemInfoLink.DisplayName=Syst\u00E9mov\u00E9 informace -SystemLogLink.Description=Syst\u00E9mov\u00FD log ukl\u00E1d\u00E1 v\u00FDstup java.util.logging, kter\u00FD se t\u00FDk\u00E1 Jenkinse. +SystemLogLink.Description=Syst\u00E9mov\u00FD log ukl\u00E1d\u00E1 v\u00FDstup java.util.logging, kter\u00FD se t\u00FDk\u00E1 Jenkinse. diff --git a/core/src/main/resources/jenkins/management/Messages_da.properties b/core/src/main/resources/jenkins/management/Messages_da.properties index e005c088fbc0..e7549ed089b0 100644 --- a/core/src/main/resources/jenkins/management/Messages_da.properties +++ b/core/src/main/resources/jenkins/management/Messages_da.properties @@ -27,7 +27,7 @@ CliLink.Description=Tilg\u00E5/bestyr Jenkins fra din shell eller fra dit skript ConfigureLink.Description=Konfigurer globale indstillinger og stier. ShutdownLink.Description=Stopper udf\u00F8ring at nye byg, s\u00E5 systemet kan lukke sikkert ned. ReloadLink.DisplayName=Genindl\u00E6s konfiguration fra harddisk -SystemLogLink.Description=Systemloggen opsamler output fra java.util.logging relateret til Jenkins. +SystemLogLink.Description=Systemloggen opsamler output fra java.util.logging relateret til Jenkins. NodesLink.Description=Tilf\u00F8je, slette, h\u00E5ndtere og overv\u00E5ge de forskellige knuder som Jenkins k\u00F8rer jobs p\u00E5. PluginsLink.DisplayName=Pluginh\u00E5ndtering StatisticsLink.Description=Tjek dit ressourceforbrug og se om du har brug for flere maskiner til dine byg. diff --git a/core/src/main/resources/jenkins/management/Messages_es.properties b/core/src/main/resources/jenkins/management/Messages_es.properties index 156b0b03581e..d3103f659f36 100644 --- a/core/src/main/resources/jenkins/management/Messages_es.properties +++ b/core/src/main/resources/jenkins/management/Messages_es.properties @@ -41,5 +41,5 @@ ReloadLink.DisplayName=Actualizar configuraci\u00F3n desde el disco duro. ConsoleLink.DisplayName=Consola de scripts ShutdownLink.Description=Detener la ejecuci\u00F3n de nuevas tareas para que el sistema pueda apagarse de manera segura. SystemInfoLink.DisplayName=Informaci\u00F3n del sistema -SystemLogLink.Description=El log del sistema captura la salidad de la clase java.util.logging en todo lo relacionado con Jenkins. +SystemLogLink.Description=El log del sistema captura la salidad de la clase java.util.logging en todo lo relacionado con Jenkins. diff --git a/core/src/main/resources/jenkins/management/Messages_fi.properties b/core/src/main/resources/jenkins/management/Messages_fi.properties index aa0c78c6592e..8b81a92b078e 100644 --- a/core/src/main/resources/jenkins/management/Messages_fi.properties +++ b/core/src/main/resources/jenkins/management/Messages_fi.properties @@ -41,5 +41,5 @@ ReloadLink.DisplayName=Uudelleenlataa konfiguraatio ConsoleLink.DisplayName=Skriptikonsoli ShutdownLink.Description=Pys\u00E4ytt\u00E4\u00E4 uusien k\u00E4\u00E4nn\u00F6ksien k\u00E4ynnist\u00E4misen niin ett\u00E4 j\u00E4rjestelm\u00E4 voidaan ajaa turvallisesti alas. SystemInfoLink.DisplayName=J\u00E4rjestelm\u00E4tiedot -SystemLogLink.Description=J\u00E4rjestelm\u00E4lokia tuostettuna java.util.logging Jenkins ulostuloon. +SystemLogLink.Description=J\u00E4rjestelm\u00E4lokia tuostettuna java.util.logging Jenkins ulostuloon. diff --git a/core/src/main/resources/jenkins/management/Messages_fr.properties b/core/src/main/resources/jenkins/management/Messages_fr.properties index 4449f47d3cc9..0b913713a666 100644 --- a/core/src/main/resources/jenkins/management/Messages_fr.properties +++ b/core/src/main/resources/jenkins/management/Messages_fr.properties @@ -39,7 +39,7 @@ SystemInfoLink.DisplayName=Informations sur le syst\u00e8me SystemInfoLink.Description=Affiche diverses informations relatives au syst\u00e8me pour aider \u00e0 la r\u00e9solution de probl\u00eames. SystemLogLink.DisplayName=Logs syst\u00e8mes -SystemLogLink.Description=Le log syst\u00e8me capture la sortie java.util.logging relative \u00e0 Jenkins. +SystemLogLink.Description=Le log syst\u00e8me capture la sortie java.util.logging relative \u00e0 Jenkins. StatisticsLink.DisplayName=Statistiques d''utilisation StatisticsLink.Description=V\u00e9rifiez l''utilisation des ressources et d\u00e9cidez si vous avez besoin d''ordinateurs suppl\u00e9mentaires pour vos builds. diff --git a/core/src/main/resources/jenkins/management/Messages_ja.properties b/core/src/main/resources/jenkins/management/Messages_ja.properties index 8f6df43e9aa6..8bfa4fb7e753 100644 --- a/core/src/main/resources/jenkins/management/Messages_ja.properties +++ b/core/src/main/resources/jenkins/management/Messages_ja.properties @@ -37,7 +37,7 @@ SystemInfoLink.Description=\ \u30c8\u30e9\u30d6\u30eb\u30b7\u30e5\u30fc\u30c6\u30a3\u30f3\u30b0\u3092\u52a9\u3051\u308b\u305f\u3081\u306e\u69d8\u3005\u306a\u74b0\u5883\u5909\u6570\u306e\u60c5\u5831\u3092\u8868\u793a\u3057\u307e\u3059\u3002 SystemLogLink.DisplayName=\u30b7\u30b9\u30c6\u30e0\u30ed\u30b0 SystemLogLink.Description=\ - \u30b7\u30b9\u30c6\u30e0\u30ed\u30b0\u306fJenkins\u95a2\u9023\u306ejava.util.logging\u304b\u3089\u306e\u51fa\u529b\u3092\u30ad\u30e3\u30d7\u30c1\u30e3\u30fc\u3057\u307e\u3059\u3002 + \u30b7\u30b9\u30c6\u30e0\u30ed\u30b0\u306fJenkins\u95a2\u9023\u306ejava.util.logging\u304b\u3089\u306e\u51fa\u529b\u3092\u30ad\u30e3\u30d7\u30c1\u30e3\u30fc\u3057\u307e\u3059\u3002 StatisticsLink.DisplayName=\u8ca0\u8377\u7d71\u8a08 StatisticsLink.Description=\u30ea\u30bd\u30fc\u30b9\u306e\u5229\u7528\u72b6\u6cc1\u3092\u30c1\u30a7\u30c3\u30af\u3057\u3066\u3001\u3082\u3063\u3068\u30b3\u30f3\u30d4\u30e5\u30fc\u30bf\u30fc\u3092\u8ffd\u52a0\u3057\u3066\u30d3\u30eb\u30c9\u3059\u308b\u5fc5\u8981\u304c\u3042\u308b\u304b\u628a\u63e1\u3057\u307e\u3059\u3002 ConsoleLink.DisplayName=\u30b9\u30af\u30ea\u30d7\u30c8\u30b3\u30f3\u30bd\u30fc\u30eb diff --git a/core/src/main/resources/jenkins/management/Messages_lt.properties b/core/src/main/resources/jenkins/management/Messages_lt.properties index 929aa43e71f1..5441f817a5ca 100644 --- a/core/src/main/resources/jenkins/management/Messages_lt.properties +++ b/core/src/main/resources/jenkins/management/Messages_lt.properties @@ -28,5 +28,5 @@ StatisticsLink.DisplayName=Apkrovos statistika SystemInfoLink.Description=Rodo \u012Fvairi\u0105 aplinkos informacij\u0105, kuri padeda aptikti problemas. SystemInfoLink.DisplayName=Sistemos informacija -SystemLogLink.Description=Sistemos \u017Eurnale kaupiama informacija i\u0161 java.util.logging i\u0161vesties, susijusios su Jenkinsu. +SystemLogLink.Description=Sistemos \u017Eurnale kaupiama informacija i\u0161 java.util.logging i\u0161vesties, susijusios su Jenkinsu. SystemLogLink.DisplayName=Sistemos \u017Eurnalas diff --git a/core/src/main/resources/jenkins/management/Messages_nb_NO.properties b/core/src/main/resources/jenkins/management/Messages_nb_NO.properties index 0321ca51e649..129d39692266 100644 --- a/core/src/main/resources/jenkins/management/Messages_nb_NO.properties +++ b/core/src/main/resources/jenkins/management/Messages_nb_NO.properties @@ -38,4 +38,4 @@ ReloadLink.Description=Nyttig n\u00E5r du har endret konfigurasjonsfiler direkte ConsoleLink.DisplayName=Skriptkonsoll ShutdownLink.Description=Stopper eksekvering av nye bygg slik at systemet kan avsluttes p\u00E5 en sikker m\u00E5te. SystemInfoLink.DisplayName=Systeminformasjon -SystemLogLink.Description=Systemloggen fanger output fra java.util.loggingoutput relatert til Jenkins. +SystemLogLink.Description=Systemloggen fanger output fra java.util.loggingoutput relatert til Jenkins. diff --git a/core/src/main/resources/jenkins/management/Messages_nl.properties b/core/src/main/resources/jenkins/management/Messages_nl.properties index 56492c525b51..33fca9dac671 100644 --- a/core/src/main/resources/jenkins/management/Messages_nl.properties +++ b/core/src/main/resources/jenkins/management/Messages_nl.properties @@ -35,7 +35,7 @@ PluginsLink.DisplayName=Beheer plugins SystemInfoLink.DisplayName=Systeeminformatie SystemInfoLink.Description=Toon omgevingsinformatie die je kan helpen bij probleemoplossing. SystemLogLink.Description=\ -Het logsysteem zal de uitvoer van java.util.logging voor Jenkins registreren. +Het logsysteem zal de uitvoer van java.util.logging voor Jenkins registreren. ConsoleLink.DisplayName=Scriptconsole ConsoleLink.Description=Voer een arbitrair script uit voor admistratieve/correctieve/diagnostische redenen. NodesLink.Description=Toevoegen, verwijderen, beheren en monitor van de verschillende Jenkins Nodes. diff --git a/core/src/main/resources/jenkins/management/Messages_pl.properties b/core/src/main/resources/jenkins/management/Messages_pl.properties index bae564f04c78..887db926a48e 100644 --- a/core/src/main/resources/jenkins/management/Messages_pl.properties +++ b/core/src/main/resources/jenkins/management/Messages_pl.properties @@ -37,7 +37,7 @@ StatisticsLink.DisplayName=Statystyki obci\u0105\u017Cenia StatisticsLink.Description=Sprawd\u017A obci\u0105\u017Cenie zasob\u00F3w systemowych i dowiedz si\u0119, czy nie potrzebujesz wi\u0119cej maszyn do uruchamiania zada\u0144. SystemLogLink.DisplayName=Dziennik systemowy -SystemLogLink.Description=Dziennik systemowy gromadzi wywoy\u0142ania java.util.logging powi\u0105zane z Jenkinsem. +SystemLogLink.Description=Dziennik systemowy gromadzi wywoy\u0142ania java.util.logging powi\u0105zane z Jenkinsem. CliLink.DisplayName=Wiersz polece\u0144 Jenkinsa CliLink.Description=Zarz\u0105dzaj Jenkinsem poziomu z wiersza polece\u0144 lub systemu. diff --git a/core/src/main/resources/jenkins/management/Messages_pt_BR.properties b/core/src/main/resources/jenkins/management/Messages_pt_BR.properties index d066dcce2e01..734611ee02a9 100644 --- a/core/src/main/resources/jenkins/management/Messages_pt_BR.properties +++ b/core/src/main/resources/jenkins/management/Messages_pt_BR.properties @@ -23,25 +23,31 @@ # CliLink.Description=Acesse e gerencie o Jenkins pelo shell, ou pelo seu script. -StatisticsLink.DisplayName=Estat\u00edsticas de carga -StatisticsLink.Description=Verifica a utiliza\u00e7\u00e3o de recursos e se voc\u00ea precisa de mais computadores para seus builds -ReloadLink.DisplayName=Recarregar configura\u00e7\u00e3o do disco +StatisticsLink.DisplayName=Estat\u00EDsticas de carga +StatisticsLink.Description=Verifica a utiliza\u00E7\u00E3o de recursos e se voc\u00EA precisa de mais computadores para suas constru\u00E7\u00F5es +ReloadLink.DisplayName=Recarregar configura\u00E7\u00E3o do disco ConfigureLink.DisplayName=Configurar o sistema -ConfigureLink.Description=Configurar op\u00e7\u00f5es globais e caminhos -ReloadLink.Description=Descartar todos os dados carregados na mem\u00f3ria e recarregar tudo do sistema de arquivos.\n\ - Isso \u00e9 \u00fatil quando seus arquivos de configura\u00e7\u00e3o foram modificados diretamente no disco. -PluginsLink.DisplayName=Gerenciar plugins -SystemInfoLink.DisplayName=Informa\u00e7\u00f5es do sistema -SystemInfoLink.Description=Mostrar v\u00e1rias informa\u00e7\u00f5es do ambiente para auxiliar na resolu\u00e7\u00e3o de problemas. -SystemLogLink.DisplayName=Log do sistema -SystemLogLink.Description=O log do sistema captura a sa\u00edda de java.util.logging relacionada ao Jenkins. +ConfigureLink.Description=Configurar op\u00E7\u00F5es globais e caminhos +ReloadLink.Description=Descartar todos os dados carregados na mem\u00F3ria e recarregar tudo do sistema de arquivos. \ + Isso \u00E9 \u00FAtil quando seus arquivos de configura\u00E7\u00E3o foram modificados diretamente no disco. +PluginsLink.DisplayName=Gerenciar extens\u00F5es +SystemInfoLink.DisplayName=Informa\u00E7\u00F5es do sistema +SystemInfoLink.Description=Mostrar v\u00E1rias informa\u00E7\u00F5es do ambiente para auxiliar na resolu\u00E7\u00E3o de problemas. +SystemLogLink.DisplayName=Registro de atividades do sistema +SystemLogLink.Description=O registro de atividades do sistema captura a sa\u00EDda de java.util.logging relacionada ao Jenkins. ConsoleLink.DisplayName=Console de script -ConsoleLink.Description=Executa script arbitr\u00e1rio para administrar, diagnosticar ou corrigir problemas. -PluginsLink.Description=Adiciona, remove, desabilita e habilita plugins que podem incrementar as funcionalidades do Jenkins. +ConsoleLink.Description=Executa script arbitr\u00E1rio para administrar, diagnosticar ou corrigir problemas. +PluginsLink.Description=Adiciona, remove, desabilita e habilita extens\u00F5es que podem incrementar as funcionalidades do Jenkins. ShutdownLink.DisplayName_cancel=Cancelar o desligamento ShutdownLink.DisplayName_prepare=Preparar para desligar -ShutdownLink.Description=Interrompe a execu\u00e7\u00e3o de novos builds, para que o sistema possa ser eventualmente desligado com seguran\u00e7a. -NodesLink.Description=Adiciona, remove, controla e monitora o v\u00e1rios n\u00f3s -NodesLink.DisplayName= Gerenciar n\u00f3s -# Jenkins CLI -CliLink.DisplayName=Jenkins CLI +ShutdownLink.Description=Interrompe a execu\u00E7\u00E3o de novas constru\u00E7\u00F5es para que o sistema possa ser eventualmente desligado com seguran\u00E7a. +NodesLink.Description=Adiciona, remove, controla e monitora o v\u00E1rios n\u00F3s +NodesLink.DisplayName= Gerenciar n\u00F3s +CliLink.DisplayName=Interface de Linha de Commando do Jenkins (CLI) +ConfigureTools.DisplayName=Ferramenta de configura\u00E7\u00E3o global +ShutdownLink.DisplayName_update=Atualizar prepara\u00E7\u00E3o de desligamento +ShutdownLink.ShutDownReason_update=Atualizar raz\u00E3o +AdministrativeMonitorsDecorator.DisplayName=Notificador de monitora\u00E7\u00F5es administrativas +ConfigureTools.Description=Configurar ferramentas, suas localiza\u00E7\u00F5es e instaladores autom\u00E1ticos. +ShutdownLink.ShuttingDownInProgressDescription=O Jenkins est\u00E1 sendo desligado no momento. Novas constru\u00E7\u00F5es n\u00E3o ser\u00E3o executadas. +ShutdownLink.ShutDownReason_title=Raz\u00E3o diff --git a/core/src/main/resources/jenkins/management/Messages_ru.properties b/core/src/main/resources/jenkins/management/Messages_ru.properties index d8f50188293e..ff3f00dbb183 100644 --- a/core/src/main/resources/jenkins/management/Messages_ru.properties +++ b/core/src/main/resources/jenkins/management/Messages_ru.properties @@ -22,7 +22,7 @@ # THE SOFTWARE. # -SystemLogLink.Description=\u0421\u0438\u0441\u0442\u0435\u043C\u043D\u044B\u0439 \u0436\u0443\u0440\u043D\u0430\u043B \u0441\u0447\u0438\u0442\u044B\u0432\u0430\u0435\u0442 \u0432\u044B\u0432\u043E\u0434 java.util.logging, \u043E\u0442\u043D\u043E\u0441\u044F\u0449\u0438\u0439\u0441\u044F \u043A Jenkins. +SystemLogLink.Description=\u0421\u0438\u0441\u0442\u0435\u043C\u043D\u044B\u0439 \u0436\u0443\u0440\u043D\u0430\u043B \u0441\u0447\u0438\u0442\u044B\u0432\u0430\u0435\u0442 \u0432\u044B\u0432\u043E\u0434 java.util.logging, \u043E\u0442\u043D\u043E\u0441\u044F\u0449\u0438\u0439\u0441\u044F \u043A Jenkins. CliLink.Description=\u0414\u043E\u0441\u0442\u0443\u043F \u0438 \u0443\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435 Jenkins \u0438\u0437 \u043A\u043E\u043C\u0430\u043D\u0434\u043D\u043E\u0439 \u043E\u0431\u043E\u043B\u043E\u0447\u043A\u0438 \u0438\u043B\u0438 \u043F\u0440\u0438 \u043F\u043E\u043C\u043E\u0449\u0438 \u0441\u043A\u0440\u0438\u043F\u0442\u043E\u0432. StatisticsLink.DisplayName=\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043A\u0430 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u044F StatisticsLink.Description=\u041A\u043E\u043D\u0442\u0440\u043E\u043B\u044C \u0437\u0430 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435\u043C \u0430\u043F\u043F\u0430\u0440\u0430\u0442\u043D\u044B\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043E\u0432. \u041F\u043E\u0437\u0432\u043E\u043B\u044F\u0435\u0442 \u0432\u044B\u044F\u0432\u0438\u0442\u044C \u043F\u043E\u0442\u0440\u0435\u0431\u043D\u043E\u0441\u0442\u044C \u0432 \u0434\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u044B\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u0430\u0445 \u0434\u043B\u044F \u0432\u044B\u043F\u043E\u043B\u043D\u0435\u043D\u0438\u044F \u0441\u0431\u043E\u0440\u043E\u043A. diff --git a/core/src/main/resources/jenkins/management/Messages_sk.properties b/core/src/main/resources/jenkins/management/Messages_sk.properties index 25ebb340a3ef..01edf6b5f2b5 100644 --- a/core/src/main/resources/jenkins/management/Messages_sk.properties +++ b/core/src/main/resources/jenkins/management/Messages_sk.properties @@ -37,4 +37,4 @@ SystemInfoLink.Description=Zobrazuje r\u00F4zne inform\u00E1cie o prostred\u00ED ReloadLink.Description=Zahodi\u0165 v\u0161etky nahran\u00E9 d\u00E1ta v pam\u00E4ti a znovu nahra\u0165 v\u0161etko z disku.\n\ Hod\u00ED sa pokia\u013E ste zmenili konfigura\u010Dn\u00E9 s\u00FAbory priamo na disku. CliLink.Description=Pr\u00EDstup/nastavenie Jenkins z pr\u00EDkazov\u00E9ho riadku alebo pomocou skriptu. -SystemLogLink.Description=Syst\u00E9mov\u00FD log uklad\u00E1 v\u00FDstup java.util.logging, ktor\u00FD sa t\u00FDka Jenkins. +SystemLogLink.Description=Syst\u00E9mov\u00FD log uklad\u00E1 v\u00FDstup java.util.logging, ktor\u00FD sa t\u00FDka Jenkins. diff --git a/core/src/main/resources/jenkins/management/Messages_sr.properties b/core/src/main/resources/jenkins/management/Messages_sr.properties index 4f4fb089f6b0..04d63ea3f82e 100644 --- a/core/src/main/resources/jenkins/management/Messages_sr.properties +++ b/core/src/main/resources/jenkins/management/Messages_sr.properties @@ -11,7 +11,7 @@ PluginsLink.DisplayName=\u041F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u SystemInfoLink.DisplayName=\u0418\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u0458\u0435 \u043E \u0441\u0438\u0441\u0442\u0435\u043C\u0443 SystemInfoLink.Description=\u041F\u0440\u0438\u043A\u0430\u0437\u0443\u0458\u0435 \u0440\u0430\u0437\u043D\u0443 \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u0458\u0443 \u043E \u0441\u0438\u0441\u0442\u0435\u043C\u0443 \u0434\u0430 \u0431\u0443 \u043F\u043E\u043C\u0430\u0433\u0430\u043B\u043E \u0441\u0430 \u0440\u0435\u0448\u0430\u0432\u0430\u045A\u0435\u043C \u043F\u0440\u043E\u0431\u043B\u0435\u043C\u0438\u043C\u0430. SystemLogLink.DisplayName=\u0416\u0443\u0440\u043D\u0430\u043B \u0441\u0438\u0441\u0442\u0435\u043C\u0430 -SystemLogLink.Description=\u0416\u0443\u0440\u043D\u0430\u043B \u0441\u0438\u0441\u0442\u0435\u043C\u0430 \u0437\u0430\u043F\u0438\u0441\u0443\u0458\u0435 \u0438\u0441\u0445\u043E\u0434 java.util.logging \u043A\u043E\u0458\u0438 \u0441\u0435 \u043E\u0434\u043D\u043E\u0441\u0438 \u043D\u0430 Jenkins. +SystemLogLink.Description=\u0416\u0443\u0440\u043D\u0430\u043B \u0441\u0438\u0441\u0442\u0435\u043C\u0430 \u0437\u0430\u043F\u0438\u0441\u0443\u0458\u0435 \u0438\u0441\u0445\u043E\u0434 java.util.logging \u043A\u043E\u0458\u0438 \u0441\u0435 \u043E\u0434\u043D\u043E\u0441\u0438 \u043D\u0430 Jenkins. StatisticsLink.DisplayName=\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043A\u0435 \u043E \u043E\u043F\u0442\u0435\u0440\u0435\u045B\u0435\u045A\u0443 StatisticsLink.Description=\u041F\u0440\u043E\u0432\u0435\u0440\u0438\u0442\u0435 \u043E\u043F\u0442\u0435\u0440\u0435\u045B\u0435\u045A\u0435 \u043D\u0430\u0434 \u0440\u0435\u0441\u0443\u0440\u0441\u0438\u043C\u0430 \u0434\u0430 \u0431\u0438 \u0441\u0442\u0435 \u043E\u0434\u0440\u0435\u0434\u0438\u043B\u0438 \u0430\u043A\u043E \u0458\u0435 \u043F\u043E\u0442\u0440\u0435\u0431\u043D\u043E \u0432\u0438\u0448\u0435 \u043C\u0430\u0448\u0438\u043D\u0430 \u0437\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443. CliLink.Description=\u0414\u043E\u0441\u0442\u0443\u043F\u0438\u0442\u0435 \u0438 \u0443\u043F\u0440\u0430\u0432\u0459\u0430\u0458\u0442\u0435 Jenkins-\u043E\u043C \u0441\u0430 \u043A\u043E\u043C\u0430\u043D\u0434\u043D\u0435 \u043B\u0438\u043D\u0438\u0458\u0435 \u0438\u043B\u0438 \u0441\u043A\u0440\u0438\u043F\u0442\u043E\u043C. diff --git a/core/src/main/resources/jenkins/management/Messages_sv_SE.properties b/core/src/main/resources/jenkins/management/Messages_sv_SE.properties index 44461cc0bf41..1f0e7231c25a 100644 --- a/core/src/main/resources/jenkins/management/Messages_sv_SE.properties +++ b/core/src/main/resources/jenkins/management/Messages_sv_SE.properties @@ -40,4 +40,4 @@ ReloadLink.DisplayName=L\u00E4s om konfigurationen fr\u00E5n disk. ConsoleLink.DisplayName=Skriptkonsoll ShutdownLink.Description=Sluta starta nya byggen, s\u00E5 att systemet sedan kan st\u00E4ngas s\u00E4kert. SystemInfoLink.DisplayName=Systeminformation -SystemLogLink.Description=Systemloggen f\u00E5ngar utskrift fr\u00E5n java.util.logging relaterat till Jenkins. +SystemLogLink.Description=Systemloggen f\u00E5ngar utskrift fr\u00E5n java.util.logging relaterat till Jenkins. diff --git a/core/src/main/resources/jenkins/management/Messages_tr.properties b/core/src/main/resources/jenkins/management/Messages_tr.properties index 677e1ce113f0..bff568b4c16e 100644 --- a/core/src/main/resources/jenkins/management/Messages_tr.properties +++ b/core/src/main/resources/jenkins/management/Messages_tr.properties @@ -22,8 +22,8 @@ # THE SOFTWARE. # -SystemLogLink.Description=Sistem logu Jenkins''le ilgili olan java.util.logging \u00E7\u0131kt\u0131lar\u0131n\u0131 yakalar. -ReloadLink.DisplayName=Konfig\u00FCrasayonu Disk''ten Y\u00FCkle +SystemLogLink.Description=Sistem logu Jenkins''le ilgili olan java.util.logging \u00E7\u0131kt\u0131lar\u0131n\u0131 yakalar. +ReloadLink.DisplayName=Konfig\u00FCrasyonu Disk''ten Y\u00FCkle ReloadLink.Description=Haf\u0131zada tutulan yap\u0131lm\u0131\u015F t\u00FCm de\u011Fi\u015Fiklikleri iptal et ve her\u015Feyi dosya sisteminden y\u00FCkle.\n\ Konfig\u00FCrasyon dosyalar\u0131n\u0131 do\u011Frudan diskten de\u011Fi\u015Ftirdiyseniz kullan\u0131\u015Fl\u0131d\u0131r PluginsLink.DisplayName=Eklentileri Y\u00F6net diff --git a/core/src/main/resources/jenkins/management/Messages_zh_TW.properties b/core/src/main/resources/jenkins/management/Messages_zh_TW.properties index 897da1f7fa46..c9c28b0afe95 100644 --- a/core/src/main/resources/jenkins/management/Messages_zh_TW.properties +++ b/core/src/main/resources/jenkins/management/Messages_zh_TW.properties @@ -1,8 +1,7 @@ # # The MIT License # -# Copyright (c) 2012-2013, CloudBees, Intl., Nicolas De loof, -# Chunghwa Telecom Co., Ltd., and Pei-Tang Huang +# Copyright (c) 2012, CloudBees, Intl., Nicolas De loof # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -21,13 +20,17 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. +# ConfigureLink.DisplayName=\u8a2d\u5b9a\u7cfb\u7d71 ConfigureLink.Description=\u8a2d\u5b9a\u5168\u57df\u8a2d\u5b9a\u53ca\u8def\u5f91\u3002 +ConfigureTools.DisplayName=\u5168\u57df\u5de5\u5177\u8a2d\u5b9a +ConfigureTools.Description=\u8a2d\u5b9a\u5de5\u5177\uff0c\u5305\u542b\u5b83\u5011\u7684\u4f4d\u7f6e\u548c\u81ea\u52d5\u5b89\u88dd\u7a0b\u5f0f\u3002 + ReloadLink.DisplayName=\u5f9e\u78c1\u789f\u91cd\u65b0\u8f09\u5165\u8a2d\u5b9a ReloadLink.Description=\u653e\u68c4\u6240\u6709\u5728\u8a18\u61b6\u9ad4\u88e1\u7684\u8cc7\u6599\uff0c\u5168\u90e8\u7531\u6a94\u6848\u7cfb\u7d71\u91cd\u65b0\u8f09\u5165\u3002\n\ - \u5982\u679c\u60a8\u76f4\u63a5\u4fee\u6539\u904e\u8a2d\u5b9a\u6a94\uff0c\u9019\u500b\u529f\u80fd\u5c31\u61c9\u8a72\u883b\u6709\u7528\u7684\u3002 +\u5982\u679c\u60a8\u76f4\u63a5\u4fee\u6539\u904e\u8a2d\u5b9a\u6a94\uff0c\u9019\u500b\u529f\u80fd\u5c31\u61c9\u8a72\u883b\u6709\u7528\u7684\u3002 PluginsLink.DisplayName=\u7ba1\u7406\u5916\u639b\u7a0b\u5f0f PluginsLink.Description=\u5916\u639b\u7a0b\u5f0f\u662f\u80fd\u64f4\u5145 Jenkins \u529f\u80fd\u7684\u7a0b\u5f0f\uff0c\u60a8\u53ef\u4ee5\u5728\u9019\u88e1\u65b0\u589e\u3001\u79fb\u9664\u3001\u505c\u7528\u6216\u662f\u555f\u7528\u5b83\u5011\u3002 @@ -47,9 +50,15 @@ CliLink.Description=\u7d93\u7531 Shell \u6216\u662f\u60a8\u5beb\u7684 Script \u5 ConsoleLink.DisplayName=Script \u4e3b\u63a7\u53f0 ConsoleLink.Description=\u57f7\u884c\u60a8\u60f3\u8981\u7684\u7cfb\u7d71\u7ba1\u7406\u3001\u554f\u984c\u6392\u9664\u6216\u8a3a\u65b7\u7528 Script\u3002 -NodesLink.DisplayName=\u7ba1\u7406\u7bc0\u9ede +NodesLink.DisplayName=\u7ba1\u7406\u7bc0\u9ede\u548c\u96f2\u7aef NodesLink.Description=\u65b0\u589e\u3001\u79fb\u9664\u3001\u63a7\u5236\u6216\u76e3\u63a7 Jenkins \u57f7\u884c\u4f5c\u696d\u7684\u5404\u500b\u7bc0\u9ede\u3002 ShutdownLink.DisplayName_prepare=\u6e96\u5099\u505c\u6a5f ShutdownLink.DisplayName_cancel=\u53d6\u6d88\u505c\u6a5f +ShutdownLink.DisplayName_update=\u66f4\u65b0\u505c\u6a5f\u6e96\u5099 ShutdownLink.Description=\u4e0d\u518d\u57f7\u884c\u65b0\u7684\u5efa\u7f6e\u4f5c\u696d\uff0c\u8b93\u7cfb\u7d71\u53ef\u4ee5\u5b89\u5168\u505c\u6a5f\u3002 +ShutdownLink.ShuttingDownInProgressDescription=Jenkins \u6b63\u5728\u505c\u6a5f\uff0c\u4e0d\u6703\u57f7\u884c\u65b0\u7684\u5efa\u7f6e\u4f5c\u696d\u3002 +ShutdownLink.ShutDownReason_title=\u539f\u56e0 +ShutdownLink.ShutDownReason_update=\u66f4\u65b0\u539f\u56e0 + +AdministrativeMonitorsDecorator.DisplayName=\u7ba1\u7406\u76e3\u8996\u5668\u901a\u77e5 diff --git a/core/src/main/resources/jenkins/management/PluginsLink/info.jelly b/core/src/main/resources/jenkins/management/PluginsLink/info.jelly deleted file mode 100644 index 98faafac4387..000000000000 --- a/core/src/main/resources/jenkins/management/PluginsLink/info.jelly +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - ${%updates available} - - \ No newline at end of file diff --git a/core/src/main/resources/jenkins/management/PluginsLink/info.properties b/core/src/main/resources/jenkins/management/PluginsLink/info.properties deleted file mode 100644 index 87fba8871b52..000000000000 --- a/core/src/main/resources/jenkins/management/PluginsLink/info.properties +++ /dev/null @@ -1 +0,0 @@ -updates\ available=There are updates available diff --git a/core/src/main/resources/jenkins/management/PluginsLink/info_bg.properties b/core/src/main/resources/jenkins/management/PluginsLink/info_bg.properties deleted file mode 100644 index 2f4386fad545..000000000000 --- a/core/src/main/resources/jenkins/management/PluginsLink/info_bg.properties +++ /dev/null @@ -1,24 +0,0 @@ -# The MIT License -# -# Bulgarian translation: Copyright (c) 2016, Alexander Shopov -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -updates\ available=\ - \u043d\u0430\u043b\u0438\u0447\u043d\u0438 \u0441\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f diff --git a/core/src/main/resources/jenkins/management/PluginsLink/info_ca.properties b/core/src/main/resources/jenkins/management/PluginsLink/info_ca.properties deleted file mode 100644 index 652c09a17e40..000000000000 --- a/core/src/main/resources/jenkins/management/PluginsLink/info_ca.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -updates\ available=Hi ha actualitzacions disponibles diff --git a/core/src/main/resources/jenkins/management/PluginsLink/info_cs.properties b/core/src/main/resources/jenkins/management/PluginsLink/info_cs.properties deleted file mode 100644 index 40f53b168eaf..000000000000 --- a/core/src/main/resources/jenkins/management/PluginsLink/info_cs.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -updates\ available=dostupn\u00E9 aktualizace diff --git a/core/src/main/resources/jenkins/management/PluginsLink/info_da.properties b/core/src/main/resources/jenkins/management/PluginsLink/info_da.properties deleted file mode 100644 index c1cfb28eee1a..000000000000 --- a/core/src/main/resources/jenkins/management/PluginsLink/info_da.properties +++ /dev/null @@ -1,25 +0,0 @@ -# -# The MIT License -# -# Copyright (c) 2012, CloudBees, Intl., Nicolas De loof -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. -# - -updates\ available=opdateringer tilg\u00e6ngelige diff --git a/core/src/main/resources/jenkins/management/PluginsLink/info_de.properties b/core/src/main/resources/jenkins/management/PluginsLink/info_de.properties deleted file mode 100644 index 0de224e49923..000000000000 --- a/core/src/main/resources/jenkins/management/PluginsLink/info_de.properties +++ /dev/null @@ -1,25 +0,0 @@ -# -# The MIT License -# -# Copyright (c) 2012, CloudBees, Intl., Nicolas De loof -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. -# - -updates\ available=Aktualisierungen verf\u00FCgbar diff --git a/core/src/main/resources/jenkins/management/PluginsLink/info_es.properties b/core/src/main/resources/jenkins/management/PluginsLink/info_es.properties deleted file mode 100644 index 9e67c8eb275f..000000000000 --- a/core/src/main/resources/jenkins/management/PluginsLink/info_es.properties +++ /dev/null @@ -1,25 +0,0 @@ -# -# The MIT License -# -# Copyright (c) 2012, CloudBees, Intl., Nicolas De loof -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. -# - -updates\ available=Existen actualizaciones disponibles diff --git a/core/src/main/resources/jenkins/management/PluginsLink/info_et.properties b/core/src/main/resources/jenkins/management/PluginsLink/info_et.properties deleted file mode 100644 index b2344b90177e..000000000000 --- a/core/src/main/resources/jenkins/management/PluginsLink/info_et.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -updates\ available=uuendused saadaval diff --git a/core/src/main/resources/jenkins/management/PluginsLink/info_fi.properties b/core/src/main/resources/jenkins/management/PluginsLink/info_fi.properties deleted file mode 100644 index 21f95b969a5e..000000000000 --- a/core/src/main/resources/jenkins/management/PluginsLink/info_fi.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -updates\ available=p\u00E4ivityksi\u00E4 saatavana diff --git a/core/src/main/resources/jenkins/management/PluginsLink/info_fr.properties b/core/src/main/resources/jenkins/management/PluginsLink/info_fr.properties deleted file mode 100644 index 4d04db4dc472..000000000000 --- a/core/src/main/resources/jenkins/management/PluginsLink/info_fr.properties +++ /dev/null @@ -1,25 +0,0 @@ -# -# The MIT License -# -# Copyright (c) 2012, CloudBees, Intl., Nicolas De loof -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. -# - -updates\ available=mises \u00E0 jour disponibles diff --git a/core/src/main/resources/jenkins/management/PluginsLink/info_he.properties b/core/src/main/resources/jenkins/management/PluginsLink/info_he.properties deleted file mode 100644 index c521892eb1c5..000000000000 --- a/core/src/main/resources/jenkins/management/PluginsLink/info_he.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -updates\ available=\u05E2\u05D3\u05DB\u05D5\u05E0\u05D9\u05DD \u05D6\u05DE\u05D9\u05E0\u05D9\u05DD diff --git a/core/src/main/resources/jenkins/management/PluginsLink/info_hu.properties b/core/src/main/resources/jenkins/management/PluginsLink/info_hu.properties deleted file mode 100644 index eb48bcff188a..000000000000 --- a/core/src/main/resources/jenkins/management/PluginsLink/info_hu.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -updates\ available=friss\u00EDt\u00E9sek el\u00E9rhet\u0151k diff --git a/core/src/main/resources/jenkins/management/PluginsLink/info_it.properties b/core/src/main/resources/jenkins/management/PluginsLink/info_it.properties deleted file mode 100644 index d54fe31b4afc..000000000000 --- a/core/src/main/resources/jenkins/management/PluginsLink/info_it.properties +++ /dev/null @@ -1,24 +0,0 @@ -# The MIT License -# -# Italian localization plugin for Jenkins -# Copyright 2020 Alessandro Menti -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -updates\ available=Sono disponibili degli aggiornamenti diff --git a/core/src/main/resources/jenkins/management/PluginsLink/info_ja.properties b/core/src/main/resources/jenkins/management/PluginsLink/info_ja.properties deleted file mode 100644 index 194d2803064b..000000000000 --- a/core/src/main/resources/jenkins/management/PluginsLink/info_ja.properties +++ /dev/null @@ -1,25 +0,0 @@ -# -# The MIT License -# -# Copyright (c) 2012, CloudBees, Intl., Nicolas De loof -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. -# - -updates\ available=\u30A2\u30C3\u30D7\u30C7\u30FC\u30C8\u3042\u308A diff --git a/core/src/main/resources/jenkins/management/PluginsLink/info_ko.properties b/core/src/main/resources/jenkins/management/PluginsLink/info_ko.properties deleted file mode 100644 index c3bda1d57235..000000000000 --- a/core/src/main/resources/jenkins/management/PluginsLink/info_ko.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -updates\ available=\uC5C5\uB370\uC774\uD2B8 \uAC00\uB2A5\uD568 diff --git a/core/src/main/resources/jenkins/management/PluginsLink/info_lt.properties b/core/src/main/resources/jenkins/management/PluginsLink/info_lt.properties deleted file mode 100644 index 767ecead8ae7..000000000000 --- a/core/src/main/resources/jenkins/management/PluginsLink/info_lt.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -updates\ available=yra atnaujinim\u0173 diff --git a/core/src/main/resources/jenkins/management/PluginsLink/info_lv.properties b/core/src/main/resources/jenkins/management/PluginsLink/info_lv.properties deleted file mode 100644 index 7a8cc0257e6b..000000000000 --- a/core/src/main/resources/jenkins/management/PluginsLink/info_lv.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -updates\ available=Pieejami jaunin\u0101jumi diff --git a/core/src/main/resources/jenkins/management/PluginsLink/info_nl.properties b/core/src/main/resources/jenkins/management/PluginsLink/info_nl.properties deleted file mode 100644 index c29bfe95a06a..000000000000 --- a/core/src/main/resources/jenkins/management/PluginsLink/info_nl.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -updates\ available=updates beschikbaar diff --git a/core/src/main/resources/jenkins/management/PluginsLink/info_pl.properties b/core/src/main/resources/jenkins/management/PluginsLink/info_pl.properties deleted file mode 100644 index 57020cf14bc8..000000000000 --- a/core/src/main/resources/jenkins/management/PluginsLink/info_pl.properties +++ /dev/null @@ -1,25 +0,0 @@ -# -# The MIT License -# -# Copyright (c) 2013, Lukasz Jader -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. -# - -updates\ available=aktualizacje s\u0105 dost\u0119pne diff --git a/core/src/main/resources/jenkins/management/PluginsLink/info_pt_BR.properties b/core/src/main/resources/jenkins/management/PluginsLink/info_pt_BR.properties deleted file mode 100644 index 577b37bb2db1..000000000000 --- a/core/src/main/resources/jenkins/management/PluginsLink/info_pt_BR.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -updates\ available=Atualiza\u00E7\u00F5es dispon\u00EDveis diff --git a/core/src/main/resources/jenkins/management/PluginsLink/info_pt_PT.properties b/core/src/main/resources/jenkins/management/PluginsLink/info_pt_PT.properties deleted file mode 100644 index bb989c80b416..000000000000 --- a/core/src/main/resources/jenkins/management/PluginsLink/info_pt_PT.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -updates\ available=Existem atualiza\u00E7\u00F5es dispon\u00EDveis diff --git a/core/src/main/resources/jenkins/management/PluginsLink/info_ru.properties b/core/src/main/resources/jenkins/management/PluginsLink/info_ru.properties deleted file mode 100644 index acd4ff0c326b..000000000000 --- a/core/src/main/resources/jenkins/management/PluginsLink/info_ru.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -updates\ available=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f diff --git a/core/src/main/resources/jenkins/management/PluginsLink/info_sk.properties b/core/src/main/resources/jenkins/management/PluginsLink/info_sk.properties deleted file mode 100644 index f3c789125046..000000000000 --- a/core/src/main/resources/jenkins/management/PluginsLink/info_sk.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -updates\ available=aktualiz\u00E1cie dostupn\u00E9 diff --git a/core/src/main/resources/jenkins/management/PluginsLink/info_sr.properties b/core/src/main/resources/jenkins/management/PluginsLink/info_sr.properties deleted file mode 100644 index 0182d8838870..000000000000 --- a/core/src/main/resources/jenkins/management/PluginsLink/info_sr.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -updates\ available=\u0418\u043C\u0430 \u043D\u043E\u0432\u0438\u0445 \u043D\u0430\u0434\u0433\u0440\u0430\u0434\u045A\u0430 diff --git a/core/src/main/resources/jenkins/management/PluginsLink/info_sv_SE.properties b/core/src/main/resources/jenkins/management/PluginsLink/info_sv_SE.properties deleted file mode 100644 index a2d5cb4ac48f..000000000000 --- a/core/src/main/resources/jenkins/management/PluginsLink/info_sv_SE.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -updates\ available=Uppdateringar finns tillg\u00E4ngliga diff --git a/core/src/main/resources/jenkins/management/PluginsLink/info_uk.properties b/core/src/main/resources/jenkins/management/PluginsLink/info_uk.properties deleted file mode 100644 index 140702db7b4a..000000000000 --- a/core/src/main/resources/jenkins/management/PluginsLink/info_uk.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -updates\ available=\u041E\u043D\u043E\u0432\u043B\u0435\u043D\u043D\u044F \u0434\u043E\u0441\u0442\u0443\u043F\u043D\u0456 diff --git a/core/src/main/resources/jenkins/management/PluginsLink/info_zh_TW.properties b/core/src/main/resources/jenkins/management/PluginsLink/info_zh_TW.properties deleted file mode 100644 index a39bd1d80642..000000000000 --- a/core/src/main/resources/jenkins/management/PluginsLink/info_zh_TW.properties +++ /dev/null @@ -1,24 +0,0 @@ -# -# The MIT License -# -# Copyright (c) 2013, Chunghwa Telecom Co., Ltd., Pei-Tang Huang -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -updates\ available=\u6709\u66F4\u65B0 diff --git a/core/src/main/resources/jenkins/management/ShutdownLink/index.groovy b/core/src/main/resources/jenkins/management/ShutdownLink/index.groovy index 252dbae1f442..a5849945f0ba 100644 --- a/core/src/main/resources/jenkins/management/ShutdownLink/index.groovy +++ b/core/src/main/resources/jenkins/management/ShutdownLink/index.groovy @@ -10,7 +10,7 @@ l.layout(norefresh: true, permission: app.MANAGE, title: my.displayName) { l.side_panel { l.tasks { l.task(icon: "icon-up icon-md", href: rootURL + '/', title: _("Back to Dashboard")) - l.task(icon: "icon-gear2 icon-md", href: "${rootURL}/manage", title: _("Manage Jenkins")) + l.task(icon: "symbol-settings", href: "${rootURL}/manage", title: _("Manage Jenkins")) } } l.main_panel { diff --git a/core/src/main/resources/jenkins/management/ShutdownLink/index_zh_TW.properties b/core/src/main/resources/jenkins/management/ShutdownLink/index_zh_TW.properties new file mode 100644 index 000000000000..9fb0edb3d77c --- /dev/null +++ b/core/src/main/resources/jenkins/management/ShutdownLink/index_zh_TW.properties @@ -0,0 +1,2 @@ +Back\ to\ Dashboard=\u8fd4\u56de\u8cc7\u8a0a\u4e3b\u9801 +Manage\ Jenkins=\u7ba1\u7406 Jenkins diff --git a/core/src/main/resources/jenkins/model/BuildDiscarderProperty/config-details_pt_BR.properties b/core/src/main/resources/jenkins/model/BuildDiscarderProperty/config-details_pt_BR.properties new file mode 100644 index 000000000000..52c240b80dec --- /dev/null +++ b/core/src/main/resources/jenkins/model/BuildDiscarderProperty/config-details_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Strategy=Estrat\u00E9gia diff --git a/core/src/main/resources/jenkins/model/BuildDiscarderProperty/config-details_zh_TW.properties b/core/src/main/resources/jenkins/model/BuildDiscarderProperty/config-details_zh_TW.properties new file mode 100644 index 000000000000..09b0562c5443 --- /dev/null +++ b/core/src/main/resources/jenkins/model/BuildDiscarderProperty/config-details_zh_TW.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Strategy=\u7b56\u7565 diff --git a/core/src/main/resources/jenkins/model/BuiltInNodeMigration/description.jelly b/core/src/main/resources/jenkins/model/BuiltInNodeMigration/description.jelly new file mode 100644 index 000000000000..bb405e931933 --- /dev/null +++ b/core/src/main/resources/jenkins/model/BuiltInNodeMigration/description.jelly @@ -0,0 +1,4 @@ + + + ${%blurb} + diff --git a/core/src/main/resources/jenkins/model/BuiltInNodeMigration/description.properties b/core/src/main/resources/jenkins/model/BuiltInNodeMigration/description.properties new file mode 100644 index 000000000000..a9aff625d85b --- /dev/null +++ b/core/src/main/resources/jenkins/model/BuiltInNodeMigration/description.properties @@ -0,0 +1 @@ +blurb = When updating Jenkins from before 2.307, this allows administrators to migrate the built-in node name and label. diff --git a/core/src/main/resources/jenkins/model/BuiltInNodeMigration/description_pt_BR.properties b/core/src/main/resources/jenkins/model/BuiltInNodeMigration/description_pt_BR.properties new file mode 100644 index 000000000000..afbf42227371 --- /dev/null +++ b/core/src/main/resources/jenkins/model/BuiltInNodeMigration/description_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +blurb=Quando atualizando o Jenkins desde antes da vers\u00E3o 2.307, isto permite administradores a migrarem o nome e r\u00F3tulo do n\u00F3 embutido. diff --git a/core/src/main/resources/jenkins/model/BuiltInNodeMigration/message.jelly b/core/src/main/resources/jenkins/model/BuiltInNodeMigration/message.jelly new file mode 100644 index 000000000000..82037ac2e4f5 --- /dev/null +++ b/core/src/main/resources/jenkins/model/BuiltInNodeMigration/message.jelly @@ -0,0 +1,10 @@ + + +
      +
      + + + + ${%blurb} +
      +
      diff --git a/core/src/main/resources/jenkins/model/BuiltInNodeMigration/message.properties b/core/src/main/resources/jenkins/model/BuiltInNodeMigration/message.properties new file mode 100644 index 000000000000..10f3afcf7b21 --- /dev/null +++ b/core/src/main/resources/jenkins/model/BuiltInNodeMigration/message.properties @@ -0,0 +1,40 @@ +# The MIT License +# +# Copyright (c) 2021 Daniel Beck +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +blurb = The word "master" is being retired as the term for the main Jenkins process and the built-in node. \ + The main process is now called "controller" and the built-in node is called just "built-in node". \ + The UI has been updated with these changes. \ + The following features are also affected: \ +
        \ +
      • The implicit label of the built-in node changes from master to built-in.
      • \ +
      • The built-in node''s NODE_NAME environment variable also changes from master to built-in.
      • \ +
      \ + These changes could affect build behavior, so are not applied automatically. \ + Before you apply these changes, you should do the following: \ +
        \ +
      • Review label assignments in job configurations and tool installers for uses of master label. \ + Any such label assignments will not match the built-in node after migration. \ + Besides updating these assignments, you could also explicitly add the master label to the built-in node. \ +
      • \ +
      • Review use of the NODE_NAME environment variable in build scripts.
      • \ +
      \ + Learn more. diff --git a/core/src/main/resources/jenkins/model/BuiltInNodeMigration/message_pl.properties b/core/src/main/resources/jenkins/model/BuiltInNodeMigration/message_pl.properties new file mode 100644 index 000000000000..241fe76e6d92 --- /dev/null +++ b/core/src/main/resources/jenkins/model/BuiltInNodeMigration/message_pl.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Copyright (c) 2022 Damian Szczepanik +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Apply\ Migration=Zastosuj migracje +Dismiss=Pomi\u0144 \ No newline at end of file diff --git a/core/src/main/resources/jenkins/model/BuiltInNodeMigration/message_pt_BR.properties b/core/src/main/resources/jenkins/model/BuiltInNodeMigration/message_pt_BR.properties new file mode 100644 index 000000000000..b9443be51345 --- /dev/null +++ b/core/src/main/resources/jenkins/model/BuiltInNodeMigration/message_pt_BR.properties @@ -0,0 +1,43 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +blurb=A palavra "mestre" ser\u00E1 aposentada como um termo descritivo para o processo principal do Jenkins e do n\u00F3 embutido. \ + O processo principal agora \u00E9 chamado de "controlador" e o n\u00F3 embutido \u00E9 chamado apenas de "n\u00F3 embutido". \ + A interface de usu\u00E1rio foi atualizada com estas mudan\u00E7as. \ + As seguintes funcionalidades tamb\u00E9m foram afetadas: \ +
        \ +
      • A etiqueta impl\u00EDcita do n\u00F3 embutido muda de mestre para embutido.
      • \ +
      • A vari\u00E1vel de ambiente NODE_NAME do n\u00F3 embutido tamb\u00E9m muda de mestre para embutido.
      • \ +
      \ + Essas mudan\u00E7as podem afetar o comportamento de constru\u00E7\u00E3o, ent\u00E3o n\u00E3o s\u00E3o aplicadas automaticamente. \ + Antes de aplicar essas mudan\u00E7as, voc\u00EA deve fazer o seguinte: \ +
        \ +
      • Rever as atribui\u00E7\u00F5es de etiquetas em configura\u00E7\u00F5es de job e instaladores de ferramentas que usam a etiqueta master. \ + Qualquer atribui\u00E7\u00E3o dessas etiquetas n\u00E3o ir\u00E3o casar com o n\u00F3 embutido depois da migra\u00E7\u00E3o. \ + Al\u00E9m de atualizar essas atribui\u00E7\u00F5es, voc\u00EA tamb\u00E9m poderia explicitamente adicionar explicitamente a etiqueta master no n\u00F3 embutido. \ +
      • \ +
      • Revisar o uso da vari\u00E1vel de ambiente NODE_NAME em scripts de constru\u00E7\u00F5es.
      • \ +
      \ + Saiba mais. +Apply\ Migration=Aplicar\ migra\u00E7\u00E3o +Dismiss=Dispensar + diff --git a/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv.properties b/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv.properties index 11c7828ddbd1..65019f3c3012 100644 --- a/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv.properties +++ b/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv.properties @@ -10,14 +10,14 @@ EXECUTOR_NUMBER.blurb=\ (among executors of the same machine) that\u2019s \ carrying out this build. This is the number you see in \ the "build executor status", except that the number starts from 0, not 1. -NODE_NAME.blurb=Name of the agent if the build is on an agent, or "master" if run on master. +NODE_NAME.blurb=Name of the agent if the build is on an agent, or "built-in" if run on the built-in node (or "master" until Jenkins 2.306). NODE_LABELS.blurb=Whitespace-separated list of labels that the node is assigned. WORKSPACE.blurb=The absolute path of the directory assigned to the build as a workspace. WORKSPACE_TMP.blurb=\ A temporary directory near the workspace that will not be browsable and will not interfere with SCM checkouts. \ May not initially exist, so be sure to create the directory as needed (e.g., mkdir -p on Linux). \ Not defined when the regular workspace is a drive root. -JENKINS_HOME.blurb=The absolute path of the directory assigned on the master node for Jenkins to store data. -JENKINS_URL.blurb=Full URL of Jenkins, like http://server:port/jenkins/ (note: only available if Jenkins URL set in system configuration). -BUILD_URL.blurb=Full URL of this build, like http://server:port/jenkins/job/foo/15/ (Jenkins URL must be set). -JOB_URL.blurb=Full URL of this job, like http://server:port/jenkins/job/foo/ (Jenkins URL must be set). +JENKINS_HOME.blurb=The absolute path of the directory assigned on the controller file system for Jenkins to store data. +JENKINS_URL.blurb=Full URL of Jenkins, like http://server:port/jenkins/ (note: only available if Jenkins URL set in system configuration). +BUILD_URL.blurb=Full URL of this build, like http://server:port/jenkins/job/foo/15/ (Jenkins URL must be set). +JOB_URL.blurb=Full URL of this job, like http://server:port/jenkins/job/foo/ (Jenkins URL must be set). diff --git a/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_de.properties b/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_de.properties index 9b427752c91c..1076f9fd4586 100644 --- a/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_de.properties +++ b/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_de.properties @@ -1,7 +1,7 @@ BUILD_NUMBER.blurb=Die aktuelle Build-Nummer, z.B. "153". BUILD_ID.blurb=Die aktuelle Build-ID. In Builds ab Jenkins 1.597 ist dies die Build-Nummer, vorher ein Zeitstempel im Format YYYY-MM-DD_hh-mm-ss. BUILD_DISPLAY_NAME.blurb=Der Anzeigename des aktuellen Builds, standardmig z.B. "#153". -JOB_NAME.blurb=Projektname des Builds, z.B. "foo" oder "foo/bar". (Um in einem Bourne Shell-Script den Pfadanteil abzuschneiden, probieren Sie: $'{'JOB_NAME##*/}) +JOB_NAME.blurb=Projektname des Builds, z.B. "foo" oder "foo/bar". (Um in einem Bourne Shell-Script den Pfadanteil abzuschneiden, probieren Sie: $'{'JOB_NAME##*/}) BUILD_TAG.blurb=Eine Zeichenkette in der Form "jenkins-$'{'JOB_NAME}-$'{'BUILD_NUMBER}". \ Diese Variable l\u00E4\u00DFt sich sehr bequem zur sp\u00E4teren Identifikation in eine \ Resource-Datei, JAR-Datei usw. ablegen. @@ -13,6 +13,6 @@ EXECUTOR_NUMBER.blurb=Die laufende Nummer des Build-Prozessors, der den aktuelle NODE_LABELS.blurb=Durch Leerzeichen getrennte Liste von Labels, die dem Knoten zugeordnet sind. WORKSPACE.blurb=Der absolute Pfad zum Arbeitsbereich. JENKINS_HOME.blurb=Der absolute Pfad des Verzeichnisses, in dem der Master-Server seine Daten speichert. -JENKINS_URL.blurb=Die absolute URL der Jenkins-Instanz, z.B. http://server:port/jenkins/. -BUILD_URL.blurb=Die absolute URL dieses Builds, z.B. http://server:port/jenkins/job/foo/15/. -JOB_URL.blurb=Die absolute URL dieses Jobs, z.B. http://server:port/jenkins/job/foo/. +JENKINS_URL.blurb=Die absolute URL der Jenkins-Instanz, z.B. http://server:port/jenkins/. +BUILD_URL.blurb=Die absolute URL dieses Builds, z.B. http://server:port/jenkins/job/foo/15/. +JOB_URL.blurb=Die absolute URL dieses Jobs, z.B. http://server:port/jenkins/job/foo/. diff --git a/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_fr.properties b/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_fr.properties index 6228f7a887a9..5742588d24d0 100644 --- a/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_fr.properties +++ b/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_fr.properties @@ -9,6 +9,6 @@ EXECUTOR_NUMBER.blurb=Le num\u00E9ro unique qui identifie l'ex\u00E9cuteur coura NODE_LABELS.blurb= WORKSPACE.blurb=Le chemin absolu vers le r\u00E9pertoire de travail. JENKINS_HOME.blurb= -JENKINS_URL.blurb=L'URL compl\u00E8te de Jenkins, au format http://server:port/jenkins/ +JENKINS_URL.blurb=L'URL compl\u00E8te de Jenkins, au format http://server:port/jenkins/ BUILD_URL.blurb= JOB_URL.blurb= diff --git a/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_it.properties b/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_it.properties index 4ede94cc5611..123e6584496f 100644 --- a/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_it.properties +++ b/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_it.properties @@ -32,7 +32,7 @@ BUILD_TAG.blurb=La stringa "jenkins-$'{'JOB_NAME}-$'{'BUILD_NUMBER}http://server:porta/jenkins/job/pippo/15/
      + http://server:porta/jenkins/job/pippo/15/ EXECUTOR_NUMBER.blurb=Il numero univoco che identifica l''esecutore corrente \ (fra gli esecutori appartenenti alla stessa macchina) che sta eseguendo \ questa compilazione. Questo il numero visualizzato nello "Stato esecutore \ @@ -40,7 +40,7 @@ EXECUTOR_NUMBER.blurb=Il numero univoco che identifica l''esecutore corrente \ JENKINS_HOME.blurb=Il percorso assoluto della directory assegnata sul nodo \ master per consentire a Jenkins di salvare i propri dati. JENKINS_URL.blurb=L''URL completo di Jenkins, ad es. \ - http://server:porta/jenkins/ (nota: disponibile solo se l''URL \ + http://server:porta/jenkins/ (nota: disponibile solo se l''URL \ di Jenkins stato impostato nella configurazione di sistema) JOB_BASE_NAME.blurb=Il nome breve del progetto a cui appartiene questa \ compilazione senza i percorsi delle directory, ad esempio "pippo" anzich \ @@ -48,7 +48,7 @@ JOB_BASE_NAME.blurb=Il nome breve del progetto a cui appartiene questa \ JOB_NAME.blurb=Il nome del progetto a cui appartiene questa compilazione, ad \ esempio "pippo" o "pippo/pluto". JOB_URL.blurb=L''URL completo di questo processo, ad es. \ - http://server:porta/jenkins/job/pippo/ (l''URL di Jenkins \ + http://server:porta/jenkins/job/pippo/ (l''URL di Jenkins \ deve essere impostato) NODE_LABELS.blurb=Un elenco separato da spazi delle etichette assegnate al \ nodo. diff --git a/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_ja.properties b/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_ja.properties index c161b5b39cfa..f43bb3bf07bc 100644 --- a/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_ja.properties +++ b/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_ja.properties @@ -1,12 +1,12 @@ BUILD_NUMBER.blurb=\u5F53\u8A72\u30D3\u30EB\u30C9\u306E\u756A\u53F7\u3002\u4F8B "153" JOB_NAME.blurb=\u30D3\u30EB\u30C9\u306E\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u540D\u3002\u4F8B "foo" BUILD_TAG.blurb=\u6587\u5B57\u5217 "jenkins-$'{'JOB_NAME}-$'{'BUILD_NUMBER}"\u3002\ - \u7C21\u6613\u306A\u8B58\u5225\u5B50\u3068\u3057\u3066\u3001\u30EA\u30BD\u30FC\u30B9\u30D5\u30A1\u30A4\u30EB\u3084jar\u30D5\u30A1\u30A4\u30EB\u306A\u3069\u306B\u4ED8\u4E0E\u3059\u308B\u306E\u306B\u4FBF\u5229\u3067\u3059\u3002 + \u7C21\u6613\u306A\u8B58\u5225\u5B50\u3068\u3057\u3066\u3001\u30EA\u30BD\u30FC\u30B9\u30D5\u30A1\u30A4\u30EB\u3084jar\u30D5\u30A1\u30A4\u30EB\u306A\u3069\u306B\u4ED8\u4E0E\u3059\u308B\u306E\u306B\u4FBF\u5229\u3067\u3059\u3002 EXECUTOR_NUMBER.blurb=\u3053\u306E\u30D3\u30EB\u30C9\u3092\u5B9F\u884C\u3057\u3066\u3044\u308B\u73FE\u5728\u306E\u30A8\u30B0\u30BC\u30AD\u30E5\u30FC\u30BF\u30FC\u3092\u8B58\u5225\u3059\u308B(\u540C\u4E00\u30DE\u30B7\u30F3\u306E\u4E2D\u3067)\u30E6\u30CB\u30FC\u30AF\u306A\u756A\u53F7\u3002\ "\u30D3\u30EB\u30C9\u5B9F\u884C\u72B6\u614B"\u306B\u8868\u793A\u3055\u308C\u3066\u3044\u308B\u6570\u5B57\u3067\u3059\u304C\u30011\u3067\u306F\u306A\u304F0\u304B\u3089\u59CB\u307E\u308B\u6570\u5B57\u3067\u3059\u3002 NODE_LABELS.blurb=\u30CE\u30FC\u30C9\u306B\u8A2D\u5B9A\u3055\u308C\u305F\u30E9\u30D9\u30EB\u306E\u30EA\u30B9\u30C8\uFF08\u30B9\u30DA\u30FC\u30B9\u533A\u5207\u308A)\u3002 WORKSPACE.blurb=\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u306E\u7D76\u5BFE\u30D1\u30B9\u3002 JENKINS_HOME.blurb= -JENKINS_URL.blurb=Jenkins\u306EURL\u3002\u4F8B http://server:port/jenkins/ -BUILD_URL.blurb=\u3053\u306E\u30D3\u30EB\u30C9\u306EURL\u3002 \u4F8B http://server:port/jenkins/job/foo/15/ -JOB_URL.blurb=\u3053\u306E\u30B8\u30E7\u30D6\u306EURL\u3002 \u4F8B http://server:port/jenkins/job/foo/ +JENKINS_URL.blurb=Jenkins\u306EURL\u3002\u4F8B http://server:port/jenkins/ +BUILD_URL.blurb=\u3053\u306E\u30D3\u30EB\u30C9\u306EURL\u3002 \u4F8B http://server:port/jenkins/job/foo/15/ +JOB_URL.blurb=\u3053\u306E\u30B8\u30E7\u30D6\u306EURL\u3002 \u4F8B http://server:port/jenkins/job/foo/ diff --git a/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_nl.properties b/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_nl.properties index e1a907a0958e..b5c5a58c883f 100644 --- a/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_nl.properties +++ b/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_nl.properties @@ -9,6 +9,6 @@ EXECUTOR_NUMBER.blurb=Het unieke nummer, waarmee uw huidige uitvoerder ge\u00EFd NODE_LABELS.blurb= WORKSPACE.blurb=Het absolute pad naar de werkplaats. JENKINS_HOME.blurb= -JENKINS_URL.blurb=Volledige URL voor Jenkins, v.b. http://server:port/jenkins/ +JENKINS_URL.blurb=Volledige URL voor Jenkins, v.b. http://server:port/jenkins/ BUILD_URL.blurb= JOB_URL.blurb= diff --git a/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_sr.properties b/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_sr.properties index be55e99003bf..cd96f70b5889 100644 --- a/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_sr.properties +++ b/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_sr.properties @@ -11,6 +11,6 @@ NODE_NAME.blurb=\u0418\u043C\u0435 \u0430\u0433\u0435\u043D\u0442\u0430 \u0430\u NODE_LABELS.blurb= WORKSPACE.blurb=\u0420\u0430\u0437\u043C\u0430\u043A-\u043E\u0434\u0432\u043E\u0458\u0435\u043D\u0438 \u0441\u043F\u0438\u0441\u0430\u043A \u043B\u0430\u0431\u0435\u043B\u0430 \u0434\u043E\u0434\u0435\u0459\u0435\u043D\u043E \u043C\u0430\u0448\u0438\u043D\u0438. JENKINS_HOME.blurb=\u041F\u0443\u043D\u043E \u043F\u0443\u0442\u0430\u045A\u0435 \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0458\u0443\u043C\u0443 \u0434\u043E\u0434\u0435\u0459\u0435\u043D\u043E \u0433\u043B\u0430\u0432\u043D\u043E\u0458 \u043C\u0430\u0448\u0438\u043D\u0438, \u0433\u0434\u0435 \u045B\u0435 Jenkins \u0447\u0443\u0432\u0430\u0442\u0438 \u0441\u0432\u043E\u0458\u0435 \u043F\u043E\u0434\u0430\u0442\u043A\u0435. -JENKINS_URL.blurb=\u041A\u043E\u043C\u043F\u043B\u0435\u0442\u043D\u0430 Jenkins URL-\u0430\u0434\u0440\u0435\u0441\u0430, \u043A\u0430\u043E http://server:port/jenkins/ (\u0441\u0430\u043C\u043E \u0434\u043E\u0441\u0442\u0443\u043F\u043D\u043E \u0430\u043A\u043E \u0458\u0435 Jenkins URL \u043F\u043E\u0441\u0442\u0430\u0432\u0459\u0435\u043D\u043E \u0443 \u0441\u0438\u0441\u0442\u0435\u043C\u0441\u043A\u0438\u043C \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430) -BUILD_URL.blurb=\u041A\u043E\u043C\u043F\u043B\u0435\u0442\u043D\u0430 URL-\u0430\u0434\u0440\u0435\u0441\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435, \u043D\u043F\u0440. http://server:port/jenkins/job/foo/15/ (Jenkins URL \u043C\u043E\u0440\u0430 \u0431\u0438\u0442\u0438 \u043F\u043E\u0441\u0442\u0430\u0432\u0459\u0435\u043D\u043E) -JOB_URL.blurb=\u041A\u043E\u043C\u043F\u043B\u0435\u0442\u043D\u0430 URL-\u0430\u0434\u0440\u0435\u0441\u0430 \u0437\u0430\u0434\u0430\u0442\u043A\u0430, \u043D\u043F\u0440. http://server:port/jenkins/job/foo/ (Jenkins URL \u043C\u043E\u0440\u0430 \u0431\u0438\u0442\u0438 \u043F\u043E\u0441\u0442\u0430\u0432\u0459\u0435\u043D\u043E) +JENKINS_URL.blurb=\u041A\u043E\u043C\u043F\u043B\u0435\u0442\u043D\u0430 Jenkins URL-\u0430\u0434\u0440\u0435\u0441\u0430, \u043A\u0430\u043E http://server:port/jenkins/ (\u0441\u0430\u043C\u043E \u0434\u043E\u0441\u0442\u0443\u043F\u043D\u043E \u0430\u043A\u043E \u0458\u0435 Jenkins URL \u043F\u043E\u0441\u0442\u0430\u0432\u0459\u0435\u043D\u043E \u0443 \u0441\u0438\u0441\u0442\u0435\u043C\u0441\u043A\u0438\u043C \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430) +BUILD_URL.blurb=\u041A\u043E\u043C\u043F\u043B\u0435\u0442\u043D\u0430 URL-\u0430\u0434\u0440\u0435\u0441\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435, \u043D\u043F\u0440. http://server:port/jenkins/job/foo/15/ (Jenkins URL \u043C\u043E\u0440\u0430 \u0431\u0438\u0442\u0438 \u043F\u043E\u0441\u0442\u0430\u0432\u0459\u0435\u043D\u043E) +JOB_URL.blurb=\u041A\u043E\u043C\u043F\u043B\u0435\u0442\u043D\u0430 URL-\u0430\u0434\u0440\u0435\u0441\u0430 \u0437\u0430\u0434\u0430\u0442\u043A\u0430, \u043D\u043F\u0440. http://server:port/jenkins/job/foo/ (Jenkins URL \u043C\u043E\u0440\u0430 \u0431\u0438\u0442\u0438 \u043F\u043E\u0441\u0442\u0430\u0432\u0459\u0435\u043D\u043E) diff --git a/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_zh_TW.properties b/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_zh_TW.properties index ea3372fd9ace..6f299d50bedd 100644 --- a/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_zh_TW.properties +++ b/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_zh_TW.properties @@ -21,22 +21,19 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -BUILD_NUMBER.blurb=\u76ee\u524d\u5efa\u7f6e\u7de8\u865f\uff0c\u4f8b\u5982 "153" \u3002 -BUILD_ID.blurb=\u76ee\u524d\u5efa\u7f6e\u7684ID\u3002\u9019\u500b\u503c\u5728 Jenkins 1.597 \u7248\u672c\u4e4b\u5f8c\u8207 BUILD_NUMBER \u4e00\u6a23\uff0c1.597 \u7248\u4e4b\u524d\u5247\u662f\u683c\u5f0f\u70ba YYYY-MM-DD_hh-mm-ss \u7684\u6642\u9593\u6233\u3002 -BUILD_DISPLAY_NAME.blurb=\u76ee\u524d\u5efa\u7f6e\u7684\u540d\u5b57\u3002\u5728\u9810\u8a2d\u7684\u60c5\u6cc1\u4e0b\uff0c\u5b83\u7684\u683c\u5f0f\u6703\u662f "#153" \u3002 -JOB_NAME.blurb=\u5efa\u7f6e\u7684\u5c08\u6848\u540d\u7a31\uff0c\u4f8b\u5982 "foo" \u6216 "foo/bar"\u3002 -JOB_BASE_NAME.blurb=\u53bb\u6389\u8cc7\u6599\u593e\u8def\u5f91\u7684\u540d\u5b57\uff0c\u50cf\u662f "foo" \u4e4b\u65bc "bar/foo"\u3002 -BUILD_TAG.blurb="jenkins-$'{'JOB_NAME}-$'{'BUILD_NUMBER}" \u5b57\u4e32\u3002\u65b9\u4fbf\u653e\u5230\u8cc7\u6e90\u6a94\u3001JAR \u6a94...\u88e1\uff0c\u5e6b\u52a9\u8b58\u5225\u3002 -EXECUTOR_NUMBER.blurb=\ - \u57f7\u884c\u672c\u6b21\u5efa\u7f6e\u7684\u57f7\u884c\u7a0b\u5f0f\u7de8\u865f\uff0c\u53ef\u7528\u4f86\u9451\u5225\u540c\u6a5f\u5668\u4e0a\u7684\u4e0d\u540c\u57f7\u884c\u7a0b\u5f0f\u3002\ - \u4e5f\u5c31\u662f\u60a8\u5728\u300c\u5efa\u7f6e\u57f7\u884c\u7a0b\u5f0f\u72c0\u614b\u300d\u88e1\u770b\u5230\u7684\u865f\u78bc\uff0c\u53ea\u662f\u9019\u88e1\u5f9e 0 \u958b\u59cb\u7b97\uff0c\u4e0d\u662f 1\u3002 -NODE_NAME.blurb=\u7bc0\u9ede\u540d\u7a31\u3002\u82e5\u672c\u5efa\u7f6e\u662f\u5728 agent \u4e0a\u5efa\u7f6e\u7684\u8a71\uff0c\u9019\u500b\u503c\u6703\u662f agent \u7684\u540d\u5b57\uff1b\u82e5\u662f\u5728 master \u4e0a\u5efa\u7f6e\u7684\u8a71\uff0c\u5247\u70ba "master"\u3002 +CI.blurb=\u56fa\u5b9a\u8a2d\u70ba\u5b57\u4e32\u300ctrue\u300d\u4ee5\u793a\u6b64\u70ba\u300c\u6301\u7e8c\u6574\u5408\u300d\u57f7\u884c\u74b0\u5883\u3002 +BUILD_NUMBER.blurb=\u76ee\u524d\u5efa\u7f6e\u7de8\u865f\uff0c\u4f8b\u5982\u300c153\u300d\u3002 +BUILD_ID.blurb=\u76ee\u524d\u5efa\u7f6e\u7684 ID\u3002\u9019\u500b\u503c\u5728 Jenkins 1.597 \u7248\u672c\u4e4b\u5f8c\u8207 BUILD_NUMBER \u4e00\u6a23\uff0c1.597 \u7248\u4e4b\u524d\u5247\u662f\u683c\u5f0f\u70ba YYYY-MM-DD_hh-mm-ss \u7684\u6642\u9593\u6233\u3002 +BUILD_DISPLAY_NAME.blurb=\u76ee\u524d\u5efa\u7f6e\u7684\u986f\u793a\u540d\u7a31\u3002\u9810\u8a2d\u60c5\u6cc1\u4e0b\uff0c\u5b83\u7684\u683c\u5f0f\u6703\u662f\u300c\#153\u300d\u3002 +JOB_NAME.blurb=\u6b64\u5efa\u7f6e\u7684\u5c08\u6848\u540d\u7a31\uff0c\u4f8b\u5982\u300cfoo\u300d\u6216\u300cfoo/bar\u300d\u3002 +JOB_BASE_NAME.blurb=\u53bb\u6389\u8cc7\u6599\u593e\u8def\u5f91\u7684\u540d\u5b57\uff0c\u50cf\u662f\u300cfoo\u300d\u4e4b\u65bc\u300cbar/foo\u300d\u3002 +BUILD_TAG.blurb=\u300cjenkins-$'{'JOB_NAME}-$'{'BUILD_NUMBER}\u300d \u5b57\u4e32\u3002JOB_NAME \u4e2d\u7684\u6240\u6709\u659c\u7dda\u300c/\u300d\u6703\u88ab\u53d6\u4ee3\u70ba\u9023\u63a5\u865f\u300c-\u300d\u3002\u65b9\u4fbf\u653e\u5230\u8cc7\u6e90\u6a94\u3001JAR \u6a94...\u88e1\uff0c\u5e6b\u52a9\u8b58\u5225\u3002 +EXECUTOR_NUMBER.blurb=\u57f7\u884c\u672c\u6b21\u5efa\u7f6e\u7684\u57f7\u884c\u7a0b\u5f0f\u7de8\u865f\uff0c\u53ef\u7528\u4f86\u9451\u5225\u540c\u6a5f\u5668\u4e0a\u7684\u4e0d\u540c\u57f7\u884c\u7a0b\u5f0f\u3002\u4e5f\u5c31\u662f\u60a8\u5728\u300c\u5efa\u7f6e\u57f7\u884c\u7a0b\u5f0f\u72c0\u614b\u300d\u88e1\u770b\u5230\u7684\u865f\u78bc\uff0c\u53ea\u662f\u9019\u88e1\u5f9e 0 \u958b\u59cb\u7b97\uff0c\u4e0d\u662f 1\u3002 +NODE_NAME.blurb=\u7bc0\u9ede\u540d\u7a31\u3002\u82e5\u672c\u5efa\u7f6e\u662f\u5728 Agent \u4e0a\u57f7\u884c\u7684\u8a71\uff0c\u9019\u500b\u503c\u6703\u662f Agent \u7684\u540d\u5b57\uff1b\u82e5\u662f\u5728\u5167\u5efa\u7bc0\u9ede\u4e0a\u57f7\u884c\u7684\u8a71\uff0c\u5247\u70ba\u300c\u5167\u5efa\u300d\uff08Jenkins 2.306 \u7248\u4ee5\u524d\u70ba\u300cmaster\u300d\uff09\u3002 NODE_LABELS.blurb=\u4ee5\u7a7a\u767d\u5206\u9694\u7684\u7bc0\u9ede\u6a19\u7c64\u6e05\u55ae\u3002 WORKSPACE.blurb=\u5efa\u7f6e\u5de5\u4f5c\u5340\u76ee\u9304\u7684\u7d55\u5c0d\u8def\u5f91\u3002 -WORKSPACE_TMP.blurb=\u9130\u8fd1\u5de5\u4f5c\u5340\u7684\u66ab\u5b58\u8cc7\u6599\u593e\u3002\u5b83\u65e2\u4e0d\u80fd\u88ab\u700f\u89bd\uff0c\u4e5f\u4e0d\u6703\u5e72\u64fe\u5230 SCM checkouts\u3002 \ - \u9019\u500b\u8cc7\u6599\u593e\u539f\u672c\u53ef\u80fd\u6c92\u6709\u88ab\u5efa\u7acb\u51fa\u4f86\uff0c\u56e0\u6b64\u82e5\u9700\u8981\u7684\u8a71\uff0c\u8acb\u5efa\u7acb\u8a72\u8cc7\u6599\u593e\uff08\u4f8b\u5982\u5728 Linux\u4e0a\u4e0b mkdir -p \u6307\u4ee4\uff09\ - \u3002 \u82e5\u5de5\u4f5c\u5340\u662f drive root \u6642\uff0cWORKSPACE_TMP \u5247\u4e0d\u6703\u88ab\u5b9a\u7fa9\u3002 -JENKINS_HOME.blurb=Master \u7bc0\u9ede\u8cc7\u6599\u5b58\u653e\u76ee\u9304\u7684\u7d55\u5c0d\u8def\u5f91\u3002 -JENKINS_URL.blurb=Jenkins \u5b8c\u6574\u7db2\u5740\uff0c\u4f8b\u5982 http://server:port/jenkins/ -BUILD_URL.blurb=\u672c\u6b21\u5efa\u7f6e\u5b8c\u6574\u7db2\u5740\uff0c\u4f8b\u5982 http://server:port/jenkins/job/foo/15/ -JOB_URL.blurb=\u4f5c\u696d\u5b8c\u6574\u7db2\u5740\uff0c\u4f8b\u5982 http://server:port/jenkins/job/foo/ +WORKSPACE_TMP.blurb=\u9130\u8fd1\u5de5\u4f5c\u5340\u7684\u66ab\u5b58\u8cc7\u6599\u593e\u3002\u5b83\u65e2\u4e0d\u80fd\u88ab\u700f\u89bd\uff0c\u4e5f\u4e0d\u6703\u5e72\u64fe\u5230 SCM checkouts\u3002 \u9019\u500b\u8cc7\u6599\u593e\u539f\u672c\u53ef\u80fd\u6c92\u6709\u88ab\u5efa\u7acb\u51fa\u4f86\uff0c\u56e0\u6b64\u82e5\u9700\u8981\u7684\u8a71\uff0c\u8acb\u5efa\u7acb\u8a72\u8cc7\u6599\u593e\uff08\u4f8b\u5982\u5728 Linux\u4e0a\u4e0b mkdir -p \u6307\u4ee4\uff09\u3002 \u82e5\u5de5\u4f5c\u5340\u662f drive root \u6642\uff0cWORKSPACE_TMP \u5247\u4e0d\u6703\u88ab\u5b9a\u7fa9\u3002 +JENKINS_HOME.blurb=Controller \u7684\u6a94\u6848\u7cfb\u7d71\u4e0a\uff0c\u5206\u914d\u7d66 Jenkins \u5132\u5b58\u8cc7\u6599\u76ee\u9304\u7684\u7d55\u5c0d\u8def\u5f91\u3002 +JENKINS_URL.blurb=Jenkins \u7684\u5b8c\u6574 URL\uff0c\u4f8b\u5982 http\://server\:port/jenkins/\uff08\u5099\u8a3b\uff1a\u53ea\u5728\u7cfb\u7d71\u8a2d\u5b9a\u4e2d\u7684 Jenkins URL \u6709\u8a2d\u5b9a\u6642\u624d\u6709\u6548\uff09\u3002 +BUILD_URL.blurb=\u672c\u6b21\u5efa\u7f6e\u5b8c\u6574 URL\uff0c\u4f8b\u5982 http\://server\:port/jenkins/job/foo/15/\uff08\u4e00\u5b9a\u8981\u8a2d\u5b9a Jenkins URL \uff09\u3002 +JOB_URL.blurb=\u6b64\u4f5c\u696d\u7684\u5b8c\u6574 URL\uff0c\u4f8b\u5982 http\://server\:port/jenkins/job/foo/\uff08\u4e00\u5b9a\u8981\u8a2d\u5b9a Jenkins URL \uff09\u3002 diff --git a/core/src/main/resources/jenkins/model/DefaultSimplePageDecorator/simple-header_pt_BR.properties b/core/src/main/resources/jenkins/model/DefaultSimplePageDecorator/simple-header_pt_BR.properties new file mode 100644 index 000000000000..58cf29c636d7 --- /dev/null +++ b/core/src/main/resources/jenkins/model/DefaultSimplePageDecorator/simple-header_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Welcome\ to\ Jenkins!=Bem-vindo\ ao\ Jenkins! diff --git a/core/src/main/resources/jenkins/model/DefaultSimplePageDecorator/simple-header_zh_TW.properties b/core/src/main/resources/jenkins/model/DefaultSimplePageDecorator/simple-header_zh_TW.properties new file mode 100644 index 000000000000..d76c19d29ad8 --- /dev/null +++ b/core/src/main/resources/jenkins/model/DefaultSimplePageDecorator/simple-header_zh_TW.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Welcome\ to\ Jenkins\!=\u6b61\u8fce\u4f7f\u7528 Jenkins\! diff --git a/core/src/main/resources/jenkins/model/GlobalCloudConfiguration/index.groovy b/core/src/main/resources/jenkins/model/GlobalCloudConfiguration/index.groovy index 691fbe5bba77..581985664851 100644 --- a/core/src/main/resources/jenkins/model/GlobalCloudConfiguration/index.groovy +++ b/core/src/main/resources/jenkins/model/GlobalCloudConfiguration/index.groovy @@ -13,21 +13,19 @@ l.layout(norefresh:true, permission:app.SYSTEM_READ, title:my.displayName) { l.side_panel { l.tasks { l.task(icon:"icon-up icon-md", href:rootURL+'/', title:_("Back to Dashboard")) - l.task(icon:"icon-gear2 icon-md", href:"${rootURL}/computer/", title:_("Manage Nodes")) + l.task(icon:"symbol-settings", href:"${rootURL}/computer/", title:_("Manage Nodes")) } } + l.app_bar(title: my.displayName) l.main_panel { - h1 { - l.icon(class: 'icon-health-40to59 icon-xlg') - // TODO more appropriate icon - text(my.displayName) - } def clouds = Cloud.all() if (!clouds.isEmpty()) { p() - div(class:"behavior-loading", _("LOADING")) + div(class:"behavior-loading") { + l.spinner(text: _("LOADING")) + } - f.form(method:"post",name:"config",action:"configure") { + f.form(method:"post",name:"config",action:"configure", class: "jenkins-form") { f.block { if (app.clouds.size() == 0 && !h.hasPermission(app.ADMINISTER)) { p(_("No clouds have been configured.")) diff --git a/core/src/main/resources/jenkins/model/GlobalCloudConfiguration/index_zh_TW.properties b/core/src/main/resources/jenkins/model/GlobalCloudConfiguration/index_zh_TW.properties index 4b67e8c93e06..e87e636ae5c1 100644 --- a/core/src/main/resources/jenkins/model/GlobalCloudConfiguration/index_zh_TW.properties +++ b/core/src/main/resources/jenkins/model/GlobalCloudConfiguration/index_zh_TW.properties @@ -20,6 +20,8 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. +Back\ to\ Dashboard=\u8fd4\u56de\u8cc7\u8a0a\u4e3b\u9801 +Manage\ Nodes=\u7ba1\u7406\u7bc0\u9ede Cloud=\u96f2 Add\ a\ new\ cloud=\u65b0\u589e\u96f2 Delete\ cloud=\u522a\u9664\u96f2 diff --git a/core/src/main/resources/jenkins/model/GlobalProjectNamingStrategyConfiguration/config.groovy b/core/src/main/resources/jenkins/model/GlobalProjectNamingStrategyConfiguration/config.groovy index 4edce2f25ea1..70a178dccb60 100644 --- a/core/src/main/resources/jenkins/model/GlobalProjectNamingStrategyConfiguration/config.groovy +++ b/core/src/main/resources/jenkins/model/GlobalProjectNamingStrategyConfiguration/config.groovy @@ -4,12 +4,14 @@ import jenkins.model.ProjectNamingStrategy def f=namespace(lib.FormTagLib) -f.optionalBlock( field:"useProjectNamingStrategy", title:_("useNamingStrategy"), checked:app.useProjectNamingStrategy) { +div(class: "jenkins-form-item") { + f.optionalBlock( field:"useProjectNamingStrategy", title:_("useNamingStrategy"), checked:app.useProjectNamingStrategy) { - f.entry(title:_("namingStrategyTitle")) { - div(style:"width:100%") { - f.descriptorRadioList(title:_("strategy"), varName:"namingStrategy", instance:app.projectNamingStrategy, descriptors:ProjectNamingStrategy.all()) + f.entry(title:_("namingStrategyTitle")) { + div(style:"width:100%") { + f.descriptorRadioList(title:_("strategy"), varName:"namingStrategy", instance:app.projectNamingStrategy, descriptors:ProjectNamingStrategy.all()) + } } - } + } } diff --git a/core/src/main/resources/jenkins/model/Jenkins/EnforceSlaveAgentPortAdministrativeMonitor/description.jelly b/core/src/main/resources/jenkins/model/Jenkins/EnforceSlaveAgentPortAdministrativeMonitor/description.jelly new file mode 100644 index 000000000000..bb405e931933 --- /dev/null +++ b/core/src/main/resources/jenkins/model/Jenkins/EnforceSlaveAgentPortAdministrativeMonitor/description.jelly @@ -0,0 +1,4 @@ + + + ${%blurb} + diff --git a/core/src/main/resources/jenkins/model/Jenkins/EnforceSlaveAgentPortAdministrativeMonitor/description.properties b/core/src/main/resources/jenkins/model/Jenkins/EnforceSlaveAgentPortAdministrativeMonitor/description.properties new file mode 100644 index 000000000000..75cb812fd542 --- /dev/null +++ b/core/src/main/resources/jenkins/model/Jenkins/EnforceSlaveAgentPortAdministrativeMonitor/description.properties @@ -0,0 +1 @@ +blurb = Informs administrators that the TCP agent port is different than its enforced value and will be reset on restart. diff --git a/core/src/main/resources/jenkins/model/Jenkins/EnforceSlaveAgentPortAdministrativeMonitor/description_pt_BR.properties b/core/src/main/resources/jenkins/model/Jenkins/EnforceSlaveAgentPortAdministrativeMonitor/description_pt_BR.properties new file mode 100644 index 000000000000..983ce1d2c4f2 --- /dev/null +++ b/core/src/main/resources/jenkins/model/Jenkins/EnforceSlaveAgentPortAdministrativeMonitor/description_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +blurb=Informa aos administradores que a porta TCP do agent \u00E9 diferente do valor imposto e ser\u00E1 revertido no rein\u00EDcio do sistema. diff --git a/core/src/main/resources/jenkins/model/Jenkins/EnforceSlaveAgentPortAdministrativeMonitor/description_zh_TW.properties b/core/src/main/resources/jenkins/model/Jenkins/EnforceSlaveAgentPortAdministrativeMonitor/description_zh_TW.properties new file mode 100644 index 000000000000..884a79be8d82 --- /dev/null +++ b/core/src/main/resources/jenkins/model/Jenkins/EnforceSlaveAgentPortAdministrativeMonitor/description_zh_TW.properties @@ -0,0 +1 @@ +blurb=\u901a\u77e5\u7ba1\u7406\u54e1 TCP Agent \u9023\u63a5\u57e0\u4e0d\u540c\u65bc\u5f37\u5236\u503c\u4e14\u91cd\u65b0\u555f\u52d5\u5f8c\u6703\u91cd\u8a2d\u3002 diff --git a/core/src/main/resources/jenkins/model/Jenkins/EnforceSlaveAgentPortAdministrativeMonitor/message_pt_BR.properties b/core/src/main/resources/jenkins/model/Jenkins/EnforceSlaveAgentPortAdministrativeMonitor/message_pt_BR.properties new file mode 100644 index 000000000000..34a61f15aefb --- /dev/null +++ b/core/src/main/resources/jenkins/model/Jenkins/EnforceSlaveAgentPortAdministrativeMonitor/message_pt_BR.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +description=A porta TCP do agente foi modificada mas estava especificada atrav\u00E9s da propriedade de sistema {0} na inicializa\u00E7\u00E3o. Este valor ser\u00E1 reiniciado para {1,number,#} e, um rein\u00EDcio do sistema. +reset=Reiniciar para {0,number,#} diff --git a/core/src/main/resources/jenkins/model/Jenkins/EnforceSlaveAgentPortAdministrativeMonitor/message_zh_TW.properties b/core/src/main/resources/jenkins/model/Jenkins/EnforceSlaveAgentPortAdministrativeMonitor/message_zh_TW.properties new file mode 100644 index 000000000000..cd289a42b0e4 --- /dev/null +++ b/core/src/main/resources/jenkins/model/Jenkins/EnforceSlaveAgentPortAdministrativeMonitor/message_zh_TW.properties @@ -0,0 +1,2 @@ +description=TCP Agent \u9023\u63a5\u57e0\u5df2\u8b8a\u66f4\u4f46\u5df2\u5728\u555f\u52d5\u6642\u7531\u7cfb\u7d71\u5c6c\u6027 {0} \u6240\u6307\u5b9a\u3002\u5b83\u7684\u503c\u6703\u5728\u91cd\u65b0\u555f\u52d5\u5f8c\u88ab\u91cd\u8a2d\u70ba {1,number,\#}\u3002 +reset=\u91cd\u8a2d\u70ba {0,number,\#} diff --git a/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/_api_pt_BR.properties b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/_api_pt_BR.properties new file mode 100644 index 000000000000..d2c3d5934410 --- /dev/null +++ b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/_api_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Load\ Statistics=Carregar\ estat\u00EDsticas diff --git a/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/_api_zh_TW.properties b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/_api_zh_TW.properties new file mode 100644 index 000000000000..627093aaf215 --- /dev/null +++ b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/_api_zh_TW.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Load\ Statistics=\u8ca0\u8f09\u7d71\u8a08 diff --git a/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure.jelly b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure.jelly index 883b6b6a3edf..e40af4263aca 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure.jelly +++ b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure.jelly @@ -50,7 +50,7 @@ THE SOFTWARE. - + diff --git a/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_bg.properties b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_bg.properties index 2b04ba83b17e..364c9355aea9 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_bg.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_bg.properties @@ -22,7 +22,7 @@ Node\ Properties=\ \u0421\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u043d\u0430 \u043c\u0430\u0448\u0438\u043d\u0430\u0442\u0430 -\#\ of\ executors=\ +Number\ of\ executors=\ \u0411\u0440\u043e\u0439 \u0438\u0437\u043f\u044a\u043b\u043d\u044f\u0432\u0430\u0449\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0438 Description=\ \u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 diff --git a/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_da.properties b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_da.properties index 044345cffa2d..7a96d13c2efc 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_da.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_da.properties @@ -20,7 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -\#\ of\ executors=# afviklere +Number\ of\ executors=# afviklere Labels=Etiketter Node\ Properties=Nodeegenskaber Save=Gem diff --git a/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_de.properties b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_de.properties index 3866fab827af..fdd503186521 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_de.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_de.properties @@ -20,7 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -\#\ of\ executors=Anzahl der Build-Prozessoren +Number\ of\ executors=Anzahl der Build-Prozessoren Labels=Labels Node\ Properties=Eigenschaften des Knotens Save=Speichern diff --git a/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_es.properties b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_es.properties index 2d9d4621161c..43717235d55b 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_es.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_es.properties @@ -20,7 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -\#\ of\ executors=N\u00FAmero de ejecutores +Number\ of\ executors=N\u00FAmero de ejecutores Labels=Etiquetas Node\ Properties=Propiedades del nodo Save=Guardar diff --git a/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_fi.properties b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_fi.properties index 817dbcfb382d..89ddc34e807a 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_fi.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_fi.properties @@ -20,7 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -\#\ of\ executors=Suorittaajien lukum\u00E4\u00E4r\u00E4 +Number\ of\ executors=Suorittaajien lukum\u00E4\u00E4r\u00E4 Labels= Node\ Properties= Save=Tallenna diff --git a/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_fr.properties b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_fr.properties index 818b3e19f580..547830bb37e5 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_fr.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_fr.properties @@ -20,7 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -\#\ of\ executors=Nombre d''ex\u00E9cuteurs +Number\ of\ executors=Nombre d''ex\u00E9cuteurs Labels=\u00C9tiquettes Node\ Properties=Propri\u00E9t\u00E9s du N\u0153ud Save=Sauvegarder diff --git a/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_hu.properties b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_hu.properties index ed3579dc27de..094613a10391 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_hu.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_hu.properties @@ -20,5 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -\#\ of\ executors=A v\u00E9grehajt\u00F3k sz\u00E1ma +Number\ of\ executors=A v\u00E9grehajt\u00F3k sz\u00E1ma diff --git a/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_it.properties b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_it.properties index 2da11de2b309..ba735e37f2a6 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_it.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_it.properties @@ -21,7 +21,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -\#\ of\ executors=Numero di esecutori +Number\ of\ executors=Numero di esecutori Description=Descrizione Labels=Etichette Node\ Properties=Propriet nodo diff --git a/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_ja.properties b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_ja.properties index d193c398d7cc..ac93d9a97410 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_ja.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_ja.properties @@ -20,7 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -\#\ of\ executors=\u540c\u6642\u5b9f\u884c\u6570 +Number\ of\ executors=\u540c\u6642\u5b9f\u884c\u6570 Labels=\u30E9\u30D9\u30EB Node\ Properties=\u30CE\u30FC\u30C9\u30D7\u30ED\u30D1\u30C6\u30A3 Save=\u4FDD\u5B58 diff --git a/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_lt.properties b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_lt.properties index 342570a4e1b9..690370c78fb0 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_lt.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_lt.properties @@ -1,4 +1,4 @@ -\#\ of\ executors=# vykdytoj\u0173 +Number\ of\ executors=# vykdytoj\u0173 Labels=Etiket\u0117s Node\ Properties=Mazgo savyb\u0117s Save=\u012era\u0161yti diff --git a/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_nl.properties b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_nl.properties index d2de775079bc..90cf2220dbe8 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_nl.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_nl.properties @@ -20,7 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -\#\ of\ executors=Uitvoerders +Number\ of\ executors=Uitvoerders Labels=Labels Node\ Properties= Save=Bewaar diff --git a/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_pt_BR.properties b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_pt_BR.properties index 869b1cbec4c0..dbc3b9782bda 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_pt_BR.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_pt_BR.properties @@ -20,7 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -\#\ of\ executors=N\u00famero de executores +Number\ of\ executors=N\u00famero de executores Labels=R\u00F3tulos Node\ Properties=Propriedades do n\u00F3 Save=Salvar diff --git a/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_ru.properties b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_ru.properties index 9b7a6556f57f..42957dd5ac34 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_ru.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_ru.properties @@ -20,7 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -\#\ of\ executors=\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0432-\u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u0435\u0439 +Number\ of\ executors=\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0432-\u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u0435\u0439 Description=\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 Labels=\u041c\u0435\u0442\u043a\u0438 Node\ Properties=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0443\u0437\u043b\u0430 diff --git a/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_sr.properties b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_sr.properties index 7329797f439b..7b0da707aee3 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_sr.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_sr.properties @@ -3,5 +3,5 @@ Labels=\u041B\u0430\u0431\u0435\u043B\u0435 Node\ Properties=\u041F\u043E\u0441\u0442\u0430\u0432\u043A\u0435 \u043C\u0430\u0448\u0438\u043D\u0435 Save=\u0421\u0430\u0447\u0443\u0432\u0430\u0458 -\#\ of\ executors=\u0431\u0440\u043E\u0458 \u0438\u0437\u0432\u0440\u0448\u0438\u0442\u0435\u0459\u0430 +Number\ of\ executors=\u0431\u0440\u043E\u0458 \u0438\u0437\u0432\u0440\u0448\u0438\u0442\u0435\u0459\u0430 Description=\u041E\u043F\u0438\u0441 diff --git a/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_sv_SE.properties b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_sv_SE.properties index eb0ee590c2d6..81237787943b 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_sv_SE.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_sv_SE.properties @@ -20,7 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -\#\ of\ executors= +Number\ of\ executors= Labels=Etiketter Node\ Properties=Nodegenskaper Save=Spara diff --git a/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_tr.properties b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_tr.properties index b9a08b753c9f..e97ee5ba5b08 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_tr.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_tr.properties @@ -20,7 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -\#\ of\ executors=Yap\u0131land\u0131rma i\u015flemleri say\u0131s\u0131 +Number\ of\ executors=Yap\u0131land\u0131rma i\u015flemleri say\u0131s\u0131 Labels=Etiketler Node\ Properties= Save=Kaydet diff --git a/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_zh_TW.properties b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_zh_TW.properties index f69145df6088..b973199719e2 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_zh_TW.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_zh_TW.properties @@ -21,7 +21,7 @@ # THE SOFTWARE. Description=\u8aaa\u660e -\#\ of\ executors=\u57f7\u884c\u7a0b\u5f0f\u6578 +Number\ of\ executors=\u57f7\u884c\u7a0b\u5f0f\u6578 Labels=\u6a19\u7c64 Node\ Properties=\u7bc0\u9ede\u5c6c\u6027 Save=\u5132\u5b58 diff --git a/core/src/main/resources/jenkins/model/Jenkins/_cli_ko.properties b/core/src/main/resources/jenkins/model/Jenkins/_cli_ko.properties index f62b0bcd815d..d459d5dafe49 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/_cli_ko.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/_cli_ko.properties @@ -1,4 +1,4 @@ # This file is under the MIT License by authors Available\ Commands=\uC0AC\uC6A9\uAC00\uB2A5\uD55C \uBA85\uB839\uB4E4 -blurb=Jenkins\uC758 \uB2E4\uC591\uD55C \uAE30\uB2A5\uC744 command-line \uD234\uC744 \uC0AC\uC6A9\uD558\uC5EC \uC811\uADFC\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4. \uC774\uAE30\uB2A5\uC5D0 \uB300\uD55C \uB354 \uC790\uC138\uD55C \uB0B4\uC6A9\uC740\uC774 Wiki\uB97C \uBCF4\uC138\uC694. \uC2DC\uC791\uD558\uB824\uBA74, jenkins-cli.jar\uC744 \uB2E4\uC6B4\uB85C\uB4DC \uD55C\uB4A4 \uB2E4\uC74C\uACFC \uAC19\uC774 \uC2E4\uD589\uD569\uB2C8\uB2E4: +blurb=Jenkins\uC758 \uB2E4\uC591\uD55C \uAE30\uB2A5\uC744 command-line \uD234\uC744 \uC0AC\uC6A9\uD558\uC5EC \uC811\uADFC\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4. \uC774\uAE30\uB2A5\uC5D0 \uB300\uD55C \uB354 \uC790\uC138\uD55C \uB0B4\uC6A9\uC740\uC774 Wiki\uB97C \uBCF4\uC138\uC694. \uC2DC\uC791\uD558\uB824\uBA74, jenkins-cli.jar\uC744 \uB2E4\uC6B4\uB85C\uB4DC \uD55C\uB4A4 \uB2E4\uC74C\uACFC \uAC19\uC774 \uC2E4\uD589\uD569\uB2C8\uB2E4: diff --git a/core/src/main/resources/jenkins/model/Jenkins/_cli_sv_SE.properties b/core/src/main/resources/jenkins/model/Jenkins/_cli_sv_SE.properties index 515acb75fc99..8355f19a5c91 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/_cli_sv_SE.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/_cli_sv_SE.properties @@ -2,4 +2,4 @@ Available\ Commands=Tillg\u00E4ngliga kommandon Jenkins\ CLI=Jenkins CLI (kommandorads\u00E5tkomst) -blurb=Du kan komma \u00E5t diverse funktioner i Jenkins genom ett kommandoradsverktyg. Se Wikin f\u00F6r mer detaljer av den h\u00E4r funktionen. F\u00F6r att komma ig\u00E5ng, ladda ner jenkins-cli.jar och k\u00F6r enligt f\u00F6ljande: +blurb=Du kan komma \u00E5t diverse funktioner i Jenkins genom ett kommandoradsverktyg. Se Wikin f\u00F6r mer detaljer av den h\u00E4r funktionen. F\u00F6r att komma ig\u00E5ng, ladda ner jenkins-cli.jar och k\u00F6r enligt f\u00F6ljande: diff --git a/core/src/main/resources/jenkins/model/Jenkins/_cloud-note.groovy b/core/src/main/resources/jenkins/model/Jenkins/_cloud-note.groovy deleted file mode 100644 index 9b4a929d975d..000000000000 --- a/core/src/main/resources/jenkins/model/Jenkins/_cloud-note.groovy +++ /dev/null @@ -1,19 +0,0 @@ -package jenkins.model.Jenkins - -import hudson.slaves.Cloud - -// TODO remove this once it's been long enough that users got used to this. - -def f = namespace(lib.FormTagLib) - -def clouds = Cloud.all() - -if (!clouds.isEmpty()) { - f.section(title: _("Cloud")) { - f.block { - div(class: 'alert alert-info') { - raw(_("note", rootURL)) - } - } - } -} diff --git a/core/src/main/resources/jenkins/model/Jenkins/_cloud-note.properties b/core/src/main/resources/jenkins/model/Jenkins/_cloud-note.properties deleted file mode 100644 index d9cada5eb8e2..000000000000 --- a/core/src/main/resources/jenkins/model/Jenkins/_cloud-note.properties +++ /dev/null @@ -1 +0,0 @@ -note=The cloud configuration has moved to a separate configuration page. diff --git a/core/src/main/resources/jenkins/model/Jenkins/_cloud-note_it.properties b/core/src/main/resources/jenkins/model/Jenkins/_cloud-note_it.properties deleted file mode 100644 index 4d3cdb1c6470..000000000000 --- a/core/src/main/resources/jenkins/model/Jenkins/_cloud-note_it.properties +++ /dev/null @@ -1,24 +0,0 @@ -# The MIT License -# -# Italian localization plugin for Jenkins -# Copyright 2020 Alessandro Menti -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Cloud=Cloud diff --git a/core/src/main/resources/jenkins/model/Jenkins/_restart_pt_BR.properties b/core/src/main/resources/jenkins/model/Jenkins/_restart_pt_BR.properties index 701fc9240785..72ed2753f858 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/_restart_pt_BR.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/_restart_pt_BR.properties @@ -21,4 +21,6 @@ # THE SOFTWARE. Yes=Sim -Are\ you\ sure\ about\ restarting\ Jenkins?=Tem certeza que deseja reiniciar o Jenkins? +Restart\ Jenkins=Reiniciar o Jenkins +Jenkins\ cannot\ restart\ itself\ as\ currently\ configured.=O\ Jenkins\ n\u00E3o\ pode\ se\ reiniciar\ da\ forma\ como\ est\u00E1\ configurado\ no\ momento. +Are\ you\ sure\ you\ want\ to\ restart\ Jenkins?=Voc\u00EA\ tem\ certeza\ de\ que\ quer\ reiniciar\ o\ Jenkins? diff --git a/core/src/main/resources/jenkins/model/Jenkins/_restart_zh_TW.properties b/core/src/main/resources/jenkins/model/Jenkins/_restart_zh_TW.properties index 7f64e086941b..21b559b9ac3b 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/_restart_zh_TW.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/_restart_zh_TW.properties @@ -20,5 +20,8 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Are\ you\ sure\ about\ restarting\ Jenkins?=\u60A8\u78BA\u5B9A\u8981\u91CD\u65B0\u555F\u52D5 Jenkins? -Yes=\u662F +Are\ you\ sure\ about\ restarting\ Jenkins?=\u60a8\u78ba\u5b9a\u8981\u91cd\u65b0\u555f\u52d5 Jenkins \u55ce\uff1f +Yes=\u662f +Jenkins\ cannot\ restart\ itself\ as\ currently\ configured.=Jenkins \u7121\u6cd5\u5728\u76ee\u524d\u7684\u8a2d\u5b9a\u503c\u4e0b\u81ea\u884c\u91cd\u65b0\u555f\u52d5\u3002 +Restart\ Jenkins=\u91cd\u65b0\u555f\u52d5 Jenkins +Are\ you\ sure\ you\ want\ to\ restart\ Jenkins?=\u60a8\u78ba\u5b9a\u8981\u91cd\u65b0\u555f\u52d5 Jenkins \u55ce\uff1f diff --git a/core/src/main/resources/jenkins/model/Jenkins/_safeRestart_pt_BR.properties b/core/src/main/resources/jenkins/model/Jenkins/_safeRestart_pt_BR.properties index 5b343261cb99..937005d6d1a6 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/_safeRestart_pt_BR.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/_safeRestart_pt_BR.properties @@ -21,4 +21,5 @@ # THE SOFTWARE. Yes=Sim -Are\ you\ sure\ about\ restarting\ Jenkins?\ Jenkins\ will\ restart\ once\ all\ running\ jobs\ are\ finished.=Tem certeza que deseja reiniciar o Jenkins? +Jenkins\ cannot\ restart\ itself\ as\ currently\ configured.=O\ Jenkins\ n\u00E3o\ pode\ se\ reiniciar\ da\ forma\ como\ est\u00E1\ atualmente\ configurado. +Are\ you\ sure\ you\ want\ to\ restart\ Jenkins?\ Jenkins\ will\ restart\ once\ all\ running\ jobs\ are\ finished.=Voc\u00EA\ tem\ certeza\ de\ que\ quer\ reiniciar\ o\ Jenkins?\ Ele\ reiniciar\u00E1\ uma\ vez\ que\ todos\ os\ jobs\ estejam\ conclu\u00EDdos. diff --git a/core/src/main/resources/jenkins/model/Jenkins/_safeRestart_zh_TW.properties b/core/src/main/resources/jenkins/model/Jenkins/_safeRestart_zh_TW.properties index 752fd50d547b..50d8ef2c27e3 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/_safeRestart_zh_TW.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/_safeRestart_zh_TW.properties @@ -21,6 +21,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Are\ you\ sure\ about\ restarting\ Jenkins?\ Jenkins\ will\ restart\ once\ all\ running\ jobs\ are\ finished.=\ - \u60a8\u78ba\u5b9a\u8981\u91cd\u65b0\u555f\u52d5 Jenkins \u55ce? Jenkins \u6703\u5728\u6240\u6709\u4f5c\u696d\u90fd\u5b8c\u6210\u5f8c\u91cd\u65b0\u555f\u52d5\u3002 +Are\ you\ sure\ about\ restarting\ Jenkins?\ Jenkins\ will\ restart\ once\ all\ running\ jobs\ are\ finished.=\u60a8\u78ba\u5b9a\u8981\u91cd\u65b0\u555f\u52d5 Jenkins \u55ce? Jenkins \u6703\u5728\u6240\u6709\u4f5c\u696d\u90fd\u5b8c\u6210\u5f8c\u91cd\u65b0\u555f\u52d5\u3002 Yes=\u662f +Jenkins\ cannot\ restart\ itself\ as\ currently\ configured.=Jenkins \u7121\u6cd5\u5728\u76ee\u524d\u7684\u8a2d\u5b9a\u503c\u4e0b\u81ea\u884c\u91cd\u65b0\u555f\u52d5\u3002 +Are\ you\ sure\ you\ want\ to\ restart\ Jenkins?\ Jenkins\ will\ restart\ once\ all\ running\ jobs\ are\ finished.=\u60a8\u78ba\u5b9a\u8981\u91cd\u65b0\u555f\u52d5 Jenkins \u55ce\uff1fJenkins \u6703\u5728\u6240\u6709\u4f5c\u696d\u90fd\u5b8c\u6210\u5f8c\u91cd\u65b0\u555f\u52d5\u3002 diff --git a/core/src/main/resources/jenkins/model/Jenkins/configure.jelly b/core/src/main/resources/jenkins/model/Jenkins/configure.jelly index 444b2bef4c84..10e15136cda4 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/configure.jelly +++ b/core/src/main/resources/jenkins/model/Jenkins/configure.jelly @@ -29,17 +29,20 @@ THE SOFTWARE. - + + + + -
      ${%LOADING}
      - +
      + - - ${it.rootDir} + +
      ${it.rootDir}
      - + @@ -50,15 +53,11 @@ THE SOFTWARE. - + - - - - diff --git a/core/src/main/resources/jenkins/model/Jenkins/configure_pt_BR.properties b/core/src/main/resources/jenkins/model/Jenkins/configure_pt_BR.properties index 1c41ae92bbfd..09737e724eaf 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/configure_pt_BR.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/configure_pt_BR.properties @@ -24,6 +24,6 @@ Home\ directory=Diret\u00F3rio principal System\ Message=Mensagem do sistema Save=Salvar LOADING=CARREGANDO -Build\ Record\ Root\ Directory=Diret\u00F3rio ra\u00EDz dos registros de builds -Workspace\ Root\ Directory=Diret\u00F3rio raiz do workspace Configure\ System=Configurar o sistema +By\ default,\ Jenkins\ stores\ all\ of\ its\ data\ in\ this\ directory\ on\ the\ file\ system=O\ Jenkins\ por\ padr\u00E3o\ armazena\ todos\ os\ seus\ dados\ neste\ diret\u00F3rio\ no\ sistema\ de\ arquivos. +This\ message\ will\ be\ displayed\ at\ the\ top\ of\ the\ Jenkins\ main\ page.\ This\ can\ be\ useful\ for\ posting\ notifications\ to\ your\ users=Esta\ mensagem\ ser\u00E1\ mostrada\ no\ topo\ da\ p\u00E1gina\ principal\ do\ Jenkins.\ Isto\ pode\ ser\ \u00FAtil\ para\ postar\ notifica\u00E7\u00F5es\ para\ seus\ usu\u00E1rios diff --git a/core/src/main/resources/jenkins/model/Jenkins/configure_zh_TW.properties b/core/src/main/resources/jenkins/model/Jenkins/configure_zh_TW.properties index ce48e6e8a756..57f280862a18 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/configure_zh_TW.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/configure_zh_TW.properties @@ -23,8 +23,10 @@ Configure\ System=\u8a2d\u5b9a\u7cfb\u7d71 LOADING=\u8f09\u5165\u4e2d -Home\ directory=\u4e3b\u76ee\u9304 +Home\ directory=\u5bb6\u76ee\u9304 Workspace\ Root\ Directory=\u5de5\u4f5c\u5340\u6839\u76ee\u9304 Build\ Record\ Root\ Directory=\u5efa\u7f6e\u8a18\u9304\u6839\u76ee\u9304 System\ Message=\u7cfb\u7d71\u8a0a\u606f Save=\u5132\u5b58 +This\ message\ will\ be\ displayed\ at\ the\ top\ of\ the\ Jenkins\ main\ page.\ This\ can\ be\ useful\ for\ posting\ notifications\ to\ your\ users=\u6b64\u8a0a\u606f\u6703\u986f\u793a\u5728 Jenkins \u7684\u4e3b\u9801\u4e0a\u65b9\u3002\u9019\u5f88\u9069\u5408\u7528\u4f86\u5411\u60a8\u7684\u4f7f\u7528\u8005\u767c\u4f48\u901a\u77e5\u3002 +By\ default,\ Jenkins\ stores\ all\ of\ its\ data\ in\ this\ directory\ on\ the\ file\ system=Jenkins \u9810\u8a2d\u6703\u5c07\u5b83\u7684\u6240\u6709\u8cc7\u6599\u5132\u5b58\u65bc\u6a94\u6848\u7cfb\u7d71\u4e0a\u7684\u9019\u500b\u76ee\u9304\u3002 diff --git a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck.jelly b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck.jelly index cdd23d927c66..06258f85690e 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck.jelly +++ b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck.jelly @@ -31,7 +31,6 @@ THE SOFTWARE.

      - ${%Check File Fingerprint}

      @@ -41,7 +40,7 @@ THE SOFTWARE.
      - + diff --git a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck.properties b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck.properties index 97ec4a729321..c675fa8afe6d 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck.properties @@ -24,4 +24,4 @@ description=\ Got a jar file but don\u2019t know which version it is?
      \ Find out by checking its fingerprint against \ the database in Jenkins. -fingerprint.link=https://jenkins.io/redirect/fingerprint +fingerprint.link=https://www.jenkins.io/redirect/fingerprint diff --git a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_bg.properties b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_bg.properties index b5ca36cd2941..971ff254ce0e 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_bg.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_bg.properties @@ -33,8 +33,8 @@ Check\ File\ Fingerprint=\ description=\ \u041d\u0435 \u0437\u043d\u0430\u0435\u0442\u0435 \u0432\u0435\u0440\u0441\u0438\u044f\u0442\u0430 \u043d\u0430 \u043d\u044f\u043a\u043e\u0439 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u0435\u043d \u201e.jar\u201c \u0444\u0430\u0439\u043b?
      \ \u041f\u0440\u043e\u0432\u0435\u0440\u0435\u0442\u0435 \u0437\u0430 \u0446\u0438\u0444\u0440\u043e\u0432\u0438\u044f \u043c\u0443 \u043e\u0442\u043f\u0435\u0447\u0430\u0442\u044a\u043a \u0432 \u0431\u0430\u0437\u0430\u0442\u0430 \u043d\u0430 Jenkins. -# https://jenkins.io/redirect/fingerprint +# https://www.jenkins.io/redirect/fingerprint fingerprint.link=\ - https://jenkins.io/redirect/fingerprint + https://www.jenkins.io/redirect/fingerprint more\ details=\ \u041e\u0449\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 diff --git a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_cs.properties b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_cs.properties index 21554b33849c..3c18f5cbfad1 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_cs.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_cs.properties @@ -5,5 +5,5 @@ Check\ File\ Fingerprint=Ov\u011B\u0159it otisk souboru File\ to\ check=Soubor k ov\u011B\u0159en\u00ED description=M\u00E1te jar soubor ale nev\u00EDte k jak\u00E9 verzi pat\u0159\u00ED?
      \ Ov\u011B\u0159te si jej v Jenkinsov\u011B datab\u00E1zi otisk\u016F -fingerprint.link=https://jenkins.io/redirect/fingerprint +fingerprint.link=https://www.jenkins.io/redirect/fingerprint more\ details=dal\u0161\u00ED informace diff --git a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_da.properties b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_da.properties index c7f395b6d7c0..bf3b4ac519b6 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_da.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_da.properties @@ -22,7 +22,7 @@ Check\ File\ Fingerprint=Check filfingeraftryk File\ to\ check=Fil der skal checkes -fingerprint.link=https://jenkins.io/redirect/fingerprint +fingerprint.link=https://www.jenkins.io/redirect/fingerprint description=\ Har du f\u00e5et en jar fil, men ved ikke hvilken version den har?
      \ Find ud af det ved at checke imod filfingeraftryksdatabasen i Jenkins diff --git a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_de.properties b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_de.properties index 2dad94b0b58e..977b33cc4b9f 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_de.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_de.properties @@ -27,4 +27,4 @@ more\ details=mehr... description=\ Die Version einer JAR-Datei lsst sich ber die von \ Jenkins gespeicherten Fingerabdrcke herausfinden. -fingerprint.link=https://jenkins.io/redirect/fingerprint +fingerprint.link=https://www.jenkins.io/redirect/fingerprint diff --git a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_el.properties b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_el.properties index 6d496604cc9f..7b3b766f0805 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_el.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_el.properties @@ -4,5 +4,5 @@ Check=\u0388\u03BB\u03B5\u03B3\u03C7\u03BF\u03C2 Check\ File\ Fingerprint=\u0388\u03BB\u03B5\u03B3\u03C7\u03BF\u03C2 \u0391\u03C0\u03BF\u03C4\u03C5\u03C0\u03C9\u03BC\u03AC\u03C4\u03C9\u03BD \u0391\u03C1\u03C7\u03B5\u03AF\u03C9\u03BD File\ to\ check=\u0391\u03C1\u03C7\u03B5\u03AF\u03BF \u03C0\u03C1\u03BF\u03C2 \u03AD\u03BB\u03B5\u03B3\u03C7\u03BF description=\u0388\u03C7\u03B5\u03C4\u03B5 \u03BA\u03AC\u03C0\u03BF\u03B9\u03BF jar \u03B1\u03C1\u03C7\u03B5\u03AF\u03BF \u03B1\u03BB\u03BB\u03AC \u03B4\u03B5\u03BD \u03BE\u03AD\u03C1\u03B5\u03C4\u03B5 \u03C4\u03BF\u03BD \u03B1\u03C1\u03B9\u03B8\u03BC\u03CC \u03AD\u03BA\u03B4\u03BF\u03C3\u03AE\u03C2 \u03C4\u03BF\u03C5;
      \u0392\u03C1\u03B5\u03AF\u03C4\u03B5 \u03C4\u03B7\u03BD \u03B5\u03BB\u03AD\u03B3\u03C7\u03BF\u03BD\u03C4\u03B1\u03C2 \u03C4\u03BF \u03C8\u03B7\u03C6\u03B9\u03B1\u03BA\u03CC \u03B1\u03C0\u03BF\u03C4\u03CD\u03C0\u03C9\u03BC\u03B1 \u03C4\u03BF\u03C5 \u03B1\u03C1\u03C7\u03B5\u03AF\u03BF\u03C5 \u03BA\u03B1\u03B9 \u03C3\u03C5\u03B3\u03BA\u03C1\u03AF\u03BD\u03BF\u03BD\u03C4\u03AC\u03C2 \u03C4\u03BF \u03BC\u03B5 \u03C4\u03B7 \u03B2\u03AC\u03C3\u03B7 \u03B1\u03C0\u03BF\u03C4\u03C5\u03C0\u03C9\u03BC\u03AC\u03C4\u03C9\u03BD \u03C3\u03C4\u03BF Jenkins -fingerprint.link=https://jenkins.io/redirect/fingerprint +fingerprint.link=https://www.jenkins.io/redirect/fingerprint more\ details=\u03C0\u03B5\u03C1\u03B9\u03C3\u03C3\u03CC\u03C4\u03B5\u03C1\u03B5\u03C2 \u03BB\u03B5\u03C0\u03C4\u03BF\u03BC\u03AD\u03C1\u03B5\u03B9\u03B5\u03C2 diff --git a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_es.properties b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_es.properties index 1ea94a235ddc..dbebacf47588 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_es.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_es.properties @@ -23,7 +23,7 @@ description=\ Si tienes un fichero ''jar'' en tu disco duro del que desconoces su versin
      \ Puedes identificarlo enviandolo a Jenkins para que busque su firma en la base de datos de firmas registradas. -fingerprint.link=https://jenkins.io/redirect/fingerprint +fingerprint.link=https://www.jenkins.io/redirect/fingerprint File\ to\ check=Selecciona un fichero para comprobar Check=Comprobar Check\ File\ Fingerprint=Comprobar ficheros diff --git a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_fr.properties b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_fr.properties index 64b9adc2bf39..5b3d615f749c 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_fr.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_fr.properties @@ -24,5 +24,5 @@ Check\ File\ Fingerprint=V File\ to\ check=Fichier vrifier Check=Vrifier description=Vous avez un fichier jar mais vous ne connaissez pas sa version ?
      Vous pourrez la trouver en comparant l''empreinte num\u00E9rique avec celles dans la base de donn\u00E9es de Jenkins -fingerprint.link=https://jenkins.io/redirect/fingerprint +fingerprint.link=https://www.jenkins.io/redirect/fingerprint more\ details=plus de dtails diff --git a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_it.properties b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_it.properties index 17ea409c4973..f2887d0c843c 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_it.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_it.properties @@ -27,5 +27,5 @@ description=Si dispone di un file JAR ma non si sa a che versione appartenga?\
      Lo si pu scoprire ricercando la sua impronta digitale nel database \ di Jenkins. File\ to\ check=File da controllare -fingerprint.link=https://jenkins.io/redirect/fingerprint +fingerprint.link=https://www.jenkins.io/redirect/fingerprint more\ details=Ulteriori informazioni diff --git a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_ja.properties b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_ja.properties index 3b43850a2c26..95036e44447b 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_ja.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_ja.properties @@ -27,4 +27,4 @@ description=\ jar\u30D5\u30A1\u30A4\u30EB\u3092\u53D6\u5F97\u3057\u305F\u306E\u306B\u3001\u3069\u306E\u30D0\u30FC\u30B8\u30E7\u30F3\u304B\u5206\u304B\u3089\u306A\u3044\u306E\u3067\u3059\u304B?
      \ Jenkins\u306E\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3067\u30D5\u30A1\u30A4\u30EB\u6307\u7D0B\u3092\u30C1\u30A7\u30C3\u30AF\u3059\u308C\u3070\u3001\u5206\u304B\u308A\u307E\u3059\u3002 more\ details=\u8A73\u7D30 -fingerprint.link=https://jenkins.io/redirect/fingerprint +fingerprint.link=https://www.jenkins.io/redirect/fingerprint diff --git a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_lt.properties b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_lt.properties index cb3c706f659e..5066f663ba6f 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_lt.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_lt.properties @@ -1,7 +1,7 @@ description=\ Gavote jar fail\u0105 bet ne\u017einote, kokia jo versija?
      \ Su\u017einokite patikrindami antspaud\u0105 Jenkinso duomen\u0173 baz\u0117je -fingerprint.link=https://jenkins.io/redirect/fingerprint +fingerprint.link=https://www.jenkins.io/redirect/fingerprint Check=Tikrinti Check\ File\ Fingerprint=Tikrinti failo antspaud\u0105 more\ details=daugiau informacijos diff --git a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_lv.properties b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_lv.properties index 0f20c4fb474a..5718e94a13f2 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_lv.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_lv.properties @@ -24,5 +24,5 @@ Check=P\u0101rbaud\u012Bt Check\ File\ Fingerprint=P\u0101rbaude Faila Nospiedumam File\ to\ check=Fails, kuru p\u0101baud\u012Bt description=Ir *.jar fails, kuram nezini versiju?
      Uzzini to, p\u0101rbaudot pirkstu nospiedumu pret Jenkins datub\u0101zi. -fingerprint.link=https://jenkins.io/redirect/fingerprint +fingerprint.link=https://www.jenkins.io/redirect/fingerprint more\ details=vair\u0101k inform\u0101cijas diff --git a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_nl.properties b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_nl.properties index 86bb057ad47f..1ded266febfd 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_nl.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_nl.properties @@ -24,5 +24,5 @@ Check\ File\ Fingerprint=Controleer de vingerafdruk van bestanden File\ to\ check=Te controleren bestand Check=Controleren description=Heb je een jar-bestand waarvan je de versie niet weet?
      Vind de versie door de vingerafdruk in de database in Jenkins te zoeken. -fingerprint.link=https://jenkins.io/redirect/fingerprint +fingerprint.link=https://www.jenkins.io/redirect/fingerprint more\ details=meer details diff --git a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_pl.properties b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_pl.properties index adf8853649fa..33c03fb917d7 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_pl.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_pl.properties @@ -24,5 +24,5 @@ Check=Sprawd\u017A Check\ File\ Fingerprint=Wyszukaj wyst\u0105pienia artefaktu File\ to\ check=Plik do sprawdzenia description=Masz plik ale nie wiesz w kt\u00F3rych zadaniach wyst\u0119puje?
      Wyszukaj je w bazie danych Jenkinsa. -fingerprint.link=https://jenkins.io/redirect/fingerprint +fingerprint.link=https://www.jenkins.io/redirect/fingerprint more\ details=wi\u0119cej detali diff --git a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_pt_BR.properties b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_pt_BR.properties index 9b3705a72cd7..64667db85d28 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_pt_BR.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_pt_BR.properties @@ -23,8 +23,8 @@ Check\ File\ Fingerprint=Verificar impress\u00E3o digital do arquivo File\ to\ check=Arquivo para verificar Check=Verificar -# https://jenkins.io/redirect/fingerprint -fingerprint.link=https://jenkins.io/redirect/fingerprint +# https://www.jenkins.io/redirect/fingerprint +fingerprint.link=https://www.jenkins.io/redirect/fingerprint # \ # Got a jar file but don''t know which version it is?
      \ # Find that out by checking the fingerprint against \ diff --git a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_ru.properties b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_ru.properties index 2bda6cc429ea..ea8b01288c73 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_ru.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_ru.properties @@ -24,5 +24,5 @@ Check\ File\ Fingerprint=\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c File\ to\ check=\u0424\u0430\u0439\u043b \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 Check=\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c description=\u041D\u0435 \u0437\u043D\u0430\u0435\u0442\u0435 \u0432\u0435\u0440\u0441\u0438\u044E Jar-\u0444\u0430\u0439\u043B\u0430?
      \u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C \u0432\u0430\u0448 jar-\u0444\u0430\u0439\u043B \u0434\u043B\u044F \u0435\u0433\u043E \u0441\u0440\u0430\u0432\u043D\u0435\u043D\u0438\u044F \u0441 \u0431\u0430\u0437\u043E\u0439 \u043E\u0442\u043F\u0435\u0447\u0430\u0442\u043A\u043E\u0432 \u0444\u0430\u0439\u043B\u043E\u0432 Jenkins -fingerprint.link=https://jenkins.io/redirect/fingerprint +fingerprint.link=https://www.jenkins.io/redirect/fingerprint more\ details=\u0434\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u0430\u044F \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F diff --git a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_sk.properties b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_sk.properties index 714bd48aa4b2..37da8a88cf44 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_sk.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_sk.properties @@ -3,5 +3,5 @@ Check=Skontroluj Check\ File\ Fingerprint=Skontroluj odtla\u010Dok s\u00FAboru File\ to\ check=S\u00FAbor na kontrolu -fingerprint.link=https://jenkins.io/redirect/fingerprint +fingerprint.link=https://www.jenkins.io/redirect/fingerprint more\ details=viac detailov diff --git a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_sr.properties b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_sr.properties index 5e41956e636e..6c00c43d80fa 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_sr.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_sr.properties @@ -3,7 +3,7 @@ Check\ File\ Fingerprint=\u041F\u0440\u043E\u0432\u0435\u0440\u0438 description=\u041D\u0435\u0437\u043D\u0430\u0442\u0435 \u0432\u0435\u0440\u0437\u0438\u0458\u0443 \u043E\u0434 \u043D\u0435\u043A\u0435 '.jar' \u0430\u0440\u0445\u0438\u0432\u0435?
      \ \u041F\u0440\u043E\u0432\u0435\u0440\u0438\u0442\u0435 \u043F\u043E \u0434\u0438\u0433\u0438\u0442\u0430\u043B\u043D\u043E\u043C \u043E\u0442\u0438\u0441\u043A\u0443. -fingerprint.link=https://jenkins.io/redirect/fingerprint +fingerprint.link=https://www.jenkins.io/redirect/fingerprint more\ details=\u0412\u0438\u0448\u0435 \u0434\u0435\u0442\u0430\u0459\u0430 File\ to\ check=\u0410\u0440\u0445\u0438\u0432\u0430 \u0437\u0430 \u043F\u0440\u043E\u0432\u0435\u0440\u0438\u0432\u0430\u045A\u0435 Check=\u041F\u0440\u043E\u0432\u0435\u0440\u0438 diff --git a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_sv_SE.properties b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_sv_SE.properties index 0e75e28d3964..22f7fc864dd6 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_sv_SE.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_sv_SE.properties @@ -24,5 +24,5 @@ Check=Kontrollera Check\ File\ Fingerprint=Kontrollera filkontrollsumma File\ to\ check=Fil att kontrollera description=Har du en jar fil men vet inte vilket version den \u00E4r?
      Kontrollera det via kontrollsumman i Jenkins databas -fingerprint.link=https://jenkins.io/redirect/fingerprint +fingerprint.link=https://www.jenkins.io/redirect/fingerprint more\ details=mer detaljer diff --git a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_zh_TW.properties b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_zh_TW.properties index 3258dafaee7a..7e2232a5f502 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_zh_TW.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_zh_TW.properties @@ -1,17 +1,17 @@ # The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc. -# +# +# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Seiji Sogabe +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: -# +# # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. -# +# # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -19,10 +19,9 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. - +description=\u624b\u908a\u6709\u500b JAR \u6a94\uff0c\u4f46\u662f\u537b\u4e0d\u77e5\u9053\u5b83\u5230\u5e95\u662f\u54ea\u4e00\u7248\u7684\uff1f
      \u900f\u904e\u6a94\u6848\u7684\u6307\u7d0b\u5230 Jenkins \u7684\u8cc7\u6599\u5eab\u88e1\u627e\u770b\u770b\u5427\u3002 +fingerprint.link=https\://www.jenkins.io/redirect/fingerprint Check\ File\ Fingerprint=\u6aa2\u67e5\u6a94\u6848\u6307\u7d0b -description=\u624B\u908A\u6709\u500B JAR \u6A94\uFF0C\u4F46\u662F\u537B\u4E0D\u77E5\u9053\u5B83\u5230\u5E95\u662F\u54EA\u4E00\u7248\u7684?
      \u900F\u904E\u6A94\u6848\u7684\u7279\u5FB5\u503C\u5230 Jenkins \u7684\u8CC7\u6599\u5EAB\u88E1\u627E\u770B\u770B\u5427 -fingerprint.link=https://jenkins.io/redirect/fingerprint more\ details=\u8a73\u7d30\u8cc7\u6599 File\ to\ check=\u8981\u6aa2\u67e5\u7684\u6a94\u6848 Check=\u6aa2\u67e5 diff --git a/core/src/main/resources/jenkins/model/Jenkins/help-markupFormatter.html b/core/src/main/resources/jenkins/model/Jenkins/help-markupFormatter.html index 21f0e1d8ef39..12621e2aa042 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/help-markupFormatter.html +++ b/core/src/main/resources/jenkins/model/Jenkins/help-markupFormatter.html @@ -8,6 +8,6 @@

      While this is convenient and people often use it to load <iframe>, <script>. and so on to mash up data from other sources, this capability enables malicious users to mount - XSS attacks. + XSS attacks. If the risk outweighs the benefit, install additional markup formatter plugins and use them.

      diff --git a/core/src/main/resources/jenkins/model/Jenkins/help-markupFormatter_bg.html b/core/src/main/resources/jenkins/model/Jenkins/help-markupFormatter_bg.html index ed0ba000e1f4..e0cd7e418e2f 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/help-markupFormatter_bg.html +++ b/core/src/main/resources/jenkins/model/Jenkins/help-markupFormatter_bg.html @@ -10,7 +10,7 @@ Това е доста удобно и хората го ползват, за да зареждат <iframe>, <script> и т.н., това позволява на недобронамерените потребители да извършат атаки чрез - XSS. + XSS. Ако рискът е прекомерно голям, инсталирайте допълнителна приставка за форматиране на текста и ползвайте нея. diff --git a/core/src/main/resources/jenkins/model/Jenkins/help-markupFormatter_ja.html b/core/src/main/resources/jenkins/model/Jenkins/help-markupFormatter_ja.html index 380b735d1de3..8eca80f7610d 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/help-markupFormatter_ja.html +++ b/core/src/main/resources/jenkins/model/Jenkins/help-markupFormatter_ja.html @@ -6,7 +6,7 @@

      これはとても便利なので、<iframe>, <script>をロードするために、また他のソースからのデータを取り込むためによく使用しますが、 - 悪意のあるユーザーがクロスサイトスクリプティング + 悪意のあるユーザーがクロスサイトスクリプティング をしかけることを容易にしてしまいます。 便利さより危険性を重視するなら、他のフォーマッタープラグインをインストールして使用してください。 - \ No newline at end of file + diff --git a/core/src/main/resources/jenkins/model/Jenkins/help-markupFormatter_zh_TW.html b/core/src/main/resources/jenkins/model/Jenkins/help-markupFormatter_zh_TW.html index 01da0749a14c..8753cb6fb4a3 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/help-markupFormatter_zh_TW.html +++ b/core/src/main/resources/jenkins/model/Jenkins/help-markupFormatter_zh_TW.html @@ -7,6 +7,6 @@

      這樣很方便,大家常用來載入 <iframe> 或 <script>,整合其他來源的資料。 但是也有可能被惡意使用者掛上 - XSS 攻擊。 + XSS 攻擊。 如果您評估的風險大過好處,請另外安裝使用標記格式外掛程式。 diff --git a/core/src/main/resources/jenkins/model/Jenkins/legend_ar.properties b/core/src/main/resources/jenkins/model/Jenkins/legend_ar.properties deleted file mode 100644 index 16aed0425213..000000000000 --- a/core/src/main/resources/jenkins/model/Jenkins/legend_ar.properties +++ /dev/null @@ -1,15 +0,0 @@ -# This file is under the MIT License by authors - -blue=\u0622\u062E\u0631 \u0628\u0646\u0627\u0621 \u0643\u0627\u0646 \u0646\u0627\u062C\u062D\u0627\u064B. -blue_anime=\u0622\u062E\u0631 \u0628\u0646\u0627\u0621 \u0643\u0627\u0646 \u0646\u0627\u062C\u062D\u0627\u064B. \u0628\u0646\u0627\u0621 \u062C\u062F\u064A\u062F \u0637\u0648\u0631 \u0627\u0644\u0645\u0639\u0627\u0644\u062C\u0629. -grey=\u0627\u0644\u0645\u0634\u0631\u0648\u0639 \u0644\u064A\u0633 \u0644\u0647 \u0623\u064A \u0628\u0646\u0627\u0621 \u0645\u0646 \u0642\u0628\u0644\u060C \u0623\u0648 \u0627\u0644\u0645\u0634\u0631\u0648\u0639 \u0645\u0639\u0637\u0644. -grey_anime=\u0623\u0648\u0644 \u0628\u0646\u0627\u0621 \u0644\u0644\u0645\u0634\u0631\u0648\u0639 \u0637\u0648\u0631 \u0627\u0644\u0645\u0639\u0627\u0644\u062C\u0629. -health-00to20=\u0635\u062D\u0629 \u0627\u0644\u0645\u0634\u0631\u0648\u0639 20% \u0623\u0648\u0644 \u0623\u0642\u0644. \u0628\u0625\u0645\u0643\u0627\u0646\u0643 \u062A\u0645\u0631\u064A\u0631 \u0627\u0644\u0641\u0623\u0631\u0629 \u0641\u0648\u0642 \u0623\u064A\u0642\u0648\u0646\u0629 \u0627\u0644\u0645\u0634\u0631\u0648\u0639 \u0644\u062A\u062D\u0635\u0644 \u0639\u0644\u0649 \u062A\u0641\u0627\u0635\u064A\u0644 \u0625\u0636\u0627\u0641\u064A\u0629. -health-21to40=\u0635\u062D\u0629 \u0627\u0644\u0645\u0634\u0631\u0648\u0639 \u0641\u0648\u0642 20% \u0648\u062A\u0635\u0644 \u0644 40%. \u0628\u0625\u0645\u0643\u0627\u0646\u0643 \u062A\u0645\u0631\u064A\u0631 \u0627\u0644\u0641\u0623\u0631\u0629 \u0641\u0648\u0642 \u0623\u064A\u0642\u0648\u0646\u0629 \u0627\u0644\u0645\u0634\u0631\u0648\u0639 \u0644\u062A\u062D\u0635\u0644 \u0639\u0644\u0649 \u062A\u0641\u0627\u0635\u064A\u0644 \u0625\u0636\u0627\u0641\u064A\u0629. -health-41to60=\u0635\u062D\u0629 \u0627\u0644\u0645\u0634\u0631\u0648\u0639 \u0641\u0648\u0642 40% \u0648\u062A\u0635\u0644 \u0644 60%. \u0628\u0625\u0645\u0643\u0627\u0646\u0643 \u062A\u0645\u0631\u064A\u0631 \u0627\u0644\u0641\u0623\u0631\u0629 \u0641\u0648\u0642 \u0623\u064A\u0642\u0648\u0646\u0629 \u0627\u0644\u0645\u0634\u0631\u0648\u0639 \u0644\u062A\u062D\u0635\u0644 \u0639\u0644\u0649 \u062A\u0641\u0627\u0635\u064A\u0644 \u0625\u0636\u0627\u0641\u064A\u0629. -health-61to80=\u0635\u062D\u0629 \u0627\u0644\u0645\u0634\u0631\u0648\u0639 \u0641\u0648\u0642 60% \u0648\u062A\u0635\u0644 \u0644 80%. \u0628\u0625\u0645\u0643\u0627\u0646\u0643 \u062A\u0645\u0631\u064A\u0631 \u0627\u0644\u0641\u0623\u0631\u0629 \u0641\u0648\u0642 \u0623\u064A\u0642\u0648\u0646\u0629 \u0627\u0644\u0645\u0634\u0631\u0648\u0639 \u0644\u062A\u062D\u0635\u0644 \u0639\u0644\u0649 \u062A\u0641\u0627\u0635\u064A\u0644 \u0625\u0636\u0627\u0641\u064A\u0629. -health-81plus=\u0635\u062D\u0629 \u0627\u0644\u0645\u0634\u0631\u0648\u0639 \u0641\u0648\u0642 80%. \u0628\u0625\u0645\u0643\u0627\u0646\u0643 \u062A\u0645\u0631\u064A\u0631 \u0627\u0644\u0641\u0623\u0631\u0629 \u0641\u0648\u0642 \u0623\u064A\u0642\u0648\u0646\u0629 \u0627\u0644\u0645\u0634\u0631\u0648\u0639 \u0644\u062A\u062D\u0635\u0644 \u0639\u0644\u0649 \u062A\u0641\u0627\u0635\u064A\u0644 \u0625\u0636\u0627\u0641\u064A\u0629. -red=\u0622\u062E\u0631 \u0628\u0646\u0627\u0621 \u0641\u0634\u0644 \u0628\u0634\u0643\u0644 \u0642\u0627\u062A\u0644. -red_anime=\u0622\u062E\u0631 \u0628\u0646\u0627\u0621 \u0641\u0634\u0644 \u0628\u0634\u0643\u0644 \u0642\u0627\u062A\u0644. \u0628\u0646\u0627\u0621 \u062C\u062F\u064A\u062F \u0637\u0648\u0631 \u0627\u0644\u0645\u0639\u0627\u0644\u062C\u0629. -yellow=\u0622\u062E\u0631 \u0628\u0646\u0627\u0621 \u0643\u0627\u0646 \u0646\u0627\u062C\u062D\u0627\u064B \u0648\u0644\u0643\u0646 \u063A\u064A\u0631 \u062B\u0627\u0628\u062A. \u0647\u0630\u0647 \u062A\u0633\u062A\u062E\u062F\u0645 \u0628\u0634\u0643\u0644 \u0631\u0626\u064A\u0633\u064A \u0644\u0644\u062A\u0639\u0628\u064A\u0631 \u0639\u0646 \u0641\u0634\u0644 \u0641\u064A \u0627\u0644\u0627\u062E\u062A\u0628\u0627\u0631\u0627\u062A. -yellow_anime=\u0622\u062E\u0631 \u0628\u0646\u0627\u0621 \u0643\u0627\u0646 \u0646\u0627\u062C\u062D\u0627\u064B \u0648\u0644\u0643\u0646 \u063A\u064A\u0631 \u062B\u0627\u0628\u062A. \u0628\u0646\u0627\u0621 \u062C\u062F\u064A\u062F \u0637\u0648\u0631 \u0627\u0644\u0645\u0639\u0627\u0644\u062C\u0629. diff --git a/core/src/main/resources/jenkins/model/Jenkins/legend_fr.properties b/core/src/main/resources/jenkins/model/Jenkins/legend_fr.properties index 322a7d9d53f4..35b8cc6b21bd 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/legend_fr.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/legend_fr.properties @@ -22,6 +22,10 @@ grey=Le projet n''a jamais \u00e9t\u00e9 construit avant ou est d\u00e9sactiv\u00e9. grey_anime=Le premier build du projet est en cours. +darkgrey=Le dernier build a \u00e9t\u00e9 abandonn\u00e9. +darkgrey_anime=Le dernier build a \u00e9t\u00e9 abandonn\u00e9. Un nouveau build est en cours. +lightgrey=Le projet n''a jamais \u00e9t\u00e9 construit. +lightgrey_anime=Le premier build est en cours. blue=Le dernier build s''est achev\u00e9 avec succ\u00e8s. blue_anime=Le dernier build s''est achev\u00e9 avec succ\u00e8s. Un nouveau build est en cours. yellow=Le dernier build s''est achev\u00e9 avec succ\u00e8s mais est instable. \ diff --git a/core/src/main/resources/jenkins/model/Jenkins/legend_ko.properties b/core/src/main/resources/jenkins/model/Jenkins/legend_ko.properties index 699b262351b6..0e629cbd23ab 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/legend_ko.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/legend_ko.properties @@ -20,21 +20,20 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -blue=\uB9C8\uC9C0\uB9C9 \uBE4C\uB4DC\uAC00 \uC131\uACF5\uD568. -blue_anime=\uB9C8\uC9C0\uB9C9 \uBE4C\uB4DC\uAC00 \uC131\uACF5\uD568. \uC2E0\uADDC \uBE4C\uB4DC\uAC00 \uC9C4\uD589 \uC911\uC784. -grey=\uD504\uB85C\uC81D\uD2B8\uAC00 \uBE4C\uB4DC\uB41C \uC801\uC774 \uC5C6\uAC70\uB098, \uC0AC\uC6A9\uBD88\uAC00\uC784. -grey_anime=\uD504\uB85C\uC81D\uD2B8\uC758 \uCD5C\uCD08 \uBE4C\uB4DC\uAC00 \uC9C4\uD589 \uC911\uC784. -health-00to19=\uD504\uB85C\uC81D\uD2B8 \uAC74\uAC15\uC0C1\uD0DC\uAC00 \uC801\uC5B4\uB3C4 20% \uBBF8\uB9CC \uC784. \uC880 \uB354 \uC790\uC138\uD55C \uC124\uBA85\uC744 \uC704\uD574\uC11C \uD504\uB85C\uC81D\uD2B8 \uC544\uC774\uCF58 \uC704\uC5D0 \uB9C8\uC6B0\uC2A4\uB97C \uC704\uCE58\uC2DC\uD0AC \uC218 \uC788\uC74C -health-00to20=\uD504\uB85C\uC81D\uD2B8 \uAC74\uAC15\uC0C1\uD0DC\uAC00 20% \uC774\uD558\uC784. \uB9C8\uC6B0\uC2A4\uB97C \uD504\uB85C\uC81D\uD2B8 \uC544\uC774\uCF58\uC5D0 \uC62C\uB824\uB193\uC73C\uBA74 \uB354 \uC790\uC138\uD55C \uC124\uBA85\uC744 \uBCFC \uC218 \uC788\uC2B5\uB2C8\uB2E4. -health-20to39=\uD504\uB85C\uC81D\uD2B8 \uAC74\uAC15\uC0C1\uD0DC\uAC00 \uC801\uC5B4\uB3C4 20% \uC774\uC0C1 40% \uBBF8\uB9CC \uC784. \uC880 \uB354 \uC790\uC138\uD55C \uC124\uBA85\uC744 \uC704\uD574\uC11C \uD504\uB85C\uC81D\uD2B8 \uC544\uC774\uCF58 \uC704\uC5D0 \uB9C8\uC6B0\uC2A4\uB97C \uC704\uCE58\uC2DC\uD0AC \uC218 \uC788\uC74C -health-21to40=\uD504\uB85C\uC81D\uD2B8 \uAC74\uAC15\uC0C1\uD0DC\uAC00 20% \uCD08\uACFC 40% \uC774\uD558\uC784. \uB9C8\uC6B0\uC2A4\uB97C \uD504\uB85C\uC81D\uD2B8 \uC544\uC774\uCF58\uC5D0 \uC62C\uB824\uB193\uC73C\uBA74 \uB354 \uC790\uC138\uD55C \uC124\uBA85\uC744 \uBCFC \uC218 \uC788\uC2B5\uB2C8\uB2E4. -health-40to59=\uD504\uB85C\uC81D\uD2B8 \uAC74\uAC15\uC0C1\uD0DC\uAC00 \uC801\uC5B4\uB3C4 40% \uC774\uC0C1 60% \uBBF8\uB9CC \uC784. \uC880 \uB354 \uC790\uC138\uD55C \uC124\uBA85\uC744 \uC704\uD574\uC11C \uD504\uB85C\uC81D\uD2B8 \uC544\uC774\uCF58 \uC704\uC5D0 \uB9C8\uC6B0\uC2A4\uB97C \uC704\uCE58\uC2DC\uD0AC \uC218 \uC788\uC74C -health-41to60=\uD504\uB85C\uC81D\uD2B8 \uAC74\uAC15\uC0C1\uD0DC\uAC00 40% \uCD08\uACFC 60% \uC774\uD558\uC784. \uB9C8\uC6B0\uC2A4\uB97C \uD504\uB85C\uC81D\uD2B8 \uC544\uC774\uCF58\uC5D0 \uC62C\uB824\uB193\uC73C\uBA74 \uB354 \uC790\uC138\uD55C \uC124\uBA85\uC744 \uBCFC \uC218 \uC788\uC2B5\uB2C8\uB2E4. -health-60to79=\uD504\uB85C\uC81D\uD2B8 \uAC74\uAC15\uC0C1\uD0DC\uAC00 \uC801\uC5B4\uB3C4 60% \uC774\uC0C1 80% \uBBF8\uB9CC \uC784. \uC880 \uB354 \uC790\uC138\uD55C \uC124\uBA85\uC744 \uC704\uD574\uC11C \uD504\uB85C\uC81D\uD2B8 \uC544\uC774\uCF58 \uC704\uC5D0 \uB9C8\uC6B0\uC2A4\uB97C \uC704\uCE58\uC2DC\uD0AC \uC218 \uC788\uC74C -health-61to80=\uD504\uB85C\uC81D\uD2B8 \uAC74\uAC15\uC0C1\uD0DC\uAC00 60% \uCD08\uACFC\uC784. \uB9C8\uC6B0\uC2A4\uB97C \uD504\uB85C\uC81D\uD2B8 \uC544\uC774\uCF58\uC5D0 \uC62C\uB824\uB193\uC73C\uBA74 \uB354 \uC790\uC138\uD55C \uC124\uBA85\uC744 \uBCFC \uC218 \uC788\uC2B5\uB2C8\uB2E4. -health-80plus=\uD504\uB85C\uC81D\uD2B8 \uAC74\uAC15\uC0C1\uD0DC\uAC00 \uC801\uC5B4\uB3C4 80%\uC784. \uC880 \uB354 \uC790\uC138\uD55C \uC124\uBA85\uC744 \uC704\uD574\uC11C \uD504\uB85C\uC81D\uD2B8 \uC544\uC774\uCF58 \uC704\uC5D0 \uB9C8\uC6B0\uC2A4\uB97C \uC704\uCE58\uC2DC\uD0AC \uC218 \uC788\uC74C -health-81plus=\uD504\uB85C\uC81D\uD2B8 \uAC74\uAC15\uC0C1\uD0DC\uAC00 28% \uCD08\uACFC\uC784. \uB9C8\uC6B0\uC2A4\uB97C \uD504\uB85C\uC81D\uD2B8 \uC544\uC774\uCF58\uC5D0 \uC62C\uB824\uB193\uC73C\uBA74 \uB354 \uC790\uC138\uD55C \uC124\uBA85\uC744 \uBCFC \uC218 \uC788\uC2B5\uB2C8\uB2E4. -red=\uB9C8\uC9C0\uB9C9 \uBE4C\uB4DC\uAC00 \uC2EC\uAC01\uD558\uAC8C \uC2E4\uD328\uD568. -red_anime=\uB9C8\uC9C0\uB9C9 \uBE4C\uB4DC\uAC00 \uC2EC\uAC01\uD558\uAC8C \uC2E4\uD328\uD568. \uC2E0\uADDC \uBE4C\uB4DC\uAC00 \uC9C4\uD589 \uC911\uC784. -yellow=\uB9C8\uC9C0\uB9C9 \uBE4C\uB4DC\uAC00 \uC131\uACF5\uD588\uC9C0\uB9CC \uBD88\uC548\uC815\uD568. \uC8FC\uB85C \uB0A8\uC544\uC788\uB358 \uAC80\uC99D \uC2E4\uD328\uB97C \uC0AC\uC6A9\uD55C \uAC83\uC784. -yellow_anime=\uB9C8\uC9C0\uB9C9 \uBE4C\uB4DC\uAC00 \uC131\uACF5\uD588\uC9C0\uB9CC \uBD88\uC548\uC815\uD568. \uC2E0\uADDC \uBE4C\uB4DC\uAC00 \uC9C4\uD589 \uC911\uC784 +lightgrey=\uD504\uB85C\uC81D\uD2B8\uAC00 \uBE4C\uB4DC\uB41C \uC801\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. +lightgrey_anime=\uD504\uB85C\uC81D\uD2B8\uC758 \uCD5C\uCD08 \uBE4C\uB4DC\uAC00 \uC9C4\uD589 \uC911\uC785\uB2C8\uB2E4. +grey=\uD504\uB85C\uC81D\uD2B8\uAC00 \uBE4C\uB4DC\uB41C \uC801\uC774 \uC5C6\uAC70\uB098, \uBE44\uD65C\uC131 \uC0C1\uD0DC\uC785\uB2C8\uB2E4. +grey_anime=\uD504\uB85C\uC81D\uD2B8\uC758 \uCD5C\uCD08 \uBE4C\uB4DC\uAC00 \uC9C4\uD589 \uC911\uC785\uB2C8\uB2E4. +darkgrey=\uB9C8\uC9C0\uB9C9 \uBE4C\uB4DC\uAC00 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4. +darkgrey_anime=\uB9C8\uC9C0\uB9C9 \uBE4C\uB4DC\uAC00 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uC0C8\uB85C\uC6B4 \uBE4C\uB4DC\uAC00 \uC9C4\uD589 \uC911\uC785\uB2C8\uB2E4. +blue=\uB9C8\uC9C0\uB9C9 \uBE4C\uB4DC\uAC00 \uC131\uACF5\uD588\uC2B5\uB2C8\uB2E4. +blue_anime=\uB9C8\uC9C0\uB9C9 \uBE4C\uB4DC\uAC00 \uC131\uACF5\uD588\uC2B5\uB2C8\uB2E4. \uC0C8\uB85C\uC6B4 \uBE4C\uB4DC\uAC00 \uC9C4\uD589 \uC911\uC785\uB2C8\uB2E4. +yellow=\uB9C8\uC9C0\uB9C9 \uBE4C\uB4DC\uAC00 \uC131\uACF5\uD588\uC9C0\uB9CC \uBD88\uC548\uC815\uD569\uB2C8\uB2E4. \uC774\uAC83\uC740 \uC8FC\uB85C \uD14C\uC2A4\uD2B8 \uC2E4\uD328\uB97C \uB098\uD0C0\uB0B4\uB294 \uB370 \uC0AC\uC6A9\uB429\uB2C8\uB2E4. +yellow_anime=\uB9C8\uC9C0\uB9C9 \uBE4C\uB4DC\uAC00 \uC131\uACF5\uD588\uC9C0\uB9CC \uBD88\uC548\uC815\uD569\uB2C8\uB2E4. \uC0C8\uB85C\uC6B4 \uBE4C\uB4DC\uAC00 \uC9C4\uD589 \uC911\uC785\uB2C8\uB2E4. +red=\uB9C8\uC9C0\uB9C9 \uBE4C\uB4DC\uAC00 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4. +red_anime=\uB9C8\uC9C0\uB9C9 \uBE4C\uB4DC\uAC00 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4. \uC0C8\uB85C\uC6B4 \uBE4C\uB4DC\uAC00 \uC9C4\uD589 \uC911\uC785\uB2C8\uB2E4. +health-81plus=\uD504\uB85C\uC81D\uD2B8 \uAC74\uAC15\uC0C1\uD0DC\uAC00 80% \uCD08\uACFC\uC785\uB2C8\uB2E4. \uB9C8\uC6B0\uC2A4\uB97C \uD504\uB85C\uC81D\uD2B8 \uC544\uC774\uCF58\uC5D0 \uC62C\uB824\uB193\uC73C\uBA74 \uB354 \uC790\uC138\uD55C \uC124\uBA85\uC744 \uBCFC \uC218 \uC788\uC2B5\uB2C8\uB2E4. +health-61to80=\uD504\uB85C\uC81D\uD2B8 \uAC74\uAC15\uC0C1\uD0DC\uAC00 60% \uCD08\uACFC 80% \uC774\uD558\uC785\uB2C8\uB2E4. \uB9C8\uC6B0\uC2A4\uB97C \uD504\uB85C\uC81D\uD2B8 \uC544\uC774\uCF58\uC5D0 \uC62C\uB824\uB193\uC73C\uBA74 \uB354 \uC790\uC138\uD55C \uC124\uBA85\uC744 \uBCFC \uC218 \uC788\uC2B5\uB2C8\uB2E4. +health-41to60=\uD504\uB85C\uC81D\uD2B8 \uAC74\uAC15\uC0C1\uD0DC\uAC00 40% \uCD08\uACFC 60% \uC774\uD558\uC785\uB2C8\uB2E4. \uB9C8\uC6B0\uC2A4\uB97C \uD504\uB85C\uC81D\uD2B8 \uC544\uC774\uCF58\uC5D0 \uC62C\uB824\uB193\uC73C\uBA74 \uB354 \uC790\uC138\uD55C \uC124\uBA85\uC744 \uBCFC \uC218 \uC788\uC2B5\uB2C8\uB2E4. +health-21to40=\uD504\uB85C\uC81D\uD2B8 \uAC74\uAC15\uC0C1\uD0DC\uAC00 20% \uCD08\uACFC 40% \uC774\uD558\uC785\uB2C8\uB2E4. \uB9C8\uC6B0\uC2A4\uB97C \uD504\uB85C\uC81D\uD2B8 \uC544\uC774\uCF58\uC5D0 \uC62C\uB824\uB193\uC73C\uBA74 \uB354 \uC790\uC138\uD55C \uC124\uBA85\uC744 \uBCFC \uC218 \uC788\uC2B5\uB2C8\uB2E4. +health-00to20=\uD504\uB85C\uC81D\uD2B8 \uAC74\uAC15\uC0C1\uD0DC\uAC00 20% \uC774\uD558\uC785\uB2C8\uB2E4. \uB9C8\uC6B0\uC2A4\uB97C \uD504\uB85C\uC81D\uD2B8 \uC544\uC774\uCF58\uC5D0 \uC62C\uB824\uB193\uC73C\uBA74 \uB354 \uC790\uC138\uD55C \uC124\uBA85\uC744 \uBCFC \uC218 \uC788\uC2B5\uB2C8\uB2E4. diff --git a/core/src/main/resources/jenkins/model/Jenkins/legend_pt_BR.properties b/core/src/main/resources/jenkins/model/Jenkins/legend_pt_BR.properties index 10ace3c7d537..dce9fed931fd 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/legend_pt_BR.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/legend_pt_BR.properties @@ -20,31 +20,22 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -# The last build was successful but unstable. A new build is in progress. -yellow_anime=O \u00FAltimo build foi bem-sucedido mas inst\u00E1vel. Um novo build est\u00E1 em andamento. -# Project health is over 20% and up to 40%. You can hover the mouse over the project''s icon for a more detailed explanation. +yellow_anime=A \u00FAltima constru\u00E7\u00E3o foi bem-sucedida mas inst\u00E1vel. Uma nova constru\u00E7\u00E3o est\u00E1 em andamento. health-21to40=A sa\u00FAde do seu projeto esta entre 20% e 40%. Passe o mouse no \u00EDcone para mais detalhes. -# Project health is over 40% and up to 60%. You can hover the mouse over the project''s icon for a more detailed explanation. health-41to60=A sa\u00FAde do projeto est\u00E1 entre 40% e 60%. Passe o mouse no \u00EDcone para mais detalhes. -# The last build fatally failed. -red=O \u00FAltimo build teve um erro fatal - -# The project has never been built before, or the project is disabled. -grey=Essa foi o primeiro build do projeto, ou esse projeto estava desativado. -# Project health is over 60% and up to 80%. You can hover the mouse over the project''s icon for a more detailed explanation. +red=A \u00FAltima constru\u00E7\u00E3o teve um erro fatal +grey=Este projeto nunca foi constru\u00EDdo antes ou est\u00E1 desabilitado. health-61to80=A sa\u00FAde do projeto est\u00E1 entre 60% e 80%. Passe o mouse no \u00EDcone para mais detalhes. -# The last build was successful but unstable.\ -# This is primarily used to represent test failures. -yellow=O \u00FAltimo build foi bem-sucedido, mas inst\u00E1vel. Isto \u00E9 utilizado primeiramente para representar falhas nos testes. -# The last build was successful. A new build is in progress. -blue_anime=O \u00FAltimo build foi bem-sucedido. Um novo build est\u00E1 em andamento. -# Project health is 20% or less. You can hover the mouse over the project''s icon for a more detailed explanation. +yellow=A \u00FAltima constru\u00E7\u00E3o build foi bem-sucedida, mas inst\u00E1vel. \ + Isto \u00E9 primariamente utilizado para representar falhas nos testes. +blue_anime=A \u00FAltima constru\u00E7\u00E3o foi bem-sucedida. Uma nova constru\u00E7\u00E3o est\u00E1 em andamento. health-00to20=A sa\u00FAde do seu projeto est\u00E1 em 20% ou menos. Passe o mouse no \u00EDcone do projeto para mais detalhes. -# The first build of the project is in progress. -grey_anime=O primeiro build do projeto est\u00E1 em andamento. -# The last build was successful. -blue=O \u00FAltimo build foi bem-sucedido. -# Project health is over 80%. You can hover the mouse over the project''s icon for a more detailed explanation. +grey_anime=A primeira constru\u00E7\u00E3o do projeto est\u00E1 em andamento. +blue=A \u00FAltima constru\u00E7\u00E3o foi bem-sucedida. health-81plus=A sa\u00FAde do projeto foi maior que 80%. Passe o mouse no \u00EDcone para mais detalhes. # The last build fatally failed. A new build is in progress. -red_anime=O \u00FAltimo build teve um erro fatal. Um novo build est\u00E1 em andamento. +red_anime=A \u00FAltima constru\u00E7\u00E3o teve um erro fatal. Uma nova constru\u00E7\u00E3o est\u00E1 em andamento. +darkgrey=A \u00FAltima constru\u00E7\u00E3o foi abortada. +darkgrey_anime=A \u00FAltima constru\u00E7\u00E3o foi abortada. Uma nova constru\u00E7\u00E3o est\u00E1 em progresso. +lightgrey_anime=A primeira constru\u00E7\u00E3o est\u00E1 em progresso. +lightgrey=O projeto nunca foi constru\u00EDdo antes. diff --git a/core/src/main/resources/jenkins/model/Jenkins/legend_zh_TW.properties b/core/src/main/resources/jenkins/model/Jenkins/legend_zh_TW.properties index 1f8fc779ed21..5e5763b11975 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/legend_zh_TW.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/legend_zh_TW.properties @@ -1,18 +1,18 @@ # The MIT License -# +# # Copyright (c) 2004-2013, Sun Microsystems, Inc., Chunghwa Telecom Co., Ltd., # and Pei-Tang Huang -# +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: -# +# # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. -# +# # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -20,15 +20,18 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. - -grey=\u9019\u500b\u5c08\u6848\u5f9e\u4f86\u6c92\u5efa\u7f6e\u904e\uff0c\u6216\u662f\u5df2\u7d93\u88ab\u95dc\u9589\u3002 -grey_anime=\u6b63\u5728\u7b2c\u4e00\u6b21\u5efa\u7f6e\u5c08\u6848\u3002 +grey=\u9019\u500b\u5c08\u6848\u5df2\u505c\u7528\u3002 +grey_anime=\u9019\u500b\u5c08\u6848\u5df2\u505c\u7528\uff0c\u4f46\u6b63\u5728\u9032\u884c\u5efa\u7f6e\u3002 +darkgrey=\u6700\u8fd1\u4e00\u6b21\u5efa\u7f6e\u5df2\u4e2d\u6b62\u3002 +darkgrey_anime=\u6700\u8fd1\u4e00\u6b21\u5efa\u7f6e\u5df2\u4e2d\u6b62\u3002\u6b63\u5728\u5efa\u7f6e\u65b0\u7248\u672c\u3002 +lightgrey=\u8a72\u5c08\u6848\u4e0d\u66fe\u5efa\u7f6e\u3002 +lightgrey_anime=\u6b63\u5728\u9032\u884c\u7b2c\u4e00\u6b21\u5efa\u7f6e\u3002 blue=\u6700\u8fd1\u4e00\u6b21\u7684\u5efa\u7f6e\u662f\u6210\u529f\u7684\u3002 -blue_anime=\u6700\u8fd1\u4e00\u6b21\u7684\u5efa\u7f6e\u6210\u529f\u3002\u6b63\u5728\u5efa\u7f6e\u65b0\u7248\u3002 +blue_anime=\u6700\u8fd1\u4e00\u6b21\u7684\u5efa\u7f6e\u6210\u529f\u3002\u6b63\u5728\u5efa\u7f6e\u65b0\u7248\u672c\u3002 yellow=\u6700\u8fd1\u4e00\u6b21\u7684\u5efa\u7f6e\u6210\u529f\uff0c\u4f46\u662f\u4e26\u4e0d\u7a69\u5b9a\u3002\u53ef\u80fd\u662f\u6709\u6e2c\u8a66\u6848\u4f8b\u6c92\u901a\u904e\u3002 -yellow_anime=\u6700\u8fd1\u4e00\u6b21\u7684\u5efa\u7f6e\u6210\u529f\u4f46\u4e0d\u7a69\u5b9a\u3002\u6b63\u5728\u5efa\u7f6e\u65b0\u7248\u3002 +yellow_anime=\u6700\u8fd1\u4e00\u6b21\u7684\u5efa\u7f6e\u6210\u529f\u4f46\u4e0d\u7a69\u5b9a\u3002\u6b63\u5728\u5efa\u7f6e\u65b0\u7248\u672c\u3002 red=\u6700\u8fd1\u4e00\u6b21\u5efa\u7f6e\u6158\u70c8\u7684\u5931\u6557\u4e86\u3002 -red_anime=\u6700\u8fd1\u4e00\u6b21\u7684\u5efa\u7f6e\u5931\u6557\u3002\u6b63\u5728\u5efa\u7f6e\u65b0\u7248\u3002 +red_anime=\u6700\u8fd1\u4e00\u6b21\u7684\u5efa\u7f6e\u5931\u6557\u3002\u6b63\u5728\u5efa\u7f6e\u65b0\u7248\u672c\u3002 health-81plus=\u5c08\u6848\u5065\u5eb7\u9ad8\u65bc 80%\u3002\u5c07\u6ed1\u9f20\u6e38\u6a19\u79fb\u5230\u5c08\u6848\u5716\u793a\u4e0a\uff0c\u53ef\u4ee5\u770b\u5230\u66f4\u8a73\u7d30\u7684\u89e3\u91cb\u3002 health-61to80=\u5c08\u6848\u5065\u5eb7\u72c0\u6cc1\u4ecb\u65bc 60% \u5230 80% \u4e4b\u9593\u3002\u5c07\u6ed1\u9f20\u6e38\u6a19\u79fb\u5230\u5c08\u6848\u5716\u793a\u4e0a\uff0c\u53ef\u4ee5\u770b\u5230\u66f4\u8a73\u7d30\u7684\u89e3\u91cb\u3002 health-41to60=\u5c08\u6848\u5065\u5eb7\u72c0\u6cc1\u4ecb\u65bc 40% \u5230 60% \u4e4b\u9593\u3002\u5c07\u6ed1\u9f20\u6e38\u6a19\u79fb\u5230\u5c08\u6848\u5716\u793a\u4e0a\uff0c\u53ef\u4ee5\u770b\u5230\u66f4\u8a73\u7d30\u7684\u89e3\u91cb\u3002 diff --git a/core/src/main/resources/jenkins/model/Jenkins/loginError_pt_BR.properties b/core/src/main/resources/jenkins/model/Jenkins/loginError_pt_BR.properties index 7da1ac214fdb..c7371beb3087 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/loginError_pt_BR.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/loginError_pt_BR.properties @@ -20,7 +20,3 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Invalid\ login\ information.\ Please\ try\ again.=Usu\u00e1rio ou senha inv\u00e1lidos. Por favor tente novamente. -Try\ again=Tente novamente -Login\ Error=Erro de autentica\u00e7\u00e3o de usu\u00e1rio -If\ you\ are\ a\ system\ administrator\ and\ suspect\ this\ to\ be\ a\ configuration\ problem,\ see\ the\ server\ console\ output\ for\ more\ details.=Se voc\u00ea for administrador do sistema e suspeitar de um problema de configura\u00e7\u00e3o, veja o console de sa\u00edda para mais detalhes. diff --git a/core/src/main/resources/jenkins/model/Jenkins/login_pt_BR.properties b/core/src/main/resources/jenkins/model/Jenkins/login_pt_BR.properties index 514c556d52ec..3d62385de508 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/login_pt_BR.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/login_pt_BR.properties @@ -20,8 +20,9 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -User=Usu\u00e1rio Password=Senha -Remember\ me\ on\ this\ computer=Salvar minhas informa\u00e7\u00f5es neste computador -login=Login -signUp=Criar uma nova conta se voc\u00ea ainda n\u00e3o for um usu\u00e1rio. +signUp=Criar uma nova conta se voc\u00EA ainda n\u00E3o for um usu\u00E1rio. +Invalid\ username\ or\ password=Usu\u00E1rio\ ou\ senha\ inv\u00E1lida +Username=Nome do usu\u00E1rio +signIn=Entrar +Keep\ me\ signed\ in=Mantenha-me\ conectado diff --git a/core/src/main/resources/jenkins/model/Jenkins/login_zh_TW.properties b/core/src/main/resources/jenkins/model/Jenkins/login_zh_TW.properties index 1b0eb94f4f85..22b1e4e82f95 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/login_zh_TW.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/login_zh_TW.properties @@ -1,18 +1,17 @@ # The MIT License -# -# Copyright (c) 2004-2013, Sun Microsystems, Inc., Chunghwa Telecom Co., Ltd., -# and Pei-Tang Huang -# +# +# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: -# +# # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. -# +# # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -20,9 +19,10 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. - -User=\u4f7f\u7528\u8005\u5e33\u865f -Password=\u5bc6\u78bc -Remember\ me\ on\ this\ computer=\u5728\u9019\u53f0\u96fb\u8166\u4e0a\u8a18\u4f4f\u767b\u5165\u72c0\u614b +signUp=\u8acb\u767b\u5165\u6216\u5efa\u7acb\u65b0\u5e33\u6236\u3002 login=\u767b\u5165 -signUp=\u5982\u679c\u60a8\u9084\u6c92\u6709\u5e33\u865f\uff0c\u5efa\u4e00\u500b\u5427\u3002 +signIn=\u767b\u5165 +Invalid\ username\ or\ password=\u5e33\u865f\u6216\u5bc6\u78bc\u932f\u8aa4 +Password=\u5bc6\u78bc +Username=\u5e33\u865f +Keep\ me\ signed\ in=\u4fdd\u6301\u767b\u5165 diff --git a/core/src/main/resources/jenkins/model/Jenkins/manage.jelly b/core/src/main/resources/jenkins/model/Jenkins/manage.jelly index 161c04c590f2..15032f5c0147 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/manage.jelly +++ b/core/src/main/resources/jenkins/model/Jenkins/manage.jelly @@ -27,115 +27,84 @@ THE SOFTWARE. --> - - - - + + - - - + + + - -

      ${%Manage Jenkins}

      - -
      - - - - -
      - - -
      -

      ${category.key.label}

      - ${taskTags!=null and attrs.contextMenu!='false' ? taskTags.addHeader(category.key.label) : null} -
      - - - - - - - - - - - - - -
      - - - ${taskTags!=null and attrs.contextMenu!='false' ? taskTags.add(m.urlName, iconUrl, m.displayName, m.requiresPOST, m.requiresConfirmation) : null} - - - - - - - - - - - -
      -
      ${m.displayName}
      -
      -
      -
      -
      -
      - - - - - - - - - - -
      -
      ${m.displayName}
      -
      -
      -
      -
      -
      - - - - - - - - - - -
      -
      ${m.displayName}
      -
      -
      -
      -
      -
      -
      -
      -
      + +
      + + -
      +
      -
      - - + +
      +

      ${category.key.label}

      + ${taskTags!=null and attrs.contextMenu!='false' ? taskTags.addHeader(category.key.label) : null} +
      + + +
      + + + + + + ${taskTags!=null and attrs.contextMenu!='false' ? taskTags.add(m.urlName, iconSrc, iconXml, m.displayName, m.requiresPOST, m.requiresConfirmation) : null} + + + + +
      +
      ${m.displayName}
      +
      +
      +
      +
      +
      + + + +
      +
      ${m.displayName}
      +
      +
      +
      +
      +
      + + + +
      +
      ${m.displayName}
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      + + diff --git a/core/src/main/resources/jenkins/model/Jenkins/manage.properties b/core/src/main/resources/jenkins/model/Jenkins/manage.properties index ffd34b83006a..774466c6ef63 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/manage.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/manage.properties @@ -21,3 +21,5 @@ # THE SOFTWARE. are.you.sure={0}: are you sure? +updateAvailable={0} update available +updatesAvailable={0} updates available \ No newline at end of file diff --git a/core/src/main/resources/jenkins/model/Jenkins/manage_bg.properties b/core/src/main/resources/jenkins/model/Jenkins/manage_bg.properties index d709566657f4..17cf3f900573 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/manage_bg.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/manage_bg.properties @@ -42,5 +42,5 @@ Stops\ executing\ new\ builds,\ so\ that\ the\ system\ can\ be\ eventually\ shut \u0421\u043f\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0438\u0437\u043f\u044a\u043b\u043d\u0435\u043d\u0438\u0435\u0442\u043e \u043d\u0430 \u043d\u043e\u0432\u0438 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f, \u0437\u0430 \u0434\u0430 \u043c\u043e\u0436\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0442\u0430 \u0434\u0430 \u0441\u0435\ \u0438\u0437\u043a\u043b\u044e\u0447\u0438 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e. SystemLogText=\ - \u0421\u0438\u0441\u0442\u0435\u043c\u043d\u0438\u044f\u0442 \u0436\u0443\u0440\u043d\u0430\u043b \u043f\u0440\u0438\u0445\u0432\u0430\u0449\u0430 \u0438\u0437\u0445\u043e\u0434\u0430 \u043e\u0442 java.util.logging, \u043a\u043e\u0439\u0442\u043e \u0441\u0435\ + \u0421\u0438\u0441\u0442\u0435\u043c\u043d\u0438\u044f\u0442 \u0436\u0443\u0440\u043d\u0430\u043b \u043f\u0440\u0438\u0445\u0432\u0430\u0449\u0430 \u0438\u0437\u0445\u043e\u0434\u0430 \u043e\u0442 java.util.logging, \u043a\u043e\u0439\u0442\u043e \u0441\u0435\ \u043f\u043e\u043b\u0437\u0432\u0430 \u043e\u0442 Jenkins. diff --git a/core/src/main/resources/jenkins/model/Jenkins/manage_ca.properties b/core/src/main/resources/jenkins/model/Jenkins/manage_ca.properties index d8ab18ca0828..93652d939f00 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/manage_ca.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/manage_ca.properties @@ -19,5 +19,5 @@ Script\ Console=Consola de Script Stops\ executing\ new\ builds,\ so\ that\ the\ system\ can\ be\ eventually\ shut\ down\ safely.=Detindre la execuci\u00F3 de nous builds, de tal forma que el sistema puga apagar-se amb seguretat. System\ Information=Informaci\u00F3 de sistema System\ Log=Log de sistema -SystemLogText=Eixida de captures del log del Sistema de java.util.logging relacionades amb Jenkins. +SystemLogText=Eixida de captures del log del Sistema de java.util.logging relacionades amb Jenkins. Useful\ when\ you\ modified\ config\ files\ directly\ on\ disk.=\u00DAtil quan vost\u00E9 modifica els fitxers de configuraci\u00F3 directament al disc. diff --git a/core/src/main/resources/jenkins/model/Jenkins/manage_cs.properties b/core/src/main/resources/jenkins/model/Jenkins/manage_cs.properties index 092d1f5b8188..bc481c75b8e5 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/manage_cs.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/manage_cs.properties @@ -40,6 +40,6 @@ Script\ Console=Konzole pro skripty Stops\ executing\ new\ builds,\ so\ that\ the\ system\ can\ be\ eventually\ shut\ down\ safely.=Zastav\u00ED spou\u0161t\u011Bn\u00ED nov\u00FDch build-\u016F - aby Jenkins mohl b\u00FDt bezpe\u010Dn\u011B vypnut. System\ Information=Syst\u00E9m - Informace System\ Log=Syst\u00E9m - Log -SystemLogText=Loggovac\u00ED soubor syst\u00E9mu zachycuje v\u00FDstup z java.util.logging v\u00FDstupu vztahuj\u00EDc\u00EDmu se k Jenkins-u. +SystemLogText=Loggovac\u00ED soubor syst\u00E9mu zachycuje v\u00FDstup z java.util.logging v\u00FDstupu vztahuj\u00EDc\u00EDmu se k Jenkins-u. Useful\ when\ you\ modified\ config\ files\ directly\ on\ disk.=Pot\u0159ebn\u00E9, pokud modifikujete konfigura\u010Dn\u00ED soubory p\u0159\u00EDmo na disku. are.you.sure={0}: opravdu to chcete? diff --git a/core/src/main/resources/jenkins/model/Jenkins/manage_es.properties b/core/src/main/resources/jenkins/model/Jenkins/manage_es.properties index 10bed0f48413..fc9ae1cf1b3a 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/manage_es.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/manage_es.properties @@ -26,5 +26,5 @@ Jenkins\ CLI=Interfaz de l\u00EDnea de comandos (CLI) de Jenkins Manage\ Jenkins=Administrar Jenkins Reload\ Configuration\ from\ Disk=Recargar configuraci\u00F3n desde el disco duro. Stops\ executing\ new\ builds,\ so\ that\ the\ system\ can\ be\ eventually\ shut\ down\ safely.=Detener la ejecuci\u00F3n de nuevas construcciones para que el sistema pueda apagarse de manera segura. -SystemLogText=El log del sistema captura la salida de la clase java.util.logging en todo lo relacionado con Jenkins. +SystemLogText=El log del sistema captura la salida de la clase java.util.logging en todo lo relacionado con Jenkins. are.you.sure=est\u00E1s seguro? diff --git a/core/src/main/resources/jenkins/model/Jenkins/manage_fi.properties b/core/src/main/resources/jenkins/model/Jenkins/manage_fi.properties index 7d43d00ef498..21ea59c903a3 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/manage_fi.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/manage_fi.properties @@ -35,5 +35,5 @@ Manage\ Nodes=Hallitse Jenkins-solmuja Reload\ Configuration\ from\ Disk=Uudelleenlataa asetukset Script\ Console=Skriptikonsoli Stops\ executing\ new\ builds,\ so\ that\ the\ system\ can\ be\ eventually\ shut\ down\ safely.=Pys\u00E4ytt\u00E4\u00E4 uusien k\u00E4\u00E4nn\u00F6ksien k\u00E4ynnist\u00E4misen, ett\u00E4 j\u00E4rjestelm\u00E4 voidaan ajaa turvallisesti alas. -SystemLogText=J\u00E4rjestelm\u00E4lokissa n\u00E4kyy Jenkinsiin liittyv\u00E4 java.util.logging-tuloste. +SystemLogText=J\u00E4rjestelm\u00E4lokissa n\u00E4kyy Jenkinsiin liittyv\u00E4 java.util.logging-tuloste. Useful\ when\ you\ modified\ config\ files\ directly\ on\ disk.=K\u00E4yt\u00E4 t\u00E4t\u00E4, kun asetustiedostoja on muokattu. diff --git a/core/src/main/resources/jenkins/model/Jenkins/manage_he.properties b/core/src/main/resources/jenkins/model/Jenkins/manage_he.properties index fc6d622645a8..e7dfb58405f5 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/manage_he.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/manage_he.properties @@ -32,6 +32,6 @@ LoadStatisticsText=\u05D1\u05D3\u05D5\u05E7 \u05D0\u05EA \u05E0\u05D9\u05E6\u05D Manage\ Jenkins=\u05D4\u05D2\u05D3\u05E8\u05EA \u05D2\u05F3\u05E0\u05E7\u05D9\u05E0\u05E1 Stops\ executing\ new\ builds,\ so\ that\ the\ system\ can\ be\ eventually\ shut\ down\ safely.=\u05D0\u05DC \u05EA\u05D0\u05E4\u05E9\u05E8 \u05DC\u05D1\u05E0\u05D9\u05D5\u05EA \u05D7\u05D3\u05E9\u05D5\u05EA \u05DC\u05D4\u05EA\u05D7\u05D9\u05DC, \u05DB\u05D3\u05D9 \u05E9\u05E0\u05D9\u05EA\u05DF \u05D9\u05D4\u05D9\u05D4 \u05DC\u05DB\u05D1\u05D5\u05EA \u05D4\u05DE\u05E2\u05E8\u05DB\u05EA \u05D1\u05D1\u05D8\u05D7\u05D4. System\ Log=\u05DC\u05D5\u05D2\u05D9\u05DD \u05E9\u05DC \u05D4\u05DE\u05E2\u05E8\u05DB\u05EA -SystemLogText=\u05DC\u05D5\u05D2\u05D9\u05DD \u05E9\u05DC \u05D4\u05DE\u05E2\u05E8\u05DB\u05EA \u05DC\u05D5\u05DB\u05D3\u05D9\u05DD \u05E4\u05DC\u05D8 \u05DE-java.util.logging \u05E9\u05E7\u05E9\u05D5\u05E8 \u05DC\u05D2\u05F3\u05E0\u05E7\u05D9\u05E0\u05E1. +SystemLogText=\u05DC\u05D5\u05D2\u05D9\u05DD \u05E9\u05DC \u05D4\u05DE\u05E2\u05E8\u05DB\u05EA \u05DC\u05D5\u05DB\u05D3\u05D9\u05DD \u05E4\u05DC\u05D8 \u05DE-java.util.logging \u05E9\u05E7\u05E9\u05D5\u05E8 \u05DC\u05D2\u05F3\u05E0\u05E7\u05D9\u05E0\u05E1. Useful\ when\ you\ modified\ config\ files\ directly\ on\ disk.=\u05E9\u05D9\u05DE\u05D5\u05E9\u05D9 \u05DB\u05D0\u05E9\u05E8 \u05E2\u05D3\u05DB\u05E0\u05EA \u05E7\u05D1\u05E6\u05D9 \u05DE\u05E2\u05E8\u05DB\u05EA \u05D9\u05E9\u05D9\u05E8\u05D5\u05EA \u05E2\u05DC \u05D4\u05D3\u05D9\u05E1\u05E7 are.you.sure={0}: \u05D4\u05D0\u05DD \u05D0\u05EA\u05D4 \u05D1\u05D8\u05D5\u05D7? diff --git a/core/src/main/resources/jenkins/model/Jenkins/manage_hu.properties b/core/src/main/resources/jenkins/model/Jenkins/manage_hu.properties index c325e3848730..54cb38a37680 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/manage_hu.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/manage_hu.properties @@ -36,4 +36,4 @@ Script\ Console=Szkript konzol Stops\ executing\ new\ builds,\ so\ that\ the\ system\ can\ be\ eventually\ shut\ down\ safely.=Le\u00E1ll\u00EDtja az \u00FAj \u00E9p\u00EDt\u00E9sek futtat\u00E1s\u00E1t, \u00EDgy a rendszer biztons\u00E1gosan le\u00E1ll\u00EDthat\u00F3 lesz. System\ Information=Rendszer inform\u00E1ci\u00F3k System\ Log=Rendszer napl\u00F3 -SystemLogText=A rendszer log elkapja a java.util.logging kimenet\u00E9nek Jenkins-re vonatkoz\u00F3 \u00FCzeneteit. +SystemLogText=A rendszer log elkapja a java.util.logging kimenet\u00E9nek Jenkins-re vonatkoz\u00F3 \u00FCzeneteit. diff --git a/core/src/main/resources/jenkins/model/Jenkins/manage_ko.properties b/core/src/main/resources/jenkins/model/Jenkins/manage_ko.properties index 078b20a03aed..4cd66f008cf4 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/manage_ko.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/manage_ko.properties @@ -31,6 +31,6 @@ Prepare\ for\ Shutdown=\uB044\uAE30 \uC804 \uC900\uBE44 Reload\ Configuration\ from\ Disk=\uB514\uC2A4\uD06C\uC5D0\uC11C \uC124\uC815\uC744 \uB2E4\uC2DC \uB85C\uB4DC Script\ Console=\uC2A4\uD06C\uB9BD\uD2B8 \uCF58\uC194 Stops\ executing\ new\ builds,\ so\ that\ the\ system\ can\ be\ eventually\ shut\ down\ safely.=\uC0C8\uB85C\uC6B4 \uBE4C\uB4DC -SystemLogText=java.util.loggin\uC5D0\uC11C \uCD9C\uB825\uB41C \uC820\uD0A8\uC2A4\uC640 \uB87C\uACAC\uB41C \uC2DC\uC2A4\uD15C \uB85C\uADF8 +SystemLogText=java.util.loggin\uC5D0\uC11C \uCD9C\uB825\uB41C \uC820\uD0A8\uC2A4\uC640 \uB87C\uACAC\uB41C \uC2DC\uC2A4\uD15C \uB85C\uADF8 Useful\ when\ you\ modified\ config\ files\ directly\ on\ disk.=\uB514\uC2A4\uD06C\uC758 \uD30C\uC77C\uC744 \uC9C1\uC811 \uBCC0\uACBD\uD588\uC744 \uB54C \uC720\uC6A9\uD569\uB2C8\uB2E4. are.you.sure=\uD655\uC2E4 \uD569\uB2C8\uAE4C? diff --git a/core/src/main/resources/jenkins/model/Jenkins/manage_nl.properties b/core/src/main/resources/jenkins/model/Jenkins/manage_nl.properties index 04600075c172..39c2ffbcf19f 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/manage_nl.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/manage_nl.properties @@ -37,6 +37,6 @@ Prepare\ for\ Shutdown=Afsluiten voorbereiden Reload\ Configuration\ from\ Disk=Configuratie opnieuw vanaf schijf laden Stops\ executing\ new\ builds,\ so\ that\ the\ system\ can\ be\ eventually\ shut\ down\ safely.=Uitvoering van nieuwe bouwopdrachten stoppen, opdat het systeem uiteindelijk veilig kan afsluiten. System\ Log=Systeemlogboek -SystemLogText=De uitvoer van java.util.logging voor Jenkins wordt geregistreerd. +SystemLogText=De uitvoer van java.util.logging voor Jenkins wordt geregistreerd. Useful\ when\ you\ modified\ config\ files\ directly\ on\ disk.=Dit is nuttig wanneer u configuratiebestanden buiten Jenkins om heeft bewerkt. are.you.sure={0}: weet u het zeker? diff --git a/core/src/main/resources/jenkins/model/Jenkins/manage_pt_BR.properties b/core/src/main/resources/jenkins/model/Jenkins/manage_pt_BR.properties index e264c8e7a0f1..be23d139a575 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/manage_pt_BR.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/manage_pt_BR.properties @@ -22,3 +22,4 @@ Manage\ Jenkins=Gerenciar o Jenkins are.you.sure={0}: tem certeza? +updateAvailable={0} atualiza\u00E7\u00E3o(\u00F5es) dispon\u00EDvel(is) diff --git a/core/src/main/resources/jenkins/model/Jenkins/manage_sr.properties b/core/src/main/resources/jenkins/model/Jenkins/manage_sr.properties index bfe93430db7b..8a9de234c0eb 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/manage_sr.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/manage_sr.properties @@ -22,5 +22,5 @@ JenkinsCliText=\u041F\u0440\u0438\u0441\u0442\u0443\u043F \u0438 \u0443\u043F\u0 Executes\ arbitrary\ script\ for\ administration/trouble-shooting/diagnostics.=\u0418\u0437\u0432\u0440\u0448\u0430\u0432\u0430 \u0430\u0440\u0431\u0438\u0442\u0440\u0430\u0440\u043D\u0438 \u0441\u043A\u0438\u0440\u043F\u0442 \u0437\u0430 \u0430\u0434\u043C\u0438\u043D\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0458\u0443, \u0440\u0435\u0448\u0430\u0432\u0430\u045A\u0435 \u043F\u0440\u043E\u0431\u043B\u0435\u043C\u0430, \u0438 \u0434\u0438\u0430\u0433\u043D\u043E\u0441\u0442\u0438\u043A\u0443. Stops\ executing\ new\ builds,\ so\ that\ the\ system\ can\ be\ eventually\ shut\ down\ safely.=\u041F\u0440\u0435\u0441\u0442\u0430\u0458\u0435 \u043D\u043E\u0432\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u0434\u0430 \u0431\u0438 \u043C\u043E\u0433\u0430\u043E \u0441\u0438\u0441\u0442\u0435\u043C \u0431\u0435\u0437\u0431\u0435\u0434\u043D\u043E \u0443\u0433\u0430\u0441\u0438\u0441\u0442\u0438. Script\ Console=\u041A\u043E\u043D\u0437\u043E\u043B\u0430 -SystemLogText=\u0416\u0443\u0440\u043D\u0430\u043B \u0441\u0438\u0441\u0442\u0435\u043C\u0430 \u0437\u0430\u043F\u0438\u0441\u0443\u0458\u0435 \u0438\u0441\u0445\u043E\u0434 java.util.logging \u043A\u043E\u0458\u0438 \u0441\u0435 \u043E\u0434\u043D\u043E\u0441\u0438 \u043D\u0430 Jenkins. +SystemLogText=\u0416\u0443\u0440\u043D\u0430\u043B \u0441\u0438\u0441\u0442\u0435\u043C\u0430 \u0437\u0430\u043F\u0438\u0441\u0443\u0458\u0435 \u0438\u0441\u0445\u043E\u0434 java.util.logging \u043A\u043E\u0458\u0438 \u0441\u0435 \u043E\u0434\u043D\u043E\u0441\u0438 \u043D\u0430 Jenkins. Add,\ remove,\ disable\ or\ enable\ plugins\ that\ can\ extend\ the\ functionality\ of\ Jenkins.=\u0414\u043E\u0434\u0430\u0458\u0442\u0435, \u0443\u043A\u043B\u043E\u043D\u0438\u0442\u0435, \u0438\u043B\u0438 \u043E\u043D\u0435\u043C\u043E\u0433\u0443\u045B\u0438\u0442\u0435 \u043C\u043E\u0434\u0443\u043B\u0435 \u043A\u043E\u0458\u0435 \u043F\u0440\u043E\u0448\u0438\u0440\u0443\u0458\u0443 \u043C\u043E\u0433\u0443\u045B\u043D\u043E\u0441\u0442\u0435 Jenkins-\u0430. diff --git a/core/src/main/resources/jenkins/model/Jenkins/manage_uk.properties b/core/src/main/resources/jenkins/model/Jenkins/manage_uk.properties index eb97b99c0a09..aa1f08034c94 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/manage_uk.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/manage_uk.properties @@ -36,6 +36,6 @@ Prepare\ for\ Shutdown=\u041F\u0456\u0434\u0433\u043E\u0442\u0443\u0432\u0430\u0 Stops\ executing\ new\ builds,\ so\ that\ the\ system\ can\ be\ eventually\ shut\ down\ safely.=\u0417\u0443\u043F\u0438\u043D\u044F\u0454 \u0432\u0438\u043A\u043E\u043D\u0430\u043D\u043D\u044F \u043D\u043E\u0432\u0438\u0445 \u0437\u0431\u0456\u0440\u043E\u043A, \u0442\u0430\u043A\u0438\u043C \u0447\u0438\u043D\u043E\u043C, \u0449\u043E \u0441\u0438\u0441\u0442\u0435\u043C\u0430 \u043C\u043E\u0436\u0435 \u0431\u0443\u0442\u0438 \u0432 \u043A\u0456\u043D\u0446\u0435\u0432\u043E\u043C\u0443 \u0440\u0430\u0445\u0443\u043D\u043A\u0443 \u0437\u0433\u043E\u0440\u043D\u0443\u0442\u0430 \u0431\u0435\u0437\u043F\u0435\u0447\u043D\u043E. System\ Information=\u0412\u0456\u0434\u043E\u043C\u043E\u0441\u0442\u0456 \u043F\u0440\u043E \u0441\u0438\u0441\u0442\u0435\u043C\u0443 System\ Log=\u0421\u0438\u0441\u0442\u0435\u043C\u043D\u0438\u0439 \u043B\u043E\u0433 -SystemLogText=\u0421\u0438\u0441\u0442\u0435\u043C\u043D\u0438\u0439 \u0436\u0443\u0440\u043D\u0430\u043B \u0444\u0456\u043A\u0441\u0443\u0454 \u0432\u0438\u0432\u0456\u0434 \u0434\u0430\u043D\u0438\u0445 \u0437 java.util.logging \u043F\u043E\u0432''\u044F\u0437\u0430\u043D\u0438\u0445 \u0437 \u0414\u0436\u0435\u043D\u043A\u0456\u043D\u0441. +SystemLogText=\u0421\u0438\u0441\u0442\u0435\u043C\u043D\u0438\u0439 \u0436\u0443\u0440\u043D\u0430\u043B \u0444\u0456\u043A\u0441\u0443\u0454 \u0432\u0438\u0432\u0456\u0434 \u0434\u0430\u043D\u0438\u0445 \u0437 java.util.logging \u043F\u043E\u0432''\u044F\u0437\u0430\u043D\u0438\u0445 \u0437 \u0414\u0436\u0435\u043D\u043A\u0456\u043D\u0441. Useful\ when\ you\ modified\ config\ files\ directly\ on\ disk.=\u041A\u043E\u0440\u0438\u0441\u043D\u043E \u044F\u043A\u0449\u043E \u0432\u0438 \u043C\u043E\u0434\u0438\u0444\u0456\u043A\u0443\u0454\u0442\u0435 \u043A\u043E\u043D\u0444\u0456\u0433\u0443\u0440\u0430\u0446\u0456\u0439\u043D\u0456 \u0444\u0430\u0439\u043B\u0438 \u043F\u0440\u044F\u043C\u043E \u043D\u0430 \u0434\u0438\u0441\u043A\u0443 are.you.sure={0}: \u0412\u0438 \u0432\u043F\u0435\u0432\u043D\u0435\u043D\u0456? diff --git a/core/src/main/resources/jenkins/model/Jenkins/manage_zh_TW.properties b/core/src/main/resources/jenkins/model/Jenkins/manage_zh_TW.properties index 4bc31dd98205..08b405ac478e 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/manage_zh_TW.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/manage_zh_TW.properties @@ -20,11 +20,12 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. - +are.you.sure={0}\: \u60a8\u78ba\u5b9a\u55ce\uff1f +updateAvailable={0} \u6709\u66f4\u65b0 +updatesAvailable={0} \u6709\u66f4\u65b0 Manage\ Jenkins=\u7ba1\u7406 Jenkins Configure\ System=\u8a2d\u5b9a\u7cfb\u7d71 -Configure\ global\ settings\ and\ paths.=\u8a2d\u5b9a\u5168\u57df\u8a2d\u5b9a\u503c\u53ca\u8def\u5f91 +Configure\ global\ settings\ and\ paths.=\u8a2d\u5b9a\u5168\u57df\u8a2d\u5b9a\u503c\u53ca\u8def\u5f91\u3002 Cancel\ Shutdown=\u53d6\u6d88\u505c\u6a5f Prepare\ for\ Shutdown=\u6e96\u5099\u505c\u6a5f -Stops\ executing\ new\ builds,\ so\ that\ the\ system\ can\ be\ eventually\ shut\ down\ safely.=\ - \u505c\u6b62\u65b0\u7684\u5efa\u7f6e\u4f5c\u696d\uff0c\u8b93\u7cfb\u7d71\u6700\u5f8c\u53ef\u4ee5\u5b89\u5168\u7684\u505c\u6a5f\u3002 +Stops\ executing\ new\ builds,\ so\ that\ the\ system\ can\ be\ eventually\ shut\ down\ safely.=\u505c\u6b62\u65b0\u7684\u5efa\u7f6e\u4f5c\u696d\uff0c\u8b93\u7cfb\u7d71\u6700\u5f8c\u53ef\u4ee5\u5b89\u5168\u7684\u505c\u6a5f\u3002 diff --git a/core/src/main/resources/jenkins/model/Jenkins/newView.jelly b/core/src/main/resources/jenkins/model/Jenkins/newView.jelly index e9ef5debb862..78fff8aee57d 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/newView.jelly +++ b/core/src/main/resources/jenkins/model/Jenkins/newView.jelly @@ -26,13 +26,12 @@ THE SOFTWARE. New View page --> - + - - diff --git a/core/src/main/resources/jenkins/model/Jenkins/newView.properties b/core/src/main/resources/jenkins/model/Jenkins/newView.properties new file mode 100644 index 000000000000..499c94c6edaf --- /dev/null +++ b/core/src/main/resources/jenkins/model/Jenkins/newView.properties @@ -0,0 +1,2 @@ +New\ View=New view +View\ name=Name \ No newline at end of file diff --git a/core/src/main/resources/jenkins/model/Jenkins/newView_zh_TW.properties b/core/src/main/resources/jenkins/model/Jenkins/newView_zh_TW.properties index 52be1dcdfdb3..1fb5eaa4b916 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/newView_zh_TW.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/newView_zh_TW.properties @@ -1,25 +1,3 @@ -# The MIT License -# -# Copyright (c) 2004-2013, Sun Microsystems, Inc., Chunghwa Telecom Co., Ltd., -# and Pei-Tang Huang -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - New\ View=\u65b0\u589e\u8996\u666f -View\ name=\u8996\u666f\u540d\u7a31 +View\ name=\u540d\u7a31 +Copy\ Existing\ View=\u8907\u88fd\u65e2\u6709\u7684\u8996\u666f diff --git a/core/src/main/resources/jenkins/model/Jenkins/noPrincipal.properties b/core/src/main/resources/jenkins/model/Jenkins/noPrincipal.properties index 78958278e52d..d2c1895eeaba 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/noPrincipal.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/noPrincipal.properties @@ -22,4 +22,4 @@ blurb=\ The web container doesn''t seem to be configured to do authentication. \ - Check the container documentation and/or also consult jenkins-users@googlegroups.com + Check the container documentation and/or also consult jenkins-users@googlegroups.com diff --git a/core/src/main/resources/jenkins/model/Jenkins/noPrincipal_bg.properties b/core/src/main/resources/jenkins/model/Jenkins/noPrincipal_bg.properties index 41b5aa09d113..fc6159cdf2da 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/noPrincipal_bg.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/noPrincipal_bg.properties @@ -22,7 +22,7 @@ # \ # The web container doesn't seem to be configured to do authentication. \ -# Check the container documentation and/or also consult jenkins-users@googlegroups.com +# Check the container documentation and/or also consult jenkins-users@googlegroups.com blurb=\ \u0423\u0435\u0431 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044a\u0442 \u043d\u0435 \u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d \u0437\u0430 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f. \u041f\u0440\u0435\u0433\u043b\u0435\u0434\u0430\u0439\u0442\u0435 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f\u0442\u0430 \u043c\u0443\ - \u0438 \u0430\u0440\u0445\u0438\u0432\u0438\u0442\u0435 \u043d\u0430 \u0444\u043e\u0440\u0443\u043c\u0430 jenkins-users@googlegroups.com + \u0438 \u0430\u0440\u0445\u0438\u0432\u0438\u0442\u0435 \u043d\u0430 \u0444\u043e\u0440\u0443\u043c\u0430 jenkins-users@googlegroups.com diff --git a/core/src/main/resources/jenkins/model/Jenkins/noPrincipal_da.properties b/core/src/main/resources/jenkins/model/Jenkins/noPrincipal_da.properties index 0350c282f86c..687369beab2c 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/noPrincipal_da.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/noPrincipal_da.properties @@ -21,4 +21,4 @@ # THE SOFTWARE. blurb=Web containeren ser ikke ud til at v\u00e6re konfigureret til brugergodkendelse. \ -Check containerens dokumentation og/eller r\u00e5df\u00f8r dig med jenkins-users@googlegroups.com +Check containerens dokumentation og/eller r\u00e5df\u00f8r dig med jenkins-users@googlegroups.com diff --git a/core/src/main/resources/jenkins/model/Jenkins/noPrincipal_de.properties b/core/src/main/resources/jenkins/model/Jenkins/noPrincipal_de.properties index 02e67099a625..dc69dd3e9f8a 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/noPrincipal_de.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/noPrincipal_de.properties @@ -23,4 +23,4 @@ blurb=\ Der Servlet-Container scheint nicht fr Benutzerauthentifizierung konfiguriert \ worden zu sein. Prfen Sie die Dokumentation des Servlet-Containers oder schreiben Sie eine \ - E-Mail an jenkinsci-users@googlegroups.com, die Mailingliste fr Jenkins-Benutzer. + E-Mail an jenkinsci-users@googlegroups.com, die Mailingliste fr Jenkins-Benutzer. diff --git a/core/src/main/resources/jenkins/model/Jenkins/noPrincipal_es.properties b/core/src/main/resources/jenkins/model/Jenkins/noPrincipal_es.properties index 9b6e4de534f2..3e9145a97b13 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/noPrincipal_es.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/noPrincipal_es.properties @@ -21,5 +21,5 @@ # THE SOFTWARE. blurb=El contenedor de servlets parece no estar configurado para autenticacin. \ - Echa un vistazo a la documentacin del contenedor y/o consulta jenkins-users@googlegroups.com + Echa un vistazo a la documentacin del contenedor y/o consulta jenkins-users@googlegroups.com diff --git a/core/src/main/resources/jenkins/model/Jenkins/noPrincipal_it.properties b/core/src/main/resources/jenkins/model/Jenkins/noPrincipal_it.properties index 5d47e1bf4001..72f174de94a4 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/noPrincipal_it.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/noPrincipal_it.properties @@ -23,4 +23,4 @@ blurb=Sembra che il container Web non sia configurato per eseguire \ l''autenticazione. Controllare la documentazione del container e/o anche \ - jenkins-users@googlegroups.com + jenkins-users@googlegroups.com diff --git a/core/src/main/resources/jenkins/model/Jenkins/noPrincipal_ja.properties b/core/src/main/resources/jenkins/model/Jenkins/noPrincipal_ja.properties index 9ac5816c99b1..10095746d462 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/noPrincipal_ja.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/noPrincipal_ja.properties @@ -22,5 +22,5 @@ blurb=\ \u30A6\u30A7\u30D6\u30B3\u30F3\u30C6\u30CA\u30FC\u304C\u8A8D\u8A3C\u3059\u308B\u3088\u3046\u306B\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u306A\u3044\u3088\u3046\u3067\u3059\u3002\ - \u30B3\u30F3\u30C6\u30CA\u30FC\u306E\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3092\u53C2\u8003\u306B\u3059\u308B\u304B\u3001jenkins-users@googlegroups.com\u304B \ - jenkins-ja@googlegroups.com\u306B\u554F\u3044\u5408\u308F\u305B\u3066\u304F\u3060\u3055\u3044\u3002 + \u30B3\u30F3\u30C6\u30CA\u30FC\u306E\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3092\u53C2\u8003\u306B\u3059\u308B\u304B\u3001jenkins-users@googlegroups.com\u304B \ + jenkins-ja@googlegroups.com\u306B\u554F\u3044\u5408\u308F\u305B\u3066\u304F\u3060\u3055\u3044\u3002 diff --git a/core/src/main/resources/jenkins/model/Jenkins/noPrincipal_lt.properties b/core/src/main/resources/jenkins/model/Jenkins/noPrincipal_lt.properties index 6f7b4303e18c..9a479a8363af 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/noPrincipal_lt.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/noPrincipal_lt.properties @@ -1,3 +1,3 @@ blurb=\ Web konteineris nesukonfig\u016bruotas vykdyti autentikacij\u0105. \ - Patikrinkite konteinerio dokumentacij\u0105 ir/arba pasitarkite su jenkins-users@googlegroups.com + Patikrinkite konteinerio dokumentacij\u0105 ir/arba pasitarkite su jenkins-users@googlegroups.com diff --git a/core/src/main/resources/jenkins/model/Jenkins/noPrincipal_pt_BR.properties b/core/src/main/resources/jenkins/model/Jenkins/noPrincipal_pt_BR.properties index 683b6246b720..9f784b2863b8 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/noPrincipal_pt_BR.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/noPrincipal_pt_BR.properties @@ -22,6 +22,6 @@ # \ # The web container doesn't seem to be configured to do authentication. \ -# Check the container documentation and/or also consult jenkins-users@googlegroups.com -blurb=O container de servlets parece n\u00e3o estar configurado para fazer autentica\u00e7\u00e3o. jenkins-users@googlegroups.com +# Check the container documentation and/or also consult jenkins-users@googlegroups.com +blurb=O container de servlets parece n\u00e3o estar configurado para fazer autentica\u00e7\u00e3o. jenkins-users@googlegroups.com diff --git a/core/src/main/resources/jenkins/model/Jenkins/noPrincipal_sr.properties b/core/src/main/resources/jenkins/model/Jenkins/noPrincipal_sr.properties index c112029bdf75..5fa1bea6a8af 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/noPrincipal_sr.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/noPrincipal_sr.properties @@ -1,3 +1,3 @@ # This file is under the MIT License by authors -blurb=\u0412\u0435\u0431-\u043A\u043E\u043D\u0442\u0435\u0458\u043D\u0435\u0440 \u043D\u0438\u0458\u0435 \u043E\u0441\u043F\u043E\u0441\u043E\u0431\u0459\u0435\u043D \u0437\u0430 \u0430\u0443\u0442\u0435\u043D\u0442\u0438\u043A\u0430\u0446\u0438\u0458\u0443. \u041F\u0440\u043E\u0432\u0435\u0440\u0438\u0442\u0435 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430\u0446\u0438\u0458\u0443 \u0438 jenkins-users@googlegroups.com. +blurb=\u0412\u0435\u0431-\u043A\u043E\u043D\u0442\u0435\u0458\u043D\u0435\u0440 \u043D\u0438\u0458\u0435 \u043E\u0441\u043F\u043E\u0441\u043E\u0431\u0459\u0435\u043D \u0437\u0430 \u0430\u0443\u0442\u0435\u043D\u0442\u0438\u043A\u0430\u0446\u0438\u0458\u0443. \u041F\u0440\u043E\u0432\u0435\u0440\u0438\u0442\u0435 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430\u0446\u0438\u0458\u0443 \u0438 jenkins-users@googlegroups.com. diff --git a/core/src/main/resources/jenkins/model/Jenkins/oops.jelly b/core/src/main/resources/jenkins/model/Jenkins/oops.jelly index f8cbb84497b7..28238c660253 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/oops.jelly +++ b/core/src/main/resources/jenkins/model/Jenkins/oops.jelly @@ -32,7 +32,7 @@ THE SOFTWARE.

      - ${%Oops!} + ${%Oops!}

      ${%problemHappened}

      diff --git a/core/src/main/resources/jenkins/model/Jenkins/oops.properties b/core/src/main/resources/jenkins/model/Jenkins/oops.properties index 633729e9b1c5..97a1887fe88d 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/oops.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/oops.properties @@ -1,6 +1,6 @@ problemHappened= A problem occurred while processing the request. -checkJIRA= Please check our bug tracker to see if a similar problem has already been reported. +checkJIRA= Please check our bug tracker to see if a similar problem has already been reported. vote= If it is already reported, please vote and put a comment on it to let us gauge the impact of the problem. pleaseReport= If you think this is a new issue, please file a new issue. stackTracePlease= When you file an issue, make sure to add the entire stack trace, along with the version of Jenkins and relevant plugins. -checkML= The users list might be also useful in understanding what has happened. +checkML= The users list might be also useful in understanding what has happened. diff --git a/core/src/main/resources/jenkins/model/Jenkins/oops_bg.properties b/core/src/main/resources/jenkins/model/Jenkins/oops_bg.properties index badf5f47e637..8741b98a6e9d 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/oops_bg.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/oops_bg.properties @@ -34,9 +34,9 @@ Bug\ tracker=\ \u0421\u043b\u0435\u0434\u0435\u043d\u0435 \u043d\u0430 \u0433\u0440\u0435\u0448\u043a\u0438 Stack\ trace=\ \u0421\u0442\u0435\u043a \u043d\u0430 \u0438\u0437\u0432\u0438\u043a\u0432\u0430\u043d\u0438\u044f\u0442\u0430 -# The users list might be also useful in understanding what has happened. +# The users list might be also useful in understanding what has happened. checkML=\ - \u041f\u043e\u0449\u0435\u043d\u0441\u043a\u0438\u0442\u0435 \u0441\u043f\u0438\u0441\u044a\u0446\u0438\ + \u041f\u043e\u0449\u0435\u043d\u0441\u043a\u0438\u0442\u0435 \u0441\u043f\u0438\u0441\u044a\u0446\u0438\ \u0441\u0430 \u0435\u0434\u043d\u043e \u043e\u0442 \u043c\u0435\u0441\u0442\u0430\u0442\u0430, \u043a\u044a\u0434\u0435\u0442\u043e \u043c\u043e\u0436\u0435 \u0434\u0430 \u043f\u043e\u0442\u044a\u0440\u0441\u0438\u0442\u0435 \u043e\u0431\u044f\u0441\u043d\u0435\u043d\u0438\u0435 \u0438 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043d\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430. # If you think this is a new issue, please file a new issue. pleaseReport=\ @@ -44,9 +44,9 @@ pleaseReport=\ # A problem occurred while processing the request. problemHappened=\ \u0412\u044a\u0437\u043d\u0438\u043a\u043d\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u043f\u0440\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430\u0442\u0430 \u043d\u0430 \u0437\u0430\u044f\u0432\u043a\u0430. -# Please check our bug tracker to see if a similar problem has already been reported. +# Please check our bug tracker to see if a similar problem has already been reported. checkJIRA=\ - \u041f\u0440\u043e\u0432\u0435\u0440\u0435\u0442\u0435 \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0442\u0430 \u0437\u0430 \u0433\u0440\u0435\u0448\u043a\u0438\ + \u041f\u0440\u043e\u0432\u0435\u0440\u0435\u0442\u0435 \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0442\u0430 \u0437\u0430 \u0433\u0440\u0435\u0448\u043a\u0438\ \u0434\u0430\u043b\u0438 \u0442\u043e\u0437\u0438 \u0438\u043b\u0438 \u043f\u043e\u0434\u043e\u0431\u0435\u043d \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0432\u0435\u0447\u0435 \u0435 \u0434\u043e\u043a\u043b\u0430\u0434\u0432\u0430\u043d. Twitter\:\ @jenkinsci=\ Twitter: @jenkinsci diff --git a/core/src/main/resources/jenkins/model/Jenkins/oops_de.properties b/core/src/main/resources/jenkins/model/Jenkins/oops_de.properties index 1e7f4ad70c1e..ca189e6d0f28 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/oops_de.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/oops_de.properties @@ -23,8 +23,8 @@ Jenkins\ project=Jenkins-Projekt stackTracePlease=Achten Sie beim Verfassen eines Bug-Reports darauf, mindestens den vollst\u00E4ndigen Stack-Trace, sowie die Versionen von Jenkins und relevanter Plugins mitzuteilen. Oops!=Hoppla! -checkML=Die Mailingliste f\u00FCr Jenkins-Nutzer k\u00F6nnte ebenfalls hilfreich sein, um das Problem zu verstehen. -checkJIRA=Bitte suchen Sie in unserem Bug-Tracker nach bereits erstellten, \u00E4hnlichen Bug-Reports. +checkML=Die Mailingliste f\u00FCr Jenkins-Nutzer k\u00F6nnte ebenfalls hilfreich sein, um das Problem zu verstehen. +checkJIRA=Bitte suchen Sie in unserem Bug-Tracker nach bereits erstellten, \u00E4hnlichen Bug-Reports. Bug\ tracker=Bug-Tracker Stack\ trace=Stack-Trace vote=Wenn es zu diesem Fehler bereits einen Bericht gibt, stimmen Sie bitte f\u00FCr ihn. diff --git a/core/src/main/resources/jenkins/model/Jenkins/oops_it.properties b/core/src/main/resources/jenkins/model/Jenkins/oops_it.properties index a228320cb22e..7987affdeaa1 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/oops_it.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/oops_it.properties @@ -21,10 +21,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -checkJIRA=Si consulti il \ +checkJIRA=Si consulti il \ nostro sistema di tracciamento dei bug per vedere se gi stato \ segnalato un problema simile. -checkML=Anche la \ +checkML=Anche la \ lista di distribuzione degli utenti potrebbe essere utile per capire \ quanto accaduto. Oops!=Ops! diff --git a/core/src/main/resources/jenkins/model/Jenkins/oops_ja.properties b/core/src/main/resources/jenkins/model/Jenkins/oops_ja.properties index 5c969e203db8..cb6e2a04a7be 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/oops_ja.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/oops_ja.properties @@ -21,11 +21,11 @@ # THE SOFTWARE. problemHappened= \u30ea\u30af\u30a8\u30b9\u30c8\u51e6\u7406\u4e2d\u306b\u554f\u984c\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 -checkJIRA= \u30d0\u30b0\u7ba1\u7406\u30b7\u30b9\u30c6\u30e0\u3092\u30c1\u30a7\u30c3\u30af\u3057\u3066\u3001\u540c\u3058\u3088\u3046\u306a\u554f\u984c\u304c\u5831\u544a\u3055\u308c\u3066\u3044\u306a\u3044\u304b\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +checkJIRA= \u30d0\u30b0\u7ba1\u7406\u30b7\u30b9\u30c6\u30e0\u3092\u30c1\u30a7\u30c3\u30af\u3057\u3066\u3001\u540c\u3058\u3088\u3046\u306a\u554f\u984c\u304c\u5831\u544a\u3055\u308c\u3066\u3044\u306a\u3044\u304b\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002 vote= \u5831\u544a\u6e08\u307f\u3067\u3042\u308c\u3070\u3001\u6295\u7968(vote)\u3057\u3066\u30b3\u30e1\u30f3\u30c8\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u305d\u3046\u3059\u308c\u3070\u3001\u305d\u306e\u554f\u984c\u306e\u5f71\u97ff\u306e\u5927\u304d\u3055\u304c\u958b\u767a\u8005\u306b\u4f1d\u308f\u308a\u307e\u3059\u3002 pleaseReport= \u3082\u3057\u3001\u5831\u544a\u3055\u308c\u3066\u3044\u306a\u3044\u554f\u984c\u3067\u3042\u308c\u3070\u3001\u30c1\u30b1\u30c3\u30c8\u3092\u767b\u9332\u3057\u3066\u304f\u3060\u3055\u3044\u3002 stackTracePlease= \u30c1\u30b1\u30c3\u30c8\u3092\u767b\u9332\u3059\u308b\u3068\u304d\u306b\u306f\u3001Jenkins\u3068\u95a2\u9023\u3059\u308b\u30d7\u30e9\u30b0\u30a4\u30f3\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u3068\u3042\u308f\u305b\u3066\u3001\u5fc5\u305a\u30b9\u30bf\u30c3\u30af\u30c8\u30ec\u30fc\u30b9\u3092\u3059\u3079\u3066\u6dfb\u4ed8\u3057\u304f\u3060\u3055\u3044\u3002 -checkML= \u4f55\u304c\u8d77\u304d\u305f\u306e\u304b\u7406\u89e3\u3059\u308b\u306b\u306f\u3001\u30e1\u30fc\u30ea\u30f3\u30b0\u30ea\u30b9\u30c8\u304c\u53c2\u8003\u306b\u306a\u308a\u307e\u3059\u3002 +checkML= \u4f55\u304c\u8d77\u304d\u305f\u306e\u304b\u7406\u89e3\u3059\u308b\u306b\u306f\u3001\u30e1\u30fc\u30ea\u30f3\u30b0\u30ea\u30b9\u30c8\u304c\u53c2\u8003\u306b\u306a\u308a\u307e\u3059\u3002 Jenkins\ project=JenkinsWeb\u30b5\u30a4\u30c8 Bug\ tracker=\u30d0\u30b0\u7ba1\u7406\u30b7\u30b9\u30c6\u30e0 diff --git a/core/src/main/resources/jenkins/model/Jenkins/oops_lt.properties b/core/src/main/resources/jenkins/model/Jenkins/oops_lt.properties index 2c81dbaea9ee..8f43960f0e04 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/oops_lt.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/oops_lt.properties @@ -1,9 +1,9 @@ problemHappened=Vykdant u\u017eklaus\u0105 atsitiko problema. -checkJIRA=Pra\u0161ome patikrinti m\u016bs\u0173 problem\u0173 sistem\u0105, ar ten n\u0117ra prane\u0161ta apie pana\u0161i\u0105 problem\u0105. +checkJIRA=Pra\u0161ome patikrinti m\u016bs\u0173 problem\u0173 sistem\u0105, ar ten n\u0117ra prane\u0161ta apie pana\u0161i\u0105 problem\u0105. vote=Jei jau prane\u0161ta, pra\u0161ome balsuoti ir prid\u0117ti komentar\u0173, kad mes gal\u0117tume padidinti \u0161ios problemos svarb\u0105. pleaseReport=Jei galvojate, kad tai nauja problema, pra\u0161ome u\u017epildyti nauj\u0105 problem\u0105. stackTracePlease=Kai pildote problem\u0105, b\u016btinai prid\u0117kite piln\u0105 klaidos i\u0161vest\u012f (stack trace), kartu su Jenkinso ir susijusi\u0173 pried\u0173 versijomis. -checkML=Naudotoj\u0173 s\u0105ra\u0161ynas gali taipogi praversti susigaudant, kas atsitiko. +checkML=Naudotoj\u0173 s\u0105ra\u0161ynas gali taipogi praversti susigaudant, kas atsitiko. Jenkins\ project=Jenkinso projektas Stack\ trace=Klaid\u0173 i\u0161klotin\u0117 Oops!=Oi! diff --git a/core/src/main/resources/jenkins/model/Jenkins/oops_pt_BR.properties b/core/src/main/resources/jenkins/model/Jenkins/oops_pt_BR.properties index 966fd834bd9f..8f21812f295e 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/oops_pt_BR.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/oops_pt_BR.properties @@ -24,17 +24,13 @@ problemHappened=Um problema ocorreu durante o processamento da requisi\u00e7\u00e3o. # If it is already reported, please vote and put a comment on it to let us gauge the impact of the problem. vote=Caso tenha sido reportado, por favor vote e comente para que possamos medir o impacto do problema. -# Please check our bug tracker to see if a similar problem has already been reported. -checkJIRA=Por favor verifique nosso bug tracker para verificar se um problema similar j\u00e1 foi reportado. -Bug\ tracker=Bug tracker +# Please check our bug tracker to see if a similar problem has already been reported. +checkJIRA=Por favor verifique nosso bug tracker para verificar se um problema similar j\u00e1 foi reportado. Stack\ trace=Stack trace -Mailing\ Lists=Listas de e-mail -Twitter\:\ @jenkinsci=Twitter: @jenkinsci -Jenkins\ project=Projeto Jenkins Oops!=Ops! # If you think this is a new issue, please file a new issue. pleaseReport=Caso voc\u00ea acredite que seja um novo problema, por favor preencha uma reclama\u00e7\u00e3o -# The users list might be also useful in understanding what has happened. -checkML=A lista de usu\u00e1rios pode ser \u00fatil para entender o que aconteceu. +# The users list might be also useful in understanding what has happened. +checkML=A lista de usu\u00e1rios pode ser \u00fatil para entender o que aconteceu. # When you file an issue, make sure to add the entire stack trace, along with the version of Jenkins and relevant plugins. stackTracePlease=Quando voc\u00ea preencher uma reclama\u00e7\u00e3o, assegure-se de adicionar o stack trace completo, junto com a vers\u00e3o do Jenkins e plugins relevantes. diff --git a/core/src/main/resources/jenkins/model/Jenkins/oops_ru.properties b/core/src/main/resources/jenkins/model/Jenkins/oops_ru.properties index 43783ba71819..350dd85b3557 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/oops_ru.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/oops_ru.properties @@ -5,8 +5,8 @@ Oops!=\u0423\u043f\u0441! Stack\ trace=\u0421\u0442\u0435\u043a \u0432\u044b\u0437\u043e\u0432\u043e\u0432 stackTracePlease=\u041f\u0440\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043e\u0448\u0438\u0431\u043a\u0438, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u0435 \u0432 \u043d\u0435\u0433\u043e \u043f\u043e\u043b\u043d\u044b\u0439 \u0441\u0442\u0435\u043a \u0432\u044b\u0437\u043e\u0432\u043e\u0432, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0432\u0435\u0440\u0441\u0438\u044e Jenkins'\u0430 \u0438 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432. Twitter\:\ @jenkinsci=\u0422\u0432\u0438\u0442\u0442\u0435\u0440: @jenkinsci -checkJIRA=\u041f\u043e\u0441\u0435\u0442\u0438\u0442\u0435 \u043d\u0430\u0448 \u0431\u0430\u0433-\u0442\u0440\u0435\u043a\u0435\u0440, \u0447\u0442\u043e\u0431\u044b \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u043f\u043e\u0445\u043e\u0436\u0443\u044e \u043e\u0448\u0438\u0431\u043a\u0443. -checkML=\u041f\u043e\u0447\u0442\u043e\u0432\u044b\u0435 \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438 \u0442\u043e\u0436\u0435 \u043c\u043e\u0433\u0443\u0442 \u043f\u043e\u043c\u043e\u0447\u044c \u043f\u043e\u043d\u044f\u0442\u044c, \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u043e. +checkJIRA=\u041f\u043e\u0441\u0435\u0442\u0438\u0442\u0435 \u043d\u0430\u0448 \u0431\u0430\u0433-\u0442\u0440\u0435\u043a\u0435\u0440, \u0447\u0442\u043e\u0431\u044b \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u043f\u043e\u0445\u043e\u0436\u0443\u044e \u043e\u0448\u0438\u0431\u043a\u0443. +checkML=\u041f\u043e\u0447\u0442\u043e\u0432\u044b\u0435 \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438 \u0442\u043e\u0436\u0435 \u043c\u043e\u0433\u0443\u0442 \u043f\u043e\u043c\u043e\u0447\u044c \u043f\u043e\u043d\u044f\u0442\u044c, \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u043e. pleaseReport=\u0415\u0441\u043b\u0438 \u0432\u044b \u0434\u0443\u043c\u0430\u0435\u0442\u0435, \u0447\u0442\u043e \u044d\u0442\u043e \u043d\u043e\u0432\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0441\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u043d\u043e\u0432\u044b\u0439 \u0431\u0430\u0433 \u0432 JIRA. problemHappened=\u041e\u0448\u0438\u0431\u043a\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430. vote=\u0415\u0441\u043b\u0438 \u044d\u0442\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u0443\u0436\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0430, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u0440\u043e\u0433\u043e\u043b\u043e\u0441\u0443\u0439\u0442\u0435 \u0437\u0430 \u043d\u0435\u0451 \u0438 \u043e\u0442\u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0438\u0440\u0443\u0439\u0442\u0435, \u0447\u0442\u043e\u0431\u044b \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u043e\u0446\u0435\u043d\u0438\u0442\u044c \u0432\u043b\u0438\u044f\u043d\u0438\u0435 \u043e\u0448\u0438\u0431\u043a\u0438. diff --git a/core/src/main/resources/jenkins/model/Jenkins/oops_sr.properties b/core/src/main/resources/jenkins/model/Jenkins/oops_sr.properties index 26bb3cee5bd9..d219355795c6 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/oops_sr.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/oops_sr.properties @@ -6,9 +6,9 @@ Mailing\ Lists=Mailing \u043B\u0441\u0438\u0442\u0435 Twitter\:\ @jenkinsci=Twitter: @jenkinsci Oops\!=\u041F\u0440\u043E\u0431\u043B\u0435\u043C! problemHappened=\u0414\u043E\u0448\u043B\u043E \u0458\u0435 \u0434\u043E \u0433\u0440\u0435\u0448\u043A\u0435 \u043F\u0440\u0438\u043B\u0438\u043A\u043E\u043C \u043E\u0431\u0440\u0430\u0434\u0435 \u0437\u0430\u0445\u0442\u0435\u0432\u0430. -checkJIRA=\u041F\u0440\u0435\u0433\u043B\u0435\u0434\u0430\u0458\u0442\u0435 \u0441\u0438\u0441\u0442\u0435\u043C \u0437\u0430 \u043F\u0440\u0430\u045B\u0435\u045A\u0435 \u0433\u0440\u0435\u0448\u0430\u043A\u0430 \u0434\u0430 \u043D\u0438\u0458\u0435 \u043D\u0435\u043A\u043E \u0432\u0435\u045B \u0434\u0430\u043E \u0438\u0437\u0432\u0435\u0448\u0442\u0430\u0458 \u043E \u043F\u0440\u043E\u0431\u043B\u0435\u043C\u0443. +checkJIRA=\u041F\u0440\u0435\u0433\u043B\u0435\u0434\u0430\u0458\u0442\u0435 \u0441\u0438\u0441\u0442\u0435\u043C \u0437\u0430 \u043F\u0440\u0430\u045B\u0435\u045A\u0435 \u0433\u0440\u0435\u0448\u0430\u043A\u0430 \u0434\u0430 \u043D\u0438\u0458\u0435 \u043D\u0435\u043A\u043E \u0432\u0435\u045B \u0434\u0430\u043E \u0438\u0437\u0432\u0435\u0448\u0442\u0430\u0458 \u043E \u043F\u0440\u043E\u0431\u043B\u0435\u043C\u0443. vote=\u0410\u043A\u043E \u0432\u0435\u045B \u0438\u043C\u0430 \u0438\u0437\u0432\u0435\u0448\u0442\u0430\u0458\u0430, \u043C\u043E\u043B\u0438\u043C\u043E \u0432\u0430\u0441 \u0433\u043B\u0430\u0441\u0430\u0458\u0442\u0435 \u0438 \u043E\u0441\u0442\u0430\u0432\u0438\u0442\u0435 \u043A\u043E\u043C\u0435\u043D\u0442\u0430\u0440 \u0434\u0430 \u0431\u0438\u0445 \u043C\u043E\u0433\u043B\u0438 \u043F\u0440\u0430\u0442\u0438\u043B\u0438 \u0448\u0438\u0440\u0438\u043D\u0443 \u043F\u0440\u043E\u0431\u043B\u0435\u043C\u0430. pleaseReport=\u0410\u043A\u043E \u043C\u0438\u0441\u043B\u0438\u0442\u0435 \u0434\u0430 \u043D\u043E\u0432\u0438 \u043F\u0440\u043E\u0431\u043B\u0435\u043C, \u043C\u043E\u043B\u0438\u043C\u043E \u0432\u0430\u0441 \u043F\u043E\u0434\u043D\u0435\u0441\u0438\u0442\u0435 \u0438\u0437\u0432\u0435\u0448\u0442\u0430\u0438\u0458 \u043E \u045A\u0435\u043C\u0443. stackTracePlease=\u041A\u0430\u0434 \u0434\u0430\u0458\u0435\u0442\u0435 \u0438\u0437\u0432\u0435\u0448\u0442\u0430\u0458, \u043C\u043E\u043B\u0438\u043C\u043E \u0432\u0430\u0441 \u043F\u0440\u043E\u0441\u043B\u0435\u0434\u0438\u0442\u0435 \u0446\u0435\u043B\u0443 \u0442\u0440\u0430\u0441\u0443 \u0441\u0442\u0435\u043A\u0430, \u0438 \u0432\u0435\u0440\u0437\u0438\u0458\u0435 Jenkins-\u0430 \u0438 \u0431\u0438\u0442\u043D\u0438\u0445 \u043C\u043E\u0434\u0443\u043B\u0430. -checkML=\u0421\u043F\u0438\u0441\u0430\u043A \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u043A\u0430 \u043C\u043E\u0436\u0435 \u0432\u0430\u043C \u043F\u043E\u043C\u043E\u045B\u0438 \u0434\u0430 \u043D\u0430\u0452\u0435\u0442\u0435 \u0448\u0442\u0430 \u0441\u0435 \u0434\u043E\u0433\u043E\u0434\u0438\u043B\u043E. +checkML=\u0421\u043F\u0438\u0441\u0430\u043A \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u043A\u0430 \u043C\u043E\u0436\u0435 \u0432\u0430\u043C \u043F\u043E\u043C\u043E\u045B\u0438 \u0434\u0430 \u043D\u0430\u0452\u0435\u0442\u0435 \u0448\u0442\u0430 \u0441\u0435 \u0434\u043E\u0433\u043E\u0434\u0438\u043B\u043E. Stack\ trace=\u0422\u0440\u0430\u0441\u0430 \u0441\u0442\u0435\u043A\u0443 diff --git a/core/src/main/resources/jenkins/model/Jenkins/oops_zh_TW.properties b/core/src/main/resources/jenkins/model/Jenkins/oops_zh_TW.properties new file mode 100644 index 000000000000..e16eede61b20 --- /dev/null +++ b/core/src/main/resources/jenkins/model/Jenkins/oops_zh_TW.properties @@ -0,0 +1,8 @@ +problemHappened=\u8655\u7406\u8981\u6c42\u6642\u767c\u751f\u932f\u8aa4\u3002 +checkJIRA=\u8acb\u67e5\u770b\u6211\u5011\u7684\u7f3a\u9677\u8ffd\u8e64\u7cfb\u7d71\u78ba\u8a8d\u662f\u5426\u6709\u985e\u4f3c\u7684\u554f\u984c\u5df2\u7d93\u88ab\u56de\u5831\u4e86\u3002 +vote=\u5982\u679c\u5b83\u5df2\u7d93\u88ab\u56de\u5831\u4e86\uff0c\u8acb\u6295\u7968\u4e26\u7559\u8a00\u8b93\u6211\u5011\u8a55\u4f30\u9019\u500b\u554f\u984c\u7684\u5f71\u97ff\u3002 +pleaseReport=\u5982\u679c\u60a8\u8a8d\u70ba\u9019\u662f\u4e00\u500b\u65b0\u554f\u984c\uff0c\u8acb\u5efa\u7acb\u65b0\u554f\u984c\u3002 +stackTracePlease=\u7576\u60a8\u5efa\u7acb\u65b0\u554f\u984c\u6642\uff0c\u8acb\u78ba\u4fdd\u52a0\u5165\u6574\u500b\u5806\u758a\u8ffd\u8e64\uff0c\u5305\u542b Jenkins \u7248\u672c\u548c\u76f8\u95dc\u7684\u5916\u639b\u3002 +checkML=\u7db2\u8def\u8ad6\u58c7\u53ef\u80fd\u4e5f\u6709\u52a9\u65bc\u91d0\u6e05\u554f\u984c\u3002 +Oops\!=\u7cdf\u4e86\u500b\u7cd5\uff01 +Stack\ trace=\u5806\u758a\u8ffd\u8e64 diff --git a/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help.properties b/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help.properties index e2eda72ec0c2..5307f80e9354 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help.properties @@ -25,4 +25,4 @@ body=\ When you have projects that depend on each other, Jenkins can track which build of \ the upstream project is used by which build of the downstream project, by using \ the records created by \ - the fingerprint support. + the fingerprint support. diff --git a/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_bg.properties b/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_bg.properties index 1aecee88e4f1..513f9f5c8d4a 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_bg.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_bg.properties @@ -26,12 +26,12 @@ For\ this\ feature\ to\ work,\ the\ following\ conditions\ need\ to\ be\ met\:=\ # When you have projects that depend on each other, Jenkins can track which build of \ # the upstream project is used by which build of the downstream project, by using \ # the records created by \ -# the fingerprint support. +# the fingerprint support. body=\ \u041a\u043e\u0433\u0430\u0442\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0438 \u0437\u0430\u0432\u0438\u0441\u044f\u0442 \u0435\u0434\u0438\u043d \u043e\u0442 \u0434\u0440\u0443\u0433, Jenkins \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u043b\u0435\u0434\u0438 \u043a\u043e\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u043d\u0430\ \u043f\u0440\u0435\u0434\u0448\u0435\u0441\u0442\u0432\u0430\u0449 \u043f\u0440\u043e\u0435\u043a\u0442 \u0441\u0435 \u043f\u043e\u043b\u0437\u0432\u0430 \u043e\u0442 \u0441\u043b\u0435\u0434\u0432\u0430\u0449 \u043f\u0440\u043e\u0435\u043a\u0442 \u0438 \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u043a\u0430\u0442\u043e \u0441\u044a\u0437\u0434\u0430\u0432\u0430 \u0431\u0430\u0437\u0430 \u043e\u0442\ \u0434\u0430\u043d\u043d\u0438 \u043e\u0442\ - \u0446\u0438\u0444\u0440\u043e\u0432\u0438\u0442\u0435\ + \u0446\u0438\u0444\u0440\u043e\u0432\u0438\u0442\u0435\ \u043e\u0442\u043f\u0435\u0447\u0430\u0442\u044a\u0446\u0438. The\ downstream\ project\ records\ the\ fingerprints\ of\ the\ upstream\ files\ it\ uses.=\ \u041f\u043e\u0441\u043b\u0435\u0434\u0432\u0430\u0449\u0438\u044f\u0442 \u043f\u0440\u043e\u0435\u043a\u0442 \u043f\u0430\u0437\u0438 \u0446\u0438\u0444\u0440\u043e\u0432\u0438\u0442\u0435 \u043e\u0442\u043f\u0435\u0447\u0430\u0442\u044a\u0446\u0438 \u043d\u0430 \u0440\u0435\u0437\u0443\u043b\u0442\u0430\u0442\u0438\u0442\u0435 \u043e\u0442 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f\u0442\u0430. diff --git a/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_de.properties b/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_de.properties index 26330f50c266..384957a2d675 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_de.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_de.properties @@ -24,7 +24,7 @@ Title=Was ist eine "Projektbeziehung"? body=\ Wenn Sie voneinander abhngige Projekte entwickeln, kann Jenkins fr Sie herausfinden, welcher Build \ eines vorgelagerten Projektes fr welchen Build eines nachgelagerten Projektes verwendet wurde. Dies geschieht ber \ - gespeicherte "Fingerabdrcke", die mit Hilfe der Fingerabdruck-Funktion erzeugt wurden. + gespeicherte "Fingerabdrcke", die mit Hilfe der Fingerabdruck-Funktion erzeugt wurden. For\ this\ feature\ to\ work,\ the\ following\ conditions\ need\ to\ be\ met\:=Um Projektbeziehungen nachzuverfolgen, mssen folgende Bedingungen erfllt sein: The\ upstream\ project\ records\ the\ fingerprints\ of\ its\ build\ artifacts.=Das vorgelagerte Projekt zeichnet Fingerabdrcke seiner Build-Artefakte auf. The\ downstream\ project\ records\ the\ fingerprints\ of\ the\ upstream\ files\ it\ uses.=Das nachgelagerte Projekt zeichnet Fingerabdrcke der verwendeten Dateien aus vorgelagerten Projekten auf. diff --git a/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_es.properties b/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_es.properties index fd34299623d6..279da4c3ae92 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_es.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_es.properties @@ -21,7 +21,7 @@ # THE SOFTWARE. Title=Cual es la relacin entre proyectos? -body=Cuando hay proyectos que dependen unos de otros, Jenkins puede hacer un seguimiento de qu\u00E9 proyectos padres est\u00E1n siendo utilizado por otros proyectos hijos usando un registro de firmas de los ficheros generados. Echa un vistazo a esta pagina: the fingerprint support. +body=Cuando hay proyectos que dependen unos de otros, Jenkins puede hacer un seguimiento de qu\u00E9 proyectos padres est\u00E1n siendo utilizado por otros proyectos hijos usando un registro de firmas de los ficheros generados. Echa un vistazo a esta pagina: the fingerprint support. This\ allows\ Jenkins\ to\ correlate\ two\ projects.=Esto facilita que Jenkins pueda correlacionar los dos proyectos The\ upstream\ project\ records\ the\ fingerprints\ of\ its\ build\ artifacts.=Que el proyecto padre registre la firma de todos los ficheros que genera. diff --git a/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_et.properties b/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_et.properties index 9967d4a849c5..e1ab0ba0ca2c 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_et.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_et.properties @@ -5,4 +5,4 @@ The\ downstream\ project\ records\ the\ fingerprints\ of\ the\ upstream\ files\ The\ upstream\ project\ records\ the\ fingerprints\ of\ its\ build\ artifacts.=\u00DClesvoolu projekt salvestab oma j\u00E4rkude tulemuste s\u00F5rmej\u00E4ljed. This\ allows\ Jenkins\ to\ correlate\ two\ projects.=See lubab Jenkinsil seostada kaks projekti. Title=Mis on "projektide seosed"? -body=Kui teil on kaks projekti mis s\u00F5ltuvad \u00FCksteisest, siis suudab Jenkins j\u00E4lgida seda millist \u00FClesvoolu projekti j\u00E4rku kasutatakse mingi allavoolu projekti j\u00E4rgu jaoks, kasutades s\u00F5rmej\u00E4lje toe poolt loodud kirjeid. +body=Kui teil on kaks projekti mis s\u00F5ltuvad \u00FCksteisest, siis suudab Jenkins j\u00E4lgida seda millist \u00FClesvoolu projekti j\u00E4rku kasutatakse mingi allavoolu projekti j\u00E4rgu jaoks, kasutades s\u00F5rmej\u00E4lje toe poolt loodud kirjeid. diff --git a/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_fr.properties b/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_fr.properties index 95eabb720b76..9be88e6747b7 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_fr.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_fr.properties @@ -22,10 +22,10 @@ Title=Que sont les "relations entre projets"? body=\ - Lorsque vous avez des projets qui dpendent les uns des autres, Jenkins peut tracer quel build \ + Lorsque vous avez des projets qui dpendent les uns des autres, Jenkins peut tracer quel build \ de projet en amont est utilis par quel build de projet en aval, en utilisant \ les enregistrements crs par \ - le support de l''empreinte numrique. + le support de l''empreinte numrique. For\ this\ feature\ to\ work,\ the\ following\ conditions\ need\ to\ be\ met\:=Pour que cette fonctionnalit marche, les conditions suivantes sont requises: The\ upstream\ project\ records\ the\ fingerprints\ of\ its\ build\ artifacts.=Le projet en amont enregistre les empreintes numriques de ses artefacts de build. The\ downstream\ project\ records\ the\ fingerprints\ of\ the\ upstream\ files\ it\ uses.=Le projet en aval enregistre les empreintes num\u00E9riques des fichiers amont qu''il utilise. diff --git a/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_it.properties b/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_it.properties index 9dfb5d65ea0c..532f0862ae1b 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_it.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_it.properties @@ -24,7 +24,7 @@ body=Quando si hanno dei progetti dipendenti fra loro, Jenkins pu tener \ traccia della compilazione del progetto upstream che stata utilizzata in \ una precisa compilazione del progetto downstream utilizzando i record \ - creati dal supporto per \ + creati dal supporto per \ le impronte digitali. For\ this\ feature\ to\ work,\ the\ following\ conditions\ need\ to\ be\ met\:=\ Affinch questa funzionalit possa essere utilizzata, devono essere \ diff --git a/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_ja.properties b/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_ja.properties index 9e672b26b85c..37f1ae9325ae 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_ja.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_ja.properties @@ -24,7 +24,7 @@ Title="\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u76f8\u95a2\u95a2\u4fc2"\u3068\u306f body=\ \u4e92\u3044\u306b\u4f9d\u5b58\u3059\u308b\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u304c\u3042\u308b\u5834\u5408\u3001 Jenkins\u306f\u3069\u306e\u4e0a\u6d41\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u304c\u3069\u306e\u4e0b\u6d41\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306b\u4f7f\u7528\u3055\u308c\u3066\u3044\u308b\u304b\u3092\u3001\ - \u6307\u7d0b\u30b5\u30dd\u30fc\u30c8\ + \u6307\u7d0b\u30b5\u30dd\u30fc\u30c8\ \u306b\u3088\u3063\u3066\u4f5c\u6210\u3055\u308c\u305f\u8a18\u9332\u3092\u4f7f\u7528\u3059\u308b\u3053\u3068\u3067\u8ffd\u8de1\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002 For\ this\ feature\ to\ work,\ the\ following\ conditions\ need\ to\ be\ met\:=\ diff --git a/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_lt.properties b/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_lt.properties index 1a4336fef8f7..2b95a2abbc2b 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_lt.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_lt.properties @@ -1,7 +1,7 @@ Title=Kas yra \u201eprojekt\u0173 priklausomyb\u0117\u201c? body=\ Kai turite projektus, kurie priklauso vienas nuo kito, naudodamas \u012fra\u0161us, sukurtus \ - pir\u0161t\u0173 antspaud\u0173 palaikymo Jenkinsas gali sekti, kuris ankstesnio projekto vykdymas \ + pir\u0161t\u0173 antspaud\u0173 palaikymo Jenkinsas gali sekti, kuris ankstesnio projekto vykdymas \ naudojamas kuriame \u017eemesnio projekto vykdyme. The\ downstream\ project\ records\ the\ fingerprints\ of\ the\ upstream\ files\ it\ uses.=V\u0117lesnis projektas registruoja panaudot\u0173 ankstesniojo projekto fail\u0173 antspaudus. The\ upstream\ project\ records\ the\ fingerprints\ of\ its\ build\ artifacts.=Ankstesnis projektas registruoja savo vykdymo rezultat\u0173 antspaudus. diff --git a/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_nl.properties b/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_nl.properties index d679641c6054..2dd561690f3c 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_nl.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_nl.properties @@ -24,7 +24,7 @@ Title=Wat zijn projectrelaties? body=\ Wanneer je projecten ontwikkelt die van elkaar afhankelijk zijn, kan Jenkins voor jou uitzoeken welke \ bouwpoging van een bovenliggend project gebruikt wordt door een onderliggend project. Dit gebeurt aan \ - de hand van de geregistreerd elektronische vingerafdrukken van \ + de hand van de geregistreerd elektronische vingerafdrukken van \ de door een bouwpoging opgeleverde artefacten. For\ this\ feature\ to\ work,\ the\ following\ conditions\ need\ to\ be\ met\:=De volgende voorwaarden dienen voldaan te worden om met deze functionaliteit te werken: The\ upstream\ project\ records\ the\ fingerprints\ of\ its\ build\ artifacts.=Het bovenliggende project registreert elektronische vingerafdrukken van zijn bouwartefacten. diff --git a/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_pt_BR.properties b/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_pt_BR.properties index 9940c38ec785..b7c73c609f61 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_pt_BR.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_pt_BR.properties @@ -22,9 +22,9 @@ Title=O que \u00e9 "Projeto de relacionamento"? body=\ - Quando voc\u00ea tem projetos que dependem um do outro, o Jenkins pode rastrear qual build \u00e9 hierarquicamente superior, \ + Quando voc\u00ea tem projetos que dependem um do outro, o Jenkins pode rastrear qual build \u00e9 hierarquicamente superior, \ usando os registros criados pelo \ - suporte de fingerprint. + suporte de fingerprint. For\ this\ feature\ to\ work,\ the\ following\ conditions\ need\ to\ be\ met\:=Para esta caracter\u00edstica funcionar, as seguintes condi\u00e7\u00f5es s\u00e3o necess\u00e1rias The\ upstream\ project\ records\ the\ fingerprints\ of\ its\ build\ artifacts.=O projeto pai grava os fingerprints de seus artefatos de build. This\ allows\ Jenkins\ to\ correlate\ two\ projects.=Isto permite que o Jenkins correlacione dois projetos. diff --git a/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_ru.properties b/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_ru.properties index 0a7598452867..2f8bc0b98db2 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_ru.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_ru.properties @@ -28,4 +28,4 @@ Title=\u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 "\u043e\u0442\u043d\u043 body=\ \u041a\u043e\u0433\u0434\u0430 \u0443 \u0432\u0430\u0441 \u0435\u0441\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442\u044b, \u043e\u0434\u0438\u043d \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0434\u0440\u0443\u0433\u043e\u0433\u043e, Jenkins \u043c\u043e\u0436\u0435\u0442 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c, \ \u043a\u0430\u043a\u0430\u044f \u0441\u0431\u043e\u0440\u043a\u0430 \u0432\u043e\u0441\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0430 \u0432 \u043a\u0430\u043a\u043e\u0439 \u0441\u0431\u043e\u0440\u043a\u0435 \u043d\u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \ - \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043d\u044b\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 \u043e\u0442\u043f\u0435\u0447\u0430\u0442\u043a\u043e\u0432. + \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043d\u044b\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 \u043e\u0442\u043f\u0435\u0447\u0430\u0442\u043a\u043e\u0432. diff --git a/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_sr.properties b/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_sr.properties index 5b3cc081f2bb..3f340e178a3b 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_sr.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_sr.properties @@ -1,7 +1,7 @@ # This file is under the MIT License by authors Title=\u0428\u0442\u0430 \u0458\u0435 "\u0432\u0435\u0437\u0430 \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0430"? -body=Jenkins \u043C\u043E\u0436\u0435 \u043F\u0440\u0430\u0442\u0438\u0442\u0438 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443 \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0435 \u043A\u043E\u0458\u0438 \u0437\u0430\u0432\u0438\u0441\u0435 \u0458\u0435\u0434\u0430\u043D \u043E\u0434 \u0434\u0440\u0443\u0433\u043E\u0433 \u043A\u043E\u0440\u0438\u0441\u0442\u0435\u045B\u0438 \u0434\u0438\u0433\u0438\u0442\u0430\u043B\u043D\u0438 \u043E\u0442\u0438\u0441\u0430\u043A. +body=Jenkins \u043C\u043E\u0436\u0435 \u043F\u0440\u0430\u0442\u0438\u0442\u0438 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443 \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0435 \u043A\u043E\u0458\u0438 \u0437\u0430\u0432\u0438\u0441\u0435 \u0458\u0435\u0434\u0430\u043D \u043E\u0434 \u0434\u0440\u0443\u0433\u043E\u0433 \u043A\u043E\u0440\u0438\u0441\u0442\u0435\u045B\u0438 \u0434\u0438\u0433\u0438\u0442\u0430\u043B\u043D\u0438 \u043E\u0442\u0438\u0441\u0430\u043A. For\ this\ feature\ to\ work,\ the\ following\ conditions\ need\ to\ be\ met\:=\u0414\u0430 \u0431\u0438 \u0442\u043E \u0440\u0430\u0434\u0438\u043B\u043E, \u0442\u0440\u0435\u0431\u0430 \u043E\u0431\u0435\u0437\u0431\u0435\u0434\u0438\u0442\u0438: The\ upstream\ project\ records\ the\ fingerprints\ of\ its\ build\ artifacts.=Upstream \u043F\u0440\u043E\u0458\u0435\u043A\u0430\u0442 \u0447\u0443\u0432\u0430 \u043E\u0442\u0438\u0441\u043A\u0435 \u0441\u0432\u043E\u0458\u0438\u0445 \u0430\u0440\u0442\u0438\u0444\u0430\u043A\u0430\u0442\u0438 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435. The\ downstream\ project\ records\ the\ fingerprints\ of\ the\ upstream\ files\ it\ uses.=Downstream \u043F\u0440\u043E\u0458\u0435\u043A\u0430\u0442 \u0431\u0435\u043B\u0435\u0436\u0438 \u0434\u0438\u0433\u0438\u0442\u0430\u043B\u043D\u0435 \u043E\u0442\u0438\u0441\u043A\u0435 \u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0430 \u043E\u0434 \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0430 \u043E\u0434 \u043A\u043E\u0433\u0430 \u0437\u0430\u0432\u0438\u0441\u0438. diff --git a/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_tr.properties b/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_tr.properties index 64af732691b5..46fba638ccde 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_tr.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_tr.properties @@ -22,7 +22,7 @@ Title="Proje ili\u015fkisi" nedir? body=\ - E\u011fer birbirine ba\u011fl\u0131 projeleriniz varsa, Jenkins parmakizi deste\u011fi\ + E\u011fer birbirine ba\u011fl\u0131 projeleriniz varsa, Jenkins parmakizi deste\u011fi\ ile olu\u015fturulan kay\u0131tlar\u0131 kullanarak hangi upstream projenin hangi downstream proje taraf\u0131ndan\ kullan\u0131ld\u0131\u011f\u0131n\u0131 takip edebilir. For\ this\ feature\ to\ work,\ the\ following\ conditions\ need\ to\ be\ met\:=Bu \u00f6zelli\u011fin \u00e7al\u0131\u015fabilmesi i\u00e7in devam\u0131ndaki \u015fartlar\u0131n sa\u011flanmas\u0131 gerekir: diff --git a/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_zh_TW.properties b/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_zh_TW.properties index 2fcffa4ddb44..8b7087e28193 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_zh_TW.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/projectRelationship-help_zh_TW.properties @@ -1,18 +1,18 @@ # The MIT License -# +# # Copyright (c) 2004-2013, Sun Microsystems, Inc., Chunghwa Telecom Co., Ltd., # and Pei-Tang Huang -# +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: -# +# # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. -# +# # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -20,13 +20,9 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. - Title=\u4ec0\u9ebc\u662f\u300c\u5c08\u6848\u95dc\u806f\u300d? -body=\ - \u5982\u679c\u60a8\u7684\u5c08\u6848\u9593\u5f7c\u6b64\u6709\u95dc\u806f\uff0cJenkins \u80fd\u8ffd\u8e64\u4e0b\u6e38\u5c08\u6848\u5230\u5e95\u662f\u4f7f\u7528\u5230\u4e0a\u6e38\u5c08\u6848\u7684\u54ea\u4e00\u7248\u9032\u884c\u5efa\u69cb\u3002\ - \u9019\u500b\u529f\u80fd\u662f\u7d93\u7531\u6a94\u6848\u6307\u7d0b\u529f\u80fd\u6240\u7522\u751f\u7684\u8a18\u9304\u4f86\u9054\u6210\u3002 - -For\ this\ feature\ to\ work,\ the\ following\ conditions\ need\ to\ be\ met\:=\u7b26\u5408\u4e0b\u5217\u689d\u4ef6\u624d\u80fd\u4f7f\u7528\u9019\u500b\u529f\u80fd: -The\ upstream\ project\ records\ the\ fingerprints\ of\ its\ build\ artifacts.=\u4e0a\u6e38\u5c08\u6848\u8981\u8a18\u9304\u5efa\u7f6e\u6210\u54c1\u7684\u6307\u7d0b. -The\ downstream\ project\ records\ the\ fingerprints\ of\ the\ upstream\ files\ it\ uses.=\u4e0b\u6e38\u5c08\u6848\u8981\u8a18\u9304\u7528\u5230\u7684\u4e0a\u6e38\u6a94\u6848\u6307\u7d0b. -This\ allows\ Jenkins\ to\ correlate\ two\ projects.=\u5982\u6b64\u4e00\u4f86 Jenkins \u5c31\u80fd\u81ea\u52d5\u95dc\u806f\u9019\u5169\u500b\u5c08\u6848\u3002 +body=\u5982\u679c\u60a8\u7684\u5c08\u6848\u9593\u5f7c\u6b64\u6709\u95dc\u806f\uff0cJenkins \u5c31\u80fd\u8ffd\u8e64\u4e0b\u6e38\u5c08\u6848\u5230\u5e95\u662f\u4f7f\u7528\u5230\u4e0a\u6e38\u5c08\u6848\u7684\u54ea\u4e00\u7248\u9032\u884c\u5efa\u7f6e\u3002\u9019\u500b\u529f\u80fd\u662f\u5229\u7528\u6a94\u6848\u6307\u7d0b\u529f\u80fd\u6240\u7522\u751f\u7684\u8a18\u9304\u4f86\u9054\u6210\u3002 +For\ this\ feature\ to\ work,\ the\ following\ conditions\ need\ to\ be\ met\:=\u7b26\u5408\u4e0b\u5217\u689d\u4ef6\u624d\u80fd\u4f7f\u7528\u9019\u500b\u529f\u80fd\: +The\ upstream\ project\ records\ the\ fingerprints\ of\ its\ build\ artifacts.=\u4e0a\u6e38\u5c08\u6848\u8981\u8a18\u9304\u5efa\u7f6e\u6210\u54c1\u7684\u6307\u7d0b\u3002 +The\ downstream\ project\ records\ the\ fingerprints\ of\ the\ upstream\ files\ it\ uses.=\u4e0b\u6e38\u5c08\u6848\u8981\u8a18\u9304\u7528\u5230\u7684\u4e0a\u6e38\u6a94\u6848\u6307\u7d0b\u3002 +This\ allows\ Jenkins\ to\ correlate\ two\ projects.=\u5982\u6b64\u4e00\u4f86 Jenkins \u5c31\u80fd\u95dc\u806f\u9019\u5169\u500b\u5c08\u6848\u3002 diff --git a/core/src/main/resources/jenkins/model/Jenkins/projectRelationship.jelly b/core/src/main/resources/jenkins/model/Jenkins/projectRelationship.jelly index a0322e03b462..b862c0d14c90 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/projectRelationship.jelly +++ b/core/src/main/resources/jenkins/model/Jenkins/projectRelationship.jelly @@ -28,9 +28,13 @@ THE SOFTWARE. + + + + + -

      ${%Project Relationship}

      + - - - - - - - - - - - - - - + + +
      + + + + + + + + + + + + - +
      - - + diff --git a/core/src/main/resources/hudson/views/BuildButtonColumn/column_pt_BR.properties b/core/src/main/resources/hudson/views/BuildButtonColumn/column_pt_BR.properties new file mode 100644 index 000000000000..5b1cc665b451 --- /dev/null +++ b/core/src/main/resources/hudson/views/BuildButtonColumn/column_pt_BR.properties @@ -0,0 +1,25 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Schedule_a_task_with_parameters=Agendar um {1} com par\u00E2metros para {0} +Schedule_a_task=Agendar um {1} para {0} +Task_scheduled={0} agendado diff --git a/core/src/main/resources/hudson/views/BuildButtonColumn/column_zh_TW.properties b/core/src/main/resources/hudson/views/BuildButtonColumn/column_zh_TW.properties new file mode 100644 index 000000000000..ae5243d9bbd0 --- /dev/null +++ b/core/src/main/resources/hudson/views/BuildButtonColumn/column_zh_TW.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, id:sorokh, Martin Eigenbrodt +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +Task_scheduled=\u5df2\u6392\u5b9a {0} +Schedule_a_task=\u5df2\u70ba {0} \u6392\u5b9a {1} +Schedule_a_task_with_parameters=\u5df2\u70ba {0} \u6392\u5b9a\u5e36\u53c3\u6578\u7684 {1} diff --git a/core/src/main/resources/hudson/views/BuildButtonColumn/icon.js b/core/src/main/resources/hudson/views/BuildButtonColumn/icon.js new file mode 100644 index 000000000000..58d836b6f2af --- /dev/null +++ b/core/src/main/resources/hudson/views/BuildButtonColumn/icon.js @@ -0,0 +1,12 @@ +Behaviour.specify(".build-button-column-icon-reference-holder", 'build-button-column', 0, function (e) { + var url = e.getAttribute('data-url'); + var message = e.getAttribute('data-notification') + var id = e.getAttribute('data-id'); + var icon = document.getElementById(id); + + icon.onclick = function(el) { + new Ajax.Request(url); + hoverNotification(message, this, -100); + return false; + } +}); diff --git a/core/src/main/resources/hudson/views/DefaultViewsTabBar/viewTabs_ar.properties b/core/src/main/resources/hudson/views/DefaultViewsTabBar/viewTabs_ar.properties deleted file mode 100644 index eb05f138cc78..000000000000 --- a/core/src/main/resources/hudson/views/DefaultViewsTabBar/viewTabs_ar.properties +++ /dev/null @@ -1,23 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -New\ View=\u0646\u0627\u0641\u0630\u0629 \u062C\u062F\u064A\u062F\u0629 diff --git a/core/src/main/resources/hudson/views/GlobalDefaultViewConfiguration/config.groovy b/core/src/main/resources/hudson/views/GlobalDefaultViewConfiguration/config.groovy index c729c35b1006..4deb2a91c7ea 100644 --- a/core/src/main/resources/hudson/views/GlobalDefaultViewConfiguration/config.groovy +++ b/core/src/main/resources/hudson/views/GlobalDefaultViewConfiguration/config.groovy @@ -4,10 +4,12 @@ def f=namespace(lib.FormTagLib) if (app.views.size()>1) { f.entry(title:_("Default view"), field:"defaultView") { - select("class":"setting-input", name:"primaryView") { - app.views.each { v -> - f.option(value:v.viewName, selected:app.primaryView==v) { - text(v.viewName) + div(class:"jenkins-select") { + select(name:"primaryView", class:"jenkins-select__input") { + app.views.each { v -> + f.option(value:v.viewName, selected:app.primaryView==v) { + text(v.viewName) + } } } } diff --git a/core/src/main/resources/hudson/views/JobColumn/column.jelly b/core/src/main/resources/hudson/views/JobColumn/column.jelly index ecb560cfce92..1e9811dff991 100644 --- a/core/src/main/resources/hudson/views/JobColumn/column.jelly +++ b/core/src/main/resources/hudson/views/JobColumn/column.jelly @@ -26,6 +26,6 @@ THE SOFTWARE. - + ${%S}${%S} ${%W} + ${%W} +
      - - - - -
      - x - -
      + +
      + ${%No builds} +
      - -
      @@ -48,7 +52,6 @@ THE SOFTWARE. diff --git a/core/src/main/resources/jenkins/model/Jenkins/systemInfo.jelly b/core/src/main/resources/jenkins/model/Jenkins/systemInfo.jelly index 8992064d33da..f9ab9b258cd8 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/systemInfo.jelly +++ b/core/src/main/resources/jenkins/model/Jenkins/systemInfo.jelly @@ -30,88 +30,121 @@ THE SOFTWARE. - + +
      +

      ${%System Properties}

      - - - +
      +
      + +
      + +
      +

      ${%Environment Variables}

      - - -

      ${%Plugins}

      -
      -
      + + + + +
      +
      +

      ${%Plugins}

      +
      +
      +
      + + + + + + + + - - - - - - + + + - - - + + + -
      ${%Name}${%Version}${%Enabled}
      - ${%No plugins installed.} -
      ${%Name}${%Version}${%Enabled} + ${%No plugins installed.} +
      + + + + + +
      -

      ${%Memory Usage}

      - - - - - - - - - -
      - ${%Timespan}: - - - ${%Short} - - - ${%Short} - - - - - - ${%Medium} - - - ${%Medium} - - - - - - ${%Long} - - - ${%Long} - - +
      +
      +
      +

      ${%Memory Usage}

      - - +
      + + + + + + + + + + +
      + ${%Timespan}: + + + ${%Short} + + + ${%Short} + + + + + + ${%Medium} + + + ${%Medium} + + + + + + ${%Long} + + + ${%Long} + + +
      + + -

      ${%Thread Dumps}

      +
      +
      +

      ${%Thread Dumps}

      +
      +

      ${%threadDump_blurb('threadDump')}

      diff --git a/core/src/main/resources/jenkins/model/Jenkins/systemInfo_pt_BR.properties b/core/src/main/resources/jenkins/model/Jenkins/systemInfo_pt_BR.properties index e9fea4ceafe8..1339329b1eeb 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/systemInfo_pt_BR.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/systemInfo_pt_BR.properties @@ -21,12 +21,18 @@ # THE SOFTWARE. Name=Nome -Plugins=Plugins +Plugins=Extens\u00F5es System\ Properties=Propriedades do sistema Enabled=Habilitado -Environment\ Variables=Vari\u00e1veis de ambiente +Environment\ Variables=Vari\u00E1veis de ambiente Version=Vers\u00E3o -Thread\ Dumps=Thread Dumps -No\ plugins\ installed.=Nenhum plugin instalado. -System\ Information=Informa\u00e7\u00f5es do sistema - +Thread\ Dumps=Despejo de mem\u00F3ria de linhas de execu\u00E7\u00E3o +No\ plugins\ installed.=Nenhuma extens\u00E3o instalada. +System\ Information=Informa\u00E7\u00F5es do sistema +Long=Longo +Medium=M\u00E9dio +Timespan=Intervalo de tempo +Memory\ Usage=Uso\ de\ mem\u00F3ria +Memory\ usage\ graph=Gr\u00E1fico\ de\ uso\ de\ mem\u00F3ria +Short=Curto +threadDump_blurb=Visite esta p\u00E1gina para despejos de mem\u00F3ria de linhas de execu\u00E7\u00E3o do controlador embutido e agentes diff --git a/core/src/main/resources/jenkins/model/Jenkins/systemInfo_zh_TW.properties b/core/src/main/resources/jenkins/model/Jenkins/systemInfo_zh_TW.properties index 7739087e73cc..8f84d5716ab5 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/systemInfo_zh_TW.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/systemInfo_zh_TW.properties @@ -1,26 +1,4 @@ -# The MIT License -# -# Copyright (c) 2004-2013, Sun Microsystems, Inc., Chunghwa Telecom Co., Ltd., -# and Pei-Tang Huang -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - +threadDump_blurb=\u9020\u8a2a\u6b64\u9801\u9762\u4ee5\u53d6\u5f97 Master \u548c Agent \u7684\u57f7\u884c\u5e8f\u50be\u5370\u3002 System\ Information=\u7cfb\u7d71\u8cc7\u8a0a System\ Properties=\u7cfb\u7d71\u5c6c\u6027 Environment\ Variables=\u74b0\u5883\u8b8a\u6578 @@ -29,5 +7,10 @@ No\ plugins\ installed.=\u6c92\u6709\u5b89\u88dd\u5916\u639b\u7a0b\u5f0f\u3002 Enabled=\u555f\u7528\u72c0\u6cc1 Name=\u540d\u7a31 Version=\u7248\u672c - Thread\ Dumps=\u57f7\u884c\u7dd2\u50be\u5370 +Long=\u9577 +Medium=\u4e2d +Memory\ Usage=\u8a18\u61b6\u9ad4\u4f7f\u7528\u91cf +Memory\ usage\ graph=\u8a18\u61b6\u9ad4\u4f7f\u7528\u91cf\u5716\u8868 +Short=\u77ed +Timespan=\u6642\u9593\u7bc4\u570d diff --git a/core/src/main/resources/jenkins/model/JenkinsLocationConfiguration/help-url.html b/core/src/main/resources/jenkins/model/JenkinsLocationConfiguration/help-url.html index a2a83aa04f52..1d468fe2a6fe 100644 --- a/core/src/main/resources/jenkins/model/JenkinsLocationConfiguration/help-url.html +++ b/core/src/main/resources/jenkins/model/JenkinsLocationConfiguration/help-url.html @@ -1,6 +1,6 @@
      Optionally specify the HTTP address of the Jenkins installation, such - as http://yourhost.yourdomain/jenkins/. This value is used to + as http://yourhost.yourdomain/jenkins/. This value is used to let Jenkins know how to refer to itself, ie. to display images or to create links in emails. diff --git a/core/src/main/resources/jenkins/model/JenkinsLocationConfiguration/help-url_bg.html b/core/src/main/resources/jenkins/model/JenkinsLocationConfiguration/help-url_bg.html index f75209667411..3fe8e8ef5dc3 100644 --- a/core/src/main/resources/jenkins/model/JenkinsLocationConfiguration/help-url_bg.html +++ b/core/src/main/resources/jenkins/model/JenkinsLocationConfiguration/help-url_bg.html @@ -1,6 +1,6 @@
      Възможност да зададете адреса по HTTP на инсталацията на Jenkins като: - http://yourhost.yourdomain/jenkins/. Стойността се ползва, + http://yourhost.yourdomain/jenkins/. Стойността се ползва, за да може Jenkins да сочи себе си, примерно при показването на изображения или при генерирането на връзки в електронните писма. diff --git a/core/src/main/resources/jenkins/model/JenkinsLocationConfiguration/help-url_de.html b/core/src/main/resources/jenkins/model/JenkinsLocationConfiguration/help-url_de.html index 0e7b95c6ce2f..0e94aa254694 100644 --- a/core/src/main/resources/jenkins/model/JenkinsLocationConfiguration/help-url_de.html +++ b/core/src/main/resources/jenkins/model/JenkinsLocationConfiguration/help-url_de.html @@ -1,6 +1,6 @@
      Optional: Geben Sie hier die HTTP-Adresse der Jenkins-Instanz an, z.B: - http://yourhost.yourdomain/jenkins/. Dieser Wert wird verwendet, + http://yourhost.yourdomain/jenkins/. Dieser Wert wird verwendet, um Links in E-Mail-Benachrichtigungen einzufügen.

      diff --git a/core/src/main/resources/jenkins/model/JenkinsLocationConfiguration/help-url_fr.html b/core/src/main/resources/jenkins/model/JenkinsLocationConfiguration/help-url_fr.html index 2150154beb1d..1287c11b2f94 100644 --- a/core/src/main/resources/jenkins/model/JenkinsLocationConfiguration/help-url_fr.html +++ b/core/src/main/resources/jenkins/model/JenkinsLocationConfiguration/help-url_fr.html @@ -1,6 +1,6 @@ 

      Spécifie optionnellement l'adresse HTTP de l'installation de Jenkins, - comme http://yourhost.yourdomain/jenkins/. + comme http://yourhost.yourdomain/jenkins/. Cette valeur est utilisée pour mettre des liens dans les emails envoyés par Jenkins. diff --git a/core/src/main/resources/jenkins/model/JenkinsLocationConfiguration/help-url_it.html b/core/src/main/resources/jenkins/model/JenkinsLocationConfiguration/help-url_it.html index 0a02fc258635..654e170b2c80 100644 --- a/core/src/main/resources/jenkins/model/JenkinsLocationConfiguration/help-url_it.html +++ b/core/src/main/resources/jenkins/model/JenkinsLocationConfiguration/help-url_it.html @@ -1,6 +1,6 @@
      Specificare facoltativamente l'indirizzo HTTP dell'installazione di Jenkins, - come http://host.dominio/jenkins/. Questo valore è utilizzato per + come http://host.dominio/jenkins/. Questo valore è utilizzato per far sapere a Jenkins come far riferimento a se stesso, ad es. per visualizzare immagini o creare collegamenti nei messaggi di posta elettronica. diff --git a/core/src/main/resources/jenkins/model/JenkinsLocationConfiguration/help-url_ja.html b/core/src/main/resources/jenkins/model/JenkinsLocationConfiguration/help-url_ja.html index 2997d94fa450..db978934e68e 100644 --- a/core/src/main/resources/jenkins/model/JenkinsLocationConfiguration/help-url_ja.html +++ b/core/src/main/resources/jenkins/model/JenkinsLocationConfiguration/help-url_ja.html @@ -1,5 +1,5 @@
      - JenkinsのURLアドレスを指定(任意)します(例 http://yourhost.yourdomain/jenkins/)。 + JenkinsのURLアドレスを指定(任意)します(例 http://yourhost.yourdomain/jenkins/)。 この値を使用して、Jenkinsが送信するE-mailにリンクを記述します。

      diff --git a/core/src/main/resources/jenkins/model/JenkinsLocationConfiguration/help-url_nl.html b/core/src/main/resources/jenkins/model/JenkinsLocationConfiguration/help-url_nl.html index 7d289b878493..bbdd5b7e767f 100644 --- a/core/src/main/resources/jenkins/model/JenkinsLocationConfiguration/help-url_nl.html +++ b/core/src/main/resources/jenkins/model/JenkinsLocationConfiguration/help-url_nl.html @@ -1,6 +1,6 @@

      Optioneel u kunt het HTTP adres van uw Jenkins instantie - (v.b. http://uwnode.uwdomein/jenkins/) opgeven. Deze waarde + (v.b. http://uwnode.uwdomein/jenkins/) opgeven. Deze waarde zal gebruikt worden voor het genereren van webreferenties in de e-mails die Jenkins uitstuurt. diff --git a/core/src/main/resources/jenkins/model/JenkinsLocationConfiguration/help-url_pt_BR.html b/core/src/main/resources/jenkins/model/JenkinsLocationConfiguration/help-url_pt_BR.html index 370d5244eca5..04fbf082613a 100644 --- a/core/src/main/resources/jenkins/model/JenkinsLocationConfiguration/help-url_pt_BR.html +++ b/core/src/main/resources/jenkins/model/JenkinsLocationConfiguration/help-url_pt_BR.html @@ -1,6 +1,6 @@
      Opcionalmente, especifique o endereço HTTP da instalação do Jenkins, tal - como http://seuhost.seudominio/jenkins/. Este valor é usado para + como http://seuhost.seudominio/jenkins/. Este valor é usado para por links nos e-mails gerados pelo Jenkins.

      diff --git a/core/src/main/resources/jenkins/model/JenkinsLocationConfiguration/help-url_ru.html b/core/src/main/resources/jenkins/model/JenkinsLocationConfiguration/help-url_ru.html index b0704e8c391a..8992c0022edc 100644 --- a/core/src/main/resources/jenkins/model/JenkinsLocationConfiguration/help-url_ru.html +++ b/core/src/main/resources/jenkins/model/JenkinsLocationConfiguration/help-url_ru.html @@ -1,5 +1,5 @@ 

      - Укажите адрес текущей инсталляции Jenkins в виде http://yourhost.yourdomain:8080/jenkins/. + Укажите адрес текущей инсталляции Jenkins в виде http://yourhost.yourdomain:8080/jenkins/. Это значение бодет использоваться для генерации ссылок из сообщений в Jenkins. (опционально) diff --git a/core/src/main/resources/jenkins/model/JenkinsLocationConfiguration/help-url_tr.html b/core/src/main/resources/jenkins/model/JenkinsLocationConfiguration/help-url_tr.html index 6fa061fc1ba8..9500f4c55144 100644 --- a/core/src/main/resources/jenkins/model/JenkinsLocationConfiguration/help-url_tr.html +++ b/core/src/main/resources/jenkins/model/JenkinsLocationConfiguration/help-url_tr.html @@ -1,5 +1,5 @@
      - Jenkins kurulumunuzun HTTP adresini, http://yourhost.yourdomain/jenkins/ + Jenkins kurulumunuzun HTTP adresini, http://yourhost.yourdomain/jenkins/ şeklinde burada belirtebilirsiniz, böylelikle e-posta içerisinde Jenkins ile ilgili linkler bu URL yardımı ile oluşturulacaktır. diff --git a/core/src/main/resources/jenkins/model/JobGlobalBuildDiscarderStrategy/config_pt_BR.properties b/core/src/main/resources/jenkins/model/JobGlobalBuildDiscarderStrategy/config_pt_BR.properties new file mode 100644 index 000000000000..cea9a13c32d2 --- /dev/null +++ b/core/src/main/resources/jenkins/model/JobGlobalBuildDiscarderStrategy/config_pt_BR.properties @@ -0,0 +1,25 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +blurb=Descartadores de constru\u00E7\u00E3o configurados para o job s\u00E3o executados somente depois que a constru\u00E7\u00E3o termina. \ +Esta op\u00E7\u00E3o executa os jobs de descartadores de constru\u00E7\u00E3o periodicamente, aplicando mudan\u00E7as de configura\u00E7\u00E3o mesmo quando nenhuma constru\u00E7\u00E3o \u00E9 executada. \ +Esta op\u00E7\u00E3o n\u00E3o tem efeito se n\u00E3o existir nenhum descatador configurado para o job. diff --git a/core/src/main/resources/jenkins/model/JobGlobalBuildDiscarderStrategy/config_zh_TW.properties b/core/src/main/resources/jenkins/model/JobGlobalBuildDiscarderStrategy/config_zh_TW.properties new file mode 100644 index 000000000000..5c6a4265984d --- /dev/null +++ b/core/src/main/resources/jenkins/model/JobGlobalBuildDiscarderStrategy/config_zh_TW.properties @@ -0,0 +1 @@ +blurb=\u8a2d\u5b9a\u7d66\u4f5c\u696d\u7684\u5efa\u7f6e\u6368\u68c4\u5668\u53ea\u5728\u5efa\u7f6e\u5b8c\u6210\u5f8c\u57f7\u884c\u3002\u6b64\u9078\u9805\u6703\u5b9a\u671f\u57f7\u884c\u4f5c\u696d\u8a2d\u5b9a\u7684\u5efa\u7f6e\u6368\u68c4\u5668\uff0c\u5373\u4f7f\u6c92\u6709\u57f7\u884c\u65b0\u5efa\u7f6e\u4e5f\u6703\u5957\u7528\u8a2d\u5b9a\u8b8a\u66f4\u3002\u5982\u679c\u4f5c\u696d\u6c92\u6709\u8a2d\u5b9a\u5efa\u7f6e\u6368\u68c4\u5668\uff0c\u6b64\u9078\u9805\u4e0d\u6703\u6709\u6548\u679c\u3002 diff --git a/core/src/main/resources/jenkins/model/MasterBuildConfiguration/config.groovy b/core/src/main/resources/jenkins/model/MasterBuildConfiguration/config.groovy index 9ad0aaa0c574..e0e2224df795 100644 --- a/core/src/main/resources/jenkins/model/MasterBuildConfiguration/config.groovy +++ b/core/src/main/resources/jenkins/model/MasterBuildConfiguration/config.groovy @@ -8,4 +8,4 @@ f.entry(title:_("# of executors"), field:"numExecutors") { f.entry(title:_("Labels"),field:"labelString") { f.textbox() } -f.slave_mode(name:"master.mode",node:app) +f.slave_mode(name:"builtin.mode",node:app) diff --git a/core/src/main/resources/jenkins/model/Messages.properties b/core/src/main/resources/jenkins/model/Messages.properties index 178483d10d74..ef2028aa5fd5 100644 --- a/core/src/main/resources/jenkins/model/Messages.properties +++ b/core/src/main/resources/jenkins/model/Messages.properties @@ -24,8 +24,8 @@ # THE SOFTWARE. Hudson.BadPortNumber=Bad port number {0} -Hudson.Computer.Caption=Master -Hudson.Computer.DisplayName=master +Hudson.Computer.Caption=Built-in Node +Hudson.Computer.DisplayName=Built-in Hudson.Computer.IncorrectNumberOfExecutors=Incorrect field "Number of executors". It should be a non-negative number. Hudson.ControlCodeNotAllowed=No control code is allowed: {0} Hudson.DisplayName=Jenkins @@ -40,8 +40,8 @@ Hudson.ViewName=All Hudson.NotUsesUTF8ToDecodeURL=\ Your container doesn\u2019t use UTF-8 to decode URLs. If you use non-ASCII characters as a job name etc, \ this will cause problems. \ - See Tomcat i18n for more details. -Hudson.NodeDescription=the master Jenkins node + See Tomcat i18n for more details. +Hudson.NodeDescription=the Jenkins controller''s built-in node CLI.restart.shortDescription=Restart Jenkins. CLI.safe-restart.shortDescription=Safely restart Jenkins. @@ -57,6 +57,7 @@ IdStrategy.CaseSensitive.DisplayName=Case sensitive IdStrategy.CaseSensitiveEmailAddress.DisplayName=Case sensitive (email address) Mailer.Address.Not.Configured=address not configured yet +JenkinsLocationConfiguration.does_not_look_like_an_email_address=Does not look like an email address Mailer.Localhost.Error=Please set a valid host name, instead of localhost Mailer.NotHttp.Error=The URL is invalid, please ensure you are using http:// or https:// with a valid domain. @@ -77,5 +78,7 @@ CLI.enable-job.shortDescription=Enables a job. GlobalCloudConfiguration.DisplayName=Configure Clouds +BuiltInNodeMigration.DisplayName=Built-In Node Name and Label Migration + SimpleGlobalBuildDiscarderStrategy.displayName=Specific Build Discarder JobGlobalBuildDiscarderStrategy.displayName=Project Build Discarder diff --git a/core/src/main/resources/jenkins/model/Messages_bg.properties b/core/src/main/resources/jenkins/model/Messages_bg.properties index 7ec1be6cca1b..66c640728953 100644 --- a/core/src/main/resources/jenkins/model/Messages_bg.properties +++ b/core/src/main/resources/jenkins/model/Messages_bg.properties @@ -53,7 +53,7 @@ Hudson.NotUsesUTF8ToDecodeURL=\ \u0434\u0435\u043a\u043e\u0434\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0430\u0434\u0440\u0435\u0441\u0438\u0442\u0435. \u0418\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u043d\u0435\u0442\u043e \u043d\u0430 \u0437\u043d\u0430\u0446\u0438 \u0438\u0437\u0432\u044a\u043d ASCII \u0432 \u0438\u043c\u0435\u043d\u0430\u0442\u0430 \u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0438\ \u0438 \u0434\u0440. \u043c\u043e\u0436\u0435 \u0434\u0430 \u0434\u043e\u0432\u0435\u0434\u0435 \u0434\u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0438. \u0417\u0430 \u043f\u043e\u0432\u0435\u0447\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043f\u043e\u0433\u043b\u0435\u0434\u043d\u0435\u0442\u0435 \u0440\u0430\u0437\u0434\u0435\u043b\u0430 \u0437\u0430\ \ + href="https://www.jenkins.io/redirect/troubleshooting/utf8-url-decoding">\ \u0438\u043d\u0442\u0435\u0440\u043d\u0430\u0446\u0438\u043e\u043d\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043d\u0430 Tomcat i18n. Hudson.NodeDescription=\ \u043e\u0441\u043d\u043e\u0432\u043d\u0438\u044f\u0442 \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440 \u043d\u0430 Jenkins diff --git a/core/src/main/resources/jenkins/model/Messages_de.properties b/core/src/main/resources/jenkins/model/Messages_de.properties index d19189566a1e..d7fd936e4281 100644 --- a/core/src/main/resources/jenkins/model/Messages_de.properties +++ b/core/src/main/resources/jenkins/model/Messages_de.properties @@ -36,8 +36,8 @@ Hudson.ViewName=Alle Hudson.NotUsesUTF8ToDecodeURL=\ Ihr Servlet-Container verwendet kein UTF-8, um URLs zu dekodieren. Falls Sie Nicht-ASCII-Zeichen \ in Elementnamen usw. verwenden, kann dies Probleme mit sich bringen. Beachten Sie bitte die Hinweise zu \ - Servlet-Containern bzw. \ - Tomcat i18N). + Servlet-Containern bzw. \ + Tomcat i18N). Hudson.NodeDescription=Jenkins Master-Knoten CLI.restart.shortDescription=Jenkins neu starten. @@ -47,7 +47,7 @@ CLI.safe-restart.shortDescription=Startet Jenkins neu. DefaultProjectNamingStrategy.DisplayName=keine Einschr\u00E4nkung Mailer.Address.Not.Configured=Adresse nicht konfiguriert -Mailer.Localhost.Error=Bitte verwenden Sie einen konkreten Hostnamen anstelle von localhost. +Mailer.Localhost.Error=Bitte verwenden Sie einen konkreten Hostnamen anstelle von localhost . NewViewLink.NewView=Ansicht anlegen diff --git a/core/src/main/resources/jenkins/model/Messages_es.properties b/core/src/main/resources/jenkins/model/Messages_es.properties index 34aa5c6979f3..4045e15761dc 100644 --- a/core/src/main/resources/jenkins/model/Messages_es.properties +++ b/core/src/main/resources/jenkins/model/Messages_es.properties @@ -35,7 +35,7 @@ Hudson.ViewName=Todo Hudson.NotUsesUTF8ToDecodeURL=\ El contenedor de servlets no usa UTF-8 para decodificar URLs. Esto causar\u00e1 problemas si se usan nombres \ con caracteres no ASCII. Echa un vistazo a \ - Tomcat i18n para mas detalles. + Tomcat i18n para mas detalles. Hudson.ReadPermission.Description=\ El permiso de lectura es necesario para visualizar casi todas las p\u00e1ginas de Jenkins.\ Este permiso es \u00fatil cuando se quiere que usuarios no autenticados puedan ver las p\u00e1ginas. \ diff --git a/core/src/main/resources/jenkins/model/Messages_fr.properties b/core/src/main/resources/jenkins/model/Messages_fr.properties index 2a7a693b1fcb..7b3b2bd60564 100644 --- a/core/src/main/resources/jenkins/model/Messages_fr.properties +++ b/core/src/main/resources/jenkins/model/Messages_fr.properties @@ -34,7 +34,7 @@ Hudson.ViewName=Tous Hudson.NotUsesUTF8ToDecodeURL=\ Votre conteneur n''utilise pas UTF-8 pour d\u00e9coder les URLs. Si vous utilisez des caract\u00e8res non-ASCII \ dans le nom d''un job ou autre, cela causera des probl\u00e8mes. \ - Consultez les pages sur les Tomcat i18n pour plus de d\u00e9tails. + Consultez les pages sur les Tomcat i18n pour plus de d\u00e9tails. Hudson.ReadPermission.Description=\ Le droit en lecture est n\u00e9cessaire pour voir la plupart des pages de Jenkins. \ Ce droit est utile quand vous ne voulez pas que les utilisateurs non authentifi\u00e9s puissent voir les pages Jenkins \ diff --git a/core/src/main/resources/jenkins/model/Messages_it.properties b/core/src/main/resources/jenkins/model/Messages_it.properties index 0d807b41ccf4..e32c7d8012f2 100644 --- a/core/src/main/resources/jenkins/model/Messages_it.properties +++ b/core/src/main/resources/jenkins/model/Messages_it.properties @@ -56,7 +56,7 @@ Hudson.NoName=Non Hudson.NotUsesUTF8ToDecodeURL=\ Il container non utilizza UTF-8 per decodificare gli URL. L''utilizzo di \ caratteri non ASCII come nome processo o in altri ambiti causer problemi. \ - Si veda \ + Si veda \ Internazionalizzazione di Tomcat per ulteriori dettagli. Hudson.UnsafeChar="{0}" un carattere non sicuro Hudson.ViewAlreadyExists=Una vista di nome "{0}" esiste gi diff --git a/core/src/main/resources/jenkins/model/Messages_ja.properties b/core/src/main/resources/jenkins/model/Messages_ja.properties index 94bf9db86c35..5890cc63d749 100644 --- a/core/src/main/resources/jenkins/model/Messages_ja.properties +++ b/core/src/main/resources/jenkins/model/Messages_ja.properties @@ -35,7 +35,7 @@ Hudson.ViewAlreadyExists="{0}"\u3068\u3044\u3046\u30d3\u30e5\u30fc\u306f\u65e2\u Hudson.ViewName=\u3059\u3079\u3066 Hudson.NotUsesUTF8ToDecodeURL=\ URL\u304cUTF-8\u3067\u30c7\u30b3\u30fc\u30c9\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\u30b8\u30e7\u30d6\u540d\u306a\u3069\u306bnon-ASCII\u306a\u6587\u5b57\u3092\u4f7f\u7528\u3059\u308b\u5834\u5408\u306f\u3001\ - Tomcat i18N\u3092\u53c2\u8003\u306b\u8a2d\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002 + Tomcat i18N\u3092\u53c2\u8003\u306b\u8a2d\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002 Hudson.ReadPermission.Description=\ \u53c2\u7167\u30d1\u30fc\u30df\u30c3\u30b7\u30e7\u30f3\u306f\u3001Jenkins\u306e\u307b\u307c\u3059\u3079\u3066\u306e\u753b\u9762\u3092\u53c2\u7167\u3059\u308b\u306e\u306b\u5fc5\u8981\u3067\u3059\u3002\ \u3053\u306e\u30d1\u30fc\u30df\u30c3\u30b7\u30e7\u30f3\u306f\u3001\u8a8d\u8a3c\u3055\u308c\u3066\u3044\u306a\u3044\u30e6\u30fc\u30b6\u30fc\u306b\u306fJenkins\u306e\u753b\u9762\u3092\u53c2\u7167\u3055\u305b\u305f\u304f\u306a\u3044\u5834\u5408\u306b\u4fbf\u5229\u3067\u3059\u3002\ diff --git a/core/src/main/resources/jenkins/model/Messages_ko.properties b/core/src/main/resources/jenkins/model/Messages_ko.properties index 04b2ab8b4109..7e7a1320dcfa 100644 --- a/core/src/main/resources/jenkins/model/Messages_ko.properties +++ b/core/src/main/resources/jenkins/model/Messages_ko.properties @@ -1 +1,12 @@ +Hudson.BadPortNumber= \uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 \uD3EC\uD2B8\uBC88\uD638 {0} +Hudson.JobAlreadyExists=\uC774\uBBF8 \uAC19\uC740 \uC774\uB984\uC758 job\uC774 \uC874\uC7AC\uD569\uB2C8\uB2E4 \u2018{0}\u2019 +Hudson.ViewAlreadyExists="{0}" \uC774\uB984\uC758 \uBDF0\uAC00 \uC774\uBBF8 \uC874\uC7AC\uD569\uB2C8\uB2E4. + +CLI.restart.shortDescription=Jenkins\uB97C \uC548\uC804\uD558\uAC8C \uC7AC\uC2DC\uC791 + +NewViewLink.NewView=\uC0C8\uB85C\uC6B4 \uBDF0 + +ParameterizedJobMixIn.build_with_parameters=\uD30C\uB77C\uBBF8\uD130\uC640 \uD568\uAED8 \uBE4C\uB4DC +ParameterizedJobMixIn.build_now=\uC9C0\uAE08 \uBE4C\uB4DC +BlockedBecauseOfBuildInProgress.shortDescription=\uBE4C\uB4DC #{0} \uAC00 \uC774\uBBF8 \uC9C4\uD589\uC911\uC785\uB2C8\uB2E4{1} BuildDiscarderProperty.displayName=\uC624\uB798\uB41C \uBE4C\uB4DC \uC0AD\uC81C diff --git a/core/src/main/resources/jenkins/model/Messages_pt_BR.properties b/core/src/main/resources/jenkins/model/Messages_pt_BR.properties index 2a36f86d84d3..7ffc93135747 100644 --- a/core/src/main/resources/jenkins/model/Messages_pt_BR.properties +++ b/core/src/main/resources/jenkins/model/Messages_pt_BR.properties @@ -20,55 +20,49 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Hudson.BadPortNumber=N\u00famero de porta ruim {0} -Hudson.Computer.Caption=Master -Hudson.Computer.DisplayName=master -Hudson.ControlCodeNotAllowed=Nenhum c\u00f3digo de controle \u00e9 permitido: {0} +Hudson.BadPortNumber=N\u00FAmero de porta ruim {0} +Hudson.Computer.Caption=N\u00F3 embutido +Hudson.Computer.DisplayName=Embutido +Hudson.ControlCodeNotAllowed=Nenhum c\u00F3digo de controle \u00E9 permitido: {0} Hudson.DisplayName=Jenkins -Hudson.JobAlreadyExists=Uma job j\u00e1 existe com o nome ''{0}'' -Hudson.NoJavaInPath=Java n\u00e3o est\u00e1 em seu PATH. Talvez seja preciso configurar as JDKs? -Hudson.NodeBeingRemoved=O n\u00f3 est\u00e1 sendo removido +Hudson.JobAlreadyExists=Um job j\u00E1 existe com o nome ''{0}'' +Hudson.NoJavaInPath=Java n\u00E3o est\u00E1 em seu PATH. Talvez seja preciso configurar as JDKs? +Hudson.NodeBeingRemoved=O n\u00F3 est\u00E1 sendo removido Hudson.NoName=Nenhum nome foi especificado -Hudson.UnsafeChar=''{0}'' n\u00e3o \u00e9 um caracter seguro -Hudson.ViewAlreadyExists=J\u00e1 existe uma view com esse nome "{0}" +Hudson.UnsafeChar=''{0}'' n\u00E3o \u00E9 um caracter seguro +Hudson.ViewAlreadyExists=J\u00E1 existe uma vis\u00E3o com esse nome "{0}" Hudson.ViewName=Tudo -Hudson.NotUsesUTF8ToDecodeURL=n\u00e3o use caracteres UTF-8 nas URLs -Hudson.NodeDescription=N\u00f3 master do Jenkins - -CLI.safe-restart.shortDescription=Seguro reiniciar o Jenkins +Hudson.NotUsesUTF8ToDecodeURL=n\u00E3o use caracteres UTF-8 nas URLs +Hudson.NodeDescription=O n\u00F3 controlador embutido do Jenkins +CLI.safe-restart.shortDescription=Reiniciar o Jenkins com seguran\u00E7a CLI.restart.shortDescription=Reiniciar o Jenkins -CLI.keep-build.shortDescription=Marcar o build como permanente - -# address not configured yet -Mailer.Address.Not.Configured=Endere\u00e7o ainda n\u00e3o configurado -# Please set a valid host name, instead of localhost -Mailer.Localhost.Error=Por favor insira uma nome de host v\u00e1lido. -# Puts Jenkins into the quiet mode, wait for existing builds to be completed, and then shut down Jenkins. -CLI.safe-shutdown.shortDescription=Coloca o Jenkins no modo silencioso, aguarda pelos builds conclu\u00edrem, e ent\u00e3o desliga o Jenkins -# Pattern -PatternProjectNamingStrategy.DisplayName=Padr\u00e3o -# Aborted by {0} +CLI.keep-build.shortDescription=Marcar a constru\u00E7\u00E3o como permanente +Mailer.Address.Not.Configured=Endere\u00E7o ainda n\u00E3o configurado +Mailer.Localhost.Error=Por favor insira uma nome de hospedeiro v\u00E1lido. +CLI.safe-shutdown.shortDescription=Coloca o Jenkins no modo silencioso, aguarda as constru\u00E7\u00F5es conclu\u00EDrem e ent\u00E3o desliga o Jenkins +PatternProjectNamingStrategy.DisplayName=Padr\u00E3o CauseOfInterruption.ShortDescription=Abortado por {0} -# Name Pattern is required -PatternProjectNamingStrategy.NamePatternRequired=O padr\u00e3o do nome \u00e9 obrigat\u00f3rio -# \u2018{0}\u2019 does not match the job name convention pattern {1} -Hudson.JobNameConventionNotApplyed=\u2018{0}\u2019 n\u00e3o atende ao padr\u00e3o de nomenclatura {1} -# Immediately shuts down Jenkins server. +PatternProjectNamingStrategy.NamePatternRequired=O padr\u00E3o do nome \u00E9 obrigat\u00F3rio +Hudson.JobNameConventionNotApplyed=\u2018{0}\u2019 n\u00E3o atende ao padr\u00E3o de nomenclatura {1} CLI.shutdown.shortDescription=Desliga o servidor imediatamente -# Case sensitive (email address) -IdStrategy.CaseSensitiveEmailAddress.DisplayName=Diferencia mai\u00fasculas de min\u00fasculas (endere\u00e7o de e-mail) -# Case insensitive -IdStrategy.CaseInsensitive.DisplayName=N\u00e3o diferencia mai\u00fasculas de min\u00fasculas -# Case sensitive -IdStrategy.CaseSensitive.DisplayName=Diferencia mai\u00fasculas de min\u00fasculas -# regular expression's syntax is invalid. -PatternProjectNamingStrategy.NamePatternInvalidSyntax=A sintaxe da express\u00e3o regular \u00e9 inv\u00e1lida -# Default -DefaultProjectNamingStrategy.DisplayName=Padr\u00e3o -ParameterizedJobMixIn.build_with_parameters=Construir com par\u00e2metros +IdStrategy.CaseSensitiveEmailAddress.DisplayName=Diferencia mai\u00FAsculas de min\u00FAsculas (endere\u00E7o de e-mail) +IdStrategy.CaseInsensitive.DisplayName=N\u00E3o diferencia mai\u00FAsculas de min\u00FAsculas +IdStrategy.CaseSensitive.DisplayName=Diferencia mai\u00FAsculas de min\u00FAsculas +PatternProjectNamingStrategy.NamePatternInvalidSyntax=A sintaxe da express\u00E3o regular \u00E9 inv\u00E1lida +DefaultProjectNamingStrategy.DisplayName=Padr\u00E3o +ParameterizedJobMixIn.build_with_parameters=Construir com par\u00E2metros ParameterizedJobMixIn.build_now=Construir agora -BlockedBecauseOfBuildInProgress.shortDescription=A builds #{0} j\u00e1 est\u00e1 em progresso{1} +BlockedBecauseOfBuildInProgress.shortDescription=A builds #{0} j\u00E1 est\u00E1 em progresso{1} BlockedBecauseOfBuildInProgress.ETA=\ (ETA: {0}) -BuildDiscarderProperty.displayName=Descartar builds antigos +BuildDiscarderProperty.displayName=Descartar constru\u00E7\u00F5es antigas CLI.disable-job.shortDescription=Desabilitar uma job CLI.enable-job.shortDescription=Habilita um job +Mailer.NotHttp.Error=A URL \u00E9 inv\u00E1lida, por favor se certifique que voc\u00EA est\u00E1 usando http:// ou https:// com um dom\u00EDnio v\u00E1lido. +Hudson.Computer.IncorrectNumberOfExecutors=Campo "N\u00FAmero de executores" incorreto. Ele precisa ser um n\u00FAmero n\u00E3o negativo. +NewViewLink.NewView=Nova vis\u00E3o +EnforceSlaveAgentPortAdministrativeMonitor.displayName=Impor porta TCP para o agente +BuiltInNodeMigration.DisplayName=Nome do n\u00F3 embutido e migra\u00E7\u00E3o de r\u00F3tulo +SimpleGlobalBuildDiscarderStrategy.displayName=Descartador de constru\u00E7\u00E3o espec\u00EDfico +GlobalCloudConfiguration.DisplayName=Configurar nuvens +JobGlobalBuildDiscarderStrategy.displayName=Descartador de constru\u00E7\u00E3o do projeto +JenkinsLocationConfiguration.does_not_look_like_an_email_address=N\u00E3o se parece com um endere\u00E7o de e-mail diff --git a/core/src/main/resources/jenkins/model/Messages_ru.properties b/core/src/main/resources/jenkins/model/Messages_ru.properties index 5fe1b314824c..255a60bca237 100644 --- a/core/src/main/resources/jenkins/model/Messages_ru.properties +++ b/core/src/main/resources/jenkins/model/Messages_ru.properties @@ -55,3 +55,4 @@ PatternProjectNamingStrategy.NamePatternInvalidSyntax=\u041D\u0435\u043A\u043E\u ParameterizedJobMixIn.build_with_parameters=\u0421\u043E\u0431\u0440\u0430\u0442\u044C \u0441 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u0430\u043C\u0438 CLI.disable-job.shortDescription=\u0417\u0430\u043F\u0440\u0435\u0442\u0438\u0442\u044C \u0437\u0430\u0434\u0430\u0447\u0443 CLI.enable-job.shortDescription=\u0420\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044C \u0437\u0430\u0434\u0430\u0447\u0443 +NewViewLink.NewView=\u041d\u043e\u0432\u043e\u0435\u0020\u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \ No newline at end of file diff --git a/core/src/main/resources/jenkins/model/Messages_sr.properties b/core/src/main/resources/jenkins/model/Messages_sr.properties index 894f3d284aa5..84c151973336 100644 --- a/core/src/main/resources/jenkins/model/Messages_sr.properties +++ b/core/src/main/resources/jenkins/model/Messages_sr.properties @@ -13,8 +13,8 @@ Hudson.JobNameConventionNotApplyed=\u2018{0}\u2019 \u043d\u0435 \u043e\u0434\u04 Hudson.ViewAlreadyExists=\u041f\u0440\u0435\u0433\u043b\u0435\u0434 \u0441\u0430 \u0438\u043c\u0435\u043d\u043e\u043c \u2018{0}\u2019 \u0432\u0435\u045b \u043f\u043e\u0441\u0442\u043e\u0458\u0438 Hudson.JobAlreadyExists=\u0417\u0430\u0434\u0430\u0442\u0430\u043a \u0441\u0430 \u0438\u043c\u0435\u043d\u043e\u043c \u2018{0}\u2019 \u0432\u0435\u045b \u043f\u043e\u0441\u0442\u043e\u0458\u0438 Hudson.ViewName=\u0421\u0432\u0435 -Hudson.NotUsesUTF8ToDecodeURL=\u0412\u0430\u0448 \u043a\u043e\u043d\u0442\u0435\u0458\u043d\u0435\u0440 \u043d\u0435 \u043a\u043e\u0440\u0438\u0441\u0442 UTF-8 \u0437\u0430 \u0434\u0435\u043a\u043e\u0434\u0438\u0440\u0430\u045a\u0435 URL-\u0430\u0434\u0440\u0435\u0441\u0435. \u0410\u043a\u043e \u043a\u043e\u0440\u0438\u0441\u0442\u0438\u0442\u0435 \u043a\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u0435 \u0432\u0430\u043d ASCII \u043d\u0438\u0437\u0430 \u0443 \u0438\u043c\u0435\u043d\u0443 \u0437\u0430\u0434\u0430\u0442\u0430\u043a\u0430, \u0438\u0442\u0434, \u043c\u043e\u0436\u0435 \u0438\u0437\u0430\u0437\u0432\u0430\u0442\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0435. \u041e\u0442\u0438\u0452\u0438 \u0442\u0435 \u043d\u0430 \u041a\u043e\u043d\u0442\u0435\u0458\u043d\u0435\u0440\u0438 \u0438 \ - Tomcat i18n \u0437\u0430 \u0458\u043e\u0448 \u0434\u0435\u0442\u0430\u0459\u0430. +Hudson.NotUsesUTF8ToDecodeURL=\u0412\u0430\u0448 \u043a\u043e\u043d\u0442\u0435\u0458\u043d\u0435\u0440 \u043d\u0435 \u043a\u043e\u0440\u0438\u0441\u0442 UTF-8 \u0437\u0430 \u0434\u0435\u043a\u043e\u0434\u0438\u0440\u0430\u045a\u0435 URL-\u0430\u0434\u0440\u0435\u0441\u0435. \u0410\u043a\u043e \u043a\u043e\u0440\u0438\u0441\u0442\u0438\u0442\u0435 \u043a\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u0435 \u0432\u0430\u043d ASCII \u043d\u0438\u0437\u0430 \u0443 \u0438\u043c\u0435\u043d\u0443 \u0437\u0430\u0434\u0430\u0442\u0430\u043a\u0430, \u0438\u0442\u0434, \u043c\u043e\u0436\u0435 \u0438\u0437\u0430\u0437\u0432\u0430\u0442\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0435. \u041e\u0442\u0438\u0452\u0438 \u0442\u0435 \u043d\u0430 \u041a\u043e\u043d\u0442\u0435\u0458\u043d\u0435\u0440\u0438 \u0438 \ + Tomcat i18n \u0437\u0430 \u0458\u043e\u0448 \u0434\u0435\u0442\u0430\u0459\u0430. Hudson.NodeDescription=\u0433\u043b\u0430\u0432\u043d\u0430 Jenkins \u043c\u0430\u0448\u0438\u043d\u0430 Hudson.NoParamsSpecified=\u041d\u0438\u0441\u0443 \u043d\u0430\u0432\u0435\u0434\u0435\u043d\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0438 \u0437\u0430 \u043e\u0432\u0430\u0458 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043e \u0438\u0437\u0433\u0440\u0430\u0434\u045a\u0435 CLI.restart.shortDescription=\u041f\u043e\u043d\u043e\u0432\u043e \u043f\u043e\u043a\u0440\u0435\u043d\u0438 Jenkins diff --git a/core/src/main/resources/jenkins/model/Messages_zh_TW.properties b/core/src/main/resources/jenkins/model/Messages_zh_TW.properties index a2a752a23d99..ed267d4ad044 100644 --- a/core/src/main/resources/jenkins/model/Messages_zh_TW.properties +++ b/core/src/main/resources/jenkins/model/Messages_zh_TW.properties @@ -1,17 +1,17 @@ # The MIT License -# +# # Copyright (c) 2013, Chunghwa Telecom Co., Ltd., Pei-Tang Huang -# +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: -# +# # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. -# +# # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,31 +21,24 @@ # THE SOFTWARE. Hudson.BadPortNumber=\u9023\u63a5\u57e0\u865f {0} \u932f\u8aa4 -Hudson.Computer.Caption=Master -Hudson.Computer.DisplayName=master -Hudson.ControlCodeNotAllowed=\u4e0d\u5141\u8a31\u63a7\u5236\u78bc: {0} +Hudson.Computer.Caption=\u5167\u5efa\u7bc0\u9ede +Hudson.Computer.DisplayName=\u5167\u5efa +Hudson.Computer.IncorrectNumberOfExecutors=\u300c\u57f7\u884c\u7a0b\u5f0f\u6578\u300d\u6b04\u4f4d\u7121\u6548\uff0c\u5b83\u5fc5\u9808\u662f\u6b63\u6574\u6578\u3002 +Hudson.ControlCodeNotAllowed=\u4e0d\u5141\u8a31\u63a7\u5236\u78bc\: {0} Hudson.DisplayName=Jenkins Hudson.JobAlreadyExists=\u5df2\u7d93\u6709\u53eb\u505a ''{0}'' \u7684\u4f5c\u696d -Hudson.NoJavaInPath=java \u4e0d\u5728 PATH \u88e1\u3002\u8aaa\u4e0d\u5b9a\u60a8\u61c9\u8a72\u8a2d\u5b9a JDK? +Hudson.NoJavaInPath=java \u4e0d\u5728 PATH \u88e1\u3002\u8aaa\u4e0d\u5b9a\u60a8\u61c9\u8a72\u8a2d\u5b9a JDK\uff1f Hudson.NoName=\u6c92\u6709\u6307\u5b9a\u540d\u7a31 Hudson.NodeBeingRemoved=\u7bc0\u9ede\u6b63\u88ab\u79fb\u9664 -Hudson.UnsafeChar=''{0}'' \u662f\u4e0d\u5b89\u5168\u7684\u5b57\u5143 -Hudson.JobNameConventionNotApplyed=''{0}'' \u4e0d\u7b26\u5408\u4f5c\u696d\u547d\u540d\u6163\u4f8b\u7684\u6a23\u5f0f {1} -Hudson.ViewAlreadyExists=\u5df2\u7d93\u6709\u53eb\u505a "{0}" \u7684\u8996\u666f +Hudson.UnsafeChar=\u300c{0}\u300d\u662f\u4e0d\u5b89\u5168\u7684\u5b57\u5143 +Hudson.JobNameConventionNotApplyed=\u300c{0}\u300d\u4e0d\u7b26\u5408\u4f5c\u696d\u547d\u540d\u6163\u4f8b\u7684\u6a23\u5f0f {1} +Hudson.ViewAlreadyExists=\u5df2\u7d93\u6709\u53eb\u505a\u300c{0}\u300d\u7684\u8996\u666f Hudson.ViewName=\u5168\u90e8 -Hudson.NotUsesUTF8ToDecodeURL=\ - \u60a8\u7684\u5bb9\u5668\u4e0d\u662f\u4f7f\u7528 UTF-8 \u89e3\u8b6f URL\u3002\u5982\u679c\u60a8\u5728\u4f5c\u696d\u7b49\u540d\u7a31\u4e2d\u4f7f\u7528\u4e86\u975e ASCII \u5b57\u5143\uff0c\u53ef\u80fd\u6703\u9020\u6210\u554f\u984c\u3002\ - \u8acb\u53c3\u8003 Container \u53ca \ - Tomcat i18n \u8cc7\u6599\u3002 -Hudson.ReadPermission.Description=\ - \u6709\u8b80\u53d6\u6b0a\u9650\u624d\u80fd\u770b\u5230 Jenkins \u7684\u5927\u90e8\u5206\u7db2\u9801\u3002\ - \u5982\u679c\u60a8\u4e0d\u60f3\u8b93\u6c92\u901a\u904e\u9a57\u8b49\u7684\u4f7f\u7528\u8005\u770b\u5230 Jenkins \u7db2\u9801\uff0c\u8acb\u64a4\u92b7 anonymous \u4f7f\u7528\u8005\u7684\u6b0a\u9650\uff0c\ - \u518d\u65b0\u589e "authenticated" \u865b\u64ec\u4f7f\u7528\u8005\uff0c\u4e26\u6388\u8207\u8b80\u53d6\u6b0a\u9650\u3002 -Hudson.NodeDescription=Jenkins \u4e3b\u7bc0\u9ede +Hudson.NotUsesUTF8ToDecodeURL=\u60a8\u7684\u5bb9\u5668\u4e0d\u662f\u4f7f\u7528 UTF-8 \u89e3\u8b6f URL\u3002\u5982\u679c\u60a8\u5728\u4f5c\u696d\u7b49\u540d\u7a31\u4e2d\u4f7f\u7528\u4e86\u975e ASCII \u5b57\u5143\uff0c\u53ef\u80fd\u6703\u9020\u6210\u554f\u984c\u3002\u8acb\u53c3\u8003 Tomcat i18n \u4ee5\u4e86\u89e3\u8a73\u60c5\u3002 +Hudson.NodeDescription=\u8a72 Jenkins Controller \u7684\u5167\u5efa\u7bc0\u9ede - -CLI.restart.shortDescription=\u91cd\u65b0\u555f\u52d5 Jenkins -CLI.safe-restart.shortDescription=\u5b89\u5168\u7684\u91cd\u65b0\u555f\u52d5 Jenkins +CLI.restart.shortDescription=\u91cd\u65b0\u555f\u52d5 Jenkins\u3002 +CLI.safe-restart.shortDescription=\u5b89\u5168\u5730\u91cd\u65b0\u555f\u52d5 Jenkins\u3002 CLI.keep-build.shortDescription=\u6c38\u4e45\u4fdd\u5b58\u9019\u6b21\u5efa\u7f6e\u3002 CauseOfInterruption.ShortDescription=\u7531 {0} \u4e2d\u6b62 CLI.shutdown.shortDescription=\u7acb\u5373\u5c07 Jenkins \u4f3a\u670d\u5668\u505c\u6a5f @@ -53,15 +46,33 @@ CLI.safe-shutdown.shortDescription=\u8b93 Jenkins \u9032\u5165\u975c\u5019\u6a21 DefaultProjectNamingStrategy.DisplayName=\u9810\u8a2d +IdStrategy.CaseInsensitive.DisplayName=\u4e0d\u5340\u5206\u5927\u5c0f\u5beb +IdStrategy.CaseSensitive.DisplayName=\u5340\u5206\u5927\u5c0f\u5beb +IdStrategy.CaseSensitiveEmailAddress.DisplayName=\u5340\u5206\u5927\u5c0f\u5beb\uff08\u96fb\u5b50\u4fe1\u7bb1\u5730\u5740\uff09 + Mailer.Address.Not.Configured=\u9084\u6c92\u8a2d\u5b9a\u5730\u5740 -Mailer.Localhost.Error=\u8acb\u8a2d\u5b9a\u6b63\u78ba\u7684\u4e3b\u6a5f\u540d\u7a31\uff0c\u4e0d\u8981\u7528 localhost +JenkinsLocationConfiguration.does_not_look_like_an_email_address=\u9019\u770b\u8d77\u4f86\u4e0d\u50cf\u96fb\u5b50\u4fe1\u7bb1\u5730\u5740 +Mailer.Localhost.Error=\u8acb\u8a2d\u5b9a\u6709\u6548\u7684\u4e3b\u6a5f\u540d\u7a31\uff0c\u4e0d\u8981\u7528 localhost +Mailer.NotHttp.Error=URL \u7121\u6548\uff0c\u8acb\u78ba\u4fdd\u60a8\u4f7f\u7528 http\:// \u6216 https\:// \u548c\u6709\u6548\u7684\u7db2\u57df\u540d\u7a31\u3002 + +NewViewLink.NewView=\u65b0\u589e\u8996\u666f PatternProjectNamingStrategy.DisplayName=\u6a23\u5f0f PatternProjectNamingStrategy.NamePatternRequired=\u4e00\u5b9a\u8981\u8f38\u5165\u540d\u7a31\u6a23\u5f0f PatternProjectNamingStrategy.NamePatternInvalidSyntax=\u6b63\u898f\u8868\u793a\u5f0f\u8a9e\u6cd5\u932f\u8aa4\u3002 +ParameterizedJobMixIn.build_with_parameters=\u5e36\u53c3\u6578\u5efa\u7f6e ParameterizedJobMixIn.build_now=\u99ac\u4e0a\u5efa\u7f6e -BlockedBecauseOfBuildInProgress.shortDescription=\u5efa\u7f6e #{0} \u57f7\u884c\u4e2d{1} -BlockedBecauseOfBuildInProgress.ETA=\ (\u9810\u4f30\u6642\u9593: {0}) -BuildDiscarderProperty.displayName=\u5FFD\u7565\u820ABuilds +BlockedBecauseOfBuildInProgress.shortDescription=\u5efa\u7f6e \#{0} \u5df2\u5728\u57f7\u884c\u4e2d{1} +BlockedBecauseOfBuildInProgress.ETA=\ (\u9810\u4f30\u6642\u9593\: {0}) +BuildDiscarderProperty.displayName=\u6368\u68c4\u820a\u5efa\u7f6e + +EnforceSlaveAgentPortAdministrativeMonitor.displayName=\u5f37\u5236 TCP Agent \u9023\u63a5\u57e0 CLI.disable-job.shortDescription=\u505c\u7528\u4f5c\u696d\u3002 CLI.enable-job.shortDescription=\u555f\u7528\u4f5c\u696d\u3002 + +GlobalCloudConfiguration.DisplayName=\u8a2d\u5b9a\u96f2\u7aef + +BuiltInNodeMigration.DisplayName=\u9077\u79fb\u5167\u5efa\u7bc0\u9ede\u540d\u7a31\u548c\u6a19\u7c64 + +SimpleGlobalBuildDiscarderStrategy.displayName=\u6307\u5b9a\u5efa\u7f6e\u6368\u68c4\u5668 +JobGlobalBuildDiscarderStrategy.displayName=\u5c08\u6848\u5efa\u7f6e\u6368\u68c4\u5668 diff --git a/core/src/main/resources/jenkins/model/OptionalJobProperty/config.jelly b/core/src/main/resources/jenkins/model/OptionalJobProperty/config.jelly index 6f46063fb5bf..4281fc183c6b 100644 --- a/core/src/main/resources/jenkins/model/OptionalJobProperty/config.jelly +++ b/core/src/main/resources/jenkins/model/OptionalJobProperty/config.jelly @@ -25,9 +25,7 @@ THE SOFTWARE. - - - - - + + + diff --git a/core/src/main/resources/jenkins/model/ProjectNamingStrategy/PatternProjectNamingStrategy/config_zh_TW.properties b/core/src/main/resources/jenkins/model/ProjectNamingStrategy/PatternProjectNamingStrategy/config_zh_TW.properties index ca1cd49e666d..0e2a35cf1c1e 100644 --- a/core/src/main/resources/jenkins/model/ProjectNamingStrategy/PatternProjectNamingStrategy/config_zh_TW.properties +++ b/core/src/main/resources/jenkins/model/ProjectNamingStrategy/PatternProjectNamingStrategy/config_zh_TW.properties @@ -20,5 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -namePattern=\u540d\u7a31\u6a23\u5f0f -forceExistingJobs=\u6eaf\u53ca\u65e2\u5f80 +namePattern = \u540d\u7a31\u6a23\u5f0f +description = \u8aaa\u660e +forceExistingJobs = \u6eaf\u53ca\u65e2\u5f80 diff --git a/core/src/main/resources/jenkins/model/RenameAction/action.jelly b/core/src/main/resources/jenkins/model/RenameAction/action.jelly index 992a1ce7cf91..6b9a1680abc4 100644 --- a/core/src/main/resources/jenkins/model/RenameAction/action.jelly +++ b/core/src/main/resources/jenkins/model/RenameAction/action.jelly @@ -26,6 +26,6 @@ THE SOFTWARE. - + diff --git a/core/src/main/resources/jenkins/model/RenameAction/action_fr.properties b/core/src/main/resources/jenkins/model/RenameAction/action_fr.properties new file mode 100644 index 000000000000..3d5f94d18fa6 --- /dev/null +++ b/core/src/main/resources/jenkins/model/RenameAction/action_fr.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright © 2021 Pauline Iogna +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Rename=Renommer diff --git a/core/src/main/resources/jenkins/model/RenameAction/action_pt_BR.properties b/core/src/main/resources/jenkins/model/RenameAction/action_pt_BR.properties new file mode 100644 index 000000000000..da79298bc326 --- /dev/null +++ b/core/src/main/resources/jenkins/model/RenameAction/action_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Rename=Renomear diff --git a/core/src/main/resources/jenkins/model/RenameAction/action_zh_TW.properties b/core/src/main/resources/jenkins/model/RenameAction/action_zh_TW.properties new file mode 100644 index 000000000000..6799eb5c6690 --- /dev/null +++ b/core/src/main/resources/jenkins/model/RenameAction/action_zh_TW.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Rename=\u91cd\u65b0\u547d\u540d diff --git a/core/src/main/resources/jenkins/model/RunIdMigrator/UnmigrationInstruction/index.jelly b/core/src/main/resources/jenkins/model/RunIdMigrator/UnmigrationInstruction/index.jelly index bb1aa64e61aa..2950f2714537 100644 --- a/core/src/main/resources/jenkins/model/RunIdMigrator/UnmigrationInstruction/index.jelly +++ b/core/src/main/resources/jenkins/model/RunIdMigrator/UnmigrationInstruction/index.jelly @@ -29,7 +29,7 @@ THE SOFTWARE.

      To reverse the effect of build record migration, run the following command - on the server. See documentation + on the server. See documentation for more details:

      diff --git a/core/src/main/resources/jenkins/model/RunIdMigrator/UnmigrationInstruction/index_pt_BR.properties b/core/src/main/resources/jenkins/model/RunIdMigrator/UnmigrationInstruction/index_pt_BR.properties new file mode 100644 index 000000000000..502d784236d4 --- /dev/null +++ b/core/src/main/resources/jenkins/model/RunIdMigrator/UnmigrationInstruction/index_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Copied=Copiado diff --git a/core/src/main/resources/jenkins/model/RunIdMigrator/UnmigrationInstruction/index_zh_TW.properties b/core/src/main/resources/jenkins/model/RunIdMigrator/UnmigrationInstruction/index_zh_TW.properties new file mode 100644 index 000000000000..17476491df5b --- /dev/null +++ b/core/src/main/resources/jenkins/model/RunIdMigrator/UnmigrationInstruction/index_zh_TW.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Copied=\u5df2\u8907\u88fd diff --git a/core/src/main/resources/jenkins/model/SimpleGlobalBuildDiscarderStrategy/config.properties b/core/src/main/resources/jenkins/model/SimpleGlobalBuildDiscarderStrategy/config.properties index 621323e43ad5..7a7d5ebe939d 100644 --- a/core/src/main/resources/jenkins/model/SimpleGlobalBuildDiscarderStrategy/config.properties +++ b/core/src/main/resources/jenkins/model/SimpleGlobalBuildDiscarderStrategy/config.properties @@ -1 +1 @@ -blurb = The selected build discarder with be applied after any build finishes, as well as periodically. +blurb = The selected build discarder will be applied after any build finishes, as well as periodically. diff --git a/core/src/main/resources/jenkins/model/SimpleGlobalBuildDiscarderStrategy/config_pt_BR.properties b/core/src/main/resources/jenkins/model/SimpleGlobalBuildDiscarderStrategy/config_pt_BR.properties new file mode 100644 index 000000000000..fdf9dd69e455 --- /dev/null +++ b/core/src/main/resources/jenkins/model/SimpleGlobalBuildDiscarderStrategy/config_pt_BR.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Strategy=Estrat\u00E9gia +blurb=O descartador de constru\u00E7\u00E3o ser\u00E1 aplicado depois que cada constru\u00E7\u00E3o terminar, assim como periodicamente. diff --git a/core/src/main/resources/jenkins/model/SimpleGlobalBuildDiscarderStrategy/config_zh_TW.properties b/core/src/main/resources/jenkins/model/SimpleGlobalBuildDiscarderStrategy/config_zh_TW.properties new file mode 100644 index 000000000000..03bcd1eb202d --- /dev/null +++ b/core/src/main/resources/jenkins/model/SimpleGlobalBuildDiscarderStrategy/config_zh_TW.properties @@ -0,0 +1,2 @@ +blurb=\u9078\u53d6\u7684\u5efa\u7f6e\u6368\u68c4\u5668\u6703\u5728\u6bcf\u6b21\u5efa\u7f6e\u5b8c\u6210\u5f8c\u57f7\u884c\u3001\u4e5f\u6703\u5b9a\u671f\u57f7\u884c\u3002 +Strategy=\u7b56\u7565 diff --git a/core/src/main/resources/jenkins/model/identity/IdentityRootAction/index_pt_BR.properties b/core/src/main/resources/jenkins/model/identity/IdentityRootAction/index_pt_BR.properties new file mode 100644 index 000000000000..791630b82f2b --- /dev/null +++ b/core/src/main/resources/jenkins/model/identity/IdentityRootAction/index_pt_BR.properties @@ -0,0 +1,28 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Public\ Key=Chave p\u00FAblica +Instance\ Identity=Inst\u00E2ncia de identidade +Fingerprint=Assinaturas +blurb=Toda inst\u00E2ncia do Jenkins tem um par de chaves p\u00FAblica e privada utilizadas para identificar de forma un\u00EDvoca a mesma. \ +A chave p\u00FAblica \u00E9 publicada no cabe\u00E7alho X-Instance-Identity para requisi\u00E7\u00F5es web para a interface de usu\u00E1rio do Jenkins. \ +Voc\u00EA pode achar a chave e a assinatura da chave nesta p\u00E1gina. diff --git a/core/src/main/resources/jenkins/model/identity/IdentityRootAction/index_zh_TW.properties b/core/src/main/resources/jenkins/model/identity/IdentityRootAction/index_zh_TW.properties new file mode 100644 index 000000000000..88492fe29bc9 --- /dev/null +++ b/core/src/main/resources/jenkins/model/identity/IdentityRootAction/index_zh_TW.properties @@ -0,0 +1,4 @@ +blurb=\u6bcf\u500b Jenkins \u57f7\u884c\u500b\u9ad4\u90fd\u6709\u4e00\u5c0d\u7528\u4f86\u8b58\u5225\u5b83\u7684\u7368\u7279\u516c\u9470\u548c\u79c1\u9470\u3002\u516c\u9470\u6703\u88ab\u653e\u5728 Jenkins UI \u7684 X-Instance-Identity \u6a19\u982d\u3002\u60a8\u4e5f\u53ef\u4ee5\u5728\u6b64\u9801\u9762\u4e0a\u627e\u5230\u8a72\u91d1\u9470\u548c\u5b83\u7684\u6307\u7d0b\u3002 +Fingerprint=\u6307\u7d0b +Public\ Key=\u516c\u958b\u91d1\u9470 +Instance\ Identity=\u57f7\u884c\u500b\u9ad4\u8b58\u5225 diff --git a/core/src/main/resources/jenkins/model/item_category/Messages_pt_BR.properties b/core/src/main/resources/jenkins/model/item_category/Messages_pt_BR.properties new file mode 100644 index 000000000000..478321cfef92 --- /dev/null +++ b/core/src/main/resources/jenkins/model/item_category/Messages_pt_BR.properties @@ -0,0 +1,28 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Uncategorized.DisplayName=N\u00E3o categorizado +Uncategorized.Description=Tipos de \u00EDtens que ainda n\u00E3o foram categorizados pelo mantenedor da extens\u00E3o. +NestedProjects.DisplayName=Projetos aninhados +StandaloneProjects.Description=Cria projetos com uma configura\u00E7\u00E3o e hist\u00F3rico auto-contidos. Estes projetos pode estar no n\u00EDvel do topo ou agrupdo em pastas. +NestedProjects.Description=Criar categorias ou hierarquias de projetos com pastas. Pastas podem ser criadas manualmente ou automaticamente baseadas em reposit\u00F3rios. +StandaloneProjects.DisplayName=Projeto aut\u00F4nomo diff --git a/core/src/main/resources/jenkins/model/item_category/Messages_zh_TW.properties b/core/src/main/resources/jenkins/model/item_category/Messages_zh_TW.properties new file mode 100644 index 000000000000..666be05fdec9 --- /dev/null +++ b/core/src/main/resources/jenkins/model/item_category/Messages_zh_TW.properties @@ -0,0 +1,28 @@ +# The MIT License +# +# Copyright (c) 2016, CloudBees, Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Uncategorized.DisplayName=\u672a\u5206\u985e +Uncategorized.Description=\u5916\u639b\u7dad\u8b77\u8005\u9084\u6c92\u6709\u5c07\u5b83\u5206\u985e\u3002 +StandaloneProjects.DisplayName=\u7368\u7acb\u5c08\u6848 +StandaloneProjects.Description=\u5efa\u7acb\u64c1\u6709\u81ea\u5df1\u7d44\u614b\u548c\u6b77\u7a0b\u7684\u5c08\u6848\u3002\u9019\u7a2e\u5c08\u6848\u53ef\u4f4d\u65bc\u8cc7\u6599\u593e\u7684\u6700\u4e0a\u5c64\u6216\u6574\u7406\u65bc\u8cc7\u6599\u593e\u4e2d\u3002 +NestedProjects.DisplayName=\u5de2\u72c0\u5c08\u6848 +NestedProjects.Description=\u5efa\u7acb\u5c08\u6848\u985e\u5225\u6216\u6709\u5305\u542b\u8cc7\u6599\u593e\u7d50\u69cb\u7684\u5c08\u6848\u3002\u8cc7\u6599\u593e\u53ef\u624b\u52d5\u6216\u81ea\u52d5\u57fa\u65bc\u5132\u5b58\u5eab\u5efa\u7acb\u3002 diff --git a/core/src/main/resources/jenkins/monitor/JavaVersionRecommendationAdminMonitor/description.jelly b/core/src/main/resources/jenkins/monitor/JavaVersionRecommendationAdminMonitor/description.jelly new file mode 100644 index 000000000000..bb405e931933 --- /dev/null +++ b/core/src/main/resources/jenkins/monitor/JavaVersionRecommendationAdminMonitor/description.jelly @@ -0,0 +1,4 @@ + + + ${%blurb} + diff --git a/core/src/main/resources/jenkins/monitor/JavaVersionRecommendationAdminMonitor/description.properties b/core/src/main/resources/jenkins/monitor/JavaVersionRecommendationAdminMonitor/description.properties new file mode 100644 index 000000000000..543b42b1caef --- /dev/null +++ b/core/src/main/resources/jenkins/monitor/JavaVersionRecommendationAdminMonitor/description.properties @@ -0,0 +1 @@ +blurb = Recommends Java 11 for running Jenkins if an older version is used. diff --git a/core/src/main/resources/jenkins/monitor/JavaVersionRecommendationAdminMonitor/description_pt_BR.properties b/core/src/main/resources/jenkins/monitor/JavaVersionRecommendationAdminMonitor/description_pt_BR.properties new file mode 100644 index 000000000000..547fd8d7c1c5 --- /dev/null +++ b/core/src/main/resources/jenkins/monitor/JavaVersionRecommendationAdminMonitor/description_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +blurb=Recomenda o Java 11 para executar o Jenkins se uma vers\u00E3o anterior est\u00E1 em uso. diff --git a/core/src/main/resources/jenkins/monitor/JavaVersionRecommendationAdminMonitor/description_zh_TW.properties b/core/src/main/resources/jenkins/monitor/JavaVersionRecommendationAdminMonitor/description_zh_TW.properties new file mode 100644 index 000000000000..1e7223e3f4c3 --- /dev/null +++ b/core/src/main/resources/jenkins/monitor/JavaVersionRecommendationAdminMonitor/description_zh_TW.properties @@ -0,0 +1 @@ +blurb=\u82e5\u60a8\u4f7f\u7528\u7684 Java \u7248\u672c\u4f4e\u65bc 11\uff0c\u63a8\u85a6\u60a8\u6539\u7528 Java 11 \u4f86\u57f7\u884c Jenkins\u3002 diff --git a/core/src/main/resources/jenkins/monitor/JavaVersionRecommendationAdminMonitor/message.jelly b/core/src/main/resources/jenkins/monitor/JavaVersionRecommendationAdminMonitor/message.jelly new file mode 100644 index 000000000000..b8f86ee21585 --- /dev/null +++ b/core/src/main/resources/jenkins/monitor/JavaVersionRecommendationAdminMonitor/message.jelly @@ -0,0 +1,36 @@ + + + + +
      + ${%Recommended_Java_Version} + + + + + + +
      +
      diff --git a/core/src/main/resources/jenkins/monitor/JavaVersionRecommendationAdminMonitor/message.properties b/core/src/main/resources/jenkins/monitor/JavaVersionRecommendationAdminMonitor/message.properties new file mode 100644 index 000000000000..7b39fc1ce180 --- /dev/null +++ b/core/src/main/resources/jenkins/monitor/JavaVersionRecommendationAdminMonitor/message.properties @@ -0,0 +1 @@ +Recommended_Java_Version=Java 11 is the recommended version to run Jenkins on; please consider upgrading. diff --git a/core/src/main/resources/jenkins/monitor/JavaVersionRecommendationAdminMonitor/message_fr.properties b/core/src/main/resources/jenkins/monitor/JavaVersionRecommendationAdminMonitor/message_fr.properties new file mode 100644 index 000000000000..460689246ffb --- /dev/null +++ b/core/src/main/resources/jenkins/monitor/JavaVersionRecommendationAdminMonitor/message_fr.properties @@ -0,0 +1,3 @@ +Recommended_Java_Version=La version recommand\u00e9e pour utiliser Jenkins est Java 11 ; merci de faire une mise \u00e0 jour. +More\ Info=Plus d''informations +Dismiss=Ignorer diff --git a/core/src/main/resources/jenkins/monitor/JavaVersionRecommendationAdminMonitor/message_pt_BR.properties b/core/src/main/resources/jenkins/monitor/JavaVersionRecommendationAdminMonitor/message_pt_BR.properties new file mode 100644 index 000000000000..4bddbde46f10 --- /dev/null +++ b/core/src/main/resources/jenkins/monitor/JavaVersionRecommendationAdminMonitor/message_pt_BR.properties @@ -0,0 +1,25 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +More\ Info=Mais informa\u00E7\u00E3o +Recommended_Java_Version=O Java 11 \u00E9 a vers\u00E3o recomendad para o Jenkins rodar; por favor considere uma atualiza\u00E7\u00E3o. +Dismiss=Dispensar diff --git a/core/src/main/resources/jenkins/monitor/JavaVersionRecommendationAdminMonitor/message_ru.properties b/core/src/main/resources/jenkins/monitor/JavaVersionRecommendationAdminMonitor/message_ru.properties new file mode 100644 index 000000000000..dc70d2917678 --- /dev/null +++ b/core/src/main/resources/jenkins/monitor/JavaVersionRecommendationAdminMonitor/message_ru.properties @@ -0,0 +1,3 @@ +Recommended_Java_Version=\u0420\u0435\u043A\u043E\u043C\u0435\u043D\u0434\u0443\u0435\u043C\u0430\u044F \u0432\u0435\u0440\u0441\u0438\u044F \u0434\u043B\u044F \u0437\u0430\u043F\u0443\u0441\u043A\u0430 Jenkins - Java 11. \u0420\u0430\u0441\u0441\u043C\u043E\u0442\u0440\u0438\u0442\u0435 \u0432\u043E\u0437\u043C\u043E\u0436\u043D\u043E\u0441\u0442\u044C \u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u044F. +More\ Info=\u041F\u043E\u0434\u0440\u043E\u0431\u043D\u0435\u0435 +Dismiss=\u0423\u0431\u0440\u0430\u0442\u044C diff --git a/core/src/main/resources/jenkins/monitor/JavaVersionRecommendationAdminMonitor/message_zh_TW.properties b/core/src/main/resources/jenkins/monitor/JavaVersionRecommendationAdminMonitor/message_zh_TW.properties new file mode 100644 index 000000000000..60897ec025a5 --- /dev/null +++ b/core/src/main/resources/jenkins/monitor/JavaVersionRecommendationAdminMonitor/message_zh_TW.properties @@ -0,0 +1,3 @@ +Recommended_Java_Version=\u63a8\u85a6\u60a8\u4f7f\u7528 Java 11 \u4f86\u57f7\u884c Jenkins\uff0c\u8acb\u8003\u616e\u5347\u7d1a\u3002 +Dismiss=\u4e0d\u7ba1 +More\ Info=\u66f4\u591a\u8cc7\u8a0a diff --git a/core/src/main/resources/jenkins/monitor/Messages.properties b/core/src/main/resources/jenkins/monitor/Messages.properties new file mode 100644 index 000000000000..76f59746a51c --- /dev/null +++ b/core/src/main/resources/jenkins/monitor/Messages.properties @@ -0,0 +1 @@ +JavaLevelAdminMonitor.DisplayName=Recommended Java Version diff --git a/core/src/main/resources/jenkins/monitor/Messages_pt_BR.properties b/core/src/main/resources/jenkins/monitor/Messages_pt_BR.properties new file mode 100644 index 000000000000..c77f954417ca --- /dev/null +++ b/core/src/main/resources/jenkins/monitor/Messages_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +JavaLevelAdminMonitor.DisplayName=Vers\u00E3o recomendada do Java diff --git a/core/src/main/resources/jenkins/monitor/Messages_zh_TW.properties b/core/src/main/resources/jenkins/monitor/Messages_zh_TW.properties new file mode 100644 index 000000000000..5667c44abffb --- /dev/null +++ b/core/src/main/resources/jenkins/monitor/Messages_zh_TW.properties @@ -0,0 +1 @@ +JavaLevelAdminMonitor.DisplayName=\u63a8\u85a6\u7684 Java \u7248\u672c diff --git a/core/src/main/resources/jenkins/mvn/DefaultGlobalSettingsProvider/help.html b/core/src/main/resources/jenkins/mvn/DefaultGlobalSettingsProvider/help.html index 7d7aa8fd9a0a..a4898a51a4b9 100644 --- a/core/src/main/resources/jenkins/mvn/DefaultGlobalSettingsProvider/help.html +++ b/core/src/main/resources/jenkins/mvn/DefaultGlobalSettingsProvider/help.html @@ -1,3 +1,3 @@
      - Use default maven settings ($HOME/.m2/settings.xml) as set on build node. -
      \ No newline at end of file + Use default maven settings ($HOME/.m2/settings.xml) as set on build node. + diff --git a/core/src/main/resources/jenkins/mvn/DefaultGlobalSettingsProvider/help_bg.html b/core/src/main/resources/jenkins/mvn/DefaultGlobalSettingsProvider/help_bg.html index 0adec3ce9984..b76131e32421 100644 --- a/core/src/main/resources/jenkins/mvn/DefaultGlobalSettingsProvider/help_bg.html +++ b/core/src/main/resources/jenkins/mvn/DefaultGlobalSettingsProvider/help_bg.html @@ -1,4 +1,4 @@
      Използване на стандартните настройки на maven, зададени на компютъра - ($HOME/.m2/settings.xml). -
      \ No newline at end of file + ($HOME/.m2/settings.xml). + diff --git a/core/src/main/resources/jenkins/mvn/DefaultGlobalSettingsProvider/help_it.html b/core/src/main/resources/jenkins/mvn/DefaultGlobalSettingsProvider/help_it.html index 2570378a25e0..dfefa92935db 100644 --- a/core/src/main/resources/jenkins/mvn/DefaultGlobalSettingsProvider/help_it.html +++ b/core/src/main/resources/jenkins/mvn/DefaultGlobalSettingsProvider/help_it.html @@ -1,5 +1,5 @@
      Utilizza le impostazioni predefinite di Maven - ($HOME/.m2/settings.xml) così come impostate sul nodo di + ($HOME/.m2/settings.xml) così come impostate sul nodo di compilazione.
      diff --git a/core/src/main/resources/jenkins/mvn/DefaultSettingsProvider/help.html b/core/src/main/resources/jenkins/mvn/DefaultSettingsProvider/help.html index 7d7aa8fd9a0a..a4898a51a4b9 100644 --- a/core/src/main/resources/jenkins/mvn/DefaultSettingsProvider/help.html +++ b/core/src/main/resources/jenkins/mvn/DefaultSettingsProvider/help.html @@ -1,3 +1,3 @@
      - Use default maven settings ($HOME/.m2/settings.xml) as set on build node. -
      \ No newline at end of file + Use default maven settings ($HOME/.m2/settings.xml) as set on build node. + diff --git a/core/src/main/resources/jenkins/mvn/DefaultSettingsProvider/help_bg.html b/core/src/main/resources/jenkins/mvn/DefaultSettingsProvider/help_bg.html index 0adec3ce9984..b76131e32421 100644 --- a/core/src/main/resources/jenkins/mvn/DefaultSettingsProvider/help_bg.html +++ b/core/src/main/resources/jenkins/mvn/DefaultSettingsProvider/help_bg.html @@ -1,4 +1,4 @@
      Използване на стандартните настройки на maven, зададени на компютъра - ($HOME/.m2/settings.xml). -
      \ No newline at end of file + ($HOME/.m2/settings.xml). + diff --git a/core/src/main/resources/jenkins/mvn/DefaultSettingsProvider/help_it.html b/core/src/main/resources/jenkins/mvn/DefaultSettingsProvider/help_it.html index 2570378a25e0..dfefa92935db 100644 --- a/core/src/main/resources/jenkins/mvn/DefaultSettingsProvider/help_it.html +++ b/core/src/main/resources/jenkins/mvn/DefaultSettingsProvider/help_it.html @@ -1,5 +1,5 @@
      Utilizza le impostazioni predefinite di Maven - ($HOME/.m2/settings.xml) così come impostate sul nodo di + ($HOME/.m2/settings.xml) così come impostate sul nodo di compilazione.
      diff --git a/core/src/main/resources/jenkins/mvn/FilePathGlobalSettingsProvider/config.jelly b/core/src/main/resources/jenkins/mvn/FilePathGlobalSettingsProvider/config.jelly index fcd17978b2e1..3f3ff2065305 100644 --- a/core/src/main/resources/jenkins/mvn/FilePathGlobalSettingsProvider/config.jelly +++ b/core/src/main/resources/jenkins/mvn/FilePathGlobalSettingsProvider/config.jelly @@ -24,7 +24,7 @@ THE SOFTWARE. - + \ No newline at end of file diff --git a/core/src/main/resources/jenkins/mvn/FilePathGlobalSettingsProvider/help.html b/core/src/main/resources/jenkins/mvn/FilePathGlobalSettingsProvider/help.html index 44071efcf9af..0fd18cd6fcb8 100644 --- a/core/src/main/resources/jenkins/mvn/FilePathGlobalSettingsProvider/help.html +++ b/core/src/main/resources/jenkins/mvn/FilePathGlobalSettingsProvider/help.html @@ -1,3 +1,3 @@
      - Use a custom global settings.xml file from job workspace. Such a file is checked out from SCM as part of the job or a well known location. -
      \ No newline at end of file + Use a custom global settings.xml file from job workspace. Such a file is checked out from SCM as part of the job or a well known location. + diff --git a/core/src/main/resources/jenkins/mvn/FilePathGlobalSettingsProvider/help_bg.html b/core/src/main/resources/jenkins/mvn/FilePathGlobalSettingsProvider/help_bg.html index 858aa3b662a3..507efe318033 100644 --- a/core/src/main/resources/jenkins/mvn/FilePathGlobalSettingsProvider/help_bg.html +++ b/core/src/main/resources/jenkins/mvn/FilePathGlobalSettingsProvider/help_bg.html @@ -1,5 +1,5 @@
      - Използване на специфичен глобален файл settings.xml от работното + Използване на специфичен глобален файл settings.xml от работното пространство на проекта. Той трябва да бъде изтеглен от системата за контрол на версиите като част от изграждането или да се намира на достъпно място. -
      \ No newline at end of file + diff --git a/core/src/main/resources/jenkins/mvn/FilePathGlobalSettingsProvider/help_it.html b/core/src/main/resources/jenkins/mvn/FilePathGlobalSettingsProvider/help_it.html index d6a5ef44a6c7..21f414cb3c95 100644 --- a/core/src/main/resources/jenkins/mvn/FilePathGlobalSettingsProvider/help_it.html +++ b/core/src/main/resources/jenkins/mvn/FilePathGlobalSettingsProvider/help_it.html @@ -1,5 +1,5 @@
      - Utilizza un file settings.xml globale personalizzato dallo spazio di + Utilizza un file settings.xml globale personalizzato dallo spazio di lavoro del processo. Tale file viene recuperato dal sistema di gestione del codice sorgente come parte del processo o da un percorso noto.
      diff --git a/core/src/main/resources/jenkins/mvn/FilePathGlobalSettingsProvider/help_ja.html b/core/src/main/resources/jenkins/mvn/FilePathGlobalSettingsProvider/help_ja.html index b984dbbaa0fd..7a79996bb7c8 100644 --- a/core/src/main/resources/jenkins/mvn/FilePathGlobalSettingsProvider/help_ja.html +++ b/core/src/main/resources/jenkins/mvn/FilePathGlobalSettingsProvider/help_ja.html @@ -1,4 +1,4 @@
      - 独自のsettings.xmlを使用します。ジョブの一部としてSCMからそのファイルをダウンロードしたり、 + 独自のsettings.xmlを使用します。ジョブの一部としてSCMからそのファイルをダウンロードしたり、 既知の場所にあるファイルを指定してください。 -
      \ No newline at end of file + diff --git a/core/src/main/resources/jenkins/mvn/FilePathSettingsProvider/help.html b/core/src/main/resources/jenkins/mvn/FilePathSettingsProvider/help.html index 7566b8232275..7a1e765e5df9 100644 --- a/core/src/main/resources/jenkins/mvn/FilePathSettingsProvider/help.html +++ b/core/src/main/resources/jenkins/mvn/FilePathSettingsProvider/help.html @@ -1,3 +1,3 @@
      - Use a custom settings.xml file. Such a file is checked out from SCM as part of the job or a well known location. -
      \ No newline at end of file + Use a custom settings.xml file. Such a file is checked out from SCM as part of the job or a well known location. + diff --git a/core/src/main/resources/jenkins/mvn/FilePathSettingsProvider/help_bg.html b/core/src/main/resources/jenkins/mvn/FilePathSettingsProvider/help_bg.html index b5933521e405..8bfb571d17a2 100644 --- a/core/src/main/resources/jenkins/mvn/FilePathSettingsProvider/help_bg.html +++ b/core/src/main/resources/jenkins/mvn/FilePathSettingsProvider/help_bg.html @@ -1,5 +1,5 @@
      - Използване на специфичен файл settings.xml. Той трябва да бъде + Използване на специфичен файл settings.xml. Той трябва да бъде изтеглен от системата за контрол на версиите като част от изграждането или да се намира на достъпно място. -
      \ No newline at end of file + diff --git a/core/src/main/resources/jenkins/mvn/FilePathSettingsProvider/help_it.html b/core/src/main/resources/jenkins/mvn/FilePathSettingsProvider/help_it.html index 063fdf960f60..0d3a5995529b 100644 --- a/core/src/main/resources/jenkins/mvn/FilePathSettingsProvider/help_it.html +++ b/core/src/main/resources/jenkins/mvn/FilePathSettingsProvider/help_it.html @@ -1,5 +1,5 @@
      - Utilizza un file settings.xml personalizzato. Tale file viene + Utilizza un file settings.xml personalizzato. Tale file viene recuperato dal sistema di gestione del codice sorgente come parte del processo o da un percorso noto.
      diff --git a/core/src/main/resources/jenkins/mvn/FilePathSettingsProvider/help_ja.html b/core/src/main/resources/jenkins/mvn/FilePathSettingsProvider/help_ja.html index b984dbbaa0fd..7a79996bb7c8 100644 --- a/core/src/main/resources/jenkins/mvn/FilePathSettingsProvider/help_ja.html +++ b/core/src/main/resources/jenkins/mvn/FilePathSettingsProvider/help_ja.html @@ -1,4 +1,4 @@
      - 独自のsettings.xmlを使用します。ジョブの一部としてSCMからそのファイルをダウンロードしたり、 + 独自のsettings.xmlを使用します。ジョブの一部としてSCMからそのファイルをダウンロードしたり、 既知の場所にあるファイルを指定してください。 -
      \ No newline at end of file + diff --git a/core/src/main/resources/jenkins/mvn/GlobalMavenConfig/config.groovy b/core/src/main/resources/jenkins/mvn/GlobalMavenConfig/config.groovy index ca998385e069..7d1ff84aa72f 100644 --- a/core/src/main/resources/jenkins/mvn/GlobalMavenConfig/config.groovy +++ b/core/src/main/resources/jenkins/mvn/GlobalMavenConfig/config.groovy @@ -3,6 +3,6 @@ package jenkins.mvn.GlobalMavenConfig def f = namespace(lib.FormTagLib) f.section(title:_("Maven Configuration")) { - f.dropdownDescriptorSelector(title:_("Default settings provider"), field:"settingsProvider") - f.dropdownDescriptorSelector(title:_("Default global settings provider"), field:"globalSettingsProvider") + f.dropdownDescriptorSelector(title:_("Default settings provider"), field:"settingsProvider") + f.dropdownDescriptorSelector(title:_("Default global settings provider"), field:"globalSettingsProvider") } diff --git a/core/src/main/resources/jenkins/security/ApiTokenProperty/config_pt_BR.properties b/core/src/main/resources/jenkins/security/ApiTokenProperty/config_pt_BR.properties new file mode 100644 index 000000000000..b98197dffe2b --- /dev/null +++ b/core/src/main/resources/jenkins/security/ApiTokenProperty/config_pt_BR.properties @@ -0,0 +1,47 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Show\ Legacy\ API\ Token=Mostrar\ Passe\ De\ API\ Legado +TokenDisplayedOnce=Copie este passe agora porque ele n\u00E3o poder\u00E1 ser recuperado no futuro. +RevokedToken=O passe legado foi revogado +CurrentTokens=Passe(s) atual(is) +LegacyToken=Recomendamos fortemente que voc\u00EA revogue este passe legado e o troque por um novo rec\u00E9m gerado para aumentar a seguran\u00E7a. +ConfirmRevokeSingle=Voc\u00EA tem certeza de que quer revogar este passe? Aplica\u00E7\u00F5es que o estejam usando n\u00E3o v\u00E3o conseguir se conectar mais. +Cancel=Cancelar +StatisticsDisabled.Title=Estat\u00EDsticas de use de passe est\u00E3o atualmente desabilitadas +TokenCreation=Criado {0} dia(s) atr\u00E1s +Legacy\ API\ Token=Passe\ de\ API\ legado +TokenNeverUsed.Title=Recomendamos fortemente que voc\u00EA revogue os passes que voc\u00EA n\u00E3o planeja utilizar +StatisticsDisabled=Nenhuma estat\u00EDstica dispon\u00EDvel +TokenNeverUsedTooltip=N\u00E3o h\u00E1 \u00FAltima data de uso para este passe +Change\ API\ Token=Mudar\ passe\ de\ API +AddNewToken=Adicionar novo passe +GenerateNewToken=Gerar +Default\ name=Nome\ padr\u00E3o +CopyToken=Copiar este passe +TokenLastUse=Utilizado {0} vezes, \u00FAltima data de uso foi {1} dia(s) atr\u00E1s +NoTokenYet=N\u00E3o h\u00E1 passes registrados para este usu\u00E1rio. +Copied=Copiado +NoCreationDate=N\u00E3o h\u00E1 data de cria\u00E7\u00E3o para este passe +NoCreationDateValue=Desconhecido +RevokeToken=Revogar este passe +TokenNeverUsed=Nunca utilizado diff --git a/core/src/main/resources/jenkins/security/ApiTokenProperty/config_zh_TW.properties b/core/src/main/resources/jenkins/security/ApiTokenProperty/config_zh_TW.properties new file mode 100644 index 000000000000..47e12a3d1cc9 --- /dev/null +++ b/core/src/main/resources/jenkins/security/ApiTokenProperty/config_zh_TW.properties @@ -0,0 +1,27 @@ +TokenDisplayedOnce=\u8acb\u7acb\u5373\u8907\u88fd\u6b64 Token\uff0c\u56e0\u70ba\u4e4b\u5f8c\u7121\u6cd5\u518d\u6b21\u53d6\u5f97\u3002 +AddNewToken=\u65b0\u589e Token +GenerateNewToken=\u7522\u751f +RevokeToken=\u64a4\u92b7\u6b64 Token +CopyToken=\u8907\u88fd\u6b64 Token +NoTokenYet=\u6b64\u4f7f\u7528\u8005\u6c92\u6709\u5df2\u8a3b\u518a\u7684 Token\u3002 +TokenLastUse=\u5df2\u4f7f\u7528 {0} \u6b21\uff0c\u6700\u5f8c\u4f7f\u7528\u65bc {1} \u5929\u524d +StatisticsDisabled=\u6c92\u6709\u7d71\u8a08\u8cc7\u6599 +StatisticsDisabled.Title=\u76ee\u524d\u5df2\u505c\u7528 Token \u4f7f\u7528\u60c5\u5f62\u7d71\u8a08 +TokenNeverUsed=\u5f9e\u672a\u4f7f\u7528 +TokenNeverUsedTooltip=\u8a72 Token \u6c92\u6709\u6700\u5f8c\u4f7f\u7528\u65e5\u671f +TokenNeverUsed.Title=\u6211\u5011\u5f37\u70c8\u5efa\u8b70\u60a8\u64a4\u92b7\u4e0d\u6253\u7b97\u7e7c\u7e8c\u4f7f\u7528\u7684 Token +ConfirmRevokeSingle=\u60a8\u78ba\u5b9a\u8981\u64a4\u92b7\u6b64 Token\uff1f\u4f7f\u7528\u5b83\u7684\u61c9\u7528\u7a0b\u5f0f\u5c07\u7121\u6cd5\u518d\u9023\u7dda\u3002 +CurrentTokens=\u73fe\u6709\u7684 Token +TokenCreation=\u5efa\u7acb\u65bc {0} \u5929\u524d +RenameToken=\u5132\u5b58\u8a72 Token \u7684\u65b0\u540d\u7a31 +LegacyToken=\u6211\u5011\u5f37\u70c8\u5efa\u8b70\u60a8\u64a4\u92b7\u6b64 Legacy Token \u4e26\u4ee5\u7522\u751f\u65b0\u7684 Token \u53d6\u4ee3\u5b83\u4ee5\u589e\u52a0\u5b89\u5168\u6027\u3002 +NoLegacyToken=\u8a72\u4f7f\u7528\u8005\u6c92\u6709 Legacy Token +RevokedToken=\u5df2\u64a4\u92b7\u8a72 Legacy Token +NoCreationDate=\u8a72 Token \u6c92\u6709\u5efa\u7acb\u65e5\u671f +NoCreationDateValue=\u672a\u77e5 +Legacy\ API\ Token=Legacy API Token +Show\ Legacy\ API\ Token=\u986f\u793a Legacy API Token +Copied=\u5df2\u8907\u88fd +Cancel=\u53d6\u6d88 +Change\ API\ Token=\u8b8a\u66f4 API Token +Default\ name=\u9810\u8a2d\u540d\u7a31 diff --git a/core/src/main/resources/jenkins/security/ApiTokenProperty/help-tokenStore.html b/core/src/main/resources/jenkins/security/ApiTokenProperty/help-tokenStore.html index 2b23aff54235..acdb1bd05e9a 100644 --- a/core/src/main/resources/jenkins/security/ApiTokenProperty/help-tokenStore.html +++ b/core/src/main/resources/jenkins/security/ApiTokenProperty/help-tokenStore.html @@ -1,6 +1,6 @@
      API tokens offer a way to make authenticated CLI or REST API calls. - See our wiki for more details.
      + See our wiki for more details.
      The username associated with each token is your Jenkins username.

      Some good practices for keeping your API tokens secure are: diff --git a/core/src/main/resources/jenkins/security/ApiTokenProperty/help-tokenStore_bg.html b/core/src/main/resources/jenkins/security/ApiTokenProperty/help-tokenStore_bg.html index 44a7e1d48500..ab2eb75bf0a6 100644 --- a/core/src/main/resources/jenkins/security/ApiTokenProperty/help-tokenStore_bg.html +++ b/core/src/main/resources/jenkins/security/ApiTokenProperty/help-tokenStore_bg.html @@ -1,6 +1,6 @@
      Този жетон за API дава възможност за идентификация в извикването по REST. За повече подробности погледнете - документацията в уикито. + документацията в уикито. Жетонът от това API трябва да се пази подобно на парола, защото позволява на други хора да достъпват Jenkins от ваше име и с вашите права.
      diff --git a/core/src/main/resources/jenkins/security/ApiTokenProperty/help-tokenStore_fr.html b/core/src/main/resources/jenkins/security/ApiTokenProperty/help-tokenStore_fr.html index 2b1202b4c60e..6962b6415933 100644 --- a/core/src/main/resources/jenkins/security/ApiTokenProperty/help-tokenStore_fr.html +++ b/core/src/main/resources/jenkins/security/ApiTokenProperty/help-tokenStore_fr.html @@ -1,6 +1,6 @@
      Les jetons d'API permettent l'authentification de l'utilisateur lors de l'utilisation du CLI ou des API REST. - Merci de consulter le wiki pour plus de détails.
      + Merci de consulter le wiki pour plus de détails.
      L'identifiant (username) associé au jeton est l'identifiant Jenkins.

      Les bonnes pratiques pour garder vos jetons sécurisés sont: diff --git a/core/src/main/resources/jenkins/security/ApiTokenProperty/help-tokenStore_it.html b/core/src/main/resources/jenkins/security/ApiTokenProperty/help-tokenStore_it.html index f1150c9c3169..fdd7c5c17a47 100644 --- a/core/src/main/resources/jenkins/security/ApiTokenProperty/help-tokenStore_it.html +++ b/core/src/main/resources/jenkins/security/ApiTokenProperty/help-tokenStore_it.html @@ -1,7 +1,7 @@
      I token API offrono un modo di eseguire chiamate autenticate dall'interfaccia a riga di comando o tramite API REST. Si veda - il nostro wiki per + il nostro wiki per ulteriori informazioni.
      Il nome utente associato con ogni token è il nome utente di Jenkins.

      diff --git a/core/src/main/resources/jenkins/security/ApiTokenProperty/help-tokenStore_ja.html b/core/src/main/resources/jenkins/security/ApiTokenProperty/help-tokenStore_ja.html index a1c92c37d577..388a68dce3e5 100644 --- a/core/src/main/resources/jenkins/security/ApiTokenProperty/help-tokenStore_ja.html +++ b/core/src/main/resources/jenkins/security/ApiTokenProperty/help-tokenStore_ja.html @@ -1,5 +1,5 @@
      APIトークンは、REST API使用時の認証に使用されます。 - 詳細はWikiを参照してください。 + 詳細はWikiを参照してください。 APIトークンはパスワードと同様に保護する必要があります。そうしないと、他人が詐称してJenkinsにアクセス可能になります。
      \ No newline at end of file diff --git a/core/src/main/resources/jenkins/security/ApiTokenProperty/help-tokenStore_zh_TW.html b/core/src/main/resources/jenkins/security/ApiTokenProperty/help-tokenStore_zh_TW.html index 512564dd8aa8..12014396eb6f 100644 --- a/core/src/main/resources/jenkins/security/ApiTokenProperty/help-tokenStore_zh_TW.html +++ b/core/src/main/resources/jenkins/security/ApiTokenProperty/help-tokenStore_zh_TW.html @@ -1,5 +1,5 @@
      您在呼叫 REST API 時要使用 API Token 驗證。 - 詳情請參考我們的 Wiki。 + 詳情請參考我們的 Wiki。 API Token 應該當做密碼一樣好好保管,因為有了它,其他人就能跟您一樣存取 Jenkins。
      \ No newline at end of file diff --git a/core/src/main/resources/jenkins/security/ApiTokenProperty/resources.css b/core/src/main/resources/jenkins/security/ApiTokenProperty/resources.css index 73c211376c67..631043e98ce8 100644 --- a/core/src/main/resources/jenkins/security/ApiTokenProperty/resources.css +++ b/core/src/main/resources/jenkins/security/ApiTokenProperty/resources.css @@ -144,7 +144,8 @@ } .token-list .repeated-chunk { border-width: 0; - padding-left: 0; + padding: 0; + margin: 0; } .token-list .repeatable-add{ margin: 6px 6px 3px 6px; diff --git a/core/src/main/resources/jenkins/security/Messages_pt_BR.properties b/core/src/main/resources/jenkins/security/Messages_pt_BR.properties index 048625191745..e47bf254099e 100644 --- a/core/src/main/resources/jenkins/security/Messages_pt_BR.properties +++ b/core/src/main/resources/jenkins/security/Messages_pt_BR.properties @@ -20,9 +20,29 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -# Re-keying -RekeySecretAdminMonitor.DisplayName=Re-keying -#
      Updated
      +RekeySecretAdminMonitor.DisplayName=Rechaveamento ApiTokenProperty.ChangeToken.Success=
      Atualizado
      -# API Token -ApiTokenProperty.DisplayName=API Token +ApiTokenProperty.DisplayName=Passe de API +ResourceDomainConfiguration.NeedsRootURL=S\u00F3 \u00E9 poss\u00EDvel configurar a URL raiz do recurso se a URL do Jenkins estiver configurada. +ResourceDomainConfiguration.Empty=Sem uma URL raiz de recurso, recursos ser\u00E3o servidos da URL do Jenkins com Content-Security-Policy configurado. +ResourceDomainConfiguration.SomeJenkins=A URL especificada aponta para uma inst\u00E2ncia do Jenkins mas n\u00E3o pode determinar se \u00E9 esta mesmo ou outra inst\u00E2ncia. +ResourceDomainConfiguration.NotJenkins=A URL espeficicada n\u00E3o parece apontar para uma inst\u00E2ncia do Jenkins. +ApiTokenProperty.ChangeToken.TokenIsHidden=O passe est\u00E1 oculto +UpdateSiteWarningsMonitor.DisplayName=Atualizar avisos do s\u00EDtio +ResourceDomainConfiguration.Invalid=N\u00E3o \u00E9 uma URL v\u00E1lida. +Token.Created.on=Passe criado em {0} +ResourceDomainConfiguration.IOException=Falha para conectar: {0} +ResourceDomainConfiguration.FailedIdentityCheck=Um erro ocorreu quando verificando a identidade de uma inst\u00E2ncia localiza naquela URL: {0} {1} +ResourceDomainConfiguration.SameAsJenkinsRoot=N\u00E3o pode usar o mesmo nome de hospedeiro e para a URL do Jenkins e para a URL raiz de recurso. +ResourceDomainConfiguration.SameAsCurrent=Voc\u00EA est\u00E1 atualmente acessando o Jenkins atrav\u00E9s de uma URL similar a URL raiz de recurso proposta. Salvar esta URL poder\u00E1 remover seu acesso ao Jenkins. +ApiTokenProperty.ChangeToken.SuccessHidden=
      Atualizado. Voc\u00EA precisa fazer a entrada com o usu\u00E1rio para ser o passe
      +ResourceDomainConfiguration.DisplayName=Recomenda\u00E7\u00E3o de dom\u00EDnio de recurso +ApiTokenProperty.ChangeToken.CapabilityNotAllowed=
      Capacidade de gerar um passe legado sem a exist\u00EAncia de um pr\u00E9vio est\u00E1 atualmente desabilitada pela configura\u00E7\u00E3o de seguran\u00E7a
      +ApiTokenProperty.LegacyTokenName=Passe legado +ResourceDomainConfiguration.Exception=Uma exce\u00E7\u00E3o ocorreu com a URL: {0} +QueueItemAuthenticatorMonitor.DisplayName=Controle de acesso para constru\u00E7\u00F5es +ApiTokenProperty.NoLegacyToken=Este usu\u00E1rio atualmente n\u00E3o tem um passe legado +ResourceDomainConfiguration.ThisJenkins=A URL especificada \u00E9 um candidato v\u00E1lido para URL raiz de recurso. +ResourceDomainConfiguration.InvalidRootURL=A URL do Jenkins est\u00E1 configurada para um valor inv\u00E1lido, por favor relate uma falha: {0} +ResourceDomainConfiguration.OtherJenkins=A URL especificada aponta para uma inst\u00E2ncia Jenkins diferente. +ResourceDomainConfiguration.ResourceResponse=A URL especifica aponta para uma URL raiz de recurso previamente configurada. diff --git a/core/src/main/resources/jenkins/security/QueueItemAuthenticatorMonitor/description.jelly b/core/src/main/resources/jenkins/security/QueueItemAuthenticatorMonitor/description.jelly new file mode 100644 index 000000000000..bb405e931933 --- /dev/null +++ b/core/src/main/resources/jenkins/security/QueueItemAuthenticatorMonitor/description.jelly @@ -0,0 +1,4 @@ + + + ${%blurb} + diff --git a/core/src/main/resources/jenkins/security/QueueItemAuthenticatorMonitor/description.properties b/core/src/main/resources/jenkins/security/QueueItemAuthenticatorMonitor/description.properties new file mode 100644 index 000000000000..e0e35e008504 --- /dev/null +++ b/core/src/main/resources/jenkins/security/QueueItemAuthenticatorMonitor/description.properties @@ -0,0 +1 @@ +blurb = If access control for builds is not set up, this shows a warning, explaining the problem. diff --git a/core/src/main/resources/jenkins/security/QueueItemAuthenticatorMonitor/description_pt_BR.properties b/core/src/main/resources/jenkins/security/QueueItemAuthenticatorMonitor/description_pt_BR.properties new file mode 100644 index 000000000000..fb32fa853151 --- /dev/null +++ b/core/src/main/resources/jenkins/security/QueueItemAuthenticatorMonitor/description_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +blurb=Se o controle de acesso para constru\u00E7\u00F5es n\u00E3o estiver configurado, mostre este aviso explicando o problema. diff --git a/core/src/main/resources/jenkins/security/QueueItemAuthenticatorMonitor/message.properties b/core/src/main/resources/jenkins/security/QueueItemAuthenticatorMonitor/message.properties index 3c7360921941..fa29a602bc1e 100644 --- a/core/src/main/resources/jenkins/security/QueueItemAuthenticatorMonitor/message.properties +++ b/core/src/main/resources/jenkins/security/QueueItemAuthenticatorMonitor/message.properties @@ -5,7 +5,7 @@ blurb = Builds in Jenkins run as the virtual Jenkins SYSTEM user with full Jenki queueItemAuthenticatorPresent = \u2705 An implementation of access control for builds is present. noQueueItemAuthenticatorPresent = \u274c No implementation of access control for builds is present. \ It is recommended that you install Authorize Project Plugin or another plugin \ - implementing the QueueItemAuthenticator \ + implementing the QueueItemAuthenticator \ extension point. queueItemAuthenticatorConfigured = \u2705 Access control for builds is configured. diff --git a/core/src/main/resources/jenkins/security/QueueItemAuthenticatorMonitor/message_it.properties b/core/src/main/resources/jenkins/security/QueueItemAuthenticatorMonitor/message_it.properties index 8d9bd2ae5029..c2d6983ac76c 100644 --- a/core/src/main/resources/jenkins/security/QueueItemAuthenticatorMonitor/message_it.properties +++ b/core/src/main/resources/jenkins/security/QueueItemAuthenticatorMonitor/message_it.properties @@ -45,7 +45,7 @@ noQueueItemAuthenticatorPresent=\u274c Non href="https://plugins.jenkins.io/authorize-project" rel="noopener noreferrer" target="_blank">\ componente aggiuntivo Autorizza progetto o un altro componente \ aggiuntivo che implementi il punto estensione QueueItemAuthenticator. notAnyBuildLaunchedAsSystem=\u2705 Non sono state avviate compilazioni con le \ credenziali dell''utente interno SYSTEM, il che indica che la \ diff --git a/core/src/main/resources/jenkins/security/RekeySecretAdminMonitor/description.jelly b/core/src/main/resources/jenkins/security/RekeySecretAdminMonitor/description.jelly new file mode 100644 index 000000000000..bb405e931933 --- /dev/null +++ b/core/src/main/resources/jenkins/security/RekeySecretAdminMonitor/description.jelly @@ -0,0 +1,4 @@ + + + ${%blurb} + diff --git a/core/src/main/resources/jenkins/security/RekeySecretAdminMonitor/description.properties b/core/src/main/resources/jenkins/security/RekeySecretAdminMonitor/description.properties new file mode 100644 index 000000000000..e74250b62a07 --- /dev/null +++ b/core/src/main/resources/jenkins/security/RekeySecretAdminMonitor/description.properties @@ -0,0 +1 @@ +blurb = Informs about the need to perform secret re-keying due to a security vulnerability that was fixed in 2013. diff --git a/core/src/main/resources/jenkins/security/RekeySecretAdminMonitor/description_pt_BR.properties b/core/src/main/resources/jenkins/security/RekeySecretAdminMonitor/description_pt_BR.properties new file mode 100644 index 000000000000..4180276fdcd7 --- /dev/null +++ b/core/src/main/resources/jenkins/security/RekeySecretAdminMonitor/description_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +blurb=Informa sobre a necessidade de recriar o chaveamento de segredo devido a vulnerabilidade de seguran\u00E7a corrigida em 2013. diff --git a/core/src/main/resources/jenkins/security/RekeySecretAdminMonitor/message.properties b/core/src/main/resources/jenkins/security/RekeySecretAdminMonitor/message.properties index 8a6cb0ba3411..d239da3b9e47 100644 --- a/core/src/main/resources/jenkins/security/RekeySecretAdminMonitor/message.properties +++ b/core/src/main/resources/jenkins/security/RekeySecretAdminMonitor/message.properties @@ -1,9 +1,9 @@ pleaseRekeyAsap=\ - Because of a security vulnerability discovered earlier, we need to \ + Because of a security vulnerability discovered earlier, we need to \ change the encryption key used to protect secrets in your configuration files on the disk. \ This process scans a large portion of your $JENKINS_HOME ({0}), \ find encrypted data, re-key them, which will take some time. \ - See this document for more implications about different ways of doing this \ + See this document for more implications about different ways of doing this \ (or not doing this.) This operation can be safely run in background, but cautious users \ are recommended to take backups. diff --git a/core/src/main/resources/jenkins/security/RekeySecretAdminMonitor/message_it.properties b/core/src/main/resources/jenkins/security/RekeySecretAdminMonitor/message_it.properties index a826c2d48b13..748fc1fd18fa 100644 --- a/core/src/main/resources/jenkins/security/RekeySecretAdminMonitor/message_it.properties +++ b/core/src/main/resources/jenkins/security/RekeySecretAdminMonitor/message_it.properties @@ -22,14 +22,14 @@ # THE SOFTWARE. Dismiss=Nascondi -pleaseRekeyAsap=A causa di una vulnerabilit di sicurezza scoperta in precedenza, \ necessario modificare la chiave crittografica utilizzata per proteggere i \ segreti salvati nei file di configurazione su disco. Questa procedura \ esegue la scansione della maggior parte della directory \ $JENKINS_HOME ({0}), trova i dati crittografati e \ li cripta nuovamente con la nuova chiave; tutte queste operazioni \ - richiedono del tempo. Si veda questo documento per le implicazioni derivanti dallo \ scegliere una modalit anzich un''altra (o dal non eseguire \ quest''operazione). Quest''operazione pu essere eseguita in secondo piano \ diff --git a/core/src/main/resources/jenkins/security/RekeySecretAdminMonitor/message_sr.properties b/core/src/main/resources/jenkins/security/RekeySecretAdminMonitor/message_sr.properties index fe30b7d37d70..2e4c2213a36e 100644 --- a/core/src/main/resources/jenkins/security/RekeySecretAdminMonitor/message_sr.properties +++ b/core/src/main/resources/jenkins/security/RekeySecretAdminMonitor/message_sr.properties @@ -1,18 +1,18 @@ # This file is under the MIT License by authors pleaseRekeyAsap=\ - \u0417\u0431\u043E\u0433 \u043E\u0442\u0440\u0438\u0432\u0435\u043D\u0435 \u0440\u0430\u045A\u0438\u0432\u043E\u0441\u0442\u0438, \u043C\u043E\u0440\u0430\u043C\u043E \ + \u0417\u0431\u043E\u0433 \u043E\u0442\u0440\u0438\u0432\u0435\u043D\u0435 \u0440\u0430\u045A\u0438\u0432\u043E\u0441\u0442\u0438, \u043C\u043E\u0440\u0430\u043C\u043E \ \u043F\u0440\u043E\u043C\u0435\u043D\u0438\u0442\u0438 \u043A\u0459\u0443\u0447 \u0437\u0430 \u0448\u0438\u0444\u0440\u043E\u0432\u0430\u045A\u0435 \u0442\u0430\u0458\u043D\u0438 \u0434\u0430 \u0434\u0438\u0441\u043A\u0443. \ - \u0422\u0430\u0458 \u043F\u0440\u043E\u0446\u0435\u0441 \u043F\u0440\u0435\u0442\u0440\u0430\u0436\u0438 \u0432\u0435\u043B\u0438\u043A\u0438 \u0434\u0435\u043E \u0432\u0430\u0448\u0435\u0433 $JENKINS_HOME ({0}) \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0458\u0443\u043C\u0430, \ + \u0422\u0430\u0458 \u043F\u0440\u043E\u0446\u0435\u0441 \u043F\u0440\u0435\u0442\u0440\u0430\u0436\u0438 \u0432\u0435\u043B\u0438\u043A\u0438 \u0434\u0435\u043E \u0432\u0430\u0448\u0435\u0433 $JENKINS_HOME ({0}) \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0458\u0443\u043C\u0430, \ \u0438 \u043F\u043E\u043D\u043E\u0432\u043E \u0438\u0437\u0433\u0440\u0430\u0447\u0443\u043D\u0430 \u0445\u0435\u0448 \u0437\u0430 \u043F\u0440\u043E\u043D\u0430\u0452\u0435\u043D\u0435 \u043F\u043E\u0434\u0430\u0442\u043A\u0435, \u0448\u0442\u043E \u043C\u043E\u0436\u0435 \u043F\u0440\u0438\u043B\u0438\u0447\u043D\u043E \u0434\u0443\u0433\u043E \u0442\u0440\u0430\u0458\u0430\u0442\u0438. \ - \u041F\u0440\u043E\u0447\u0438\u0442\u0430\u0458\u0442\u0435 \u043E\u0432\u0430\u0458 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442 \u0433\u0434\u0435 \u0441\u0435 \u043F\u0438\u0448\u0435 \u043E \u0432\u0438\u0448\u0435 \u0438\u043C\u043F\u043B\u0438\u043A\u0430\u0446\u0438\u0458\u0430 \u0438 \u0434\u0440\u0443\u0433\u0430\u0447\u0438\u0458\u0435 \u043D\u0430\u0447\u0438\u043D\u0435 \ + \u041F\u0440\u043E\u0447\u0438\u0442\u0430\u0458\u0442\u0435 \u043E\u0432\u0430\u0458 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442 \u0433\u0434\u0435 \u0441\u0435 \u043F\u0438\u0448\u0435 \u043E \u0432\u0438\u0448\u0435 \u0438\u043C\u043F\u043B\u0438\u043A\u0430\u0446\u0438\u0458\u0430 \u0438 \u0434\u0440\u0443\u0433\u0430\u0447\u0438\u0458\u0435 \u043D\u0430\u0447\u0438\u043D\u0435 \ \u041E\u0432\u0430 \u043E\u043F\u0435\u0440\u0430\u0446\u0438\u0458\u0430 \u0441\u0435 \u043C\u043E\u0436\u0435 \u0431\u0435\u0437\u0431\u0435\u0434\u043D\u043E \u0438\u0437\u0432\u0440\u0448\u0438\u0442\u0438 \u0443 \u043F\u043E\u0437\u0430\u0434\u0438\u043D\u0438, \u043C\u0435\u0452\u0443\u0442\u0438\u043C \u043E\u0431\u0430\u0437\u0440\u0438\u0432\u0438 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u0446\u0438 \ \u0431\u0438 \u043C\u043E\u0433\u043B\u0438 \u043D\u0430\u043F\u0440\u0430\u0432\u0438\u0442\u0438 \u0440\u0435\u0437\u0435\u0440\u0432\u043D\u0435 \u043A\u043E\u043F\u0438\u0458\u0435 \u043F\u043E\u0434\u0430\u0446\u0438\u043C\u0430. rekeyInProgress=\u041F\u043E\u043D\u043E\u0432\u043E \u0445\u0435\u0448\u0438\u0440\u0430\u045A\u0435 \u0458\u0435 \u0443 \u0442\u043E\u043A\u0443. \u041C\u043E\u0436\u0435\u0442\u0435 \u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0430\u0458\u0442\u0438 \u0436\u0443\u0440\u043D\u0430\u043B. rekeySuccessful=\ - Secrets in your $JENKINS_HOME \u0458\u0435 \u0443\u0441\u043F\u0435\u0448\u043D\u043E \u0438\u0437\u0445\u0435\u0448\u0438\u0440\u0430\u043D\u043E. \ + Secrets in your $JENKINS_HOME \u0458\u0435 \u0443\u0441\u043F\u0435\u0448\u043D\u043E \u0438\u0437\u0445\u0435\u0448\u0438\u0440\u0430\u043D\u043E. \ \u041C\u043E\u043B\u0438\u043C\u043E \u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0430\u0458\u0442\u0435 \u0436\u0443\u0440\u043D\u0430\u043B, \u043F\u043E\u0442\u0432\u0440\u0434\u0438\u0442\u0435, \u0438 \u043D\u0430\u0441\u0442\u0430\u0432\u0438\u0442\u0435 \u0438\u043B\u0438 \u043F\u043E\u043D\u043E\u0432\u043E \u0438\u0437\u0432\u0440\u0448\u0438\u0442\u0435. rekeyHadProblems=\ diff --git a/core/src/main/resources/jenkins/security/RekeySecretAdminMonitor/message_zh_TW.properties b/core/src/main/resources/jenkins/security/RekeySecretAdminMonitor/message_zh_TW.properties index 931fa7eeefb8..bcc681e1754d 100644 --- a/core/src/main/resources/jenkins/security/RekeySecretAdminMonitor/message_zh_TW.properties +++ b/core/src/main/resources/jenkins/security/RekeySecretAdminMonitor/message_zh_TW.properties @@ -21,10 +21,10 @@ # THE SOFTWARE. pleaseRekeyAsap=\ - \u70ba\u4e86\u4fee\u6b63\u5148\u524d\u767c\u73fe\u7684\u5b89\u5168\u6027\u5f31\u9ede\uff0c\ + \u70ba\u4e86\u4fee\u6b63\u5148\u524d\u767c\u73fe\u7684\u5b89\u5168\u6027\u5f31\u9ede\uff0c\ \u7528\u4f86\u4fdd\u8b77\u78c1\u789f\u4e0a\u542b\u6a5f\u654f\u8a2d\u5b9a\u6a94\u7684\u52a0\u5bc6\u91d1\u9470\u4e00\u5b9a\u8981\u66f4\u6539\u3002\ \u6574\u500b\u7a0b\u5e8f\u6703\u6383\u63cf\u60a8 $JENKINS_HOME ({0}) \u4e2d\u7684\u5927\u90e8\u5206\u6a94\u6848\uff0c\u627e\u51fa\u52a0\u5bc6\u7684\u8cc7\u6599\u91cd\u5957\u91d1\u9470\uff0c\u53ef\u80fd\u8981\u82b1\u4e0a\u4e0d\u5c11\u6642\u9593\u3002\ - \u9019\u4efd\u6587\u4ef6\u8aaa\u660e\u4e86\u5be6\u65bd (\u6216\u4ec0\u9ebc\u4e8b\u90fd\u4e0d\u505a) \u9019\u9805\u63aa\u65bd\u7684\u65b9\u6cd5\u53ca\u5f71\u97ff\u3002\ + \u9019\u4efd\u6587\u4ef6\u8aaa\u660e\u4e86\u5be6\u65bd (\u6216\u4ec0\u9ebc\u4e8b\u90fd\u4e0d\u505a) \u9019\u9805\u63aa\u65bd\u7684\u65b9\u6cd5\u53ca\u5f71\u97ff\u3002\ \u9019\u9805\u4f5c\u696d\u53ef\u4ee5\u5b89\u5168\u7684\u5728\u80cc\u666f\u57f7\u884c\uff0c\u4e0d\u904e\u5982\u679c\u60a8\u5f88\u8b39\u614e\uff0c\u5efa\u8b70\u60a8\u5148\u505a\u597d\u5099\u4efd\u3002 rekeyInProgress=\u91d1\u9470\u91cd\u5957\u4e2d\u3002\u60a8\u53ef\u4ee5\u67e5\u770b\u8a18\u9304\u3002 diff --git a/core/src/main/resources/jenkins/security/ResourceDomainConfiguration/config_pt_BR.properties b/core/src/main/resources/jenkins/security/ResourceDomainConfiguration/config_pt_BR.properties new file mode 100644 index 000000000000..7e5c2dde4721 --- /dev/null +++ b/core/src/main/resources/jenkins/security/ResourceDomainConfiguration/config_pt_BR.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Resource\ Root\ URL=URL\ do\ recurso\ ra\u00EDz +Serve\ resource\ files\ from\ another\ domain=Serve\ arquivos\ de\ recurso\ de\ outro\ dom\u00EDnio diff --git a/core/src/main/resources/jenkins/security/ResourceDomainRecommendation/description.jelly b/core/src/main/resources/jenkins/security/ResourceDomainRecommendation/description.jelly new file mode 100644 index 000000000000..bb405e931933 --- /dev/null +++ b/core/src/main/resources/jenkins/security/ResourceDomainRecommendation/description.jelly @@ -0,0 +1,4 @@ + + + ${%blurb} + diff --git a/core/src/main/resources/jenkins/security/ResourceDomainRecommendation/description.properties b/core/src/main/resources/jenkins/security/ResourceDomainRecommendation/description.properties new file mode 100644 index 000000000000..f582443e009b --- /dev/null +++ b/core/src/main/resources/jenkins/security/ResourceDomainRecommendation/description.properties @@ -0,0 +1 @@ +blurb = Informs about the resource root URL option if the Content-Security-Policy HTTP header for user-controlled resources served by Jenkins has been set to a custom value. diff --git a/core/src/main/resources/jenkins/security/ResourceDomainRecommendation/description_pt_BR.properties b/core/src/main/resources/jenkins/security/ResourceDomainRecommendation/description_pt_BR.properties new file mode 100644 index 000000000000..a25e4682f3bf --- /dev/null +++ b/core/src/main/resources/jenkins/security/ResourceDomainRecommendation/description_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +blurb=Informa sobre a URL do recurso ra\u00EDz se o cabe\u00E7alho HTTP Content-Security-Policy para recursos controlados pelo usu\u00E1rio servidos pelo Jenkins tem um valor customizado. diff --git a/core/src/main/resources/jenkins/security/UpdateSiteWarningsMonitor/description.jelly b/core/src/main/resources/jenkins/security/UpdateSiteWarningsMonitor/description.jelly new file mode 100644 index 000000000000..bb405e931933 --- /dev/null +++ b/core/src/main/resources/jenkins/security/UpdateSiteWarningsMonitor/description.jelly @@ -0,0 +1,4 @@ + + + ${%blurb} + diff --git a/core/src/main/resources/jenkins/security/UpdateSiteWarningsMonitor/description.properties b/core/src/main/resources/jenkins/security/UpdateSiteWarningsMonitor/description.properties new file mode 100644 index 000000000000..ac83e27372be --- /dev/null +++ b/core/src/main/resources/jenkins/security/UpdateSiteWarningsMonitor/description.properties @@ -0,0 +1,3 @@ +blurb = This warning informs administrators about active security warnings for installed Jenkins core or plugin versions. \ + Rather than disable this warning entirely (including any future issues), consider disabling specific messages in the global security configuration. +# TODO Add link diff --git a/core/src/main/resources/jenkins/security/UpdateSiteWarningsMonitor/description_pt_BR.properties b/core/src/main/resources/jenkins/security/UpdateSiteWarningsMonitor/description_pt_BR.properties new file mode 100644 index 000000000000..7b4294e98d78 --- /dev/null +++ b/core/src/main/resources/jenkins/security/UpdateSiteWarningsMonitor/description_pt_BR.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +blurb=Este aviso informa administradores sobre avisos de seguran\u00E7a ativos sobre vers\u00F5es do Jenkins core ou complementos. \ + Ao inv\u00E9s de desabilitar este aviso completamente (incluindo quaisquers problemas futuros), considere desabilitar mensagens espec\u00EDficas na configura\u00E7\u00E3o global de seguran\u00E7a. diff --git a/core/src/main/resources/jenkins/security/UpdateSiteWarningsMonitor/message_es.properties b/core/src/main/resources/jenkins/security/UpdateSiteWarningsMonitor/message_es.properties new file mode 100644 index 000000000000..f3f0a2c63c63 --- /dev/null +++ b/core/src/main/resources/jenkins/security/UpdateSiteWarningsMonitor/message_es.properties @@ -0,0 +1,31 @@ +# The MIT License +# +# Copyright (c) 2021, Jenkins project contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +pluginTitle = {0} {1} +coreTitle = Jenkins {0} programa y librerías + +blurb = Advertencias publicadas para los siguientes componentes instalados: +more = Advertencias adicionales ocultas debido a la configuración de seguridad actual + + +pluginManager.link = Ir al gestor de plugins +configureSecurity.link = Configurar las advertencias mostradas diff --git a/core/src/main/resources/jenkins/security/UpdateSiteWarningsMonitor/message_fr.properties b/core/src/main/resources/jenkins/security/UpdateSiteWarningsMonitor/message_fr.properties new file mode 100644 index 000000000000..420ec0748090 --- /dev/null +++ b/core/src/main/resources/jenkins/security/UpdateSiteWarningsMonitor/message_fr.properties @@ -0,0 +1,31 @@ +# The MIT License +# +# Copyright (c) 2021, Jenkins project contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +pluginTitle = {0} {1} +coreTitle = Jenkins {0} logiciel et librairies + +blurb = Des avertissements ont t publis pour ces composants installs : +more = D'autres avertissements sont cachs en raison de la configuration actuelle de scurit. + + +pluginManager.link = Aller la gestion des plugins +configureSecurity.link = Configurer les avertissements affichs diff --git a/core/src/main/resources/jenkins/security/UpdateSiteWarningsMonitor/message_ko.properties b/core/src/main/resources/jenkins/security/UpdateSiteWarningsMonitor/message_ko.properties new file mode 100644 index 000000000000..8bc95d658530 --- /dev/null +++ b/core/src/main/resources/jenkins/security/UpdateSiteWarningsMonitor/message_ko.properties @@ -0,0 +1,31 @@ +# The MIT License +# +# Copyright (c) 2022, Jenkins project contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +pluginTitle = {0} {1} +coreTitle = Jenkins {0} core and libraries + +blurb = \uD604\uC7AC \uC124\uCE58\uB41C \uB2E4\uC74C \uAD6C\uC131 \uC694\uC18C\uC5D0 \uB300\uD55C \uACBD\uACE0\uAC00 \uAC8C\uC2DC\uB418\uC5C8\uC2B5\uB2C8\uB2E4: +more = \uD604\uC7AC \uBCF4\uC548 \uAD6C\uC131\uC5D0 \uC758\uD574 \uCD94\uAC00\uC801\uC778 \uACBD\uACE0\uAC00 \uC228\uACA8\uC84C\uC2B5\uB2C8\uB2E4 + + +pluginManager.link = \uD50C\uB7EC\uADF8\uC778 \uB9E4\uB2C8\uC800\uB85C \uC774\uB3D9 +configureSecurity.link = \uB2E4\uC74C \uACBD\uACE0 \uC911 \uD45C\uC2DC\uD560 \uACBD\uACE0 \uAD6C\uC131 diff --git a/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyConfiguration/config_pt_BR.properties b/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyConfiguration/config_pt_BR.properties new file mode 100644 index 000000000000..d53e184e3390 --- /dev/null +++ b/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyConfiguration/config_pt_BR.properties @@ -0,0 +1,26 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +creationOfLegacyTokenEnabled=Permite usu\u00E1rios criarem manualmente um passe de API legado (n\u00E3o recomendado) +API\ Token=Passe\ de\ API +tokenGenerationOnCreationEnabled=Cria um novo passe de API para cada novo usu\u00E1rio criado (n\u00E3o recomendado) +usageStatisticsEnabled=Habilita as estat\u00EDsticas de uso de passe de API diff --git a/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyConfiguration/config_zh_TW.properties b/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyConfiguration/config_zh_TW.properties new file mode 100644 index 000000000000..ace14f4f7312 --- /dev/null +++ b/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyConfiguration/config_zh_TW.properties @@ -0,0 +1,4 @@ +tokenGenerationOnCreationEnabled=\u70ba\u6240\u6709\u65b0\u5efa\u7acb\u7684\u4f7f\u7528\u8005\u7522\u751f Legacy API Token\uff08\u4e0d\u5efa\u8b70\uff09 +creationOfLegacyTokenEnabled=\u5141\u8a31\u4f7f\u7528\u8005\u624b\u52d5\u5efa\u7acb Legacy API Token\uff08\u4e0d\u5efa\u8b70\uff09 +usageStatisticsEnabled=\u555f\u7528 API Token \u4f7f\u7528\u60c5\u5f62\u7d71\u8a08 +API\ Token=API Token diff --git a/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyDisabledDefaultAdministrativeMonitor/description.jelly b/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyDisabledDefaultAdministrativeMonitor/description.jelly new file mode 100644 index 000000000000..bb405e931933 --- /dev/null +++ b/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyDisabledDefaultAdministrativeMonitor/description.jelly @@ -0,0 +1,4 @@ + + + ${%blurb} + diff --git a/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyDisabledDefaultAdministrativeMonitor/description.properties b/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyDisabledDefaultAdministrativeMonitor/description.properties new file mode 100644 index 000000000000..c3257e8a51c3 --- /dev/null +++ b/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyDisabledDefaultAdministrativeMonitor/description.properties @@ -0,0 +1 @@ +blurb = Warns administrators about the legacy behavior of automatically generating API tokens for new users. diff --git a/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyDisabledDefaultAdministrativeMonitor/description_pt_BR.properties b/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyDisabledDefaultAdministrativeMonitor/description_pt_BR.properties new file mode 100644 index 000000000000..81aa87ff5d46 --- /dev/null +++ b/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyDisabledDefaultAdministrativeMonitor/description_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +blurb=Avisa administradores sobre o compartamento legado de gera\u00E7\u00E3o de passes de API para novos usu\u00E1rios. diff --git a/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyDisabledDefaultAdministrativeMonitor/description_zh_TW.properties b/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyDisabledDefaultAdministrativeMonitor/description_zh_TW.properties new file mode 100644 index 000000000000..688df886e4eb --- /dev/null +++ b/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyDisabledDefaultAdministrativeMonitor/description_zh_TW.properties @@ -0,0 +1 @@ +blurb=\u8b66\u544a\u7ba1\u7406\u54e1\u6709\u95dc\u820a\u7248\u884c\u70ba\uff1a\u81ea\u52d5\u70ba\u65b0\u4f7f\u7528\u8005\u7522\u751f API Token\u3002 diff --git a/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyDisabledDefaultAdministrativeMonitor/message_pt_BR.properties b/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyDisabledDefaultAdministrativeMonitor/message_pt_BR.properties new file mode 100644 index 000000000000..76c468d81c49 --- /dev/null +++ b/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyDisabledDefaultAdministrativeMonitor/message_pt_BR.properties @@ -0,0 +1,28 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +warningMessage=Um passe de API legado ser\u00E1 gerado automaticamente para novos usu\u00E1rios criados.
      \ + Este comportamento \u00E9 suportado por raz\u00F5es de compatibilidade retroativa mas os passes de API legados est\u00E3o descontinuados e\ + n\u00E3o s\u00E3o recomendados para uso de longo termo.
      \ + Usu\u00E1rios deveriam gerar novos passes de API conforme necess\u00E1rio a partir da p\u00E1gina de configura\u00E7\u00E3o de usu\u00E1rio. +Dismiss=Dispensar +Disable\ automatic\ generation\ of\ legacy\ API\ tokens=Disabilitar\ gera\u00E7\u00E3o\ autom\u00E1tica\ de\ passes\ de\ API\ legados diff --git a/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyDisabledDefaultAdministrativeMonitor/message_zh_TW.properties b/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyDisabledDefaultAdministrativeMonitor/message_zh_TW.properties new file mode 100644 index 000000000000..e73c9d78a6c3 --- /dev/null +++ b/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyDisabledDefaultAdministrativeMonitor/message_zh_TW.properties @@ -0,0 +1,3 @@ +warningMessage=\u5c07\u6703\u81ea\u52d5\u70ba\u65b0\u5efa\u7acb\u7684\u4f7f\u7528\u8005\u7522\u751f Legacy API Token\u3002
      \u6b64\u884c\u70ba\u662f\u70ba\u4e86\u652f\u63f4\u5411\u4e0b\u76f8\u5bb9\uff0c\u4f46 Legacy API Token \u5df2\u88ab\u6368\u68c4\u4e14\u4e0d\u5efa\u8b70\u9577\u671f\u4f7f\u7528\u3002
      \u4f7f\u7528\u8005\u61c9\u8a72\u6539\u70ba\u6309\u9700\u7522\u751f\uff0c\u5230\u4f7f\u7528\u8005\u8a2d\u5b9a\u9801\u9762\u7522\u751f API Token\u3002 +Disable\ automatic\ generation\ of\ legacy\ API\ tokens=\u505c\u7528\u81ea\u52d5\u7522\u751f Legacy API Token +Dismiss=\u4e0d\u7ba1 diff --git a/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyEnabledNewLegacyAdministrativeMonitor/description.jelly b/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyEnabledNewLegacyAdministrativeMonitor/description.jelly new file mode 100644 index 000000000000..bb405e931933 --- /dev/null +++ b/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyEnabledNewLegacyAdministrativeMonitor/description.jelly @@ -0,0 +1,4 @@ + + + ${%blurb} + diff --git a/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyEnabledNewLegacyAdministrativeMonitor/description.properties b/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyEnabledNewLegacyAdministrativeMonitor/description.properties new file mode 100644 index 000000000000..9d032c6fb748 --- /dev/null +++ b/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyEnabledNewLegacyAdministrativeMonitor/description.properties @@ -0,0 +1 @@ +blurb = Warns administrators about the legacy behavior of allowing users to generate new legacy API tokens. diff --git a/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyEnabledNewLegacyAdministrativeMonitor/description_pt_BR.properties b/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyEnabledNewLegacyAdministrativeMonitor/description_pt_BR.properties new file mode 100644 index 000000000000..9d570f54609a --- /dev/null +++ b/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyEnabledNewLegacyAdministrativeMonitor/description_pt_BR.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +blurb = Avisa administradores sobre o comportamento legado de permitir usu\u00E1rios de gerar novos passes de API legados. + diff --git a/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyEnabledNewLegacyAdministrativeMonitor/description_zh_TW.properties b/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyEnabledNewLegacyAdministrativeMonitor/description_zh_TW.properties new file mode 100644 index 000000000000..7734f8d7c4be --- /dev/null +++ b/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyEnabledNewLegacyAdministrativeMonitor/description_zh_TW.properties @@ -0,0 +1 @@ +blurb=\u8b66\u544a\u7ba1\u7406\u54e1\u6709\u95dc\u820a\u7248\u884c\u70ba\uff1a\u5141\u8a31\u4f7f\u7528\u8005\u5efa\u7acb Legacy API Token\u3002 diff --git a/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyEnabledNewLegacyAdministrativeMonitor/message_pt_BR.properties b/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyEnabledNewLegacyAdministrativeMonitor/message_pt_BR.properties new file mode 100644 index 000000000000..9dfdafb8d8f7 --- /dev/null +++ b/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyEnabledNewLegacyAdministrativeMonitor/message_pt_BR.properties @@ -0,0 +1,27 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +warningMessage=Usu\u00E1rios sem passes de API legados podem gerar um novo passe legado.
      \ +Este comportamento \u00E9 suportado por compatibilidade retroativa, mas os passes de API legados est\u00E3o descontinuados e \ +n\u00E3o s\u00E3o recomendados para uso de longo termo.
      \ +Usu\u00E1rios deveriam, pelo contr\u00E1rio, gerar passes de API conforme necess\u00E1rio da p\u00E1gina de configura\u00E7\u00E3o do usu\u00E1rio. +Dismiss=Dispensar +Prevent\ users\ from\ manually\ creating\ legacy\ API\ tokens=Previne\ usu\u00E1rios\ de\ manualmente\ criar\ passes\ de\ API\ legados diff --git a/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyEnabledNewLegacyAdministrativeMonitor/message_zh_TW.properties b/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyEnabledNewLegacyAdministrativeMonitor/message_zh_TW.properties new file mode 100644 index 000000000000..391d7f79d235 --- /dev/null +++ b/core/src/main/resources/jenkins/security/apitoken/ApiTokenPropertyEnabledNewLegacyAdministrativeMonitor/message_zh_TW.properties @@ -0,0 +1,3 @@ +warningMessage=\u6c92\u6709 Legacy API Token \u7684\u4f7f\u7528\u8005\u53ef\u4ee5\u7522\u751f\u65b0 Legacy Token\u3002
      \u6b64\u884c\u70ba\u662f\u70ba\u4e86\u652f\u63f4\u5411\u4e0b\u76f8\u5bb9\uff0c\u4f46 Legacy API Token \u5df2\u88ab\u6368\u68c4\u4e14\u4e0d\u5efa\u8b70\u9577\u671f\u4f7f\u7528\u3002
      \u4f7f\u7528\u8005\u61c9\u8a72\u6539\u70ba\u6309\u9700\u7522\u751f\uff0c\u5230\u4f7f\u7528\u8005\u8a2d\u5b9a\u9801\u9762\u7522\u751f API Token\u3002 +Prevent\ users\ from\ manually\ creating\ legacy\ API\ tokens=\u9632\u6b62\u4f7f\u7528\u8005\u624b\u52d5\u5efa\u7acb Legacy API Token +Dismiss=\u4e0d\u7ba1 diff --git a/core/src/main/resources/jenkins/security/apitoken/LegacyApiTokenAdministrativeMonitor/description.jelly b/core/src/main/resources/jenkins/security/apitoken/LegacyApiTokenAdministrativeMonitor/description.jelly new file mode 100644 index 000000000000..bb405e931933 --- /dev/null +++ b/core/src/main/resources/jenkins/security/apitoken/LegacyApiTokenAdministrativeMonitor/description.jelly @@ -0,0 +1,4 @@ + + + ${%blurb} + diff --git a/core/src/main/resources/jenkins/security/apitoken/LegacyApiTokenAdministrativeMonitor/description.properties b/core/src/main/resources/jenkins/security/apitoken/LegacyApiTokenAdministrativeMonitor/description.properties new file mode 100644 index 000000000000..6ea38444ebaa --- /dev/null +++ b/core/src/main/resources/jenkins/security/apitoken/LegacyApiTokenAdministrativeMonitor/description.properties @@ -0,0 +1 @@ +blurb = Warns administrators about the presence of legacy API tokens in the configuration of some users. diff --git a/core/src/main/resources/jenkins/security/apitoken/LegacyApiTokenAdministrativeMonitor/description_pt_BR.properties b/core/src/main/resources/jenkins/security/apitoken/LegacyApiTokenAdministrativeMonitor/description_pt_BR.properties new file mode 100644 index 000000000000..03f18529ac2e --- /dev/null +++ b/core/src/main/resources/jenkins/security/apitoken/LegacyApiTokenAdministrativeMonitor/description_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +blurb=Avisa administradores sobre a presen\u00E7a de passes de API legados na configura\u00E7\u00E3o de alguns usu\u00E1rios. diff --git a/core/src/main/resources/jenkins/security/apitoken/LegacyApiTokenAdministrativeMonitor/description_zh_TW.properties b/core/src/main/resources/jenkins/security/apitoken/LegacyApiTokenAdministrativeMonitor/description_zh_TW.properties new file mode 100644 index 000000000000..977c57954827 --- /dev/null +++ b/core/src/main/resources/jenkins/security/apitoken/LegacyApiTokenAdministrativeMonitor/description_zh_TW.properties @@ -0,0 +1 @@ +blurb=\u8b66\u544a\u7ba1\u7406\u54e1\u6709\u95dc\u67d0\u4e9b\u4f7f\u7528\u8005\u555f\u7528\u4e86 Legacy API Token\u3002 diff --git a/core/src/main/resources/jenkins/security/apitoken/LegacyApiTokenAdministrativeMonitor/manage.jelly b/core/src/main/resources/jenkins/security/apitoken/LegacyApiTokenAdministrativeMonitor/manage.jelly index 7ec991bf06c2..5e74af918294 100644 --- a/core/src/main/resources/jenkins/security/apitoken/LegacyApiTokenAdministrativeMonitor/manage.jelly +++ b/core/src/main/resources/jenkins/security/apitoken/LegacyApiTokenAdministrativeMonitor/manage.jelly @@ -35,7 +35,8 @@ THE SOFTWARE.

      ${%recommendationMessage}

      -
      +
      + @@ -53,6 +54,7 @@ THE SOFTWARE. + diff --git a/core/src/main/resources/jenkins/security/apitoken/LegacyApiTokenAdministrativeMonitor/manage_pt_BR.properties b/core/src/main/resources/jenkins/security/apitoken/LegacyApiTokenAdministrativeMonitor/manage_pt_BR.properties new file mode 100644 index 000000000000..c995a42116b4 --- /dev/null +++ b/core/src/main/resources/jenkins/security/apitoken/LegacyApiTokenAdministrativeMonitor/manage_pt_BR.properties @@ -0,0 +1,69 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Recently\ used\ token=Passe recentemente usado +NoLastUse=N\u00E3o h\u00E1 uma data de \u00FAltimo uso para este passe +RevokeAllSelected=Revogar o(s) passe(s) selecionados +HasMoreRecentlyUsedToken_warning_tooltip=Nenhum passe recente existe para este usu\u00E1rio +HasFreshToken=O passe \u00E9 recente? +No\ recently\ used\ token=Nenhum passe recentemente usado +RevokeAllSelected_nothing=Nenhum passe est\u00E1 selecionado, por favor selecione pelo menos um para revogar +HasFreshToken_warning_tooltip=Nenhum passe recente existe para este usu\u00E1rio +RevokeAllSelected_confirm=Voc\u00EA tem certeza que quer revogar todos os %num% passes selecionado(s) +UserFullName=Nome completo do usu\u00E1rio +only\ recent=somente recentes +Fresh\ token=Atualizar passe +all=tudo +UserId=ID do usu\u00E1rio +Select=Selecionar +HasMoreRecentlyUsedToken_tooltip=Um passe recentemente usado foi criado usando o novo sistema \ +e usado mais recentemente que o passe legado do usuário. \n\ +Nota: a data da cria\u00E7\u00E3o do passe legado que nunca foram usuados s\u00E3o toda vez que o Jenkins \u00E9 reiniciado, \ +o que significa que a data pode não ser precisa. +title=Gerenciar uso de passes de API legados +NoImpactedUser=N\u00E3o h\u00E1 usu\u00E1rios com passes legados +TokenName=Nome do passe +No\ fresh\ token=Nenhum passe recente +HasMoreRecentlyUsedToken=H\u00E1 passe mais recente? +HasFreshToken_ok_tooltip=Um passe recente existe para este usu\u00E1rio +HasMoreRecentlyUsedToken_ok_tooltip=Um passe mais recente existe para este usu\u00E1rio +NumOfUse=# de usos +NoCreationDate=N\u00E3o h\u00E1 data de cria\u00E7\u00E3o para este passe +NoCreationDateValue=Desconhecido +recommendationMessage=Por tais raz\u00F5es, n\u00F3s recomendados a voc\u00EA: \ +
        \ +
      • revogar os passes que nunca foram usados
      • \ +
      • pe\u00E7a aos usu\u00E1rios que est\u00E3o usando passes legados para gerarem um passe usando o novo sistema e revogar seus passes legados
      • \ +
      +NoLastUseValue=Nunca usado +only\ fresh=somente\ recente +contextMessage=Os seguintes usu\u00E1rios tem um passe legado. \ +Uma vez que passes legados s\u00E3o armazenados em um formato recuper\u00E1vel, n\u00F3s recomendados migrar para o novo sistema de passes de API. \ +Adicionalmente, em vers\u00F5es anteriores do Jenkins, passes de API vers\u00F5es automaticamente criados para cada novo usu\u00E1rio. \ +Frequentemente, esses usu\u00E1rios n\u00E3o usam o passe, resultando em uma larga superf\u00EDcie de ataque que o necess\u00E1rio. \ +A cria\u00E7\u00E3o automática de passes precisa ser habilitada explicitamente. +NumDaysSinceLastUse=Dias desde o \u00FAltimo uso +HasFreshToken_tooltip=Um passe recente \u00E9 um que foi criado com o novo sistema \ +depois do uso recente de um passe legado do usu\u00E1rio. \n\ +Nota: toda vez que o Jenkins \u00E9 reiniciado as datas de cria\u00E7\u00E3o the passes n\u00E3o utilizados s\u00E3o reiniciados \ +o que significa que as datas desses passes n\u00E3o precisas. +NumDaysSinceCreation=Dias desde a cria\u00E7\u00E3o diff --git a/core/src/main/resources/jenkins/security/apitoken/LegacyApiTokenAdministrativeMonitor/manage_zh_TW.properties b/core/src/main/resources/jenkins/security/apitoken/LegacyApiTokenAdministrativeMonitor/manage_zh_TW.properties new file mode 100644 index 000000000000..b4618c740ecf --- /dev/null +++ b/core/src/main/resources/jenkins/security/apitoken/LegacyApiTokenAdministrativeMonitor/manage_zh_TW.properties @@ -0,0 +1,35 @@ +title=\u7ba1\u7406 Legacy API Token \u4f7f\u7528\u60c5\u5f62 +contextMessage=\u4e0b\u5217\u4f7f\u7528\u8005\u64c1\u6709 Legacy API Token\u3002\u56e0\u70ba Legacy API Token \u5b58\u653e\u65bc\u53ef\u9084\u539f\u7684\u683c\u5f0f\uff0c\u6211\u5011\u5efa\u8b70\u9077\u79fb\u5230\u65b0 API Token \u7cfb\u7d71\u3002\u9644\u52a0\u8aaa\u660e\uff1a\u820a\u7248\u7684 Jenkins \u6703\u81ea\u52d5\u70ba\u6240\u6709\u65b0\u4f7f\u7528\u8005\u7522\u751f API Token\u3002\u4f7f\u7528\u8005\u901a\u5e38\u4e0d\u6703\u4f7f\u7528\u8a72 Token\uff0c\u9019\u7522\u751f\u4e86\u4e0d\u5fc5\u8981\u7684\u5de8\u5927\u653b\u64ca\u9762\u3002\u73fe\u5728\u5fc5\u9808\u660e\u78ba\u7684\u555f\u7528\u81ea\u52d5\u7522\u751f Token\u3002 +recommendationMessage=\u57fa\u65bc\u4e0a\u8ff0\u7406\u7531\uff0c\u6211\u5011\u5efa\u8b70\u60a8\uff1a
      • \u64a4\u92b7\u5f9e\u672a\u4f7f\u7528\u7684 Token
      • \u8981\u6c42\u6b63\u5728\u4f7f\u7528 Legacy Token \u7684\u4f7f\u7528\u8005\u4ee5\u65b0\u7cfb\u7d71\u7522\u751f Token \u4e26\u64a4\u92b7\u4ed6\u5011\u7684 Legacy Token
      +UserId=\u4f7f\u7528\u8005 ID +UserFullName=\u4f7f\u7528\u8005\u5168\u540d +TokenName=Token \u540d\u7a31 +NumDaysSinceCreation=\u5efa\u7acb\u5929\u6578 +NumOfUse=\u4f7f\u7528\u6b21\u6578 +NumDaysSinceLastUse=\u8ddd\u6700\u5f8c\u4f7f\u7528\u5929\u6578 +HasFreshToken=\u65b0\u9bae\u7684 Token? +HasFreshToken_tooltip=\u65b0\u9bae\u7684 Token \u662f\u6307\uff1a\u4ee5\u65b0\u7cfb\u7d71\u5efa\u7acb\u7684\uff0c\u4e14\u7522\u751f\u65bc\u4f7f\u7528\u8005\u6700\u8fd1\u4f7f\u7528\u7684 Legacy Token \u4e4b\u5f8c\u3002\n\ +\u5099\u8a3b\uff1aJenkins \u6bcf\u6b21\u91cd\u65b0\u555f\u52d5\u5f8c\uff0c\u672a\u4f7f\u7528\u7684 Legacy Token \u7684\u5efa\u7acb\u65e5\u671f\u6703\u88ab\u91cd\u8a2d\uff0c\u9019\u8868\u793a\u90a3\u4e9b Token \u7684\u5efa\u7acb\u65e5\u671f\u662f\u4e0d\u6e96\u78ba\u7684\u3002 +HasFreshToken_ok_tooltip=\u8a72\u4f7f\u7528\u8005\u6709\u65b0\u9bae\u7684 Token +HasFreshToken_warning_tooltip=\u8a72\u4f7f\u7528\u8005\u6c92\u6709\u65b0\u9bae\u7684 Token +HasMoreRecentlyUsedToken=\u6700\u8fd1\u7684 Token\uff1f +HasMoreRecentlyUsedToken_tooltip=\u6700\u8fd1\u4f7f\u7528\u7684 Token \u662f\u6307\uff1a\u4ee5\u65b0\u7cfb\u7d71\u5efa\u7acb\u7684\uff0c\u4e14\u6bd4\u4f7f\u7528\u8005\u7684\u6700\u8fd1\u4f7f\u7528\u7684 Legacy Token \u9084\u8981\u665a\u6709\u4f7f\u7528\u904e\u7684\u3002\n\ +\u5099\u8a3b\uff1aJenkins \u6bcf\u6b21\u91cd\u65b0\u555f\u52d5\u5f8c\uff0c\u672a\u4f7f\u7528\u7684 Legacy Token \u7684\u5efa\u7acb\u65e5\u671f\u6703\u88ab\u91cd\u8a2d\uff0c\u9019\u8868\u793a\u90a3\u4e9b Token \u7684\u5efa\u7acb\u65e5\u671f\u662f\u4e0d\u6e96\u78ba\u7684\u3002 +HasMoreRecentlyUsedToken_ok_tooltip=\u8a72\u4f7f\u7528\u8005\u6709\u6700\u8fd1\u7528\u904e\u7684 Token +HasMoreRecentlyUsedToken_warning_tooltip=\u8a72\u4f7f\u7528\u8005\u6c92\u6709\u6700\u8fd1\u7528\u904e\u7684 Token +NoImpactedUser=\u6c92\u6709\u4f7f\u7528\u8005\u6709 Legacy Token +NoCreationDate=\u8a72 Token \u6c92\u6709\u5efa\u7acb\u65e5\u671f +NoCreationDateValue=\u672a\u77e5 +NoLastUse=\u8a72 Token \u6c92\u6709\u6700\u5f8c\u4f7f\u7528\u65e5\u671f +NoLastUseValue=\u5f9e\u672a\u4f7f\u7528 +RevokeAllSelected=\u64a4\u92b7\u9078\u53d6\u7684 Token +RevokeAllSelected_confirm=\u60a8\u78ba\u5b9a\u8981\u64a4\u92b7\u9078\u53d6\u7684 %num% \u500b Token \u55ce +RevokeAllSelected_nothing=\u672a\u9078\u53d6 Token\uff0c\u8acb\u9078\u53d6\u81f3\u5c11\u4e00\u500b Token \u4f86\u64a4\u92b7 +Fresh\ token=\u65b0\u9bae\u7684 Token +all=\u5168\u90e8 +Recently\ used\ token=\u6700\u8fd1\u7528\u904e\u7684 Token +No\ fresh\ token=\u6c92\u6709\u65b0\u9bae\u7684 Token +only\ recent=\u53ea\u9078\u6700\u8fd1 +only\ fresh=\u53ea\u9078\u65b0\u9bae +Select=\u9078\u53d6 +No\ recently\ used\ token=\u6c92\u6709\u6700\u8fd1\u7528\u904e\u7684 Token diff --git a/core/src/main/resources/jenkins/security/apitoken/LegacyApiTokenAdministrativeMonitor/message_pt_BR.properties b/core/src/main/resources/jenkins/security/apitoken/LegacyApiTokenAdministrativeMonitor/message_pt_BR.properties new file mode 100644 index 000000000000..e66b83d243be --- /dev/null +++ b/core/src/main/resources/jenkins/security/apitoken/LegacyApiTokenAdministrativeMonitor/message_pt_BR.properties @@ -0,0 +1,25 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +warningMessage=Ainda existem usu\u00E1rios que est\u00E3o usando os passes de API legados. \ + Este sistema n\u00E3o \u00E9 t\u00E3o seguro quanto o novo porque ele armazena o passe em disco de uma forma recuper\u00E1vel.
      \ + Veja a lista de usu\u00E1rios impactados. diff --git a/core/src/main/resources/jenkins/security/apitoken/LegacyApiTokenAdministrativeMonitor/message_zh_TW.properties b/core/src/main/resources/jenkins/security/apitoken/LegacyApiTokenAdministrativeMonitor/message_zh_TW.properties new file mode 100644 index 000000000000..efc884e860f7 --- /dev/null +++ b/core/src/main/resources/jenkins/security/apitoken/LegacyApiTokenAdministrativeMonitor/message_zh_TW.properties @@ -0,0 +1 @@ +warningMessage=\u6709\u4f7f\u7528\u8005\u9084\u5728\u7528 Legacy API Token\u3002\u8a72\u7cfb\u7d71\u4e0d\u82e5\u65b0\u7684\u5b89\u5168\uff0c\u56e0\u70ba\u5b83\u5c07 Token \u4ee5\u53ef\u9084\u539f\u7684\u65b9\u5f0f\u5b58\u653e\u78c1\u789f\u4e0a\u3002
      \u8acb\u53c3\u898b\u53d7\u5f71\u97ff\u7684\u4f7f\u7528\u8005\u6e05\u55ae\u3002 diff --git a/core/src/main/resources/jenkins/security/apitoken/LegacyApiTokenAdministrativeMonitor/resources.css b/core/src/main/resources/jenkins/security/apitoken/LegacyApiTokenAdministrativeMonitor/resources.css index b1c66b8394a9..1c1ffa94ea56 100644 --- a/core/src/main/resources/jenkins/security/apitoken/LegacyApiTokenAdministrativeMonitor/resources.css +++ b/core/src/main/resources/jenkins/security/apitoken/LegacyApiTokenAdministrativeMonitor/resources.css @@ -21,10 +21,6 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -.legacy-token-usage table.align-th-left th { - text-align: left; -} - .legacy-token-usage table .no-token { padding: 8px 12px; font-style: italic; @@ -53,4 +49,4 @@ .legacy-token-usage .action-panel{ margin-top: 8px; -} \ No newline at end of file +} diff --git a/core/src/main/resources/jenkins/security/apitoken/Messages_pt_BR.properties b/core/src/main/resources/jenkins/security/apitoken/Messages_pt_BR.properties new file mode 100644 index 000000000000..544c53eeaeec --- /dev/null +++ b/core/src/main/resources/jenkins/security/apitoken/Messages_pt_BR.properties @@ -0,0 +1,25 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +LegacyApiTokenAdministrativeMonitor.displayName=Uso de passe de API legado +ApiTokenPropertyDisabledDefaultAdministrativeMonitor.displayName=Passe de API legado n\u00E3o \u00E9 gerado por padr\u00E3o +ApiTokenPropertyEnabledNewLegacyAdministrativeMonitor.displayName=Passe de API legado pode ser criado ainda que n\u00E3o exista diff --git a/core/src/main/resources/jenkins/security/apitoken/Messages_zh_TW.properties b/core/src/main/resources/jenkins/security/apitoken/Messages_zh_TW.properties new file mode 100644 index 000000000000..578238a87288 --- /dev/null +++ b/core/src/main/resources/jenkins/security/apitoken/Messages_zh_TW.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Copyright (c) 2018, CloudBees, Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +ApiTokenPropertyDisabledDefaultAdministrativeMonitor.displayName=\u9810\u8a2d\u4e0d\u6703\u7522\u751f Legacy API Token +ApiTokenPropertyEnabledNewLegacyAdministrativeMonitor.displayName=\u5373\u4f7f Legacy API Token \u4e0d\u5b58\u5728\u4e5f\u53ef\u4ee5\u5efa\u7acb +LegacyApiTokenAdministrativeMonitor.displayName=Legacy API Token \u4f7f\u7528\u60c5\u5f62 diff --git a/core/src/main/resources/jenkins/security/csrf/CSRFAdministrativeMonitor/description.jelly b/core/src/main/resources/jenkins/security/csrf/CSRFAdministrativeMonitor/description.jelly new file mode 100644 index 000000000000..bb405e931933 --- /dev/null +++ b/core/src/main/resources/jenkins/security/csrf/CSRFAdministrativeMonitor/description.jelly @@ -0,0 +1,4 @@ + + + ${%blurb} + diff --git a/core/src/main/resources/jenkins/security/csrf/CSRFAdministrativeMonitor/description.properties b/core/src/main/resources/jenkins/security/csrf/CSRFAdministrativeMonitor/description.properties new file mode 100644 index 000000000000..43166a50f295 --- /dev/null +++ b/core/src/main/resources/jenkins/security/csrf/CSRFAdministrativeMonitor/description.properties @@ -0,0 +1 @@ +blurb = Warns about disabled CSRF protection. diff --git a/core/src/main/resources/jenkins/security/csrf/CSRFAdministrativeMonitor/description_pt_BR.properties b/core/src/main/resources/jenkins/security/csrf/CSRFAdministrativeMonitor/description_pt_BR.properties new file mode 100644 index 000000000000..f1248d2b8cd1 --- /dev/null +++ b/core/src/main/resources/jenkins/security/csrf/CSRFAdministrativeMonitor/description_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +blurb=Avisa sobre desabilitar aprote\u00E7\u00E3o de CSRF. diff --git a/core/src/main/resources/jenkins/security/csrf/CSRFAdministrativeMonitor/description_zh_TW.properties b/core/src/main/resources/jenkins/security/csrf/CSRFAdministrativeMonitor/description_zh_TW.properties new file mode 100644 index 000000000000..b4dc9311c64b --- /dev/null +++ b/core/src/main/resources/jenkins/security/csrf/CSRFAdministrativeMonitor/description_zh_TW.properties @@ -0,0 +1 @@ +blurb=\u8b66\u544a\u95dc\u65bc\u505c\u7528 CSRF \u9632\u8b77\u3002 diff --git a/core/src/main/resources/jenkins/security/csrf/CSRFAdministrativeMonitor/message.jelly b/core/src/main/resources/jenkins/security/csrf/CSRFAdministrativeMonitor/message.jelly index a2eaeddc2f33..14df02a36328 100644 --- a/core/src/main/resources/jenkins/security/csrf/CSRFAdministrativeMonitor/message.jelly +++ b/core/src/main/resources/jenkins/security/csrf/CSRFAdministrativeMonitor/message.jelly @@ -28,7 +28,7 @@ THE SOFTWARE. - ${%referenceUrlContent} + ${%referenceUrlContent} ${%actionUrlContent} diff --git a/core/src/main/resources/jenkins/security/csrf/CSRFAdministrativeMonitor/message_pt_BR.properties b/core/src/main/resources/jenkins/security/csrf/CSRFAdministrativeMonitor/message_pt_BR.properties new file mode 100644 index 000000000000..2ac25244d08f --- /dev/null +++ b/core/src/main/resources/jenkins/security/csrf/CSRFAdministrativeMonitor/message_pt_BR.properties @@ -0,0 +1,28 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +warningMessage=Voc\u00EA n\u00E3o configurou um emissor CSRF. Isto pode ser um problema de seguran\u00E7a. \ +Para mais informa\u00E7\u00F5es, por favor refira-se a {0}. +actionMessage=Voc\u00EA pode mudar a configura\u00E7\u00E3o atual usando a se\u00E7\u00E3o de Seguran\u00E7a {0}. +referenceUrlContent=esta p\u00E1gina +actionUrlContent=Prote\u00E7\u00E3o de CSRF +Dismiss=Dispensar diff --git a/core/src/main/resources/jenkins/security/csrf/CSRFAdministrativeMonitor/message_zh_TW.properties b/core/src/main/resources/jenkins/security/csrf/CSRFAdministrativeMonitor/message_zh_TW.properties new file mode 100644 index 000000000000..d4b41a63bf6e --- /dev/null +++ b/core/src/main/resources/jenkins/security/csrf/CSRFAdministrativeMonitor/message_zh_TW.properties @@ -0,0 +1,5 @@ +warningMessage=\u60a8\u5c1a\u672a\u8a2d\u5b9a CSRF \u7c3d\u767c\u8005\u3002\u9019\u53ef\u80fd\u9020\u6210\u5b89\u5168\u6027\u554f\u984c\u3002\u66f4\u591a\u8cc7\u8a0a\u8acb\u53c3\u8003{0}\u3002 +actionMessage=\u60a8\u53ef\u4ee5\u5230\u5b89\u5168\u6027\u8a2d\u5b9a {0}\u8b8a\u66f4\u76ee\u524d\u7684\u8a2d\u5b9a\u3002 +referenceUrlContent=\u6b64\u9801\u9762 +actionUrlContent=CSRF \u9632\u8b77 +Dismiss=\u4e0d\u7ba1 diff --git a/core/src/main/resources/jenkins/security/csrf/Messages_pt_BR.properties b/core/src/main/resources/jenkins/security/csrf/Messages_pt_BR.properties new file mode 100644 index 000000000000..d9cfa3e97be0 --- /dev/null +++ b/core/src/main/resources/jenkins/security/csrf/Messages_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +CSRFAdministrativeMonitor.displayName=Monitor de prote\u00E7\u00E3o de CSRF diff --git a/core/src/main/resources/jenkins/security/csrf/Messages_zh_TW.properties b/core/src/main/resources/jenkins/security/csrf/Messages_zh_TW.properties new file mode 100644 index 000000000000..042ec3cb009d --- /dev/null +++ b/core/src/main/resources/jenkins/security/csrf/Messages_zh_TW.properties @@ -0,0 +1 @@ +CSRFAdministrativeMonitor.displayName=CSRF \u9632\u8b77\u76e3\u8996\u5668 diff --git a/core/src/main/resources/jenkins/security/s2m/AdminCallableMonitor/description.jelly b/core/src/main/resources/jenkins/security/s2m/AdminCallableMonitor/description.jelly new file mode 100644 index 000000000000..bb405e931933 --- /dev/null +++ b/core/src/main/resources/jenkins/security/s2m/AdminCallableMonitor/description.jelly @@ -0,0 +1,4 @@ + + + ${%blurb} + diff --git a/core/src/main/resources/jenkins/security/s2m/AdminCallableMonitor/description.properties b/core/src/main/resources/jenkins/security/s2m/AdminCallableMonitor/description.properties new file mode 100644 index 000000000000..8676abab2277 --- /dev/null +++ b/core/src/main/resources/jenkins/security/s2m/AdminCallableMonitor/description.properties @@ -0,0 +1,3 @@ +blurb = An agent attempted to send a message to the controller for execution, but agent-to-controller access control rejected it. \ + This lets administrators review the message type and approve it. +# TODO I am fairly sure this never triggers, but https://github.com/jenkinsci/jenkins/pull/5885 will hopefully remove this soon anyway. diff --git a/core/src/main/resources/jenkins/security/s2m/AdminCallableMonitor/description_pt_BR.properties b/core/src/main/resources/jenkins/security/s2m/AdminCallableMonitor/description_pt_BR.properties new file mode 100644 index 000000000000..7dacaf9399c8 --- /dev/null +++ b/core/src/main/resources/jenkins/security/s2m/AdminCallableMonitor/description_pt_BR.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +blurb=Um agente tentou enviar uma mensagem para o controlador em execu\u00E7\u00E3o, mas o controle de acesso do agente para o controlador rejeitou-a. \ +Isto permite que os administradores revisem o tipo de mensagem e aprovem-a. diff --git a/core/src/main/resources/jenkins/security/s2m/AdminCallableMonitor/message.jelly b/core/src/main/resources/jenkins/security/s2m/AdminCallableMonitor/message.jelly deleted file mode 100644 index f599db7a1b31..000000000000 --- a/core/src/main/resources/jenkins/security/s2m/AdminCallableMonitor/message.jelly +++ /dev/null @@ -1,34 +0,0 @@ - - - - -
      -
      - - - - ${%blurb} -
      -
      diff --git a/core/src/main/resources/jenkins/security/s2m/AdminCallableMonitor/message.properties b/core/src/main/resources/jenkins/security/s2m/AdminCallableMonitor/message.properties deleted file mode 100644 index 89d5bfb1799b..000000000000 --- a/core/src/main/resources/jenkins/security/s2m/AdminCallableMonitor/message.properties +++ /dev/null @@ -1,2 +0,0 @@ -blurb=Jenkins has rejected some commands from agents, because we are unsure if it is open for agents to execute, \ - but this rejection has probably broken some builds. You should examine the situation to see if they should be whitelisted. diff --git a/core/src/main/resources/jenkins/security/s2m/AdminCallableMonitor/message_bg.properties b/core/src/main/resources/jenkins/security/s2m/AdminCallableMonitor/message_bg.properties deleted file mode 100644 index 190c24f3282b..000000000000 --- a/core/src/main/resources/jenkins/security/s2m/AdminCallableMonitor/message_bg.properties +++ /dev/null @@ -1,32 +0,0 @@ -# The MIT License -# -# Bulgarian translation: Copyright (c) 2016, Alexander Shopov -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Dismiss=\ - \u041e\u0442\u043a\u0430\u0437 -# Jenkins has rejected some commands from agents, because we are unsure if it is open for agents to execute, \ -# but this rejection has probably broken some builds. You should examine the situation to see if they should be whitelisted. -blurb=\ - Jenkins \u043e\u0442\u0445\u0432\u044a\u0440\u043b\u0438 \u0447\u0430\u0441\u0442 \u043e\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u0438\u0442\u0435 \u043e\u0442 \u0430\u0433\u0435\u043d\u0442\u0438\u0442\u0435, \u0437\u0430\u0449\u043e\u0442\u043e \u043d\u0435 \u0435 \u044f\u0441\u043d\u043e \u0434\u0430\u043b\u0438 \u043c\u043e\u0436\u0435 \u0434\u0430\ - \u0433\u0438 \u043f\u0440\u0438\u0435\u043c\u0430. \u0412\u044a\u0437\u043c\u043e\u0436\u043d\u043e \u0435 \u0442\u043e\u0432\u0430 \u0434\u0430 \u0435 \u0441\u0447\u0443\u043f\u0438\u043b\u043e \u0447\u0430\u0441\u0442 \u043e\u0442 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f\u0442\u0430. \u041f\u0440\u0435\u0433\u043b\u0435\u0434\u0430\u0439\u0442\u0435 \u0433\u0438,\ - \u0437\u0430 \u0434\u0430 \u0440\u0435\u0448\u0438\u0442\u0435 \u0434\u0430\u043b\u0438 \u0438\u0437\u0440\u0438\u0447\u043d\u043e \u0434\u0430 \u043d\u0435 \u0433\u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442\u0435. -Examine=\ - \u041f\u0440\u0435\u0433\u043b\u0435\u0434 diff --git a/core/src/main/resources/jenkins/security/s2m/AdminCallableMonitor/message_de.properties b/core/src/main/resources/jenkins/security/s2m/AdminCallableMonitor/message_de.properties deleted file mode 100644 index dd2a59ad1aee..000000000000 --- a/core/src/main/resources/jenkins/security/s2m/AdminCallableMonitor/message_de.properties +++ /dev/null @@ -1,26 +0,0 @@ -# The MIT License -# -# Copyright (c) 2017 Daniel Beck and a number of other of contributors -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Dismiss=Schlie\u00DFen -Examine=Pr\u00FCfen -blurb=Jenkins hat Befehle von Agenten aufgrund der aktuellen Einstellungen abgelehnt. Dadurch sind vermutlich Builds fehlgeschlagen. \ - Es wird empfohlen, die Situation zu pr\u00FCfen, und die abgelehnten Befehle ggf. in die Positivliste aufzunehmen. diff --git a/core/src/main/resources/jenkins/security/s2m/AdminCallableMonitor/message_it.properties b/core/src/main/resources/jenkins/security/s2m/AdminCallableMonitor/message_it.properties deleted file mode 100644 index 1c88cf915c28..000000000000 --- a/core/src/main/resources/jenkins/security/s2m/AdminCallableMonitor/message_it.properties +++ /dev/null @@ -1,29 +0,0 @@ -# The MIT License -# -# Italian localization plugin for Jenkins -# Copyright 2020 Alessandro Menti -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -blurb=Jenkins ha rifiutato alcuni comandi dagli agenti perch non certo \ - che siano liberamente eseguibili da questi, ma tale rifiuto probabilmente \ - ha mandato in errore alcune compilazioni. Si dovrebbe esaminare la \ - situazione per verificare se sia possibile aggiungerli alla whitelist. -Dismiss=Nascondi -Examine=Esamina diff --git a/core/src/main/resources/jenkins/security/s2m/AdminCallableMonitor/message_pt_BR.properties b/core/src/main/resources/jenkins/security/s2m/AdminCallableMonitor/message_pt_BR.properties deleted file mode 100644 index 25a215256fc0..000000000000 --- a/core/src/main/resources/jenkins/security/s2m/AdminCallableMonitor/message_pt_BR.properties +++ /dev/null @@ -1,24 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributers -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Examine= -Dismiss= diff --git a/core/src/main/resources/jenkins/security/s2m/AdminCallableMonitor/message_sr.properties b/core/src/main/resources/jenkins/security/s2m/AdminCallableMonitor/message_sr.properties deleted file mode 100644 index e2deed27ee89..000000000000 --- a/core/src/main/resources/jenkins/security/s2m/AdminCallableMonitor/message_sr.properties +++ /dev/null @@ -1,6 +0,0 @@ -# This file is under the MIT License by authors - -Examine=\u041F\u0440\u0435\u0433\u043B\u0435\u0434\u0430\u0458 -Dismiss=\u041E\u0442\u043A\u0430\u0436\u0438 -blurb=Jenkins \u0458\u0435 \u043E\u0434\u0431\u0438\u0458\u043E \u043D\u0435\u043A\u0435 \u0430\u0433\u0435\u043D\u0442\u043E\u0432\u0435 \u043A\u043E\u043C\u0430\u043D\u0434\u0435, \u0437\u0430\u0448\u0442\u043E \u043D\u0438\u0458\u0435 \u0458\u0430\u0441\u043D\u043E \u0430\u043A\u043E \u0458\u0435 \u0434\u043E\u0437\u0432\u043E\u0459\u0435\u043D\u043E \u0430\u0433\u0435\u043D\u0442\u0438\u043C\u0430, \ - \u043C\u0435\u0452\u0443\u0442\u0438\u043C \u043E\u0432\u0430 \u043E\u043F\u0435\u0440\u0430\u0446\u0438\u0458\u0430 \u0458\u0435 \u0432\u0435\u0440\u043E\u0432\u0430\u0442\u043D\u043E \u043F\u0440\u0435\u043A\u0438\u043D\u0443\u043B\u0430 \u043D\u0435\u043A\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430. \u0420\u0430\u0437\u043C\u0438\u0441\u043B\u0438\u0442\u0435 \u0430\u043A\u043E \u0431\u0438 \u043C\u043E\u0433\u043E \u0434\u043E\u0437\u0432\u043E\u043B\u0438\u0442\u0438 \u0430\u0433\u0435\u043D\u0442\u0438\u043C\u0430. diff --git a/core/src/main/resources/jenkins/security/s2m/AdminWhitelistRule/index.jelly b/core/src/main/resources/jenkins/security/s2m/AdminWhitelistRule/index.jelly deleted file mode 100644 index c59b11ec0aaa..000000000000 --- a/core/src/main/resources/jenkins/security/s2m/AdminWhitelistRule/index.jelly +++ /dev/null @@ -1,113 +0,0 @@ - - - - - - -

      ${%Agent → Controller Access Control}

      - -

      - The Jenkins controller is now more strict about what commands its agents can send to the controller. - Unfortunately, this prevents some plugins from functioning correctly, as those plugins do not - specify which commands are open for agents to execute and which ones are not. - While plugin developers work on improving this, - as an administrator, you can mark commands as OK for agents to execute. -

      -
      - Please see the discussion of this feature to - understand the security implication of this. -
      - -
      - The agent → controller access control subsystem is currently disabled. - This is unsafe if you have agents from other less trusted people. - You can turn it back on from Global Security Configuration UI. -
      -
      - -
      -

      Currently Allowed Commands

      -

      - Agents are currently allowed to execute the following commands on the controller. -

      - - - - - -

      Currently Rejected Commands

      -

      - Agents have attempted to use the following functionalities but the plugins that implement them - did not specify whether or not they should be usable from agents. Check ones you want to allow to be executed: -

      -
        - -
      • - ${r.clazz.name} - - - - - - - (from core) - - - (from ${plugin.longName}) - - -
      • -
        -
      -
      - -

      File Access Rules

      -

      - The following rules control which part of $JENKINS_HOME can be accessed from agents: -

      - -

      - Example: -

      -
      -# deny access to anything in the SkunkWorks folder, regardless of what later rules say
      -deny read &lt;JENKINS_HOME>/jobs/SkunkWorks/.*
      -
      -# allow any access under builds
      -allow all &lt;BUILDDIR>/.*
      -
      -# allow read-only access under userContent
      -allow read,stat &lt;JENKINS_HOME>/userContent/.*
      -
      -

      - General syntax: (allow|deny) Op,Op,Op,... PathRegExp, -

      -
      - -
      - -
      -
      -
      diff --git a/core/src/main/resources/jenkins/security/s2m/AdminWhitelistRule/index_bg.properties b/core/src/main/resources/jenkins/security/s2m/AdminWhitelistRule/index_bg.properties deleted file mode 100644 index 79e58cf1d1a8..000000000000 --- a/core/src/main/resources/jenkins/security/s2m/AdminWhitelistRule/index_bg.properties +++ /dev/null @@ -1,28 +0,0 @@ -# The MIT License -# -# Bulgarian translation: Copyright (c) 2016, Alexander Shopov -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Whitelist=\ - \u041e\u0434\u043e\u0431\u0440\u0435\u043d \u0441\u043f\u0438\u0441\u044a\u043a -Update=\ - \u041e\u0431\u043d\u043e\u0432\u044f\u0432\u0430\u043d\u0435 -Agent\ &\#8594;\ Master\ Access\ Control=\ - \u0410\u0433\u0435\u043d\u0442 \u2192 \u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 \u0434\u043e\u0441\u0442\u044a\u043f\u0430 diff --git a/core/src/main/resources/jenkins/security/s2m/AdminWhitelistRule/index_de.properties b/core/src/main/resources/jenkins/security/s2m/AdminWhitelistRule/index_de.properties deleted file mode 100644 index 0f7ba5afe444..000000000000 --- a/core/src/main/resources/jenkins/security/s2m/AdminWhitelistRule/index_de.properties +++ /dev/null @@ -1,25 +0,0 @@ -# The MIT License -# -# Copyright (c) 2017 Daniel Beck and a number of other of contributors -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Whitelist=Positivliste (Whitelist) -Agent\ &\#8594;\ Master\ Access\ Control=Zugangskontrolle Agent → Master -Update=Aktualisieren diff --git a/core/src/main/resources/jenkins/security/s2m/AdminWhitelistRule/index_it.properties b/core/src/main/resources/jenkins/security/s2m/AdminWhitelistRule/index_it.properties deleted file mode 100644 index 0d5f667b67f0..000000000000 --- a/core/src/main/resources/jenkins/security/s2m/AdminWhitelistRule/index_it.properties +++ /dev/null @@ -1,26 +0,0 @@ -# The MIT License -# -# Italian localization plugin for Jenkins -# Copyright 2020 Alessandro Menti -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Agent\ &\#8594;\ Master\ Access\ Control=Controllo accessi agente→master -Update=Aggiorna -Whitelist=Whitelist diff --git a/core/src/main/resources/jenkins/security/s2m/AdminWhitelistRule/index_ja.properties b/core/src/main/resources/jenkins/security/s2m/AdminWhitelistRule/index_ja.properties deleted file mode 100644 index a4a88ca399f0..000000000000 --- a/core/src/main/resources/jenkins/security/s2m/AdminWhitelistRule/index_ja.properties +++ /dev/null @@ -1,24 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributers -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Whitelist=\u30db\u30ef\u30a4\u30c8\u30ea\u30b9\u30c8 -Update=\u66f4\u65b0 diff --git a/core/src/main/resources/jenkins/security/s2m/AdminWhitelistRule/index_pt_BR.properties b/core/src/main/resources/jenkins/security/s2m/AdminWhitelistRule/index_pt_BR.properties deleted file mode 100644 index 42d23f6efe16..000000000000 --- a/core/src/main/resources/jenkins/security/s2m/AdminWhitelistRule/index_pt_BR.properties +++ /dev/null @@ -1,24 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2015, Seiji Sogabe -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Whitelist= -Update= diff --git a/core/src/main/resources/jenkins/security/s2m/AdminWhitelistRule/index_sr.properties b/core/src/main/resources/jenkins/security/s2m/AdminWhitelistRule/index_sr.properties deleted file mode 100644 index 605e8f9eda41..000000000000 --- a/core/src/main/resources/jenkins/security/s2m/AdminWhitelistRule/index_sr.properties +++ /dev/null @@ -1,5 +0,0 @@ -# This file is under the MIT License by authors - -Whitelist= -Agent\ \u2192\ Master\ Access\ Control= -Update=\u0410\u0436\u0443\u0440\u0438\u0440\u0430\u0458 diff --git a/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchConfiguration/config.groovy b/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchConfiguration/config.groovy deleted file mode 100644 index ae486437d3eb..000000000000 --- a/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchConfiguration/config.groovy +++ /dev/null @@ -1,13 +0,0 @@ -package jenkins.security.s2m.MasterKillSwitchConfiguration - -def f=namespace(lib.FormTagLib) - -if (instance.isRelevant()) { - f.section(title: _('Agent \u2192 Controller Security')) { - f.optionalBlock(field: "masterToSlaveAccessControl", title: _("Enable Agent \u2192 Controller Access Control")) { - f.nested() { - raw _("Rules can be tweaked here") - } - } - } -} diff --git a/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchConfiguration/config_it.properties b/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchConfiguration/config_it.properties deleted file mode 100644 index 5445c9b31d4e..000000000000 --- a/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchConfiguration/config_it.properties +++ /dev/null @@ -1,29 +0,0 @@ -# The MIT License -# -# Italian localization plugin for Jenkins -# Copyright 2020 Alessandro Menti -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Agent\ \\u2192\ Master\ Security=Sicurezza agente\u2192master -Enable\ Agent\ \\u2192\ Master\ Access\ Control=Abilita controllo accessi \ - agente\u2192master -Rules\ can\ be\ tweaked\ here=\ - possibile personalizzare le regole qui diff --git a/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchConfiguration/help-masterToSlaveAccessControl.html b/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchConfiguration/help-masterToSlaveAccessControl.html deleted file mode 100644 index af45b305162a..000000000000 --- a/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchConfiguration/help-masterToSlaveAccessControl.html +++ /dev/null @@ -1,4 +0,0 @@ -
      - See Jenkins project website for discussion of this feature. - We strongly recommend you enable this. -
      diff --git a/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchConfiguration/help-masterToSlaveAccessControl_bg.html b/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchConfiguration/help-masterToSlaveAccessControl_bg.html deleted file mode 100644 index 84dc7a3dbc97..000000000000 --- a/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchConfiguration/help-masterToSlaveAccessControl_bg.html +++ /dev/null @@ -1,4 +0,0 @@ -
      - За повече информация вижте сайта на Jenkins. - Силно препоръчваме да включите тази настройка. -
      diff --git a/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchConfiguration/help-masterToSlaveAccessControl_it.html b/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchConfiguration/help-masterToSlaveAccessControl_it.html deleted file mode 100644 index 65245d31bba8..000000000000 --- a/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchConfiguration/help-masterToSlaveAccessControl_it.html +++ /dev/null @@ -1,4 +0,0 @@ -
      - Si veda il sito Web del progetto Jenkins per una trattazione di questa funzionalità. - Raccomandiamo caldamente di abilitarla. -
      diff --git a/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/description.jelly b/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/description.jelly new file mode 100644 index 000000000000..bb405e931933 --- /dev/null +++ b/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/description.jelly @@ -0,0 +1,4 @@ + + + ${%blurb} + diff --git a/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/description.properties b/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/description.properties new file mode 100644 index 000000000000..746efab0d249 --- /dev/null +++ b/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/description.properties @@ -0,0 +1 @@ +blurb = When agent-to-controller access control is disabled, this warns administrators. diff --git a/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/description_pt_BR.properties b/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/description_pt_BR.properties new file mode 100644 index 000000000000..822f0540f500 --- /dev/null +++ b/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/description_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +blurb=Quando o controle de acesso do agente para o controlador está desabilitado, isto avisa os administradores. diff --git a/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/message.jelly b/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/message.jelly deleted file mode 100644 index de2ebcb9db8f..000000000000 --- a/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/message.jelly +++ /dev/null @@ -1,34 +0,0 @@ - - - - -
      -
      - - - - ${%blurb} -
      -
      diff --git a/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/message.properties b/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/message.properties deleted file mode 100644 index e53fb8187c87..000000000000 --- a/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/message.properties +++ /dev/null @@ -1,2 +0,0 @@ -blurb=Agent to master security subsystem is currently off. \ - Please read the documentation and consider turning it on. diff --git a/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/message_bg.properties b/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/message_bg.properties deleted file mode 100644 index 906a8329f9c8..000000000000 --- a/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/message_bg.properties +++ /dev/null @@ -1,32 +0,0 @@ -# The MIT License -# -# Bulgarian translation: Copyright (c) 2016, 2017, Alexander Shopov -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Dismiss=\ - \u041e\u0442\u043a\u0430\u0437 -Examine=\ - \u041f\u0440\u0435\u0433\u043b\u0435\u0434 -# Agent to master security subsystem is currently off. \ -# Please read the documentation and consider turning it on. -blurb=\ - \u0410\u0433\u0435\u043d\u0442\u044a\u0442 \u0437\u0430 \u043e\u0441\u043d\u043e\u0432\u043d\u0430\u0442\u0430 \u043f\u043e\u0434\u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0437\u0430 \u0441\u0438\u0433\u0443\u0440\u043d\u043e\u0441\u0442\u0442\u0430 \u0435 \u0438\u0437\u043a\u043b\u044e\u0447\u0435\u043d \u0432 \u043c\u043e\u043c\u0435\u043d\u0442\u0430.\ - \u041f\u0440\u0435\u0433\u043b\u0435\u0434\u0430\u0439\u0442\u0435\ - \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f\u0442\u0430 \u0438 \u0433\u043e \u0432\u043a\u043b\u044e\u0447\u0435\u0442\u0435. diff --git a/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/message_de.properties b/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/message_de.properties deleted file mode 100644 index 9d47ee0f242e..000000000000 --- a/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/message_de.properties +++ /dev/null @@ -1,26 +0,0 @@ -# The MIT License -# -# Copyright (c) 2017 Daniel Beck and a number of other of contributors -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Examine=Pr\u00FCfen -Dismiss=Schlie\u00DFen -blurb=Das Agent-Master-Sicherheits-Subsystem ist aktuell ausgeschaltet und sollte eingeschaltet werden. \ - Bitte lesen Sie die Dokumentation. diff --git a/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/message_it.properties b/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/message_it.properties deleted file mode 100644 index f21ed6d46349..000000000000 --- a/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/message_it.properties +++ /dev/null @@ -1,29 +0,0 @@ -# The MIT License -# -# Italian localization plugin for Jenkins -# Copyright 2020 Alessandro Menti -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -blurb=Il sottosistema di sicurezza da agente a master attualmente \ - disabilitato. Si legga la documentazione e si prenda in \ - considerazione l''ipotesi di abilitarlo. -Dismiss=Nascondi -Examine=Esamina diff --git a/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/message_pt_BR.properties b/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/message_pt_BR.properties deleted file mode 100644 index 8719f15b7441..000000000000 --- a/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/message_pt_BR.properties +++ /dev/null @@ -1,26 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributers -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Examine= -Dismiss= -blurb=O agente para o master security subsystem est\u00e1 desligado. \ - Por favor leia a documenta\u00e7\u00e3o e ligue novamente. diff --git a/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/message_sr.properties b/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/message_sr.properties deleted file mode 100644 index 41945798fed1..000000000000 --- a/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/message_sr.properties +++ /dev/null @@ -1,6 +0,0 @@ -# This file is under the MIT License by authors - -Examine= -Dismiss=\u041E\u0442\u043A\u0430\u0436\u0438 -blurb=\u0421\u0438\u0441\u0442\u0435\u043C \u043E\u0431\u0435\u0437\u0431\u0435\u0436\u0438\u0432\u0430\u045A\u0430 \u0432\u0435\u0437\u043E\u043C \u0438\u0437\u043C\u0435\u0452\u0443 \u0430\u0433\u0435\u043D\u0442\u0430 \u0438 \u043C\u0430\u0441\u0442\u0435\u0440\u0430 \u0458\u0435 \u0438\u0441\u043A\u0459\u0443\u0447\u0435\u043D. \ - \u041C\u043E\u043B\u0438\u043C\u043E \u0432\u0430\u0441, \u043F\u0440\u043E\u0447\u0438\u0442\u0430\u0458\u0442\u0435 \u0434\u043E\u043A\u043C\u0435\u043D\u0442\u0430\u0446\u0438\u0458\u0443 \u0438 \u0443\u043A\u0459\u0443\u0447\u0438\u0442\u0435 \u0430\u043A\u043E \u0432\u0430\u043C \u0458\u0435 \u043F\u043E\u0442\u0440\u0435\u0431\u043D\u043E. diff --git a/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/message_tr.properties b/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/message_tr.properties deleted file mode 100644 index 4a99fc431b8e..000000000000 --- a/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/message_tr.properties +++ /dev/null @@ -1,24 +0,0 @@ -# The MIT License -# -# Copyright (c) 2021, Mustafa Ulu -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Examine=Denetle -Dismiss=Reddet diff --git a/core/src/main/resources/jenkins/security/s2m/Messages.properties b/core/src/main/resources/jenkins/security/s2m/Messages.properties deleted file mode 100644 index e2b2c28f3bd3..000000000000 --- a/core/src/main/resources/jenkins/security/s2m/Messages.properties +++ /dev/null @@ -1,2 +0,0 @@ -AdminCallableMonitor.DisplayName=Rejected Agent \u2192 Controller Access Attempt -MasterKillSwitchWarning.DisplayName=Disabled Agent \u2192 Controller Access Control diff --git a/core/src/main/resources/jenkins/security/s2m/Messages_bg.properties b/core/src/main/resources/jenkins/security/s2m/Messages_bg.properties deleted file mode 100644 index 199b5d56ec12..000000000000 --- a/core/src/main/resources/jenkins/security/s2m/Messages_bg.properties +++ /dev/null @@ -1,28 +0,0 @@ -# The MIT License -# -# Bulgarian translation: Copyright (c) 2017, Alexander Shopov -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -# Rejected Agent \u2192 Controller Access Attempt -AdminCallableMonitor.DisplayName=\ - \u041e\u0442\u0445\u0432\u044a\u0440\u043b\u0435\u043d \u043f\u043e\u0434\u0447\u0438\u043d\u0435\u043d \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440 \u2014 \u043e\u043f\u0438\u0442 \u0437\u0430 \u0434\u043e\u0441\u0442\u044a\u043f \u0434\u043e \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u0438\u044f \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440 -# Disabled Agent \u2192 Controller Access Control -MasterKillSwitchWarning.DisplayName=\ - \u0418\u0437\u043a\u043b\u044e\u0447\u0435\u043d \u043f\u043e\u0434\u0447\u0438\u043d\u0435\u043d \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440 \u2014 \u043a\u043e\u043d\u0442\u0440\u043e\u043b \u043d\u0430 \u0434\u043e\u0441\u0442\u044a\u043f\u0430 \u0434\u043e \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u0438\u044f \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440 diff --git a/core/src/main/resources/jenkins/security/s2m/Messages_de.properties b/core/src/main/resources/jenkins/security/s2m/Messages_de.properties deleted file mode 100644 index 162be628503e..000000000000 --- a/core/src/main/resources/jenkins/security/s2m/Messages_de.properties +++ /dev/null @@ -1,24 +0,0 @@ -# The MIT License -# -# Copyright (c) 2017 Daniel Beck and a number of other of contributors -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -AdminCallableMonitor.DisplayName=Zugriffsversuch Agent \u2192 Master abgelehnt -MasterKillSwitchWarning.DisplayName=Sicherheitsfunktionen Agent \u2192 Master deaktiviert diff --git a/core/src/main/resources/jenkins/security/s2m/Messages_it.properties b/core/src/main/resources/jenkins/security/s2m/Messages_it.properties deleted file mode 100644 index 2c259e5b976a..000000000000 --- a/core/src/main/resources/jenkins/security/s2m/Messages_it.properties +++ /dev/null @@ -1,27 +0,0 @@ -# The MIT License -# -# Italian localization plugin for Jenkins -# Copyright 2020 Alessandro Menti -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -AdminCallableMonitor.DisplayName=Tentativo di accesso agente\u2192master \ - rifiutato -MasterKillSwitchWarning.DisplayName=Controllo accessi agente\u2192master \ - disabilitato diff --git a/core/src/main/resources/jenkins/security/s2m/callable.conf b/core/src/main/resources/jenkins/security/s2m/callable.conf deleted file mode 100644 index cb8943df2629..000000000000 --- a/core/src/main/resources/jenkins/security/s2m/callable.conf +++ /dev/null @@ -1,29 +0,0 @@ -# GENERATED FILE. DO NOT MODIFY. -# -# This file is for Jenkins core developers to list plugin callables which we believe are safe. -# -# To whitelist other names, place *.conf files by other names into this folder. -# This file gets overwritten every time Jenkins starts. -# -# See https://jenkins.io/redirect/security-144 for more details. - -# maven plugin -hudson.maven.MavenBuildProxy$Filter$AsyncInvoker - -# cloudbees-deployer plugin -com.cloudbees.plugins.deployer.engines.Engine$FingerprintDecorator - -# subversion plugin -hudson.scm.SubversionWorkspaceSelector$1 - -# git-client plugin (prior to #147) -org.jenkinsci.plugins.gitclient.CliGitAPIImpl$GetPrivateKeys - -# ssh-credentials plugin -com.cloudbees.jenkins.plugins.sshcredentials.SSHAuthenticator$1 - -# cygwin-process-killer plugin -com.synopsys.arc.jenkinsci.plugins.cygwinprocesskiller.CygwinProcessKiller$KillerRemoteCall - -# selenium-plugin -hudson.plugins.selenium.JenkinsCapabilityMatcher$LabelMatcherCallable diff --git a/core/src/main/resources/jenkins/security/s2m/filepath-filter.conf b/core/src/main/resources/jenkins/security/s2m/filepath-filter.conf deleted file mode 100644 index ca58e15ecf3e..000000000000 --- a/core/src/main/resources/jenkins/security/s2m/filepath-filter.conf +++ /dev/null @@ -1,43 +0,0 @@ -# GENERATED FILE. DO NOT MODIFY. -# -# This file is for Jenkins core developers to list what we think are the best filtering rules -# for apparently harmless accesses to files on the Jenkins master from agents. -# -# To override these rules, place *.conf files by other names into this folder. Files are sorted -# before parsed, so using a lower number allows you to override what we have here. This file -# gets overwritten every time Jenkins starts. -# -# See https://jenkins.io/redirect/security-144 for more details. - -# This directory contains credentials, master encryption keys, and other sensitive information -# that agents have absolutely no business with. -# Unless there are rules in other files allowing access to other portions of $JENKINS_HOME, -# this rule as it stands here has no effect, because anything left unspecified is rejected. -deny all /secrets($|/.*) - -# User content is publicly readable, so quite safe for agents to read, too. -# (The xunit plugin is known to read from here.) -# https://jenkins.io/redirect/user-content-directory -allow read,stat /userContent($|/.*) - -# In the next rule we grant general access under build directories, so first we protect -# the actual build record that Jenkins core reads, which nothing should be touching. -deny all /build.xml -# Similarly for Pipeline build (WorkflowRun) metadata: -deny all /program.dat -deny all /workflow($|/.*) - -# Various plugins read/write files under build directories, so allow them all. -# - git 1.x writes changelog.xml from the agent (2.x writes from the master so need not be listed) -# - analysis-core and plugins based on it write reports to workspace-files/ -# - cobertura writes coverage.xml -# - violations writes violations.xml and other content under violations/ -# - dependency-check writes archive/artifacts.txt -# But not allowing deletion to prevent data loss and symlink to prevent jailbreaking. -allow create,mkdirs,read,stat,write /.+ - -# cobertura also writes out annotated sources to a dir under the job: -allow create,mkdirs,read,stat,write /jobs/.+/cobertura.* - -# all the other accesses that aren't specified here will be left up to other rules in this directory. -# if no rules in those other files matches, then the access will be rejected. diff --git a/core/src/main/resources/jenkins/security/seed/Messages_pt_BR.properties b/core/src/main/resources/jenkins/security/seed/Messages_pt_BR.properties new file mode 100644 index 000000000000..85b3350ef2ab --- /dev/null +++ b/core/src/main/resources/jenkins/security/seed/Messages_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +UserSeedProperty.DisplayName=Encerramento de sess\u00E3o diff --git a/core/src/main/resources/jenkins/security/seed/UserSeedProperty/config_pt_BR.properties b/core/src/main/resources/jenkins/security/seed/UserSeedProperty/config_pt_BR.properties new file mode 100644 index 000000000000..cb650e4e48d5 --- /dev/null +++ b/core/src/main/resources/jenkins/security/seed/UserSeedProperty/config_pt_BR.properties @@ -0,0 +1,27 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +resetSeed.confirmation=Todas as sess\u00F5es conectadas para este usu\u00E1rio ser\u00E3o finalizadas. \n\ +Ele(a) ter\u00E1 que refazer o processo de entrada. \n\ +Voc\u00EA tem certeza? +resetSeed.button=Finalizar todas as sess\u00F5es +resetSeed.result=A opera\u00E7\u00E3o foi um sucesso. Todas as sess\u00F5es foram encerradas. diff --git a/core/src/main/resources/jenkins/security/stapler/default-whitelist.txt b/core/src/main/resources/jenkins/security/stapler/default-whitelist.txt index c9fd1dfcba8d..b2a39e2ed602 100644 --- a/core/src/main/resources/jenkins/security/stapler/default-whitelist.txt +++ b/core/src/main/resources/jenkins/security/stapler/default-whitelist.txt @@ -131,7 +131,7 @@ method hudson.plugins.build_publisher.BuildPublisher$BuildPublisherDescriptor do ############################################### -# Changes since last successfull build Plugin # (sic) +# Changes since last successful build Plugin # ############################################### # Only has an index.jelly view, so needs to be explicit class com.cloudbees.jenkins.plugins.changelog.Changes diff --git a/core/src/main/resources/jenkins/security/whitelisted-classes.txt b/core/src/main/resources/jenkins/security/whitelisted-classes.txt index 15c32a34698f..fbcdc1a9de01 100644 --- a/core/src/main/resources/jenkins/security/whitelisted-classes.txt +++ b/core/src/main/resources/jenkins/security/whitelisted-classes.txt @@ -1,12 +1,15 @@ com.google.common.collect.AbstractListMultimap +com.google.common.collect.AbstractMapBasedMultimap com.google.common.collect.AbstractMultimap com.google.common.collect.AbstractSetMultimap -# Artifactory - https://issues.jenkins-ci.org/browse/JENKINS-48991 +# Artifactory - https://issues.jenkins.io/browse/JENKINS-48991 com.google.common.collect.ArrayListMultimap +com.google.common.collect.ArrayListMultimapGwtSerializationDependencies com.google.common.collect.EmptyImmutableList com.google.common.collect.EmptyImmutableSet com.google.common.collect.EmptyImmutableSortedSet com.google.common.collect.HashMultimap +com.google.common.collect.HashMultimapGwtSerializationDependencies # First hit: https://github.com/jenkinsci/pitmutation-plugin/ com.google.common.collect.HashMultiset com.google.common.collect.ImmutableList @@ -16,7 +19,7 @@ com.google.common.collect.ImmutableMap com.google.common.collect.ImmutableSet com.google.common.collect.ImmutableSet$SerializedForm com.google.common.collect.ImmutableSortedSet -# https://issues.jenkins-ci.org/browse/JENKINS-48989 +# https://issues.jenkins.io/browse/JENKINS-48989 com.google.common.collect.Maps$TransformedEntriesMap # https://github.com/jenkinsci/sonar-gerrit-plugin com.google.common.collect.Multimap @@ -27,14 +30,6 @@ com.google.common.collect.SingletonImmutableList com.google.common.collect.SingletonImmutableMap com.google.common.collect.SingletonImmutableSet -# TODO remove when maven-plugin 3.1 is widely adopted -hudson.maven.MavenInformation - -# TODO remove when https://github.com/jenkinsci/kubernetes-pipeline-plugin/pull/66 is widely adopted -io.fabric8.docker.api.model.Config -io.fabric8.docker.api.model.GraphDriverData -io.fabric8.docker.api.model.ImageInspect - java.io.File java.lang.Boolean java.lang.Byte @@ -136,76 +131,18 @@ java.util.logging.Level java.util.logging.LogRecord java.util.regex.Pattern -# TODO remove when https://github.com/jenkinsci/job-dsl-plugin/pull/1092 is widely adopted -javaposse.jobdsl.dsl.GeneratedJob - -# TODO remove when https://github.com/jenkinsci/monitoring-plugin/pull/6 is widely adopted -net.bull.javamelody.internal.model.CacheInformations -net.bull.javamelody.internal.model.HeapHistogram -net.bull.javamelody.internal.model.HeapHistogram$ClassInfo -net.bull.javamelody.internal.model.JavaInformations -net.bull.javamelody.internal.model.JobInformations -net.bull.javamelody.internal.model.MBeanNode -net.bull.javamelody.internal.model.MBeanNode$MBeanAttribute -net.bull.javamelody.internal.model.MemoryInformations -net.bull.javamelody.internal.model.ProcessInformations -net.bull.javamelody.internal.model.ThreadInformations -net.bull.javamelody.internal.model.TomcatInformations - org.apache.commons.fileupload.disk.DiskFileItem org.apache.commons.fileupload.util.FileItemHeadersImpl org.apache.tools.ant.Location -# TODO remove when git-client 2.7.1+ is widely adopted -org.eclipse.jgit.lib.ObjectId -org.eclipse.jgit.lib.ObjectIdOwnerMap$Entry -org.eclipse.jgit.lib.PersonIdent -org.eclipse.jgit.revwalk.RevCommit -org.eclipse.jgit.revwalk.RevObject -org.eclipse.jgit.revwalk.RevTree -org.eclipse.jgit.transport.URIish - -# TODO remove when https://github.com/jenkinsci/workflow-support-plugin/pull/50 is widely adopted -org.jboss.marshalling.TraceInformation$FieldInfo -org.jboss.marshalling.TraceInformation$ObjectInfo - -# TODO see main ruby-runtime section below -org.jenkinsci.jruby.JRubyMapper$DynamicProxy - # TODO remove when https://github.com/jenkinsci/xtrigger-lib/pull/9 is widely adopted in fstrigger-plugin, urltrigger-plugin, etc. org.jenkinsci.lib.xtrigger.XTriggerCause org.jenkinsci.lib.xtrigger.XTriggerCauseAction -# TODO remove (also XStream2.BlacklistedTypesConverter.JRUBY_PROXY) when Ruby Runtime is fixed -# Related PRs: -# - https://github.com/jenkinsci/ruby-runtime-plugin/pull/5, -# - https://github.com/jenkinsci/ruby-runtime-plugin/pull/6 -# -# oleg-nenashev in PR#6 we are trying to get help from last maintainers due to the plugin codebase splitbrain. -# It is required to fix JENKINS-50616 in a proper way for 2.107.x -org.jruby.RubyArray -org.jruby.RubyBignum -org.jruby.RubyBoolean -org.jruby.RubyBoolean$False -org.jruby.RubyBoolean$True -org.jruby.RubyFixnum -org.jruby.RubyHash -org.jruby.RubyNil -org.jruby.RubyObject -org.jruby.RubyString -org.jruby.RubySymbol -org.jruby.java.proxies.ConcreteJavaProxy -org.jruby.runtime.builtin.IRubyObject - org.jvnet.hudson.MemoryUsage org.jvnet.localizer.Localizable org.jvnet.localizer.ResourceBundleHolder -# TODO remove when https://github.com/jenkinsci/dependency-check-plugin/pull/20 is widely adopted -org.owasp.dependencycheck.dependency.Reference -org.owasp.dependencycheck.dependency.Vulnerability -org.owasp.dependencycheck.dependency.VulnerableSoftware - org.springframework.security.core.userdetails.User sun.security.rsa.RSAPublicKeyImpl diff --git a/core/src/main/resources/jenkins/slaves/JnlpSlaveAgentProtocol4/description.properties b/core/src/main/resources/jenkins/slaves/JnlpSlaveAgentProtocol4/description.properties index 9cf2b4b2f87d..4ecb60357fd6 100644 --- a/core/src/main/resources/jenkins/slaves/JnlpSlaveAgentProtocol4/description.properties +++ b/core/src/main/resources/jenkins/slaves/JnlpSlaveAgentProtocol4/description.properties @@ -1 +1 @@ -summary=A TLS secured connection between the master and the agent performed by TLS upgrade of the socket. +summary=A TLS secured connection between the controller and the agent performed by TLS upgrade of the socket. diff --git a/core/src/main/resources/jenkins/slaves/JnlpSlaveAgentProtocol4/description_pt_BR.properties b/core/src/main/resources/jenkins/slaves/JnlpSlaveAgentProtocol4/description_pt_BR.properties new file mode 100644 index 000000000000..6871537489b7 --- /dev/null +++ b/core/src/main/resources/jenkins/slaves/JnlpSlaveAgentProtocol4/description_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +summary=Uma conex\u00E3o segura via TLS entre o controlador e o agente realizada por uma atualização de TLS no soquete. diff --git a/core/src/main/resources/jenkins/slaves/JnlpSlaveAgentProtocol4/description_zh_TW.properties b/core/src/main/resources/jenkins/slaves/JnlpSlaveAgentProtocol4/description_zh_TW.properties new file mode 100644 index 000000000000..db3f8cd6b6d6 --- /dev/null +++ b/core/src/main/resources/jenkins/slaves/JnlpSlaveAgentProtocol4/description_zh_TW.properties @@ -0,0 +1 @@ +summary=\u900f\u904e TLS \u901a\u8a0a\u7aef\u5347\u7d1a Controller \u548c Agent \u9593\u7684 TLS \u5b89\u5168\u9023\u7dda\u3002 diff --git a/core/src/main/resources/jenkins/slaves/Messages_pt_BR.properties b/core/src/main/resources/jenkins/slaves/Messages_pt_BR.properties new file mode 100644 index 000000000000..c185388bf156 --- /dev/null +++ b/core/src/main/resources/jenkins/slaves/Messages_pt_BR.properties @@ -0,0 +1,27 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +DeprecatedAgentProtocolMonitor.displayName=Monitor de protocolo de agente descontinuado +JnlpSlaveAgentProtocol3.displayName=Protocolo de agente TCP de entrada/3 (descontinuado, criptografia básica) +JnlpSlaveAgentProtocol2.displayName=Protocolo de agente TCP de entrada/2 (descontinuado, sem criptografia) +JnlpSlaveAgentProtocol.displayName=Protocolo de agente TCP de entrada/1 (descontinuado, sem criptografia) +JnlpSlaveAgentProtocol4.displayName=Protocolo de agente TCP de entrada/4 (criptografia via TLS) diff --git a/core/src/main/resources/jenkins/slaves/Messages_zh_TW.properties b/core/src/main/resources/jenkins/slaves/Messages_zh_TW.properties new file mode 100644 index 000000000000..bc737ecb933d --- /dev/null +++ b/core/src/main/resources/jenkins/slaves/Messages_zh_TW.properties @@ -0,0 +1,27 @@ +# The MIT License +# +# Copyright 2016 Stephen Connolly +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +JnlpSlaveAgentProtocol.displayName=\u9023\u5165 TCP Agent \u901a\u8a0a\u5354\u5b9a/1 (\u68c4\u7528\u3001\u672a\u52a0\u5bc6) +JnlpSlaveAgentProtocol2.displayName=\u9023\u5165 TCP Agent \u901a\u8a0a\u5354\u5b9a/2 (\u68c4\u7528\u3001\u672a\u52a0\u5bc6) +JnlpSlaveAgentProtocol3.displayName=\u9023\u5165 TCP Agent \u901a\u8a0a\u5354\u5b9a/3 (\u68c4\u7528\u3001\u57fa\u672c\u52a0\u5bc6) +JnlpSlaveAgentProtocol4.displayName=\u9023\u5165 TCP Agent \u901a\u8a0a\u5354\u5b9a/4 (TLS \u52a0\u5bc6) +DeprecatedAgentProtocolMonitor.displayName=\u5df2\u68c4\u7528\u7684 Agent \u901a\u8a0a\u5354\u5b9a\u76e3\u8996\u5668 diff --git a/core/src/main/resources/jenkins/slaves/RemotingWorkDirSettings/config_pt_BR.properties b/core/src/main/resources/jenkins/slaves/RemotingWorkDirSettings/config_pt_BR.properties new file mode 100644 index 000000000000..c60bfe20d6bc --- /dev/null +++ b/core/src/main/resources/jenkins/slaves/RemotingWorkDirSettings/config_pt_BR.properties @@ -0,0 +1,26 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Fail\ if\ workspace\ is\ missing=Falhar se o espa\u00E7o de trabalho estiver faltando +Disable\ WorkDir=Desabilitar diret\u00F3rio de trabalho +Internal\ data\ directory=Diret\u00F3rio de dados internos +Custom\ WorkDir\ path=Caminho customizado para diret\u00F3rio de trabalho diff --git a/core/src/main/resources/jenkins/slaves/RemotingWorkDirSettings/config_zh_TW.properties b/core/src/main/resources/jenkins/slaves/RemotingWorkDirSettings/config_zh_TW.properties new file mode 100644 index 000000000000..ba794523380b --- /dev/null +++ b/core/src/main/resources/jenkins/slaves/RemotingWorkDirSettings/config_zh_TW.properties @@ -0,0 +1,26 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Custom\ WorkDir\ path=\u81ea\u8a02 WorkDir \u8def\u5f91 +Fail\ if\ workspace\ is\ missing=\u907a\u5931\u5de5\u4f5c\u5340\u6642\u5931\u6548 +Disable\ WorkDir=\u505c\u7528 WorkDir +Internal\ data\ directory=\u5167\u90e8\u8cc7\u6599\u76ee\u9304 diff --git a/core/src/main/resources/jenkins/slaves/systemInfo/Messages_zh_TW.properties b/core/src/main/resources/jenkins/slaves/systemInfo/Messages_zh_TW.properties index 4871413001ba..ddfa10fe1595 100644 --- a/core/src/main/resources/jenkins/slaves/systemInfo/Messages_zh_TW.properties +++ b/core/src/main/resources/jenkins/slaves/systemInfo/Messages_zh_TW.properties @@ -23,3 +23,4 @@ SystemPropertySlaveInfo.DisplayName=\u7cfb\u7d71\u5c6c\u6027 EnvVarsSlaveInfo.DisplayName=\u74b0\u5883\u8b8a\u6578 ThreadDumpSlaveInfo.DisplayName=\u57f7\u884c\u7dd2\u50be\u5370 +ClassLoaderStatisticsSlaveInfo.DisplayName=\u9060\u7aef Class Loader \u7d71\u8a08\u8cc7\u6599 diff --git a/core/src/main/resources/jenkins/split-plugin-cycles.txt b/core/src/main/resources/jenkins/split-plugin-cycles.txt index 3cec061d7eb0..848ede384feb 100644 --- a/core/src/main/resources/jenkins/split-plugin-cycles.txt +++ b/core/src/main/resources/jenkins/split-plugin-cycles.txt @@ -32,3 +32,7 @@ junit jaxb bouncycastle-api jaxb command-launcher jaxb jdk-tool jaxb + +javax-activation-api javax-mail-api +javax-activation-api sshd +javax-mail-api sshd diff --git a/core/src/main/resources/jenkins/split-plugins.txt b/core/src/main/resources/jenkins/split-plugins.txt index 0bb03189d9c8..823c851988cc 100644 --- a/core/src/main/resources/jenkins/split-plugins.txt +++ b/core/src/main/resources/jenkins/split-plugins.txt @@ -34,3 +34,6 @@ trilead-api 2.184 1.0.4 # JENKINS-64107 sshd 2.281 3.0.1 + +javax-activation-api 2.330 1.2.0-2 +javax-mail-api 2.330 1.6.2-5 diff --git a/core/src/main/resources/jenkins/tasks/filters/EnvVarsFilterGlobalConfiguration/config_pt_BR.properties b/core/src/main/resources/jenkins/tasks/filters/EnvVarsFilterGlobalConfiguration/config_pt_BR.properties new file mode 100644 index 000000000000..12551b32c618 --- /dev/null +++ b/core/src/main/resources/jenkins/tasks/filters/EnvVarsFilterGlobalConfiguration/config_pt_BR.properties @@ -0,0 +1,26 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +showGlobalRules=Mostrar regras de filtros globais +globalRules=Regras de filtro globais +addRule=Adicionar regra de filtro +jobEnvironmentVariableFilters=Filtrar vari\u00E1veis de ambiente do passo de constru\u00E7\u00E3o diff --git a/core/src/main/resources/jenkins/tasks/filters/EnvVarsFilterGlobalConfiguration/config_zh_TW.properties b/core/src/main/resources/jenkins/tasks/filters/EnvVarsFilterGlobalConfiguration/config_zh_TW.properties new file mode 100644 index 000000000000..6f120e9ac05b --- /dev/null +++ b/core/src/main/resources/jenkins/tasks/filters/EnvVarsFilterGlobalConfiguration/config_zh_TW.properties @@ -0,0 +1,25 @@ +# The MIT License +# +# Copyright (c) 2020, CloudBees, Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +jobEnvironmentVariableFilters=\u7be9\u9078\u5efa\u7f6e\u968e\u6bb5\u74b0\u5883\u8b8a\u6578 +globalRules=\u5168\u57df\u7be9\u9078\u898f\u5247 +showGlobalRules=\u986f\u793a\u5168\u57df\u7be9\u9078\u898f\u5247 +addRule=\u52a0\u5165\u7be9\u9078\u898f\u5247 diff --git a/core/src/main/resources/jenkins/tasks/filters/impl/Messages_pt_BR.properties b/core/src/main/resources/jenkins/tasks/filters/impl/Messages_pt_BR.properties new file mode 100644 index 000000000000..ff63b4a2d2fd --- /dev/null +++ b/core/src/main/resources/jenkins/tasks/filters/impl/Messages_pt_BR.properties @@ -0,0 +1,29 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +RetainVariablesLocalRule.CharacteristicEnvVarsFormValidationWarning=\u00C9 recomendado reter vari\u00E1veis de ambiente caracter\u00EDsticas porque o Jenkins as usa para identificar e matar processos fora de controle quando uma constru\u00E7\u00E3o \u00C9 feita. +RetainVariablesLocalRule_RESET_DisplayName=Reiniciar para o valor padr\u00E3o +RetainVariablesLocalRule.CharacteristicEnvVarsFormValidationOK=Em adi\u00E7\u00E3o a qualquer vari\u00E1vel de ambiente listada acima, o Jenkins irá reter vari\u00E1veis de ambiente que ele precisa para identificar e matar processos fora de controle quando uma constru\u00E7\u00E3o \u00C9 feita. +RetainVariablesLocalRule.DisplayName=Manter apenas as vari\u00E1vel de ambiente especificadas. +RetainVariablesLocalRule_REMOVE_DisplayName=Remover do ambiente +RetainVariablesLocalRule.ResetMessage=As seguintes vari\u00E1vel de ambiente foram reiniciadas para seus valores padrão de sistema por ''{0}'': {1} +RetainVariablesLocalRule.RemovalMessage=As seguintes vari\u00E1vel de ambiente foram removidas por ''{0}'': {1} diff --git a/core/src/main/resources/jenkins/tasks/filters/impl/Messages_zh_TW.properties b/core/src/main/resources/jenkins/tasks/filters/impl/Messages_zh_TW.properties new file mode 100644 index 000000000000..184c8c5eead0 --- /dev/null +++ b/core/src/main/resources/jenkins/tasks/filters/impl/Messages_zh_TW.properties @@ -0,0 +1,29 @@ +# The MIT License +# +# Copyright (c) 2020, CloudBees, Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +RetainVariablesLocalRule.DisplayName=\u53ea\u4fdd\u7559\u7279\u5b9a\u7684\u74b0\u5883\u8b8a\u6578 +RetainVariablesLocalRule_RESET_DisplayName=\u91cd\u8a2d\u70ba\u9810\u8a2d\u503c +RetainVariablesLocalRule_REMOVE_DisplayName=\u5f9e\u74b0\u5883\u79fb\u9664 +RetainVariablesLocalRule.RemovalMessage=\u4e0b\u5217\u74b0\u5883\u8b8a\u6578\u5df2\u7531\u300c{0}\u300d\u79fb\u9664\: {1} +RetainVariablesLocalRule.ResetMessage=\u4e0b\u5217\u74b0\u5883\u8b8a\u6578\u5df2\u7531\u300c{0}\u300d\u91cd\u8a2d\u70ba\u7cfb\u7d71\u9810\u8a2d\u503c\: {1} +RetainVariablesLocalRule.CharacteristicEnvVarsFormValidationWarning=\u5efa\u8b70\u4fdd\u7559\u7279\u6027\u74b0\u5883\u8b8a\u6578\uff0c\u56e0\u70ba Jenkins \u6703\u5728\u5efa\u7f6e\u5b8c\u6210\u5f8c\u4f7f\u7528\u5b83\u5011\u4f86\u8b58\u5225\u4e26\u7d42\u6b62\u5931\u63a7\u7684\u57f7\u884c\u5e8f\u3002 +RetainVariablesLocalRule.CharacteristicEnvVarsFormValidationOK=\u9664\u4e86\u4e0a\u5217\u7684\u74b0\u5883\u8b8a\u6578\uff0cJenkins \u4e5f\u6703\u4fdd\u7559\u5b83\u8981\u7528\u4f86\u8b58\u5225\u4e26\u7d42\u6b62\u5931\u63a7\u57f7\u884c\u5e8f\u7684\u74b0\u5883\u8b8a\u6578\u3002 diff --git a/core/src/main/resources/jenkins/tasks/filters/impl/RetainVariablesLocalRule/config_pt_BR.properties b/core/src/main/resources/jenkins/tasks/filters/impl/RetainVariablesLocalRule/config_pt_BR.properties new file mode 100644 index 000000000000..9da92ff81171 --- /dev/null +++ b/core/src/main/resources/jenkins/tasks/filters/impl/RetainVariablesLocalRule/config_pt_BR.properties @@ -0,0 +1,27 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +retainCharacteristicEnvVarsLabel=Reter vari\u00E1veis de ambiente caracter\u00EDsticas +variablesDescription=Todos as outras vari\u00E1veis de ambiente providas pelo Jenkins ser\u00E3o removidas. \ +Vari\u00E1veis de ambiente definidas fora do Jenkins ser\u00E3o reiniciadas para seus valores padr\u00E3o ou removidas, dependendo da op\u00E7\u00E3o ''Processar manuseio de vari\u00E1veis de ambiente'', exceto se especificado aqui. +retainProcessVariablesLabel=Processar manuseio de vari\u00E1veis de ambiente +variablesLabel=Vari\u00E1veis de ambiente para reter diff --git a/core/src/main/resources/jenkins/tasks/filters/impl/RetainVariablesLocalRule/config_zh_TW.properties b/core/src/main/resources/jenkins/tasks/filters/impl/RetainVariablesLocalRule/config_zh_TW.properties new file mode 100644 index 000000000000..7217772b9c22 --- /dev/null +++ b/core/src/main/resources/jenkins/tasks/filters/impl/RetainVariablesLocalRule/config_zh_TW.properties @@ -0,0 +1,25 @@ +# The MIT License +# +# Copyright (c) 2020, CloudBees, Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +variablesLabel=\u8981\u4fdd\u7559\u74b0\u5883\u8b8a\u6578 +variablesDescription=\u6240\u6709\u5176\u4ed6 Jenkins \u63d0\u4f9b\u7684\u74b0\u5883\u8b8a\u6578\u90fd\u5c07\u88ab\u79fb\u9664\u3002\u5728 Jenkins \u4e4b\u5916\u5b9a\u7fa9\u7684\u74b0\u5883\u8b8a\u6578\u90fd\u5c07\u88ab\u91cd\u8a2d\u70ba\u9810\u8a2d\u503c\u6216\u79fb\u9664\uff0c\u9664\u975e\u5728\u6b64\u6307\u5b9a\uff0c\u5426\u5247\u5c07\u4f9d\u64da\u300c\u57f7\u884c\u5e8f\u74b0\u5883\u8b8a\u6578\u8655\u7406\u300d\u7684\u9078\u9805\u3002 +retainCharacteristicEnvVarsLabel=\u4fdd\u7559\u7279\u6027\u74b0\u5883\u8b8a\u6578 +retainProcessVariablesLabel=\u57f7\u884c\u5e8f\u74b0\u5883\u8b8a\u6578\u8655\u7406 diff --git a/core/src/main/resources/jenkins/tasks/filters/impl/RetainVariablesLocalRule/help-retainCharacteristicEnvVars.html b/core/src/main/resources/jenkins/tasks/filters/impl/RetainVariablesLocalRule/help-retainCharacteristicEnvVars.html index 1e7e8b6a3f72..c14bd2cdd9e3 100644 --- a/core/src/main/resources/jenkins/tasks/filters/impl/RetainVariablesLocalRule/help-retainCharacteristicEnvVars.html +++ b/core/src/main/resources/jenkins/tasks/filters/impl/RetainVariablesLocalRule/help-retainCharacteristicEnvVars.html @@ -1,5 +1,5 @@

      When checked, characteristic environment variables will be retained in addition to the variables listed above. These environment variables are job- and build-specific, defined by Jenkins, and are used to identify and kill processes started by this build step. - See the documentation for more details on starting processes. + See the documentation for more details on starting processes.

      diff --git a/core/src/main/resources/jenkins/tools/GlobalToolConfiguration/index.groovy b/core/src/main/resources/jenkins/tools/GlobalToolConfiguration/index.groovy index 3223e22562a2..5caf8fc8080d 100644 --- a/core/src/main/resources/jenkins/tools/GlobalToolConfiguration/index.groovy +++ b/core/src/main/resources/jenkins/tools/GlobalToolConfiguration/index.groovy @@ -11,25 +11,21 @@ l.layout(permission:app.SYSTEM_READ, title:my.displayName) { l.side_panel { l.tasks { l.task(icon:"icon-up icon-md", href:rootURL+'/', title:_("Back to Dashboard")) - l.task(icon:"icon-gear2 icon-md", href:"${rootURL}/manage", title:_("Manage Jenkins")) + l.task(icon:"symbol-settings", href:"${rootURL}/manage", title:_("Manage Jenkins")) } } + l.app_bar(title: my.displayName) set("readOnlyMode", !app.hasPermission(app.ADMINISTER)) l.main_panel { - h1 { - l.icon(class: 'icon-setting icon-xlg') - // TODO more appropriate icon - text(my.displayName) + div(class:"behavior-loading") { + l.spinner(text: _("LOADING")) } - p() - div(class:"behavior-loading", _("LOADING")) - - f.form(method:"post",name:"config",action:"configure") { + f.form(method:"post",name:"config",action:"configure", class: "jenkins-form") { Functions.getSortedDescriptorsForGlobalConfigByDescriptor(my.FILTER).each { Descriptor descriptor -> set("descriptor",descriptor) set("instance",descriptor) - f.rowSet(name:descriptor.jsonSafeClassName) { + f.rowSet(name:descriptor.jsonSafeClassName, class: "jenkins-!-margin-bottom-0") { st.include(from:descriptor, page:descriptor.globalConfigPage) } } diff --git a/core/src/main/resources/jenkins/tools/GlobalToolConfiguration/index_zh_TW.properties b/core/src/main/resources/jenkins/tools/GlobalToolConfiguration/index_zh_TW.properties new file mode 100644 index 000000000000..9fb0edb3d77c --- /dev/null +++ b/core/src/main/resources/jenkins/tools/GlobalToolConfiguration/index_zh_TW.properties @@ -0,0 +1,2 @@ +Back\ to\ Dashboard=\u8fd4\u56de\u8cc7\u8a0a\u4e3b\u9801 +Manage\ Jenkins=\u7ba1\u7406 Jenkins diff --git a/core/src/main/resources/jenkins/triggers/Messages_pt_BR.properties b/core/src/main/resources/jenkins/triggers/Messages_pt_BR.properties index 6af37d5d0241..222b6aabdcf7 100644 --- a/core/src/main/resources/jenkins/triggers/Messages_pt_BR.properties +++ b/core/src/main/resources/jenkins/triggers/Messages_pt_BR.properties @@ -20,7 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -# Running as {0} cannot even see {1} for trigger from {2} ReverseBuildTrigger.running_as_cannot_even_see_for_trigger_f=Executando como {0} n\u00E3o \u00E9 poss\u00EDvel sequer ver {1} para disparar de {2} -# Build after other projects are built ReverseBuildTrigger.build_after_other_projects_are_built=Construir ap\u00F3s a constru\u00E7\u00E3o de outros projetos +SCMTriggerItem.PollingVetoed=Sondagem do SCM vetada por {0} diff --git a/core/src/main/resources/jenkins/triggers/Messages_zh_TW.properties b/core/src/main/resources/jenkins/triggers/Messages_zh_TW.properties new file mode 100644 index 000000000000..e1eb8e339ac9 --- /dev/null +++ b/core/src/main/resources/jenkins/triggers/Messages_zh_TW.properties @@ -0,0 +1,25 @@ +# The MIT License +# +# Copyright 2014 Jesse Glick. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +ReverseBuildTrigger.build_after_other_projects_are_built=\u5728\u5176\u4ed6\u5c08\u6848\u5efa\u7f6e\u5b8c\u6210\u5f8c\u5efa\u7f6e +ReverseBuildTrigger.running_as_cannot_even_see_for_trigger_f=\u4ee5 {0} \u8eab\u5206\u57f7\u884c\u7121\u6cd5\u5f9e {2} \u76e3\u63a7 {1} \u4f5c\u70ba\u89f8\u767c\u7a0b\u5e8f +SCMTriggerItem.PollingVetoed=SCM \u8f2a\u8a62\u88ab {0} \u7981\u6b62 diff --git a/core/src/main/resources/jenkins/triggers/ReverseBuildTrigger/config.jelly b/core/src/main/resources/jenkins/triggers/ReverseBuildTrigger/config.jelly index 3a3ddd8e62c2..7b048f8350d8 100644 --- a/core/src/main/resources/jenkins/triggers/ReverseBuildTrigger/config.jelly +++ b/core/src/main/resources/jenkins/triggers/ReverseBuildTrigger/config.jelly @@ -40,4 +40,8 @@ THE SOFTWARE. + + + diff --git a/core/src/main/resources/jenkins/triggers/ReverseBuildTrigger/config_pt_BR.properties b/core/src/main/resources/jenkins/triggers/ReverseBuildTrigger/config_pt_BR.properties index de6e64de2c7c..fd371a92b1b8 100644 --- a/core/src/main/resources/jenkins/triggers/ReverseBuildTrigger/config_pt_BR.properties +++ b/core/src/main/resources/jenkins/triggers/ReverseBuildTrigger/config_pt_BR.properties @@ -20,7 +20,8 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Trigger\ only\ if\ build\ is\ stable=Disparar apenas se o build estiver est\u00E1vel -Trigger\ even\ if\ the\ build\ is\ unstable=Disparar mesmo se o build estiver inst\u00E1vel -Trigger\ even\ if\ the\ build\ fails=Disparar mesmo se o build falhar +Trigger\ only\ if\ build\ is\ stable=Disparar apenas se a constru\u00E7\u00E3o estiver est\u00E1vel +Trigger\ even\ if\ the\ build\ is\ unstable=Disparar mesmo se a constru\u00E7\u00E3o estiver inst\u00E1vel +Trigger\ even\ if\ the\ build\ fails=Disparar mesmo se a constru\u00E7\u00E3o falhar Projects\ to\ watch=Projetos observados +Always\ trigger,\ even\ if\ the\ build\ is\ aborted=Sempre disparar, mesmo que a constru\u00E7\u00E3o seja abortada diff --git a/core/src/main/resources/jenkins/triggers/ReverseBuildTrigger/config_zh_TW.properties b/core/src/main/resources/jenkins/triggers/ReverseBuildTrigger/config_zh_TW.properties new file mode 100644 index 000000000000..d035a6f9d982 --- /dev/null +++ b/core/src/main/resources/jenkins/triggers/ReverseBuildTrigger/config_zh_TW.properties @@ -0,0 +1,27 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Trigger\ even\ if\ the\ build\ is\ unstable=\u5c31\u7b97\u5efa\u7f6e\u4e0d\u7a69\u5b9a\u4e5f\u8981\u89f8\u767c +Trigger\ even\ if\ the\ build\ fails=\u5c31\u7b97\u5efa\u7f6e\u5931\u6557\u4e5f\u8981\u89f8\u767c +Trigger\ only\ if\ build\ is\ stable=\u53ea\u5728\u5efa\u7f6e\u7a69\u5b9a\u6642\u89f8\u767c +Projects\ to\ watch=\u8981\u76e3\u63a7\u7684\u5c08\u6848 +Always\ trigger,\ even\ if\ the\ build\ is\ aborted=\u7e3d\u662f\u89f8\u767c\uff0c\u5373\u4f7f\u5efa\u7f6e\u5df2\u4e2d\u6b62 diff --git a/core/src/main/resources/jenkins/views/JenkinsHeader/headerContent.jelly b/core/src/main/resources/jenkins/views/JenkinsHeader/headerContent.jelly new file mode 100644 index 000000000000..524dfff36573 --- /dev/null +++ b/core/src/main/resources/jenkins/views/JenkinsHeader/headerContent.jelly @@ -0,0 +1,80 @@ + + + + diff --git a/core/src/main/resources/jenkins/widgets/HistoryPageFilter/queue-items.jelly b/core/src/main/resources/jenkins/widgets/HistoryPageFilter/queue-items.jelly index be46285a1329..e12d49057457 100644 --- a/core/src/main/resources/jenkins/widgets/HistoryPageFilter/queue-items.jelly +++ b/core/src/main/resources/jenkins/widgets/HistoryPageFilter/queue-items.jelly @@ -38,7 +38,7 @@ THE SOFTWARE.
      ${%UserId}
      - +
      diff --git a/core/src/main/resources/jenkins/widgets/HistoryPageFilter/queue-items_pt_BR.properties b/core/src/main/resources/jenkins/widgets/HistoryPageFilter/queue-items_pt_BR.properties new file mode 100644 index 000000000000..974c155640b4 --- /dev/null +++ b/core/src/main/resources/jenkins/widgets/HistoryPageFilter/queue-items_pt_BR.properties @@ -0,0 +1,25 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Expected\ build\ number=Esperado\ n\u00FAmero\ da\ constru\u00E7\u00E3o +pending=pendente +cancel\ this\ build=cancelar esta constru\u00E7\u00E3o diff --git a/core/src/main/resources/jenkins/widgets/HistoryPageFilter/queue-items_zh_TW.properties b/core/src/main/resources/jenkins/widgets/HistoryPageFilter/queue-items_zh_TW.properties new file mode 100644 index 000000000000..58debc67d3c8 --- /dev/null +++ b/core/src/main/resources/jenkins/widgets/HistoryPageFilter/queue-items_zh_TW.properties @@ -0,0 +1,25 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +pending=\u64f1\u7f6e +cancel\ this\ build=\u53d6\u6d88\u6b64\u5efa\u7f6e +Expected\ build\ number=\u9810\u671f\u7684\u5efa\u7f6e\u7de8\u865f diff --git a/core/src/main/resources/lib/form/advanced.jelly b/core/src/main/resources/lib/form/advanced.jelly index be1951308958..edc3b12a6e34 100644 --- a/core/src/main/resources/lib/form/advanced.jelly +++ b/core/src/main/resources/lib/form/advanced.jelly @@ -40,8 +40,8 @@ THE SOFTWARE. -
      - +
      +
      - +
      diff --git a/core/src/main/resources/lib/form/advanced/advanced.js b/core/src/main/resources/lib/form/advanced/advanced.js index d4deb93f20fb..69725eb886d1 100644 --- a/core/src/main/resources/lib/form/advanced/advanced.js +++ b/core/src/main/resources/lib/form/advanced/advanced.js @@ -32,3 +32,14 @@ Behaviour.specify("INPUT.advanced-button", 'advanced', 0, function(e) { }); e = null; // avoid memory leak }); + +Behaviour.specify('.advanced-customized-fields-info', 'advanced', 0, function(element) { + var id = element.getAttribute('data-id'); + var span = $(id) + if (span != null) { + span.style.display = ''; + } else if (console && console.log) { + var customizedFields = element.getAttribute('data-customized-fields'); + console.log('no element ' + id + ' for ' + customizedFields); + } +}); diff --git a/core/src/main/resources/lib/form/advanced_zh_TW.properties b/core/src/main/resources/lib/form/advanced_zh_TW.properties index 19586f3cf885..8167620d17ee 100644 --- a/core/src/main/resources/lib/form/advanced_zh_TW.properties +++ b/core/src/main/resources/lib/form/advanced_zh_TW.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Copyright 2013 Jesse Glick. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -19,5 +19,5 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. - -Advanced=\u9032\u968E +customizedFields=\u672c\u5340\u584a\u7684\u67d0\u4e9b\u6b04\u4f4d\u5df2\u88ab\u7de8\u8f2f\u3002 +Advanced=\u9032\u968e diff --git a/core/src/main/resources/lib/form/apply_pt_BR.properties b/core/src/main/resources/lib/form/apply_pt_BR.properties new file mode 100644 index 000000000000..877d08db1a58 --- /dev/null +++ b/core/src/main/resources/lib/form/apply_pt_BR.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Apply=Aplicar diff --git a/core/src/main/resources/lib/form/apply_zh_TW.properties b/core/src/main/resources/lib/form/apply_zh_TW.properties new file mode 100644 index 000000000000..c1d47cf93eea --- /dev/null +++ b/core/src/main/resources/lib/form/apply_zh_TW.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2018 suren +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Apply=\u5957\u7528 diff --git a/core/src/main/resources/lib/form/booleanRadio.jelly b/core/src/main/resources/lib/form/booleanRadio.jelly index 2f9bca9b9b04..d66affd233c5 100644 --- a/core/src/main/resources/lib/form/booleanRadio.jelly +++ b/core/src/main/resources/lib/form/booleanRadio.jelly @@ -39,9 +39,7 @@ THE SOFTWARE. - - - - + + diff --git a/core/src/main/resources/lib/form/bottomButtonBar.jelly b/core/src/main/resources/lib/form/bottomButtonBar.jelly index d6983f89e99e..c4766a688703 100644 --- a/core/src/main/resources/lib/form/bottomButtonBar.jelly +++ b/core/src/main/resources/lib/form/bottomButtonBar.jelly @@ -27,14 +27,12 @@ THE SOFTWARE. Creates a button bar at the bottom of the page for things like "Submit". The actual buttons should be specified as the body of this tag. - This area will always be visible in the bottom of the screen. + This area will always be visible at the bottom of the screen. - -
      -
      - -
      +
      +
      +
      - +
      diff --git a/core/src/main/resources/lib/form/breadcrumb-config-outline.jelly b/core/src/main/resources/lib/form/breadcrumb-config-outline.jelly index 19434e0f843c..e22a5861fdc9 100644 --- a/core/src/main/resources/lib/form/breadcrumb-config-outline.jelly +++ b/core/src/main/resources/lib/form/breadcrumb-config-outline.jelly @@ -26,8 +26,11 @@ THE SOFTWARE. Adds one more in-page breadcrumb that jumps to sections in the page. Put this tag right before <l:main-panel> + + Optional title for this breadcrumb + - - \ No newline at end of file + + diff --git a/core/src/main/resources/lib/form/breadcrumb-config-outline/init.js b/core/src/main/resources/lib/form/breadcrumb-config-outline/init.js index 46dc20a9e6f6..6a74045ea3ff 100644 --- a/core/src/main/resources/lib/form/breadcrumb-config-outline/init.js +++ b/core/src/main/resources/lib/form/breadcrumb-config-outline/init.js @@ -13,5 +13,9 @@ Event.observe(window, "load", function () { $(e.section).insert({top:"#"}); menu.add('#' + id, null, caption); }); - breadcrumbs.attachMenu('inpage-nav', menu); + var inpageNav = document.getElementById("inpage-nav") + var chevron = document.createElement("li") + chevron.classList.add("children") + inpageNav.parentNode.insertBefore(chevron, inpageNav.nextSibling); + breadcrumbs.attachMenu(chevron, menu); }); diff --git a/core/src/main/resources/lib/form/breadcrumb-config-outline_ar.properties b/core/src/main/resources/lib/form/breadcrumb-config-outline_ar.properties deleted file mode 100644 index 5dca61ba02f8..000000000000 --- a/core/src/main/resources/lib/form/breadcrumb-config-outline_ar.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -configuration=\u0625\u0639\u062F\u0627\u062F\u0627\u062A diff --git a/core/src/main/resources/lib/form/checkbox.jelly b/core/src/main/resources/lib/form/checkbox.jelly index dc63a1ca9123..99109623b996 100644 --- a/core/src/main/resources/lib/form/checkbox.jelly +++ b/core/src/main/resources/lib/form/checkbox.jelly @@ -46,7 +46,7 @@ THE SOFTWARE. If set to true, this will take precedence over the onclick attribute and prevent the state of the checkbox from being changed. - + Note: if you want an actual read only checkbox then add: <j:set var="readOnlyMode" value="true"/> inside your entry tag See https://www.jenkins.io/doc/developer/views/read-only/#enabling-read-only-view-support @@ -67,16 +67,18 @@ THE SOFTWARE. - - + + + + ${customizedFields.add(name)} diff --git a/core/src/main/resources/lib/form/combobox.jelly b/core/src/main/resources/lib/form/combobox.jelly index 8e9d16424730..c9c93658d436 100644 --- a/core/src/main/resources/lib/form/combobox.jelly +++ b/core/src/main/resources/lib/form/combobox.jelly @@ -62,7 +62,7 @@ THE SOFTWARE. Specify 'get' (must be lowercase) to change the HTTP method used for the AJAX requests to @checkUrl from a POST to a GET. If any other value is specified then requests will use POST. - The historical default was GET and 'post' had to be specified to change that, but this was changed in Jenkins 2.TODO. + The historical default was GET and 'post' had to be specified to change that, but this was changed in Jenkins 2.285. @@ -81,7 +81,7 @@ THE SOFTWARE. diff --git a/core/src/main/resources/lib/form/description.jelly b/core/src/main/resources/lib/form/description.jelly index 12bc8ab80575..a11363de8a09 100644 --- a/core/src/main/resources/lib/form/description.jelly +++ b/core/src/main/resources/lib/form/description.jelly @@ -27,11 +27,7 @@ THE SOFTWARE. Renders a row that shows description text below an input field. -
      -
      -
      - -
      -
      +
      +
      diff --git a/core/src/main/resources/lib/form/dropdownList.jelly b/core/src/main/resources/lib/form/dropdownList.jelly index 71e63400f400..159e4fc37ad9 100644 --- a/core/src/main/resources/lib/form/dropdownList.jelly +++ b/core/src/main/resources/lib/form/dropdownList.jelly @@ -38,17 +38,17 @@ THE SOFTWARE. -
      -
      +
      +
      ${attrs.title}
      -
      +
      - + diff --git a/core/src/main/resources/lib/form/form.jelly b/core/src/main/resources/lib/form/form.jelly index f2c5a61595ce..208177abb77d 100644 --- a/core/src/main/resources/lib/form/form.jelly +++ b/core/src/main/resources/lib/form/form.jelly @@ -38,9 +38,15 @@ THE SOFTWARE. but in Hudson you should have it for testing and page scraping, so this attribute is marked required. + + Classes to apply to the form + @enctype of the <form> HTML element. + + ID of the form. + @target of the <form> HTML element. Works like <a target="..."> and controls which window the result of the submission goes to. @@ -53,7 +59,7 @@ THE SOFTWARE. Default: false -
      +
      diff --git a/core/src/main/resources/lib/form/helpArea.jelly b/core/src/main/resources/lib/form/helpArea.jelly index 721748914ddc..4c8ab638cae0 100644 --- a/core/src/main/resources/lib/form/helpArea.jelly +++ b/core/src/main/resources/lib/form/helpArea.jelly @@ -23,11 +23,13 @@ THE SOFTWARE. --> - + Place holder to lazy-load help text via AJAX.
      -
      ${%Loading...}
      +
      + +
      diff --git a/core/src/main/resources/lib/form/helpArea_ar.properties b/core/src/main/resources/lib/form/helpArea_ar.properties deleted file mode 100644 index 9b01fbb13c6b..000000000000 --- a/core/src/main/resources/lib/form/helpArea_ar.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -Loading...=\u062C\u0627\u0631\u064A \u0627\u0644\u062A\u062D\u0645\u064A\u0644 diff --git a/core/src/main/resources/lib/form/helpLink.jelly b/core/src/main/resources/lib/form/helpLink.jelly index af1a1a7eafc3..0c1ab38aa7eb 100644 --- a/core/src/main/resources/lib/form/helpLink.jelly +++ b/core/src/main/resources/lib/form/helpLink.jelly @@ -53,13 +53,11 @@ THE SOFTWARE. - - - - + + + + ? + - - -
      diff --git a/core/src/main/resources/lib/form/helpLink_zh_TW.properties b/core/src/main/resources/lib/form/helpLink_zh_TW.properties new file mode 100644 index 000000000000..8cd5f5a7005f --- /dev/null +++ b/core/src/main/resources/lib/form/helpLink_zh_TW.properties @@ -0,0 +1 @@ +Help\ for\ feature\:=\u529f\u80fd\u8aaa\u660e\: diff --git a/core/src/main/resources/lib/form/hetero-list.jelly b/core/src/main/resources/lib/form/hetero-list.jelly index 966d72f81e51..098293450f37 100644 --- a/core/src/main/resources/lib/form/hetero-list.jelly +++ b/core/src/main/resources/lib/form/hetero-list.jelly @@ -70,8 +70,8 @@ THE SOFTWARE. to nominate additional variables and their values to be captured for descriptors. - If set to an item of the form className#classMethod, it will be used - to call className.classMethod(descriptor) to calculate each item title. + If set to an item of the form className#classMethod, it will be used + to call className.classMethod(descriptor) to calculate each item title. If true the drag and drop will not be activated. This just removes the drag and @@ -80,33 +80,28 @@ THE SOFTWARE. -
      +
      - -
      -
      -
      - ${descriptor.displayName} -
      - -
      -
      - - - + +
      +
      + + ${descriptor.displayName} + + + + + - +
      - + + + - - -
      - -
      -
      -
      + +
      @@ -114,7 +109,7 @@ THE SOFTWARE. -
      +
      diff --git a/core/src/main/resources/lib/form/number.jelly b/core/src/main/resources/lib/form/number.jelly index ffd5cb092abb..f437f83a21aa 100644 --- a/core/src/main/resources/lib/form/number.jelly +++ b/core/src/main/resources/lib/form/number.jelly @@ -25,7 +25,7 @@ THE SOFTWARE. - Generates an input field <input type="number" ... /> to be + Generates an input field <input type="number" ... /> to be used inside <f:entry/> @@ -79,7 +79,7 @@ THE SOFTWARE. Specify 'get' (must be lowercase) to change the HTTP method used for the AJAX requests to @checkUrl from a POST to a GET. If any other value is specified then requests will use POST. - The historical default was GET and 'post' had to be specified to change that, but this was changed in Jenkins 2.TODO. + The historical default was GET and 'post' had to be specified to change that, but this was changed in Jenkins 2.285. @@ -96,7 +96,7 @@ THE SOFTWARE. -
      +
      -
      +
      diff --git a/core/src/main/resources/lib/form/password.jelly b/core/src/main/resources/lib/form/password.jelly index 26fa75c615ca..538eb9753278 100644 --- a/core/src/main/resources/lib/form/password.jelly +++ b/core/src/main/resources/lib/form/password.jelly @@ -77,7 +77,7 @@ THE SOFTWARE.
      - - - - + +
      + + +
      + +
      +
      diff --git a/core/src/main/resources/lib/form/radioBlock.jelly b/core/src/main/resources/lib/form/radioBlock.jelly index 9a9db5b37760..93b2853f2bea 100644 --- a/core/src/main/resources/lib/form/radioBlock.jelly +++ b/core/src/main/resources/lib/form/radioBlock.jelly @@ -56,17 +56,20 @@ THE SOFTWARE.
      -
      -
      diff --git a/core/src/main/resources/lib/form/radioBlock/radioBlock.js b/core/src/main/resources/lib/form/radioBlock/radioBlock.js index 75d87b66f164..3d11d82c76ff 100644 --- a/core/src/main/resources/lib/form/radioBlock/radioBlock.js +++ b/core/src/main/resources/lib/form/radioBlock/radioBlock.js @@ -18,7 +18,11 @@ var radioBlockSupport = { n = blockStart; } while((n = n.next()) != blockEnd) { - n.style.display = show ? "" : "none"; + if (show) { + n.classList.remove("form-container--hidden") + } else { + n.classList.add("form-container--hidden") + } } layoutUpdateCallback.call(); } @@ -27,6 +31,7 @@ var radioBlockSupport = { // this needs to happen before TR.row-set-end rule kicks in. Behaviour.specify("INPUT.radio-block-control", 'radioBlock', -100, function(r) { r.id = "radio-block-"+(iota++); + r.nextSibling.setAttribute("for", r.id); // when one radio button is clicked, we need to update foldable block for // other radio buttons with the same name. To do this, group all the diff --git a/core/src/main/resources/lib/form/readOnlyTextbox.jelly b/core/src/main/resources/lib/form/readOnlyTextbox.jelly index 5ce6208f6e83..1bf9e3e2b207 100644 --- a/core/src/main/resources/lib/form/readOnlyTextbox.jelly +++ b/core/src/main/resources/lib/form/readOnlyTextbox.jelly @@ -25,7 +25,7 @@ THE SOFTWARE. - Generates an input field <input type="text" ... /> to be + Generates an input field <input type="text" ... /> to be used inside <f:entry/> @@ -62,7 +62,7 @@ THE SOFTWARE. -
      -
      ${header}
      +
      +
      + ${header} +
      diff --git a/core/src/main/resources/lib/form/repeatable/repeatable.js b/core/src/main/resources/lib/form/repeatable/repeatable.js index 1bd4efddf698..e30e636c3820 100644 --- a/core/src/main/resources/lib/form/repeatable/repeatable.js +++ b/core/src/main/resources/lib/form/repeatable/repeatable.js @@ -121,8 +121,10 @@ var repeatableSupport = { a.onComplete.subscribe(function() { var p = n.parentNode; p.removeChild(n); - if (p.tag) + if (p.tag) { p.tag.update(); + } + layoutUpdateCallback.call(); }); a.animate(); }, @@ -145,6 +147,7 @@ var repeatableSupport = { updateOptionalBlock(input, false); } } + layoutUpdateCallback.call(); } }; @@ -170,22 +173,34 @@ Behaviour.specify("INPUT.repeatable-add", 'repeatable', 0, function(e) { e = null; // avoid memory leak }); -Behaviour.specify("INPUT.repeatable-delete", 'repeatable', 0, function(e) { - var b = makeButton(e,function(e) { - repeatableSupport.onDelete(e.target); - }); - var be = $(b.get("element")); - be.on("mouseover",function() { - $(this).up(".repeated-chunk").addClassName("hover"); - }); - be.on("mouseout",function() { - $(this).up(".repeated-chunk").removeClassName("hover"); - }); +/** + * Converts markup for plugins that aren't using the repeatableDeleteButton tag + */ +Behaviour.specify('input.repeatable-delete', 'repeatable-button-fallbacks', 0, function (input) { + var button = document.createElement("button"); + for (var index = input.attributes.length - 1; index >= 0; --index) { + button.attributes.setNamedItem(input.attributes[index].cloneNode()); + } + if (input.value) { + button.setAttribute("tooltip", input.value); + button.removeAttribute("value"); + } + + button.classList.add('danger'); + + button.innerHTML = '' + input.parentNode.replaceChild(button, input); + console.warn('Adapted element to new markup, it should be changed to use f:repeatableDeleteButton instead in the plugin', button) +}); + - e = be = null; // avoid memory leak +Behaviour.specify("BUTTON.repeatable-delete, INPUT.repeatable-delete", 'repeatable', 1, function(e) { + e.addEventListener("click", function() { + repeatableSupport.onDelete(e); + }) }); - // radio buttons in repeatable content +// radio buttons in repeatable content // Needs to run before the radioBlock behavior so that names are already unique. Behaviour.specify("DIV.repeated-chunk", 'repeatable', -200, function(d) { var inputs = d.getElementsByTagName('INPUT'); @@ -203,4 +218,4 @@ Behaviour.specify("DIV.repeated-chunk", 'repeatable', -200, function(d) { if (inputs[i].defaultChecked) inputs[i].checked = true; } } -}); \ No newline at end of file +}); diff --git a/core/src/main/resources/lib/form/repeatableDeleteButton.jelly b/core/src/main/resources/lib/form/repeatableDeleteButton.jelly index 9e676217b25f..e00c346a1810 100644 --- a/core/src/main/resources/lib/form/repeatableDeleteButton.jelly +++ b/core/src/main/resources/lib/form/repeatableDeleteButton.jelly @@ -32,5 +32,7 @@ THE SOFTWARE. - + diff --git a/core/src/main/resources/lib/form/richtextarea.jelly b/core/src/main/resources/lib/form/richtextarea.jelly index 7649ed5e88a0..00ee41bce4ac 100644 --- a/core/src/main/resources/lib/form/richtextarea.jelly +++ b/core/src/main/resources/lib/form/richtextarea.jelly @@ -34,7 +34,7 @@ THE SOFTWARE. diff --git a/core/src/main/resources/lib/form/rowSet.jelly b/core/src/main/resources/lib/form/rowSet.jelly index 0f6f863a9f77..2ede2c842d40 100644 --- a/core/src/main/resources/lib/form/rowSet.jelly +++ b/core/src/main/resources/lib/form/rowSet.jelly @@ -35,21 +35,25 @@ THE SOFTWARE. id of the thing that serves as the group head, if that's available separately + + Removes the "jenkins-form-item" class if false + + + Classes to apply to the container (this will be the form item if 'isFormItem' is true) + -
      - - - - - - + + + + + + +
      -
      - -
      +
      - - -
      +
      + + diff --git a/core/src/main/resources/lib/form/secretTextarea/secret.js b/core/src/main/resources/lib/form/secretTextarea/secret.js index c2b312144075..d46feabab6c4 100644 --- a/core/src/main/resources/lib/form/secretTextarea/secret.js +++ b/core/src/main/resources/lib/form/secretTextarea/secret.js @@ -71,7 +71,5 @@ Behaviour.specify('.secret', 'secret-button', 0, function (e) { clearSecretValue(); replaceUpdateButton(); removeSecretLegendLabel(); - // fix UI bug when DOM changes - Event.fire(window, 'jenkins:bottom-sticker-adjust'); }; }); diff --git a/core/src/main/resources/lib/form/secretTextarea_pt_BR.properties b/core/src/main/resources/lib/form/secretTextarea_pt_BR.properties new file mode 100644 index 000000000000..8b161f74d539 --- /dev/null +++ b/core/src/main/resources/lib/form/secretTextarea_pt_BR.properties @@ -0,0 +1,27 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +EnterSecret=Entre um novo segredo abaixo +Concealed=Escondido por confidencialidade +Replace=Trocar +Add=Adicionar +NoStoredValue=Nenhum valor armazenado diff --git a/core/src/main/resources/lib/form/secretTextarea_zh_TW.properties b/core/src/main/resources/lib/form/secretTextarea_zh_TW.properties new file mode 100644 index 000000000000..f99a878934e0 --- /dev/null +++ b/core/src/main/resources/lib/form/secretTextarea_zh_TW.properties @@ -0,0 +1,28 @@ +# +# The MIT License +# +# Copyright (c) 2019 CloudBees, Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +# +Add=\u52a0\u5165 +Replace=\u53d6\u4ee3 +EnterSecret=\u5728\u4e0b\u65b9\u8f38\u5165\u65b0 Secret +Concealed=\u70ba\u4fdd\u5bc6\u800c\u96b1\u85cf +NoStoredValue=\u6c92\u6709\u5df2\u5132\u5b58\u7684\u503c diff --git a/core/src/main/resources/lib/form/section.jelly b/core/src/main/resources/lib/form/section.jelly index 204998fcbeae..3322dd3e701d 100644 --- a/core/src/main/resources/lib/form/section.jelly +++ b/core/src/main/resources/lib/form/section.jelly @@ -37,14 +37,15 @@ THE SOFTWARE. + - - -
      +
      + +
      ${title}
      - -
      - + + +
      \ No newline at end of file diff --git a/core/src/main/resources/lib/form/section_.css b/core/src/main/resources/lib/form/section_.css deleted file mode 100644 index 77d5f76211ed..000000000000 --- a/core/src/main/resources/lib/form/section_.css +++ /dev/null @@ -1,9 +0,0 @@ -.section-header { - font-weight: 600; - font-size: 1.25rem; - line-height: 1.2; - border-bottom: 1px solid #e0e0e0; - margin-bottom: 0.75rem; - margin-top: 1.5rem; - padding-bottom: 3px; -} diff --git a/core/src/main/resources/lib/form/section_.js b/core/src/main/resources/lib/form/section_.js index b6f0732dc864..a0c177c24726 100644 --- a/core/src/main/resources/lib/form/section_.js +++ b/core/src/main/resources/lib/form/section_.js @@ -52,8 +52,9 @@ var section = (function (){ for (var e=dom.firstChild; e!=null; e=e.nextSibling) { if (e.nodeType==1) { - if (e.className=="section-header" && isVisible(e)) { + if (e.className == "jenkins-section__title" && isVisible(e)) { var child = new SectionNode(e); + parent.children.push(child); // The next line seems to be unnecessary, as there are no children inside the section header itself. // So this code will always returns a flat list of section headers. diff --git a/core/src/main/resources/lib/form/select.jelly b/core/src/main/resources/lib/form/select.jelly index 7abbec55597d..2f4ee0d836f5 100644 --- a/core/src/main/resources/lib/form/select.jelly +++ b/core/src/main/resources/lib/form/select.jelly @@ -54,7 +54,7 @@ THE SOFTWARE. Specify 'get' (must be lowercase) to change the HTTP method used for the AJAX requests to @checkUrl from a POST to a GET. If any other value is specified then requests will use POST. - The historical default was GET and 'post' had to be specified to change that, but this was changed in Jenkins 2.TODO. + The historical default was GET and 'post' had to be specified to change that, but this was changed in Jenkins 2.285. @@ -63,14 +63,16 @@ THE SOFTWARE. ${descriptor.calcFillSettings(field,attrs)} - - - - - +
      + + + + + +
      diff --git a/core/src/main/resources/lib/form/serverTcpPort.groovy b/core/src/main/resources/lib/form/serverTcpPort.groovy index 81c70ff3ee26..7840cde7f8f3 100644 --- a/core/src/main/resources/lib/form/serverTcpPort.groovy +++ b/core/src/main/resources/lib/form/serverTcpPort.groovy @@ -9,38 +9,19 @@ package lib.form * port number. The getter method should just expose the port number integer. */ +int port = instance ? instance[field] : 0 -int port = instance?instance[field]:0 - -def f=namespace(lib.FormTagLib) +def f = namespace(lib.FormTagLib) def type = "${field}.type" -def id = "${field}Id" // TODO: get rid of this -div(name:field) { - label { - f.radio(name: type, value:"fixed", - checked:port>0, onclick:"\$('${id}').disabled=false") - text(_("Fixed")) - text(" : ") +div(name: field) { + f.radio(name: type, value: "fixed", title: _("Fixed"), id: "radio-${field}-fixed", checked: port > 0) { + input(type: "number", class: "jenkins-input", name: "value", id: "${field}Id", placeholder: _("Port"), + value: port > 0 ? port : null, min: 0, max: 65535, step: 1) } - input(type:"number", "class":"number", name:"value", id:id, - value: port>0 ? port : null, disabled: port>0 ? null : "true", - min:0, max:65535, step:1) - - raw(" ") //////////////////////////// - label { - f.radio(name:type, value:"random", - checked:port==0, onclick:"\$('${id}').disabled=true") - text(_("Random")) - } + f.radio(name: type, value: "random", title: _("Random"), id: "radio-${field}-random", checked: port == 0) - raw(" ") //////////////////////////// - - label { - f.radio(name:type, value:"disable", - checked:port==-1, onclick:"\$('${id}').disabled=true") - text(_("Disable")) - } + f.radio(name: type, value: "disable", title: _("Disable"), id: "radio-${field}-disable", checked: port == -1) } diff --git a/core/src/main/resources/lib/form/slave-mode.jelly b/core/src/main/resources/lib/form/slave-mode.jelly index fef9425f082c..b338b4ef0c88 100644 --- a/core/src/main/resources/lib/form/slave-mode.jelly +++ b/core/src/main/resources/lib/form/slave-mode.jelly @@ -42,11 +42,13 @@ THE SOFTWARE. - +
      + +
      diff --git a/core/src/main/resources/lib/form/textarea.jelly b/core/src/main/resources/lib/form/textarea.jelly index ab7df226e634..64bae2e84e87 100644 --- a/core/src/main/resources/lib/form/textarea.jelly +++ b/core/src/main/resources/lib/form/textarea.jelly @@ -58,12 +58,12 @@ THE SOFTWARE. Specify 'get' (must be lowercase) to change the HTTP method used for the AJAX requests to @checkUrl from a POST to a GET. If any other value is specified then requests will use POST. - The historical default was GET and 'post' had to be specified to change that, but this was changed in Jenkins 2.TODO. + The historical default was GET and 'post' had to be specified to change that, but this was changed in Jenkins 2.285. Turns this text area into CodeMirror-assisted code editing text area. This attribute specifies the mode of CodeMirror, such as "text/x-java". - See http://codemirror.net/ for more details. + See https://codemirror.net/ for more details. Specifies additional key/value pairs in the JSON format (except the start and end bracket) @@ -90,7 +90,7 @@ THE SOFTWARE.

      HACK

      "); + ExpandableTextBoxProperty xssProperty = new ExpandableTextBoxProperty("

      HACK

      "); FreeStyleProject p = j.createFreeStyleProject(); p.addProperty(xssProperty); @@ -161,7 +164,7 @@ public void noXssUsingInputValue() throws Exception { int numberOfH1Before = configurePage.getElementsByTagName("h1").size(); - HtmlInput xssInput = configurePage.getElementByName("_.xss"); + HtmlInput xssInput = configurePage.getElementByName("_.theField"); HtmlInput expandButton = (HtmlInput) xssInput.getParentNode().getNextSibling().getFirstChild(); HtmlElementUtil.click(expandButton); @@ -171,19 +174,37 @@ public void noXssUsingInputValue() throws Exception { assertEquals(numberOfH1Before, numberOfH1After); } - public static final class XssProperty extends OptionalJobProperty> { + @Test + @Issue("JENKINS-67627") + public void expandsIntoNewlines() throws Exception { + OptionalJobProperty property = new ExpandableTextBoxProperty("foo bar baz"); // A bit of a misnomer here, we're using code for an existing test + FreeStyleProject p = j.createFreeStyleProject(); + p.addProperty(property); + + JenkinsRule.WebClient wc = j.createWebClient(); + HtmlPage configurePage = wc.getPage(p, "configure"); + + HtmlInput input = configurePage.getElementByName("_.theField"); + HtmlInput expandButton = (HtmlInput) input.getParentNode().getNextSibling().getFirstChild(); + HtmlElementUtil.click(expandButton); + final DomElement textArea = configurePage.getElementByName("_.theField"); + assertTrue(textArea instanceof HtmlTextArea); + assertEquals("foo\nbar\nbaz", ((HtmlTextArea) textArea).getText()); + } + + public static final class ExpandableTextBoxProperty extends OptionalJobProperty> { - private String xss; + private String theField; - public XssProperty(String xss){ - this.xss = xss; + public ExpandableTextBoxProperty(String theField) { + this.theField = theField; } - public String getXss() { - return xss; + public String getTheField() { + return theField; } - @TestExtension("noXssUsingInputValue") + @TestExtension({"noXssUsingInputValue", "expandsIntoNewlines"}) public static class DescriptorImpl extends OptionalJobProperty.OptionalJobPropertyDescriptor { } } diff --git a/test/src/test/java/lib/form/FormTest.java b/test/src/test/java/lib/form/FormTest.java index 380ba682bd8c..908d4c39d115 100644 --- a/test/src/test/java/lib/form/FormTest.java +++ b/test/src/test/java/lib/form/FormTest.java @@ -1,10 +1,14 @@ package lib.form; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + import com.gargoylesoftware.htmlunit.html.HtmlForm; import com.gargoylesoftware.htmlunit.html.HtmlInput; import com.gargoylesoftware.htmlunit.html.HtmlPage; import hudson.model.InvisibleAction; import hudson.model.RootAction; +import java.io.IOException; import org.junit.Rule; import org.junit.Test; import org.jvnet.hudson.test.Issue; @@ -12,11 +16,6 @@ import org.jvnet.hudson.test.TestExtension; import org.xml.sax.SAXException; -import java.io.IOException; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - /** * Tests for lib/form.jelly. */ diff --git a/test/src/test/java/lib/form/HeteroListTest.java b/test/src/test/java/lib/form/HeteroListTest.java index 807570c674f5..071b7dd55df3 100644 --- a/test/src/test/java/lib/form/HeteroListTest.java +++ b/test/src/test/java/lib/form/HeteroListTest.java @@ -21,8 +21,16 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package lib.form; +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + import com.gargoylesoftware.htmlunit.html.DomElement; import com.gargoylesoftware.htmlunit.html.HtmlButton; import com.gargoylesoftware.htmlunit.html.HtmlElementUtil; @@ -38,6 +46,10 @@ import hudson.tools.ToolInstaller; import hudson.tools.ToolProperty; import hudson.util.FormValidation; +import java.io.File; +import java.util.Collections; +import java.util.List; +import java.util.Optional; import net.sourceforge.htmlunit.corejs.javascript.NativeArray; import org.jenkinsci.Symbol; import org.junit.Rule; @@ -46,19 +58,6 @@ import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.TestExtension; -import java.io.File; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Optional; - -import static org.hamcrest.CoreMatchers.containsString; -import static org.hamcrest.CoreMatchers.instanceOf; -import static org.hamcrest.CoreMatchers.not; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - public class HeteroListTest { @Rule public JenkinsRule j = new JenkinsRule(); @@ -70,7 +69,7 @@ public void xssPrevented_heteroList_usingDescriptorDisplayName() throws Exceptio RootActionImpl rootAction = ExtensionList.lookupSingleton(RootActionImpl.class); TestItemDescribable.DynamicDisplayNameDescriptor dynamic = ExtensionList.lookupSingleton(TestItemDescribable.DynamicDisplayNameDescriptor.class); - rootAction.descriptorList = Arrays.asList(dynamic); + rootAction.descriptorList = Collections.singletonList(dynamic); dynamic.displayName = "DisplayName"; @@ -86,7 +85,7 @@ public void xssPrevented_heteroList_usingDescriptorDisplayName() throws Exceptio // correspond to the hardening of escapeEntryTitleAndDescription @Test - @Issue("SECURITY-2035") + @Issue("SECURITY-2035") public void xssPrevented_usingToolInstallation_withJustDisplayName() throws Exception { JenkinsRule.WebClient wc = j.createWebClient(); @@ -94,8 +93,8 @@ public void xssPrevented_usingToolInstallation_withJustDisplayName() throws Exce // check the displayName Object resultDN = page.executeJavaScript( - "var settingFields = document.querySelectorAll('.setting-name');" + - "var children = Array.from(settingFields).filter(b => b.textContent.indexOf('XSS:') !== -1)[0].children;" + + "var settingFields = document.querySelectorAll('.jenkins-form-label');" + + "var children = Array.from(settingFields).filter(b => b.textContent.indexOf('XSS:') !== -1)[0].children;" + "Array.from(children).filter(c => c.tagName === 'IMG')" ).getJavaScriptResult(); assertThat(resultDN, instanceOf(NativeArray.class)); @@ -104,7 +103,7 @@ public void xssPrevented_usingToolInstallation_withJustDisplayName() throws Exce // check the description Object resultDesc = page.executeJavaScript( - "var settingFields = document.querySelectorAll('.setting-description');" + + "var settingFields = document.querySelectorAll('.jenkins-form-description');" + "var children = Array.from(settingFields).filter(b => b.textContent.indexOf('XSS:') !== -1)[0].children;" + "Array.from(children).filter(c => c.tagName === 'IMG')" ).getJavaScriptResult(); @@ -183,14 +182,15 @@ public void xssPrevented_usingToolInstallation_repeatableAddWithExistingAfterOpe // While keeping away the installations... advanced button as it's covered in its own test Object result = page.executeJavaScript("Array.from(document.querySelectorAll('button')).filter(b => b.textContent.indexOf('XSS') !== -1 && b.textContent.indexOf('...') === -1).map(b => b.innerHTML)").getJavaScriptResult(); assertThat(result, instanceOf(List.class)); - List resultArray = (List) result; - for (int i = 0; i < resultArray.size(); i++) { - assertThat((String) resultArray.get(i), not(containsString("<"))); + @SuppressWarnings("unchecked") + List resultList = (List) result; + for (String str : resultList) { + assertThat(str, not(containsString("<"))); } - + // "delete" then "add" makes us coming back in scenario covered by xssUsingToolInstallationRepeatableAdd } - + @Test @Issue("SECURITY-2035") public void xssPrevented_usingToolInstallation_repeatableDelete() throws Exception { @@ -201,13 +201,14 @@ public void xssPrevented_usingToolInstallation_repeatableDelete() throws Excepti // we could also re-use the same method as used in xssUsingToolInstallationRepeatableAdd page.executeJavaScript("Array.from(document.querySelectorAll('button')).filter(b => b.textContent.indexOf('Add XSS') !== -1)[0].click()"); - Object result = page.executeJavaScript("Array.from(document.querySelectorAll('button')).filter(b => b.textContent.indexOf('Delete XSS') !== -1)[0].innerHTML").getJavaScriptResult(); + Object result = page.executeJavaScript("Array.from(document.querySelectorAll('button')).filter(b => b.title.includes('Delete XSS'))[0].innerHTML").getJavaScriptResult(); assertThat(result, instanceOf(String.class)); String resultString = (String) result; - assertThat(resultString, not(containsString("<"))); + assertThat(resultString, not(containsString(" { + @Override public Descriptor getDescriptor() { return ExtensionList.lookupSingleton(DynamicDisplayNameDescriptor.class); } @@ -227,16 +228,19 @@ public String getDisplayName() { public static class RootActionImpl implements UnprotectedRootAction { public List> descriptorList; + @Override @CheckForNull public String getIconFileName() { return null; } + @Override @CheckForNull public String getDisplayName() { return null; } + @Override @CheckForNull public String getUrlName() { return "root"; @@ -254,8 +258,9 @@ public Xss(String name, String home, List> properties) public static class DescriptorImpl extends ToolDescriptor { private Xss[] installations = new Xss[0]; + @Override public String getDisplayName() { - return "XSS: "; + return "XSS: "; } @Override diff --git a/test/src/test/java/lib/form/NameRefTest.java b/test/src/test/java/lib/form/NameRefTest.java index ebe5f4d96d3e..6337d3f54fbd 100644 --- a/test/src/test/java/lib/form/NameRefTest.java +++ b/test/src/test/java/lib/form/NameRefTest.java @@ -21,11 +21,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package lib.form; +import static org.junit.Assert.assertEquals; + import com.gargoylesoftware.htmlunit.html.HtmlPage; import net.sf.json.JSONObject; -import static org.junit.Assert.assertEquals; import org.junit.Rule; import org.junit.Test; import org.jvnet.hudson.test.JenkinsRule; @@ -51,7 +53,7 @@ public static class JenkinsRuleWithJelly extends JenkinsRule { public HttpResponse doSubmitTest1(StaplerRequest req) throws Exception { JSONObject f = req.getSubmittedForm(); System.out.println(f); - assertEquals("{\"foo\":{\"bar\":{\"zot\":\"zot\"}}}",f.toString()); + assertEquals("{\"foo\":{\"bar\":{\"zot\":\"zot\"}}}", f.toString()); return HttpResponses.ok(); } diff --git a/test/src/test/java/lib/form/NumberTest.java b/test/src/test/java/lib/form/NumberTest.java index 09e0baeda20f..0bef86dbc26f 100644 --- a/test/src/test/java/lib/form/NumberTest.java +++ b/test/src/test/java/lib/form/NumberTest.java @@ -1,21 +1,22 @@ package lib.form; -import com.gargoylesoftware.htmlunit.html.*; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.emptyString; +import static org.junit.Assert.assertEquals; + +import com.gargoylesoftware.htmlunit.html.HtmlForm; +import com.gargoylesoftware.htmlunit.html.HtmlInput; +import com.gargoylesoftware.htmlunit.html.HtmlPage; import com.gargoylesoftware.htmlunit.javascript.host.event.Event; import hudson.model.InvisibleAction; import hudson.model.RootAction; +import java.io.IOException; import org.junit.Rule; import org.junit.Test; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.TestExtension; import org.xml.sax.SAXException; -import static org.junit.Assert.assertEquals; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.emptyString; - -import java.io.IOException; - /** * Tests for lib/number.jelly. */ diff --git a/test/src/test/java/lib/form/OptionTest.java b/test/src/test/java/lib/form/OptionTest.java index 2b6163324736..ef7bc66040fc 100644 --- a/test/src/test/java/lib/form/OptionTest.java +++ b/test/src/test/java/lib/form/OptionTest.java @@ -21,8 +21,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package lib.form; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; + import com.gargoylesoftware.htmlunit.html.DomElement; import com.gargoylesoftware.htmlunit.html.DomNodeList; import com.gargoylesoftware.htmlunit.html.HtmlElement; @@ -35,10 +40,6 @@ import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.TestExtension; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertTrue; - /** * Tests for lib/form/option.jelly */ @@ -120,14 +121,14 @@ private void checkNonDangerousOutputCorrect_advanced() throws Exception { } } - private String escapeForBody(String str){ + private String escapeForBody(String str) { return str .replace("&", "&") .replace("<", "<") ; } - private String escapeForBody_alternate(String str){ + private String escapeForBody_alternate(String str) { return str .replace("&", "&") .replace("<", "<") @@ -137,7 +138,7 @@ private String escapeForBody_alternate(String str){ - private String escapeForValue(String str){ + private String escapeForValue(String str) { return str .replace("&", "&") .replace("<", "<") @@ -146,7 +147,7 @@ private String escapeForValue(String str){ ; } - private String escapeForBody_uglyButSafe(String str){ + private String escapeForBody_uglyButSafe(String str) { return str .replace("&", "&") .replace("<", "<") @@ -157,7 +158,7 @@ private String escapeForBody_uglyButSafe(String str){ ; } - private String escapeForValue_uglyButSafe(String str){ + private String escapeForValue_uglyButSafe(String str) { return str .replace("&", "&") .replace("<", "<") @@ -219,11 +220,11 @@ private void checkJelly(int mode, String msgToInject, view.setMode(mode); view.setInjection(msgToInject); - if(withValueTrue){ + if (withValueTrue) { view.setWithValue(true); callPageAndCheckIfResultContainsExpected("usingJelly", bodyContainsExpected, valueContainsExpected, checkExactCharacters); } - if(withValueFalse){ + if (withValueFalse) { view.setWithValue(false); callPageAndCheckIfResultContainsExpected("usingJelly", bodyContainsExpected, valueContainsExpected, checkExactCharacters); } @@ -245,11 +246,11 @@ private void checkGroovy(int mode, String msgToInject, view.setMode(mode); view.setInjection(msgToInject); - if(withValueTrue){ + if (withValueTrue) { view.setWithValue(true); callPageAndCheckIfResultContainsExpected("usingGroovy", bodyContainsExpected, valueContainsExpected, checkExactCharacters); } - if(withValueFalse){ + if (withValueFalse) { view.setWithValue(false); callPageAndCheckIfResultContainsExpected("usingGroovy", bodyContainsExpected, valueContainsExpected, checkExactCharacters); } @@ -259,7 +260,7 @@ private void callPageAndCheckIfResultContainsExpected(String url, String bodyCon HtmlPage page = (HtmlPage) j.createWebClient().goTo(url, null); String responseContent = page.getWebResponse().getContentAsString(); - if(checkExactCharacters){ + if (checkExactCharacters) { // in this mode, we check the data directly received by the response, // without any un-escaping done by HtmlElement @@ -275,7 +276,7 @@ private void callPageAndCheckIfResultContainsExpected(String url, String bodyCon // also check there is no "