diff --git a/.gitignore b/.gitignore index 52058c8..0404fcf 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ .idea/ target/ +gradle/ *.iml diff --git a/.p4ignore b/.p4ignore index 8804c1a..2f07e9f 100644 --- a/.p4ignore +++ b/.p4ignore @@ -1,5 +1,7 @@ .gitattributes .idea/ +build/ +.gradle/ *.class # Package Files # @@ -22,6 +24,7 @@ target/ *.iml .p4config +.p4tickets .gitignore .DS_Store *.versionsBackup diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..5425c3c --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,83 @@ +pipeline { + + agent none + + stages { + + stage('Compile') { + agent { + label 'p4java' + } + steps { + sh './gradlew clean assemble' + + } + } + + stage('Verification') { + parallel { + + stage('ubuntu') { + agent { + label 'p4java' + } + stages { + stage('Test') { + steps { + lock("eng-p4java-vm_lock") { + sh './gradlew clean build' + + } + } + } + } + post { + always { + report('UbuntuTestReport') + + } + } + } + + stage('win') { + agent { + label 'p4java-win' + } + stages { + stage('Test') { + steps { + lock("eng-p4java-vm_lock") { + bat label: '', script: 'gradlew clean build' + + } + } + } + } + post { + always { + report('WindowsTestReport') + } + } + } + } + } + + stage('Launch system tests') { + steps { + build job: '/p4java-system-tests/main', wait: false + } + } + } +} + + +void report(String name) { + publishHTML target: [ + allowMissing : false, + alwaysLinkToLastBuild: true, + keepAll : true, + reportDir : 'build/reports/tests/test/', + reportFiles : 'index.html', + reportName : name + ] +} diff --git a/LICENSE.txt b/LICENSE.txt index 36bafe0..44cb43d 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -22,17 +22,25 @@ THE SOFTWARE. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + + 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE @@ -46,6 +54,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This distribution also includes the following third party software; please consult the accompanying license file for the license terms that apply to that software only: +commons-codec-1.15.jar + Licenses: + License: Apache 2.0 + Reference: https://repository.apache.org/content/repositories/releases/commons-codec/commons-codec/1.15/commons-codec-1.15.pom + LicenseText: License Text Under Appendix + + Copyrights: + Copyright: Copyright The Apache Software Foundation + Reference: https://commons.apache.org/ + commons-io-2.11.0.jar Licenses: License: Apache 2.0 @@ -57,23 +75,27 @@ commons-io-2.11.0.jar Reference: https://index.whitesourcesoftware.com/gri/app/reader/resource/content/asString/454db108-23ea-4a10-ab65-9a699dc34ab2 Author: The Apache Software Foundation -commons-lang3-3.4.jar +commons-lang3-3.12.0.jar Licenses: License: Apache 2.0 - Reference: https://repo.maven.apache.org/maven2/org/apache/commons/commons-lang3/3.4/commons-lang3-3.4.pom + Reference: https://repo.maven.apache.org/maven2/org/apache/commons/commons-lang3/3.12.0/commons-lang3-3.12.0.pom LicenseText: License Text Under Appendix Copyrights: - Copyright: Copyright 2001-2015 The Apache Software Foundation - Reference: https://index.whitesourcesoftware.com/gri/app/reader/resource/content/asString/93e762c7-d7d9-46dc-94cc-1e3ff8315f90 + Copyright: Copyright 2001-2021 The Apache Software Foundation + Reference: https://index.whitesourcesoftware.com/gri/app/reader/resource/content/asString/11239b3a-f2b6-4016-bd0c-c0ce1d0fa09e Author: The Apache Software Foundation -jsr305-3.0.1.jar +jsr305-3.0.2.jar Licenses: License: Apache 2.0 - Reference: https://repo.maven.apache.org/maven2/com/google/code/findbugs/jsr305/3.0.1/jsr305-3.0.1.pom + Reference: https://repo.maven.apache.org/maven2/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.pom LicenseText: License Text Under Appendix + Copyrights: + Copyright: Copyright 2012 http://findbugs.sourceforge.net/ + Reference: University of Maryland + jzlib-1.1.3.jar Licenses: License: BSD 3 @@ -141,198 +163,198 @@ Apache 2.0 1. Definitions. - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright [yyyy] [name of copyright owner] - Licensed 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 + Licensed 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 + 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. + 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. diff --git a/RELEASE.md b/RELEASE.md index 62e1fb1..8d59297 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,7 +1,7 @@ Release Notes for P4Java, the Perforce Java API - Version 2021.2 Patch 5 + Version 2022.1 Introduction @@ -120,7 +120,35 @@ Known Limitations /lib/security/local_policy.jar /lib/security/US_export_policy.jar - + +------------------------------------------- +Updates in 2022.1 (2022/09/29) + + #2345331 (Job #111078) + Added support to uncompress the compressed files received from server + + #2325394 (Job #111560) + Added functionality to remove file revision attributes + + #2322763 (Job #110629) + Added support for special characters (@, %, # and *) in the file spec + builder by adding ‘makeFileSpecListSpecialChars’ method + + #2328997, #2330279 (Job #110207) + Fixed a bug where sync of unicode files with bad charset was causing + corrupt files on the workspace without throwing an error + + #2346483 (Job #109218) + Fixed a bug where moves with an overlap between source and target + file/directory names raised an error. + + #2333818 (Job #112005) + Fixed a bug where unending sync operation was being caused when the + client compression option was set + + With this release we have migrated P4Java build from from Maven to + Gradle using Gradle wrapper 7.5 + ------------------------------------------- Updates in 2021.2 Patch 5 diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..fa4e22c --- /dev/null +++ b/build.gradle @@ -0,0 +1,138 @@ +plugins { + id 'java-library' + id 'maven-publish' + id 'signing' +} + +group = 'com.perforce' +version = project.hasProperty('ver') ? project.ext.ver : 'PREP-TEST_ONLY' + +sourceCompatibility = 1.8 +targetCompatibility = 1.8 + +repositories { + maven { url "https://repo.maven.apache.org/maven2" } + maven { url "https://artifactory.bnr.perforce.com:8443/artifactory/snapshots/" } +} + +dependencies { + api 'com.jcraft:jzlib:1.1.3' + api 'org.apache.commons:commons-lang3:3.12.0' + api 'commons-codec:commons-codec:1.15' + api 'commons-io:commons-io:2.11.0' + api 'com.google.code.findbugs:jsr305:3.0.2' + + testImplementation 'org.slf4j:slf4j-api:1.7.36' + testImplementation 'org.slf4j:slf4j-simple:1.7.36' + testImplementation 'org.apache.commons:commons-exec:1.3' + testImplementation 'org.apache.commons:commons-compress:1.21' + testImplementation 'junit:junit:4.12' + testImplementation 'org.mockito:mockito-core:2.7.12' + testImplementation 'com.googlecode.java-diff-utils:diffutils:1.3.0' +} + +jar { + into("META-INF/maven/$project.group/$project.name") { + from { generatePomFileForMavenJavaPublication } + rename ".*", "pom.xml" + } +} + +publishing { + publications { + mavenJava(MavenPublication) { + from components.java + versionMapping { + usage('java-api') { + fromResolutionOf('runtimeClasspath') + } + usage('java-runtime') { + fromResolutionResult() + } + } + pom { + name = 'Perforce Java API' + description = 'P4Java, the Perforce Java API is a Java-native API for accessing Perforce SCM services from within Java' + url = 'https://github.com/perforce/p4java' + organization { + name = 'Perforce Software' + url = 'http://www.perforce.com' + } + licenses { + license { + name = 'Perforce Software' + url = 'https://www.perforce.com/perforce/doc.current/user/p4java_eula.txt' + } + } + developers { + developer { + id = 'p4java' + name = 'Perforce Software' + email = 'support+java@perforce.com' + } + } + scm { + connection = 'scm:git:https://github.com/perforce/p4java.git' + developerConnection = 'scm:git:https://github.com/perforce/p4java.git' + url = 'https://github.com/perforce/p4java' + } + } + } + } + + repositories { + def mavenUser = project.hasProperty('mavenUser') ? project.ext.mavenUser : '' + def mavenPassword = project.hasProperty('mavenPassword') ? project.ext.mavenPassword : '' + + maven { + name = 'p4mavencentral-staging' + url = 'https://oss.sonatype.org/service/local/staging/deploy/maven2/' + credentials { + username = mavenUser + password = mavenPassword + } + } + maven { + name = 'artifactory-snapshots' + url = 'https://artifactory.bnr.perforce.com:8443/artifactory/snapshots/' + credentials { + username = mavenUser + password = mavenPassword + } + } + maven { + name = 'artifactory-release' + url = 'https://artifactory.bnr.perforce.com:8443/artifactory/releases/' + credentials { + username = mavenUser + password = mavenPassword + } + } + } +} + +java { + withSourcesJar() + withJavadocJar() +} + +artifacts { + archives jar + archives javadocJar + archives sourcesJar +} + +tasks.withType(Javadoc) { + (options as StandardJavadocDocletOptions).addStringOption("Xmaxwarns", "500") + (options as StandardJavadocDocletOptions).addStringOption("Xmaxerrs", "500") +} + +// Report lint check details +tasks.withType(JavaCompile) { + options.compilerArgs.add("-Xlint:deprecation") + options.compilerArgs.add("-Xlint:unchecked") +} + +signing { + sign publishing.publications +} \ No newline at end of file diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..cccdd3d --- /dev/null +++ b/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..b113f38 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/pom.xml b/pom.xml deleted file mode 100644 index 98348ae..0000000 --- a/pom.xml +++ /dev/null @@ -1,123 +0,0 @@ - - 4.0.0 - com.perforce - p4java - jar - unset - Perforce Java API - http://www.perforce.com - - - Perforce Software - http://www.perforce.com - - - - P4Java, the Perforce Java API is a Java-native API for accessing Perforce SCM services from - within Java applications, servlets, plug-ins, and other Java contexts. - - - - - Perforce Software - LICENSE.txt - repo - - - - - scm:git:https://github.com/perforce/p4java.git - scm:git:https://github.com/perforce/p4java.git - https://github.com/perforce/p4java - - - - - p4java - Perforce Software - support+java@perforce.com - - - - - 1.7 - 1.7 - UTF-8 - 0 - releases - 1.6.5 - 4.12 - 5.0.0-M2 - 4.12.0-M2 - 1.0.0-M2 - - - - - com.jcraft - jzlib - 1.1.3 - - - org.apache.commons - commons-lang3 - 3.4 - - - org.apache.commons - commons-exec - 1.3 - - - commons-codec - commons-codec - 1.13 - - - commons-io - commons-io - 2.11.0 - - - com.google.code.findbugs - jsr305 - 3.0.1 - - - org.slf4j - slf4j-api - 1.7.24 - - - org.slf4j - slf4j-simple - 1.7.24 - - - org.apache.commons - commons-compress - 1.9 - test - - - junit - junit - ${junit.version} - test - - - org.mockito - mockito-core - 2.7.12 - test - - - com.googlecode.java-diff-utils - diffutils - 1.3.0 - test - - - diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..47c406b --- /dev/null +++ b/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'p4java' diff --git a/src/main/java/com/perforce/p4java/CharsetConverter.java b/src/main/java/com/perforce/p4java/CharsetConverter.java index 07d6e9a..8bd7d09 100644 --- a/src/main/java/com/perforce/p4java/CharsetConverter.java +++ b/src/main/java/com/perforce/p4java/CharsetConverter.java @@ -37,13 +37,12 @@ public class CharsetConverter { * Creates a new charset converted that decodes/encodes bytes in the * specified non-null from/to charset objects specified. * - * @param fromCharset - * @param toCharset + * @param fromCharset fromCharset + * @param toCharset toCharset * @param ignoreBOM - true to ignore any byte order marks written by the UTF-16 * charset and omit them from all return byte buffers */ - public CharsetConverter(Charset fromCharset, Charset toCharset, - boolean ignoreBOM) { + public CharsetConverter(Charset fromCharset, Charset toCharset, boolean ignoreBOM) { // Create decoder that reports malformed/unmappable values this.decoder = fromCharset.newDecoder(); this.decoder.onMalformedInput(CodingErrorAction.REPORT); @@ -74,8 +73,8 @@ public String getToCharsetName() { * Creates a new charset converted that decodes/encodes bytes in the * specified non-null from/to charset objects specified. * - * @param fromCharset - * @param toCharset + * @param fromCharset fromCharset + * @param toCharset toCharset */ public CharsetConverter(Charset fromCharset, Charset toCharset) { this(fromCharset, toCharset, false); @@ -86,11 +85,11 @@ public CharsetConverter(Charset fromCharset, Charset toCharset) { * any existing underflow since the characters to convert are already * complete and known. * - * @param from + * @param from from * @return - byte buffer, use {@link ByteBuffer#position()} for starting * array offset, {@link ByteBuffer#limit()} for number of bytes to * read, and {@link ByteBuffer#array()} for the byte[] itself. - * @throws FileEncoderException + * @throws FileEncoderException on error */ public ByteBuffer convert(CharBuffer from) throws FileEncoderException { ByteBuffer converted = null; @@ -125,8 +124,7 @@ public ByteBuffer convert(CharBuffer from) throws FileEncoderException { // byte value of -1 == 0xFF // Big Endian BOM = FEFF // Little Endiam BOM = FFFE - if ((bom[0] == -2 && bom[1] == -1) - || (bom[0] == -1 && bom[1] == -2)) { + if ((bom[0] == -2 && bom[1] == -1) || (bom[0] == -1 && bom[1] == -2)) { // Advance past BOM if detected converted.position(2); converted.limit(limit - 2); @@ -155,16 +153,16 @@ public ByteBuffer convert(CharBuffer from) throws FileEncoderException { * the byte buffer's backing array. *

* Any remaining bytes that couldn't be converted are stored locally until - * the next call to {@link #convert(ByteBuffer)}. The from buffer specified + * the next call to . The from buffer specified * will be joined with the underflow from a previous call on subsequent - * calls to {@link #convert(ByteBuffer)}. + * calls to . * * @param from - byte buffer to convert * @return - byte buffer, use {@link ByteBuffer#position()} for starting * array offset, {@link ByteBuffer#limit()} for number of bytes to * read, and {@link ByteBuffer#array()} for the byte[] itself. - * @throws FileEncoderException - * @throws FileDecoderException + * @throws FileEncoderException on error + * @throws FileDecoderException on error */ public ByteBuffer convert(ByteBuffer from) throws FileDecoderException, FileEncoderException { if (CharsetDefs.UTF8.equals(decoder.charset())) { @@ -192,7 +190,7 @@ public ByteBuffer convert(ByteBuffer from) throws FileDecoderException, FileEnco * * @param buffer utf8 byte stream * @return whole utf8 words to convert. - * @throws FileDecoderException + * @throws FileDecoderException on error */ private ByteBuffer getUtf8BufferWindow(ByteBuffer buffer) throws FileDecoderException { // Add remainder from previous calculation diff --git a/src/main/java/com/perforce/p4java/Log.java b/src/main/java/com/perforce/p4java/Log.java index fb35041..ef42646 100644 --- a/src/main/java/com/perforce/p4java/Log.java +++ b/src/main/java/com/perforce/p4java/Log.java @@ -9,14 +9,14 @@ /** * Simple P4Java-wide logger class based on the ILogCallback callback * interface. Useful for letting P4Java consumers report errors, - * warnings, etc., generated within P4Java into their own logs.

- * + * warnings, etc., generated within P4Java into their own logs. + *

* Note that absolutely no guarantees or specifications * are made about the format or content of strings that are passed through * the logging mechanism, but in general all such strings are useful for * Perforce support staff, and many info and stats strings passed to - * the callback may be generally useful for API consumers.

- * + * the callback may be generally useful for API consumers. + *

* The Log class is itself used from within P4Java to report log * messages; the intention here is to allow consumers to call the * setLogCallback static method with a suitable log listener that @@ -24,128 +24,129 @@ * besides the setLogCallback method are mainly intended for API-internal * use, but participating apps may find the other methods useful for * interpolating marker text or other messages to the API's log. - * - * @author sshou clean code & add vargs like slf4j */ public class Log { - private static ILogCallback logCallback = null; + private static ILogCallback logCallback = null; - /** - * Get the current log callback, if any. May return null. - */ - public static ILogCallback getLogCallback() { - return Log.logCallback; - } + /** + * @return the current log callback, if any. May return null. + */ + public static ILogCallback getLogCallback() { + return Log.logCallback; + } - /** - * Set the P4Java API's internal logger to log to the passed-in - * ILogCallback log callback. If the passed-in parameter is null, - * no logging will be performed. The caller is responsible for ensuring - * that there are not thread issues with the passed-in callback, and - * that callbacks to the callback object will not block or deadlock. - * - * @param logCallback callback to be used by P4Java to report log messages to; if null, stop - * logging. - * @return the previous callback registered, or null if no such callback existed. - */ - public static ILogCallback setLogCallback(ILogCallback logCallback) { - ILogCallback oldCallback = Log.logCallback; - Log.logCallback = logCallback; - return oldCallback; - } + /** + * Set the P4Java API's internal logger to log to the passed-in + * ILogCallback log callback. If the passed-in parameter is null, + * no logging will be performed. The caller is responsible for ensuring + * that there are not thread issues with the passed-in callback, and + * that callbacks to the callback object will not block or deadlock. + * + * @param logCallback callback to be used by P4Java to report log messages to; if null, stop + * logging. + * @return the previous callback registered, or null if no such callback existed. + */ + public static ILogCallback setLogCallback(ILogCallback logCallback) { + ILogCallback oldCallback = Log.logCallback; + Log.logCallback = logCallback; + return oldCallback; + } - /** - * Report a P4Java-internal error to the log callback (if it exists). - * - * @param errorString non-null error string. - */ - public static void error(String errorString, Object... args) { - if (nonNull(logCallback)) { - String errorMessage = errorString; - if (nonNull(args)) { - errorMessage = format(errorString, args); - } - logCallback.internalError(errorMessage); - } - } + /** + * Report a P4Java-internal error to the log callback (if it exists). + * + * @param errorString non-null error string. + * @param args args + */ + public static void error(String errorString, Object... args) { + if (nonNull(logCallback)) { + String errorMessage = errorString; + if (nonNull(args)) { + errorMessage = format(errorString, args); + } + logCallback.internalError(errorMessage); + } + } - /** - * Report a P4Java-internal warning to the log callback (if it exists). - * - * @param warnString non-null warning message. - */ - public static void warn(String warnString, Object... args) { - if (nonNull(logCallback)) { - String warningMessage = warnString; - if (nonNull(args)) { - warningMessage = format(warnString, args); - } - logCallback.internalWarn(warningMessage); - } - } + /** + * Report a P4Java-internal warning to the log callback (if it exists). + * + * @param warnString non-null warning message. + * @param args args + */ + public static void warn(String warnString, Object... args) { + if (nonNull(logCallback)) { + String warningMessage = warnString; + if (nonNull(args)) { + warningMessage = format(warnString, args); + } + logCallback.internalWarn(warningMessage); + } + } - /** - * Report a P4Java-internal informational event to the log callback (if it exists). - * - * @param infoString non-null info message. - */ - public static void info(String infoString, Object... args) { - if (nonNull(logCallback)) { - String infoMessage = infoString; - if (nonNull(args)) { - infoMessage = format(infoString, args); - } - logCallback.internalInfo(infoMessage); - } - } + /** + * Report a P4Java-internal informational event to the log callback (if it exists). + * + * @param infoString non-null info message. + * @param args args + */ + public static void info(String infoString, Object... args) { + if (nonNull(logCallback)) { + String infoMessage = infoString; + if (nonNull(args)) { + infoMessage = format(infoString, args); + } + logCallback.internalInfo(infoMessage); + } + } - /** - * Report a P4Java-internal statistics message to the log callback (if it exists). - * - * @param statsString non-null stats message. - */ - public static void stats(String statsString, Object... args) { - if (nonNull(logCallback)) { - String statsMessage = statsString; - if (nonNull(args)) { - statsMessage = format(statsString, args); - } - logCallback.internalStats(statsMessage); - } - } + /** + * Report a P4Java-internal statistics message to the log callback (if it exists). + * + * @param statsString non-null stats message. + * @param args args + */ + public static void stats(String statsString, Object... args) { + if (nonNull(logCallback)) { + String statsMessage = statsString; + if (nonNull(args)) { + statsMessage = format(statsString, args); + } + logCallback.internalStats(statsMessage); + } + } - /** - * Report a P4Java-internal unexpected exception to the log callback - * (if it exists). - * - * @param thr non-null Throwable - */ - public static void exception(Throwable thr) { - if (nonNull(logCallback) && nonNull(thr)) { - logCallback.internalException(thr); - } - } + /** + * Report a P4Java-internal unexpected exception to the log callback + * (if it exists). + * + * @param thr non-null Throwable + */ + public static void exception(Throwable thr) { + if (nonNull(logCallback) && nonNull(thr)) { + logCallback.internalException(thr); + } + } - /** - * Report a P4Java-internal trace message to the log callback - * (if it exists). - */ - public static void trace(LogTraceLevel traceLevel, String traceMessage) { - if (nonNull(logCallback) - && nonNull(traceLevel) - && nonNull(traceMessage) - && isTracingAtLevel(traceLevel)) { - logCallback.internalTrace(traceLevel, traceMessage); - } - } + /** + * Report a P4Java-internal trace message to the log callback + * (if it exists). + * + * @param traceLevel traceLevel + * @param traceMessage traceMessage + */ + public static void trace(LogTraceLevel traceLevel, String traceMessage) { + if (nonNull(logCallback) && nonNull(traceLevel) && nonNull(traceMessage) && isTracingAtLevel(traceLevel)) { + logCallback.internalTrace(traceLevel, traceMessage); + } + } - /** - * Return true if the - */ - public static boolean isTracingAtLevel(LogTraceLevel traceLevel) { - return nonNull(logCallback) - && nonNull(logCallback.getTraceLevel()) - && (traceLevel.compareTo(logCallback.getTraceLevel()) <= 0); - } + /** + * @param traceLevel traceLevel + * @return true if the + */ + public static boolean isTracingAtLevel(LogTraceLevel traceLevel) { + return nonNull(logCallback) && nonNull(logCallback.getTraceLevel()) && (traceLevel.compareTo(logCallback.getTraceLevel()) <= 0); + } } diff --git a/src/main/java/com/perforce/p4java/PropertyDefs.java b/src/main/java/com/perforce/p4java/PropertyDefs.java index a35575d..b96332e 100644 --- a/src/main/java/com/perforce/p4java/PropertyDefs.java +++ b/src/main/java/com/perforce/p4java/PropertyDefs.java @@ -9,19 +9,18 @@ * through the server factory to define things like calling-program * name and version, but note that (as individually noted below) some * properties defined here must be defined at load time through the - * system properties or they will have no effect.

+ * system properties or they will have no effect. *

* Unless otherwise noted in the individual definitions below, - * properties defined here apply to all protocol implementations.

+ * properties defined here apply to all protocol implementations. *

* Unless noted otherwise below, most properties can have an optional short * form which is typically just the full form without the cumbersome * com.perforce.p4java (etc.) prefix; use of the short form is particularly * convenient for passing in properties through the server factory url * mechanism, but you have to be careful that there are no system or - * environment properties with a conflicting name.

+ * environment properties with a conflicting name. */ - public class PropertyDefs { /** @@ -104,7 +103,7 @@ public class PropertyDefs { * Property name key for the P4Java API's temporary directory. Unless * otherwise noted, this directory will be used for temporary files, and, * unless set by this property, it will default to whatever's in the - * system java.io.tmpdir property.

+ * system java.io.tmpdir property. *

* Note that sync operations will sync to temporary files in the enclosing * directory of the target file rather than to the default tmp directory if @@ -125,8 +124,7 @@ public class PropertyDefs { * mechanism. If set, an IServer returned from the server factory will * have its user name set to this value. */ - public static final String USER_NAME_KEY = Metadata.P4JAVA_PROPS_KEY_PREFIX - + USER_NAME_KEY_SHORTFORM; + public static final String USER_NAME_KEY = Metadata.P4JAVA_PROPS_KEY_PREFIX + USER_NAME_KEY_SHORTFORM; /** * Short form password key. @@ -138,8 +136,7 @@ public class PropertyDefs { * mechanism. If set, an IServer returned from the server factory will * have its password set to this value. */ - public static final String PASSWORD_KEY = Metadata.P4JAVA_PROPS_KEY_PREFIX - + PASSWORD_KEY_SHORTFORM; + public static final String PASSWORD_KEY = Metadata.P4JAVA_PROPS_KEY_PREFIX + PASSWORD_KEY_SHORTFORM; /** * Short form client name key. @@ -151,8 +148,7 @@ public class PropertyDefs { * mechanism. If set, an IServer returned from the server factory will * have its client name set to this value. */ - public static final String CLIENT_NAME_KEY = Metadata.P4JAVA_PROPS_KEY_PREFIX - + CLIENT_NAME_KEY_SHORTFORM; + public static final String CLIENT_NAME_KEY = Metadata.P4JAVA_PROPS_KEY_PREFIX + CLIENT_NAME_KEY_SHORTFORM; /** * Short form client path key. @@ -164,8 +160,7 @@ public class PropertyDefs { * mechanism. If set, an IServer returned from the server factory will * have its client path set to this value. */ - public static final String CLIENT_PATH_KEY = Metadata.P4JAVA_PROPS_KEY_PREFIX - + CLIENT_PATH_KEY_SHORTFORM; + public static final String CLIENT_PATH_KEY = Metadata.P4JAVA_PROPS_KEY_PREFIX + CLIENT_PATH_KEY_SHORTFORM; /** * Short form autoconnect key. */ @@ -176,8 +171,7 @@ public class PropertyDefs { * connect with the client name, if the clientName is also set. * Will be done after any auto logins (see below). */ - public static final String AUTO_CONNECT_KEY = Metadata.P4JAVA_PROPS_KEY_PREFIX - + AUTO_CONNECT_KEY_SHORTFORM; + public static final String AUTO_CONNECT_KEY = Metadata.P4JAVA_PROPS_KEY_PREFIX + AUTO_CONNECT_KEY_SHORTFORM; /** * Short form auto login key. @@ -190,8 +184,7 @@ public class PropertyDefs { * userName and password are also set through the properties menachnism. */ - public static final String AUTO_LOGIN_KEY = Metadata.P4JAVA_PROPS_KEY_PREFIX - + AUTO_LOGIN_KEY_SHORTFORM; + public static final String AUTO_LOGIN_KEY = Metadata.P4JAVA_PROPS_KEY_PREFIX + AUTO_LOGIN_KEY_SHORTFORM; /** * If this property is set, attempt to use this path as the p4tickets file. @@ -201,26 +194,24 @@ public class PropertyDefs { /** * If this property is set, attempt to use this path as the p4tickets file. */ - public static final String TICKET_PATH_KEY = Metadata.P4JAVA_PROPS_KEY_PREFIX - + TICKET_PATH_KEY_SHORT_FORM; + public static final String TICKET_PATH_KEY = Metadata.P4JAVA_PROPS_KEY_PREFIX + TICKET_PATH_KEY_SHORT_FORM; /** * If DEFAULT_CHARSET_KEY is set in the Java system properties, it defines the * name of the charset used to convert strings to and from the Perforce server * if that server is NOT in Unicode mode. Note that this property is * fundamental and must be set early on, i.e. in the System properties - * at P4Java startup / load time.

+ * at P4Java startup / load time. *

* If this property is not set at P4Java load time, the default charset name - * is the current JVM default charset name if not null.

+ * is the current JVM default charset name if not null. *

* Note that this value has no effect whatever when running against a non-Unicode - * Perforce server.

+ * Perforce server. *

* Note also that this property has no short form. */ - public static final String DEFAULT_CHARSET_KEY = Metadata.P4JAVA_PROPS_KEY_PREFIX - + "defaultCharset"; + public static final String DEFAULT_CHARSET_KEY = Metadata.P4JAVA_PROPS_KEY_PREFIX + "defaultCharset"; /** * Short form of the WRITE_IN_PLACE_KEY, below. @@ -231,7 +222,7 @@ public class PropertyDefs { * If WRITE_IN_PLACE_KEY is true, certain operations listed below may * write file contents from the Perforce server directly to the target * client file rather than to a temporary file (which is then renamed to - * the target file).

+ * the target file). *

* In general, this property should not be used unless you're * on a Windows box and seeing performance issues with sync operations; @@ -243,12 +234,11 @@ public class PropertyDefs { * partial file content syncs in cases where network errors occur, * but this is very rare and will not result in server-side data * loss or corruption (in fact it's yet to be observed at all within - * Perforce).

+ * Perforce). *

* Currently only the sync command honors this property. */ - public static final String WRITE_IN_PLACE_KEY = Metadata.P4JAVA_PROPS_KEY_PREFIX - + WRITE_IN_PLACE_SHORT_FORM; + public static final String WRITE_IN_PLACE_KEY = Metadata.P4JAVA_PROPS_KEY_PREFIX + WRITE_IN_PLACE_SHORT_FORM; /** * Short form of the NON_CHECKED_SYNC property (below). @@ -262,7 +252,7 @@ public class PropertyDefs { * other operations (see below) against 2010.2 or later Perforce servers will not * have integrity checks performed during the operations. The default is to * use integrity checks on these operations with 2010.2 or later servers (these - * additional checks are not done for earlier server versions).

+ * additional checks are not done for earlier server versions). *

* By default, for 2010.2 and later servers, the integrity checks are performed on * the client for sync, revert, unshelve, and integ operations, and on the server @@ -271,8 +261,7 @@ public class PropertyDefs { * * @since 2011.1 */ - public static final String NON_CHECKED_SYNC = Metadata.P4JAVA_PROPS_KEY_PREFIX - + NON_CHECKED_SYNC_SHORT_FORM; + public static final String NON_CHECKED_SYNC = Metadata.P4JAVA_PROPS_KEY_PREFIX + NON_CHECKED_SYNC_SHORT_FORM; /** * Short form of the ENABLE_TRACKING property (below). @@ -287,15 +276,14 @@ public class PropertyDefs { * for applicable commands. You can see what tables a command is accessing, * and implicitly locking. In addition to the command's usual output, the * "track" information includes the table name and the type of locks - * obtained on that table.

+ * obtained on that table. *

* Note that using "-Ztrack" users will have to handle tracking information * return from the lower level "raw" IServer.exec* methods. * * @since 2012.1 */ - public static final String ENABLE_TRACKING = Metadata.P4JAVA_PROPS_KEY_PREFIX - + ENABLE_TRACKING_SHORT_FORM; + public static final String ENABLE_TRACKING = Metadata.P4JAVA_PROPS_KEY_PREFIX + ENABLE_TRACKING_SHORT_FORM; /** * Short form of the ENABLE_STREAMS property (below). @@ -310,8 +298,7 @@ public class PropertyDefs { * * @since 2017.1 */ - public static final String ENABLE_STREAMS = Metadata.P4JAVA_PROPS_KEY_PREFIX - + ENABLE_STREAMS_SHORT_FORM; + public static final String ENABLE_STREAMS = Metadata.P4JAVA_PROPS_KEY_PREFIX + ENABLE_STREAMS_SHORT_FORM; /** * Short form of the ENABLE_ANDMAPS property (below). @@ -326,8 +313,7 @@ public class PropertyDefs { * * @since 2017.1 */ - public static final String ENABLE_ANDMAPS = Metadata.P4JAVA_PROPS_KEY_PREFIX - + ENABLE_ANDMAPS_SHORT_FORM; + public static final String ENABLE_ANDMAPS = Metadata.P4JAVA_PROPS_KEY_PREFIX + ENABLE_ANDMAPS_SHORT_FORM; /** * Short form of the ENABLE_GRAPH property (below). @@ -342,8 +328,7 @@ public class PropertyDefs { * * @since 2017.1 */ - public static final String ENABLE_GRAPH = Metadata.P4JAVA_PROPS_KEY_PREFIX - + ENABLE_GRAPH_SHORT_FORM; + public static final String ENABLE_GRAPH = Metadata.P4JAVA_PROPS_KEY_PREFIX + ENABLE_GRAPH_SHORT_FORM; /** * Short form of the FILESYS_RESTRICTSYMLINKS property (below). @@ -358,8 +343,7 @@ public class PropertyDefs { * * @since 2019.1 */ - public static final String FILESYS_RESTRICTSYMLINKS = Metadata.P4JAVA_PROPS_KEY_PREFIX - + FILESYS_RESTRICTSYMLINKS_SHORT_FORM; + public static final String FILESYS_RESTRICTSYMLINKS = Metadata.P4JAVA_PROPS_KEY_PREFIX + FILESYS_RESTRICTSYMLINKS_SHORT_FORM; /** * Short form of the FILESYS_UTF8BOM property (below). @@ -374,8 +358,7 @@ public class PropertyDefs { * * @since 2017.2 */ - public static final String FILESYS_UTF8BOM = Metadata.P4JAVA_PROPS_KEY_PREFIX - + FILESYS_UTF8BOM_SHORT_FORM; + public static final String FILESYS_UTF8BOM = Metadata.P4JAVA_PROPS_KEY_PREFIX + FILESYS_UTF8BOM_SHORT_FORM; /** * Short form of the ENABLE_PROGRESS property (below). @@ -389,16 +372,14 @@ public class PropertyDefs { * "progress" will be set to 1 to indicate that the server should send * progress messages to the client if they are available for that command. *

- *

- * Note that the progress indicator (p4 -I ) flag makes sense to be + * Note that the progress indicator {@code (p4 -I )} flag makes sense to be * used with P4Java's lower level "raw" IServer.execStreamingMapCommand() * method. This streaming method takes a callback handler and continuously * report progress (in a result map) during the lifetime of a command. * * @since 2012.3 */ - public static final String ENABLE_PROGRESS = Metadata.P4JAVA_PROPS_KEY_PREFIX - + ENABLE_PROGRESS_SHORT_FORM; + public static final String ENABLE_PROGRESS = Metadata.P4JAVA_PROPS_KEY_PREFIX + ENABLE_PROGRESS_SHORT_FORM; /** * Short form of the QUIET_MODE property (below). @@ -413,8 +394,7 @@ public class PropertyDefs { * * @since 2013.1 */ - public static final String QUIET_MODE = Metadata.P4JAVA_PROPS_KEY_PREFIX - + QUIET_MODE_SHORT_FORM; + public static final String QUIET_MODE = Metadata.P4JAVA_PROPS_KEY_PREFIX + QUIET_MODE_SHORT_FORM; /** * If this property is set, attempt to use this ignore file name. @@ -428,8 +408,7 @@ public class PropertyDefs { * * @since 2012.1 */ - public static final String IGNORE_FILE_NAME_KEY = Metadata.P4JAVA_PROPS_KEY_PREFIX - + IGNORE_FILE_NAME_KEY_SHORT_FORM; + public static final String IGNORE_FILE_NAME_KEY = Metadata.P4JAVA_PROPS_KEY_PREFIX + IGNORE_FILE_NAME_KEY_SHORT_FORM; /** * If this property is set, attempt to use this path as the p4trust file. @@ -443,8 +422,7 @@ public class PropertyDefs { * * @since 2012.1 */ - public static final String TRUST_PATH_KEY = Metadata.P4JAVA_PROPS_KEY_PREFIX - + TRUST_PATH_KEY_SHORT_FORM; + public static final String TRUST_PATH_KEY = Metadata.P4JAVA_PROPS_KEY_PREFIX + TRUST_PATH_KEY_SHORT_FORM; /** * If this property is set (to any value), attempt to use memory instead of @@ -460,8 +438,7 @@ public class PropertyDefs { * * @since 2012.3 */ - public static final String USE_AUTH_MEMORY_STORE_KEY = Metadata.P4JAVA_PROPS_KEY_PREFIX - + USE_AUTH_MEMORY_STORE_KEY_SHORT_FORM; + public static final String USE_AUTH_MEMORY_STORE_KEY = Metadata.P4JAVA_PROPS_KEY_PREFIX + USE_AUTH_MEMORY_STORE_KEY_SHORT_FORM; /** * Short form of the UNICODE_MAPPING property (below). @@ -477,8 +454,7 @@ public class PropertyDefs { * * @since 2012.3 */ - public static final String UNICODE_MAPPING = Metadata.P4JAVA_PROPS_KEY_PREFIX - + UNICODE_MAPPING_SHORT_FORM; + public static final String UNICODE_MAPPING = Metadata.P4JAVA_PROPS_KEY_PREFIX + UNICODE_MAPPING_SHORT_FORM; /** * If this property is set, attempt to use this value as the number of tries @@ -494,8 +470,7 @@ public class PropertyDefs { * * @since 2015.2 */ - public static final String AUTH_FILE_LOCK_TRY_KEY = Metadata.P4JAVA_PROPS_KEY_PREFIX - + AUTH_FILE_LOCK_TRY_KEY_SHORT_FORM; + public static final String AUTH_FILE_LOCK_TRY_KEY = Metadata.P4JAVA_PROPS_KEY_PREFIX + AUTH_FILE_LOCK_TRY_KEY_SHORT_FORM; /** * If this property is set, attempt to use this value as the number of milliseconds @@ -511,8 +486,7 @@ public class PropertyDefs { * * @since 2015.2 */ - public static final String AUTH_FILE_LOCK_DELAY_KEY = Metadata.P4JAVA_PROPS_KEY_PREFIX - + AUTH_FILE_LOCK_DELAY_KEY_SHORT_FORM; + public static final String AUTH_FILE_LOCK_DELAY_KEY = Metadata.P4JAVA_PROPS_KEY_PREFIX + AUTH_FILE_LOCK_DELAY_KEY_SHORT_FORM; /** * If this property is set, attempt to use this value as the number of milliseconds @@ -530,8 +504,7 @@ public class PropertyDefs { * * @since 2015.2 */ - public static final String AUTH_FILE_LOCK_WAIT_KEY = Metadata.P4JAVA_PROPS_KEY_PREFIX - + AUTH_FILE_LOCK_WAIT_KEY_SHORT_FORM; + public static final String AUTH_FILE_LOCK_WAIT_KEY = Metadata.P4JAVA_PROPS_KEY_PREFIX + AUTH_FILE_LOCK_WAIT_KEY_SHORT_FORM; /** * If this property is set, allows the configuration of custom specs (undoc). @@ -545,7 +518,6 @@ public class PropertyDefs { * * @since 2020.1 */ - public static final String CUSTOM_SPEC_KEY = Metadata.P4JAVA_PROPS_KEY_PREFIX - + CUSTOM_SPEC_KEY_SHORT_FORM; + public static final String CUSTOM_SPEC_KEY = Metadata.P4JAVA_PROPS_KEY_PREFIX + CUSTOM_SPEC_KEY_SHORT_FORM; } diff --git a/src/main/java/com/perforce/p4java/admin/IDbSchema.java b/src/main/java/com/perforce/p4java/admin/IDbSchema.java index 7e8f691..950738d 100644 --- a/src/main/java/com/perforce/p4java/admin/IDbSchema.java +++ b/src/main/java/com/perforce/p4java/admin/IDbSchema.java @@ -1,5 +1,5 @@ /** - * + * */ package com.perforce.p4java.admin; @@ -8,49 +8,51 @@ /** * Defines Perforce DB schema associated with a Perforce server (admin / superuser feature).

- * + * * Usage of this feature is intentionally not documented here in any detail; see * "p4 help dbschema" for more useful details. */ public interface IDbSchema { - + /** * What getVersion returns if there was no version number returned * from the server. */ final int NOVERSION = -1; - + /** - * Get the name of the table. + * @return the name of the table. */ - String getName(); - + /** - * Get the table schema version. + * @return the table schema version. */ int getVersion(); - + /** - * Get a list of column metadata maps. Note that while this list should + * @return a list of column metadata maps. Note that while this list should * never be null, individual map values within it may be null. Field (map * key) names and values are not explained here. */ List> getColumnMetadata(); - + /** * Set the name of the table. + * @param name table name */ void setName(String name); - + /** - * Get the table schema version. + * Set the table schema version. + * @param version schema version */ void setVersion(int version); - + /** * Set the colum metadata map. + * @param columnMetadata data */ void setColumnMetadata(List> columnMetadata); } diff --git a/src/main/java/com/perforce/p4java/admin/IDiskSpace.java b/src/main/java/com/perforce/p4java/admin/IDiskSpace.java index 541f4e9..08f55ee 100644 --- a/src/main/java/com/perforce/p4java/admin/IDiskSpace.java +++ b/src/main/java/com/perforce/p4java/admin/IDiskSpace.java @@ -10,44 +10,43 @@ public interface IDiskSpace { /** * Gets the location (Perforce filesystem: P4ROOT, P4JOURNAL, P4LOG, TEMP, - * or ) - * + * or depot name) + * * @return the location */ String getLocation(); /** * Gets the used bytes. - * + * * @return the used bytes */ long getUsedBytes(); /** * Gets the free bytes. - * + * * @return the free bytes */ long getFreeBytes(); /** * Gets the total bytes. - * + * * @return the total bytes */ long getTotalBytes(); /** * Gets the percent used. - * + * * @return the percent used */ int getPercentUsed(); /** - * Gets the file system type (nfs, ext2, xfs, tmpfs, ramfs, ufs, reiserfs, - * or ). - * + * Gets the file system type (nfs, ext2, xfs, tmpfs, ramfs, ufs, reiserfs, or other). + * * @return the file system type */ String getFileSystemType(); diff --git a/src/main/java/com/perforce/p4java/admin/ITriggerEntry.java b/src/main/java/com/perforce/p4java/admin/ITriggerEntry.java index 7a3def4..122fe4e 100644 --- a/src/main/java/com/perforce/p4java/admin/ITriggerEntry.java +++ b/src/main/java/com/perforce/p4java/admin/ITriggerEntry.java @@ -8,70 +8,28 @@ /** * Describes a protection entry (line) in a Perforce triggers * table. These are described in more detail in the various - * main Perforce admin documentation pages.

+ * main Perforce admin documentation pages. */ public interface ITriggerEntry extends IMapEntry { - + public enum TriggerType { - ARCHIVE("archive"), - AUTH_CHECK("auth-check"), - AUTH_CHECK_2FA("auth-check-2fa"), - AUTH_CHECK_SSO("auth-check-sso"), - AUTH_INIT_2FA("auth-init-2fa"), - AUTH_INVALIDATE("auth-invalidate"), - AUTH_PRE_2FA("auth-pre-2fa"), - AUTH_PRE_SSO("auth-pre-sso"), - AUTH_SET("auth-set"), - BGTASK("bgtask"), - CHANGE_COMMIT("change-commit"), - CHANGE_CONTENT("change-content"), - CHANGE_FAILED("change-failed"), - CHANGE_SUBMIT("change-submit"), - COMMAND("command"), - EDGE_CONTENT("edge-content"), - EDGE_SUBMIT("edge-submit"), - EXTENSION_RUN("extension-run"), - FAILED_OVER("failed-over"), - FIX_ADD("fix-add"), - FIX_DELETE("fix-delete"), - FORM_COMMIT("form-commit"), - FORM_DELETE("form-delete"), - FORM_IN("form-in"), - FORM_OUT("form-out"), - FORM_SAVE("form-save"), - GLOBAL_EXTCFG("global-extcfg"), - GRAPH_FORK_REPO("graph-fork-repo"), - GRAPH_LFS_PUSH("graph-lfs-push"), - GRAPH_PUSH_COMPLETE("graph-push-complete"), - GRAPH_PUSH_REFERENCE("graph-push-reference"), - GRAPH_PUSH_REFERENCE_COMPLETE("graph-push-reference-complete"), - GRAPH_PUSH_START("graph-push-start"), - HEARTBEAT_DEAD("heartbeat-dead"), - HEARTBEAT_MISSING("heartbeat-missing"), - HEARTBEAT_RESUMED("heartbeat-resumed"), - JOURNAL_ROTATE("journal-rotate"), - JOURNAL_ROTATE_LOCK("journal-rotate-lock"), - PULL_ARCHIVE("pull-archive"), - PUSH_COMMIT("push-commit"), - PUSH_CONTENT("push-content"), - PUSH_SUBMIT("push-submit"), - SERVICE_CHECK("service-check"), - SHELVE_COMMIT("shelve-commit"), - SHELVE_DELETE("shelve-delete"), - SHELVE_SUBMIT("shelve-submit"); + ARCHIVE("archive"), AUTH_CHECK("auth-check"), AUTH_CHECK_2FA("auth-check-2fa"), AUTH_CHECK_SSO("auth-check-sso"), AUTH_INIT_2FA("auth-init-2fa"), AUTH_INVALIDATE("auth-invalidate"), AUTH_PRE_2FA("auth-pre-2fa"), AUTH_PRE_SSO("auth-pre-sso"), AUTH_SET("auth-set"), BGTASK("bgtask"), CHANGE_COMMIT("change-commit"), CHANGE_CONTENT("change-content"), CHANGE_FAILED("change-failed"), CHANGE_SUBMIT("change-submit"), COMMAND("command"), EDGE_CONTENT("edge-content"), EDGE_SUBMIT("edge-submit"), EXTENSION_RUN("extension-run"), FAILED_OVER("failed-over"), FIX_ADD("fix-add"), FIX_DELETE("fix-delete"), FORM_COMMIT("form-commit"), FORM_DELETE("form-delete"), FORM_IN("form-in"), FORM_OUT("form-out"), FORM_SAVE("form-save"), GLOBAL_EXTCFG("global-extcfg"), GRAPH_FORK_REPO("graph-fork-repo"), GRAPH_LFS_PUSH("graph-lfs-push"), GRAPH_PUSH_COMPLETE("graph-push-complete"), GRAPH_PUSH_REFERENCE("graph-push-reference"), GRAPH_PUSH_REFERENCE_COMPLETE("graph-push-reference-complete"), GRAPH_PUSH_START("graph-push-start"), HEARTBEAT_DEAD("heartbeat-dead"), HEARTBEAT_MISSING("heartbeat-missing"), HEARTBEAT_RESUMED("heartbeat-resumed"), JOURNAL_ROTATE("journal-rotate"), JOURNAL_ROTATE_LOCK("journal-rotate-lock"), PULL_ARCHIVE("pull-archive"), PUSH_COMMIT("push-commit"), PUSH_CONTENT("push-content"), PUSH_SUBMIT("push-submit"), SERVICE_CHECK("service-check"), SHELVE_COMMIT("shelve-commit"), SHELVE_DELETE("shelve-delete"), SHELVE_SUBMIT("shelve-submit"); private final String triggerType; - private TriggerType(String triggerType) { - this.triggerType = triggerType; - } + private TriggerType(String triggerType) { + this.triggerType = triggerType; + } /** * Return a suitable Trigger type as inferred from the passed-in * string, which is assumed to be the string form of a Depot type. * Otherwise return the null. + * + * @param triggerType triggerType + * @return TriggerType */ public static TriggerType fromString(String triggerType) { if (triggerType != null) { @@ -83,42 +41,40 @@ public static TriggerType fromString(String triggerType) { } return null; } - - public String toString(){ - return this.triggerType; - } - }; + + public String toString() { + return this.triggerType; + } + } /** * Gets the trigger name. - * + * * @return the trigger name */ String getName(); - + /** * Sets the trigger name. - * - * @param name - * the trigger name + * + * @param name the trigger name */ void setName(String name); - + /** * Gets the trigger type. - * + * * @return the trigger type */ TriggerType getTriggerType(); - + /** * Sets the trigger type. - * - * @param type - * the trigger type + * + * @param type the trigger type */ void setTriggerType(TriggerType type); - + /** * For change and submit triggers, a file pattern to match files in the * changelist. This file pattern can be an exclusion mapping (-pattern), to @@ -131,11 +87,11 @@ public String toString(){ * name of the file in the depot. For command triggers, use the name of the * command to match, e.g. 'pre-user-$cmd' or a regular expression, e.g. * '(pre|post)-user-add'. * - * + * * @return the depot file path pattern or form type */ String getPath(); - + /** * For change and submit triggers, a file pattern to match files in the * changelist. This file pattern can be an exclusion mapping (-pattern), to @@ -148,26 +104,24 @@ public String toString(){ * name of the file in the depot. For command triggers, use the name of the * command to match, e.g. 'pre-user-$cmd' or a regular expression, e.g. * '(pre|post)-user-add'. * - * - * @param path - * the depot file path pattern or form type + * + * @param path the depot file path pattern or form type */ void setPath(String path); /** * Gets the trigger command. If the command contains spaces, enclose it in * double quotes. - * + * * @return the trigger comamnd */ String getCommand(); - + /** * Sets the trigger command. If the command contains spaces, enclose it in * double quotes. - * - * @param command - * the trigger command + * + * @param command the trigger command */ void setCommand(String command); } diff --git a/src/main/java/com/perforce/p4java/charset/PerforceShiftJISCharset.java b/src/main/java/com/perforce/p4java/charset/PerforceShiftJISCharset.java index 2b78970..a9d6dc5 100644 --- a/src/main/java/com/perforce/p4java/charset/PerforceShiftJISCharset.java +++ b/src/main/java/com/perforce/p4java/charset/PerforceShiftJISCharset.java @@ -3,6 +3,8 @@ */ package com.perforce.p4java.charset; +import com.perforce.p4java.PropertyDefs; + import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.Charset; @@ -10,8 +12,6 @@ import java.nio.charset.CharsetEncoder; import java.nio.charset.CoderResult; -import com.perforce.p4java.PropertyDefs; - /** * Charset implementation which performs P4ShiftJIS encoding. P4-ShiftJIS * encoding uses the MS932 (Microsoft code page 932) encoding, a superset of @@ -20,8 +20,7 @@ */ public class PerforceShiftJISCharset extends Charset { // Environment variable for enabling Perforce specific updates - public static final boolean UNICODE_MAPPING = (System.getProperty(PropertyDefs.UNICODE_MAPPING_SHORT_FORM, - System.getProperty(PropertyDefs.UNICODE_MAPPING, null))) == null ? false : true; + public static final boolean UNICODE_MAPPING = (System.getProperty(PropertyDefs.UNICODE_MAPPING_SHORT_FORM, System.getProperty(PropertyDefs.UNICODE_MAPPING, null))) == null ? false : true; // The name of the real charset encoding delegate. // Microsoft code page 932 (windows-31j, csWindows31J, windows-932, MS932) @@ -33,6 +32,9 @@ public class PerforceShiftJISCharset extends Charset { /** * Constructor for the P4ShiftJIS charset. Call the superclass constructor * to pass along the name and aliases. + * + * @param canonical canonical + * @param aliases aliases */ protected PerforceShiftJISCharset(String canonical, String[] aliases) { super(canonical, aliases); @@ -56,10 +58,10 @@ public CharsetDecoder newDecoder() { } /** - * Tells whether or not this charset contains the given charset. + * Tells whether or not this charset contains the given charset. */ public boolean contains(Charset cs) { - return this.getClass().isInstance(cs); + return this.getClass().isInstance(cs); } /** @@ -70,13 +72,13 @@ private void update(CharBuffer cb) { for (int pos = cb.position(); pos < cb.limit(); pos++) { char c = cb.get(pos); switch (c) { - case '\\': - cb.put(pos, '\u00A5'); - break; - case '\u007E': - cb.put(pos, '\u203E'); - break; - default: + case '\\': + cb.put(pos, '\u00A5'); + break; + case '\u007E': + cb.put(pos, '\u203E'); + break; + default: } } } diff --git a/src/main/java/com/perforce/p4java/client/IClient.java b/src/main/java/com/perforce/p4java/client/IClient.java index 222e80b..3cfdf7c 100644 --- a/src/main/java/com/perforce/p4java/client/IClient.java +++ b/src/main/java/com/perforce/p4java/client/IClient.java @@ -34,11 +34,11 @@ import com.perforce.p4java.option.client.RevertFilesOptions; import com.perforce.p4java.option.client.ShelveFilesOptions; import com.perforce.p4java.option.client.SyncOptions; +import com.perforce.p4java.option.client.UndoFilesOptions; import com.perforce.p4java.option.client.UnlockFilesOptions; import com.perforce.p4java.option.client.UnshelveFilesOptions; import com.perforce.p4java.option.server.ListOptions; import com.perforce.p4java.option.server.OpenedFilesOptions; -import com.perforce.p4java.option.client.UndoFilesOptions; import com.perforce.p4java.server.IServer; import com.perforce.p4java.server.callback.IStreamingCallback; @@ -49,13 +49,13 @@ /** * Extends the lightweight IClientSummary interface to provide a "heavyweight" Perforce * client object that has an associated Perforce client views and has the full panoply - * of Perforce operations defined against it.

+ * of Perforce operations defined against it. *

* Perforce clients are described in detail elsewhere, but in summary, a Perforce client object * is returned from the Perforce server using one of the getClient(s) methods or by creating a * new Perforce client through the newClient server method. Some Perforce operations are done * through a Perforce client; some are associated with a Perforce client; and some are done - * directly through the Perforce server itself.

+ * directly through the Perforce server itself. *

* IClient objects are complete, refreshable, and updateable (unlike IClientSummary objects, * which are not updateable). @@ -69,7 +69,6 @@ public interface IClient extends IClientSummary, IWhereDelegator { * @return the Perforce client view associated with this client, if any; * null otherwise. */ - ClientView getClientView(); /** @@ -85,7 +84,6 @@ public interface IClient extends IClientSummary, IWhereDelegator { * @return the Perforce change view associated with this client, if any; * null otherwise. */ - ArrayList getChangeView(); /** @@ -93,7 +91,6 @@ public interface IClient extends IClientSummary, IWhereDelegator { * * @param changeView new List of change views for the client. */ - void setChangeView(ArrayList changeView); /** @@ -103,7 +100,6 @@ public interface IClient extends IClientSummary, IWhereDelegator { * @return the IServer object representing the server associated with this * client, or null if no such server exists or has been set for this client. */ - IServer getServer(); /** @@ -115,7 +111,7 @@ public interface IClient extends IClientSummary, IWhereDelegator { void setServer(IServer server); /** - * Sync a Perforce client workspace against the Perforce server.

+ * Sync a Perforce client workspace against the Perforce server. *

* Note that this method will fail (throw a RequestException) unless the client * is the associated IServer object's current client. @@ -140,10 +136,7 @@ public interface IClient extends IClientSummary, IWhereDelegator { * its processing of the request * @throws AccessException if the Perforce server denies access to the caller */ - - List sync(List fileSpecs, boolean forceUpdate, boolean noUpdate, - boolean clientBypass, boolean serverBypass) - throws ConnectionException, RequestException, AccessException; + List sync(List fileSpecs, boolean forceUpdate, boolean noUpdate, boolean clientBypass, boolean serverBypass) throws ConnectionException, RequestException, AccessException; /** * Sync a Perforce client workspace against the Perforce server.

@@ -154,8 +147,7 @@ List sync(List fileSpecs, boolean forceUpdate, boolean noU * @throws P4JavaException if any processing errors occur during exection. * @see com.perforce.p4java.option.client.SyncOptions */ - List sync(List fileSpecs, SyncOptions syncOpts) - throws P4JavaException; + List sync(List fileSpecs, SyncOptions syncOpts) throws P4JavaException; /** * Sync a Perforce client workspace against the Perforce server in parallel.

@@ -164,16 +156,15 @@ List sync(List fileSpecs, SyncOptions syncOpts) * @param syncOpts SyncOptions object describing sync options; see SyncOptions comments. * @param psyncOpts Options related to parallalisation of sync * @return non-null list of affected files as IFileSpec elements - * @throws P4JavaException + * @throws P4JavaException on error * @see com.perforce.p4java.option.client.SyncOptions * @see com.perforce.p4java.option.client.ParallelSyncOptions * @since 2017.2 */ - List syncParallel(List fileSpecs, SyncOptions syncOpts, ParallelSyncOptions psyncOpts) - throws P4JavaException; + List syncParallel(List fileSpecs, SyncOptions syncOpts, ParallelSyncOptions psyncOpts) throws P4JavaException; /** - * Sync a Perforce client workspace against the Perforce server.

+ * Sync a Perforce client workspace against the Perforce server. *

* Note that this method takes an IStreamingCallback parameter, and the results * are sent to the user using the IStreamingCallback handleResult method; see @@ -193,12 +184,11 @@ List syncParallel(List fileSpecs, SyncOptions syncOpts, Pa * @see com.perforce.p4java.option.client.SyncOptions * @since 2012.3 */ - void sync(List fileSpecs, SyncOptions syncOpts, IStreamingCallback callback, int key) - throws P4JavaException; + void sync(List fileSpecs, SyncOptions syncOpts, IStreamingCallback callback, int key) throws P4JavaException; /** - * Sync a Perforce client workspace against the Perforce server in parallel.

- * + * Sync a Perforce client workspace against the Perforce server in parallel. + *

* Note that this method takes an IStreamingCallback parameter, and the results * are sent to the user using the IStreamingCallback handleResult method; see * the IStreamingCallback Javadoc for details. The payload passed to handleResult @@ -214,11 +204,10 @@ void sync(List fileSpecs, SyncOptions syncOpts, IStreamingCallback ca * methods to identify the action as being associated with this specific * call. * @param pSyncOpts The --parallel flag specifies options for for parallel file transfer - * @throws P4JavaException + * @throws P4JavaException on error * @since 2017.2 */ - void syncParallel(List fileSpecs, SyncOptions syncOpts, IStreamingCallback callback, - int key, ParallelSyncOptions pSyncOpts) throws P4JavaException; + void syncParallel(List fileSpecs, SyncOptions syncOpts, IStreamingCallback callback, int key, ParallelSyncOptions pSyncOpts) throws P4JavaException; /** * Perform a label sync operation for this client. See the main Perforce @@ -238,9 +227,7 @@ void syncParallel(List fileSpecs, SyncOptions syncOpts, IStreamingCal * @throws AccessException if the Perforce server denies access to the caller */ - List labelSync(List fileSpecs, String labelName, boolean noUpdate, - boolean addFiles, boolean deleteFiles) - throws ConnectionException, RequestException, AccessException; + List labelSync(List fileSpecs, String labelName, boolean noUpdate, boolean addFiles, boolean deleteFiles) throws ConnectionException, RequestException, AccessException; /** * Perform a label sync operation for this client. See the main Perforce @@ -254,16 +241,14 @@ List labelSync(List fileSpecs, String labelName, boolean n * @throws P4JavaException if an error occurs processing this method and its parameters * @see com.perforce.p4java.option.client.LabelSyncOptions */ - - List labelSync(List fileSpecs, String labelName, LabelSyncOptions opts) - throws P4JavaException; + List labelSync(List fileSpecs, String labelName, LabelSyncOptions opts) throws P4JavaException; /** * Create a new changelist for this Perforce client in the associated Perforce server. * The newly-created changelist has no files associated with it (regardless of * whether the passed-in changelist spec has files associated with it); if you * wish to add files to the new changelist, you need to do a reopen on them - * explictly after the new changelist is returned.

+ * explictly after the new changelist is returned. *

* The new changelist is returned if the command is successful; this changelist object * will include the new changelist ID. @@ -278,9 +263,7 @@ List labelSync(List fileSpecs, String labelName, LabelSync * its processing of the request * @throws AccessException if the Perforce server denies access to the caller */ - - IChangelist createChangelist(IChangelist newChangelist) - throws ConnectionException, RequestException, AccessException; + IChangelist createChangelist(IChangelist newChangelist) throws ConnectionException, RequestException, AccessException; /** * Open one or more Perforce client workspace files for adding to the Perforce server. @@ -304,10 +287,7 @@ IChangelist createChangelist(IChangelist newChangelist) * connected. * @throws AccessException if the Perforce server denies access to the caller */ - - List addFiles(List fileSpecs, boolean noUpdate, int changeListId, - String fileType, boolean useWildcards) - throws ConnectionException, AccessException; + List addFiles(List fileSpecs, boolean noUpdate, int changeListId, String fileType, boolean useWildcards) throws ConnectionException, AccessException; /** * Open one or more Perforce client workspace files for adding to the Perforce server. @@ -321,8 +301,7 @@ List addFiles(List fileSpecs, boolean noUpdate, int change * @throws P4JavaException if an error occurs processing this method and its parameters * @see com.perforce.p4java.option.client.AddFilesOptions */ - List addFiles(List fileSpecs, AddFilesOptions opts) - throws P4JavaException; + List addFiles(List fileSpecs, AddFilesOptions opts) throws P4JavaException; /** * Open one or more Perforce client workspace files for editing. @@ -354,10 +333,7 @@ List addFiles(List fileSpecs, AddFilesOptions opts) * connected. * @throws AccessException if the Perforce server denies access to the caller */ - - List editFiles(List fileSpecs, boolean noUpdate, boolean bypassClientUpdate, - int changeListId, String fileType) - throws RequestException, ConnectionException, AccessException; + List editFiles(List fileSpecs, boolean noUpdate, boolean bypassClientUpdate, int changeListId, String fileType) throws RequestException, ConnectionException, AccessException; /** * Open one or more Perforce client workspace files for editing. @@ -371,7 +347,6 @@ List editFiles(List fileSpecs, boolean noUpdate, boolean b * @throws P4JavaException if an error occurs processing this method and its parameters * @see com.perforce.p4java.option.client.EditFilesOptions */ - List editFiles(List fileSpecs, EditFilesOptions opts) throws P4JavaException; /** @@ -394,10 +369,7 @@ List editFiles(List fileSpecs, boolean noUpdate, boolean b * connected. * @throws AccessException if the Perforce server denies access to the caller */ - - List revertFiles(List fileSpecs, boolean noUpdate, int changeListId, - boolean revertOnlyUnchanged, boolean noRefresh) - throws ConnectionException, AccessException; + List revertFiles(List fileSpecs, boolean noUpdate, int changeListId, boolean revertOnlyUnchanged, boolean noRefresh) throws ConnectionException, AccessException; /** * Revert open Perforce client workspace files back to the revision previously synced @@ -412,57 +384,54 @@ List revertFiles(List fileSpecs, boolean noUpdate, int cha * @throws P4JavaException if an error occurs processing this method and its parameters * @see com.perforce.p4java.option.client.RevertFilesOptions */ - List revertFiles(List fileSpecs, RevertFilesOptions opts) throws P4JavaException; - /** - * Undo one or more previously submitted files. The 'undone' changes remain a - * part of the history, but the new revisions submitted after 'p4 undo' will - * reverse their effect. - *

- * If a single revision is specified, the specified revision is undone. - * If a revision range is specified, the entire range is undone. - *

- * - * @param fileSpecs if non-empty, undo the specified files; - * otherwise undo all qualifying files - * @param changelistId - if not IChangelist.UNKNOWN, the files are opened - * in the numbered pending changelist instead of the - * 'default' changelist. - * @param listOnly – if true, don't actually perform the move, just - * return what would happen if the move was performed - * @return list of IFileSpec objects representing the results of this undo - * @throws ConnectionException - if the Perforce server is unreachable or - * is not connected. - * @throws RequestException – if the Perforce server encounters an error - * during its processing of the request - * @throws AccessException – if the Perforce server denies access to the - * caller - */ - List undoFiles(List fileSpecs, int changelistId, boolean listOnly) - throws ConnectionException, RequestException, AccessException; - - /** - * Undo one or more previously submitted files. The 'undone' changes remain a - * part of the history, but the new revisions submitted after 'p4 undo' will - * reverse their effect. - *

- * If a single revision is specified, the specified revision is undone. - * If a revision range is specified, the entire range is undone. - *

- * - * @param fileSpecs if non-empty, undo the specified files; - * otherwise undo all qualifying files - * @param opts possibly-null UndoFilesOptions object object specifying - * method options. - * @return non-null but possibly-empty list of qualifying files to undo. Not - * all fields in individual file specs will be valid or make sense - * to be accessed. - * @throws P4JavaException if an error occurs processing this method and its - * parameters. - */ - List undoFiles(List fileSpecs, UndoFilesOptions opts) - throws P4JavaException; + /** + * Undo one or more previously submitted files. The 'undone' changes remain a + * part of the history, but the new revisions submitted after 'p4 undo' will + * reverse their effect. + *

+ * If a single revision is specified, the specified revision is undone. + * If a revision range is specified, the entire range is undone. + *

+ * + * @param fileSpecs if non-empty, undo the specified files; + * otherwise undo all qualifying files + * @param changelistId - if not IChangelist.UNKNOWN, the files are opened + * in the numbered pending changelist instead of the + * 'default' changelist. + * @param listOnly – if true, don't actually perform the move, just + * return what would happen if the move was performed + * @return list of IFileSpec objects representing the results of this undo + * @throws ConnectionException - if the Perforce server is unreachable or + * is not connected. + * @throws RequestException – if the Perforce server encounters an error + * during its processing of the request + * @throws AccessException – if the Perforce server denies access to the + * caller + */ + List undoFiles(List fileSpecs, int changelistId, boolean listOnly) throws ConnectionException, RequestException, AccessException; + + /** + * Undo one or more previously submitted files. The 'undone' changes remain a + * part of the history, but the new revisions submitted after 'p4 undo' will + * reverse their effect. + *

+ * If a single revision is specified, the specified revision is undone. + * If a revision range is specified, the entire range is undone. + *

+ * + * @param fileSpecs if non-empty, undo the specified files; + * otherwise undo all qualifying files + * @param opts possibly-null UndoFilesOptions object object specifying + * method options. + * @return non-null but possibly-empty list of qualifying files to undo. Not + * all fields in individual file specs will be valid or make sense + * to be accessed. + * @throws P4JavaException if an error occurs processing this method and its + * parameters. + */ + List undoFiles(List fileSpecs, UndoFilesOptions opts) throws P4JavaException; /** * Open Perforce client workspace files for deletion from a Perforce depot. @@ -481,9 +450,7 @@ List undoFiles(List fileSpecs, UndoFilesOptions opts) * connected. * @throws AccessException if the Perforce server denies access to the caller */ - - List deleteFiles(List fileSpecs, int changeListId, boolean noUpdate) - throws ConnectionException, AccessException; + List deleteFiles(List fileSpecs, int changeListId, boolean noUpdate) throws ConnectionException, AccessException; /** * Open Perforce client workspace files for deletion from a Perforce depot. @@ -496,14 +463,12 @@ List deleteFiles(List fileSpecs, int changeListId, boolean * @throws P4JavaException if an error occurs processing this method and its parameters * @see com.perforce.p4java.option.client.DeleteFilesOptions */ - - List deleteFiles(List fileSpecs, DeleteFilesOptions opts) - throws P4JavaException; + List deleteFiles(List fileSpecs, DeleteFilesOptions opts) throws P4JavaException; /** * If one or more Perforce file specs is passed-in, return the opened / locked status * of each file (if known) within an IFileSpec object; otherwise - * return a list of all files known to be open for this Perforce client workspace.

+ * return a list of all files known to be open for this Perforce client workspace. *

* The returned list can be modified with the other arguments as described below. * @@ -518,13 +483,11 @@ List deleteFiles(List fileSpecs, DeleteFilesOptions opts) * connected. * @throws AccessException if the Perforce server denies access to the caller */ - - List openedFiles(List fileSpecs, int maxFiles, int changeListId) - throws ConnectionException, AccessException; + List openedFiles(List fileSpecs, int maxFiles, int changeListId) throws ConnectionException, AccessException; /** * Return a list of files open for this client, optionally restricted to a - * specific path and / or changelist.

+ * specific path and / or changelist. *

* Note that if a non-null OpenedFilesOptions object is passed to this method, * the object's clientName field is ignored and the name of the client whose @@ -538,17 +501,15 @@ List openedFiles(List fileSpecs, int maxFiles, int changeL * in individual file specs will be valid or make sense to be accessed. * @throws P4JavaException if an error occurs processing this method and its parameters. */ - - List openedFiles(List fileSpecs, OpenedFilesOptions opts) - throws P4JavaException; + List openedFiles(List fileSpecs, OpenedFilesOptions opts) throws P4JavaException; /** * Return a list of all Perforce-managed files and versions that the Perforce server * believes this Perforce client workspace has as of the latest sync. If fileSpecs - * is given, this method returns, only information on those files is returned.

+ * is given, this method returns, only information on those files is returned. *

* Note that this method will return an empty list unless the client is the - * IServer object's current client.

+ * IServer object's current client. *

* Only the depotFile, revision, clientPath, and localPath fields of the returned * file specs are guaranteed to be valid. @@ -560,17 +521,15 @@ List openedFiles(List fileSpecs, OpenedFilesOptions opts) * connected.t * @throws AccessException if the Perforce server denies access to the caller */ - - List haveList(List fileSpecs) - throws ConnectionException, AccessException; + List haveList(List fileSpecs) throws ConnectionException, AccessException; /** * Return a list of all Perforce-managed repos that the Perforce server believes * this Perforce client workspace has as of the latest sync. If fileSpecs is given, - * this method returns, only information on those files is returned.

+ * this method returns, only information on those files is returned. *

* Note that this method will return an empty list unless the client is the - * IServer object's current client.

+ * IServer object's current client. *

* Only the sha, repo name, and branch name fields of the returned file specs * are guaranteed to be valid. @@ -582,9 +541,7 @@ List haveList(List fileSpecs) * connected.t * @throws AccessException if the Perforce server denies access to the caller */ - - List graphHaveList(List fileSpecs) - throws ConnectionException, AccessException; + List graphHaveList(List fileSpecs) throws ConnectionException, AccessException; /** * Reopen Perforce files in a new changelist. @@ -600,9 +557,7 @@ List graphHaveList(List fileSpecs) * connected. * @throws AccessException if the Perforce server denies access to the caller */ - - List reopenFiles(List fileSpecs, int changeListId, String fileType) - throws ConnectionException, AccessException; + List reopenFiles(List fileSpecs, int changeListId, String fileType) throws ConnectionException, AccessException; /** * Reopen Perforce files in a new changelist. @@ -612,8 +567,7 @@ List reopenFiles(List fileSpecs, int changeListId, String * @return list of IFileSpec for each specified file. * @throws P4JavaException if an error occurs processing this method and its parameters. */ - List reopenFiles(List fileSpecs, ReopenFilesOptions opts) - throws P4JavaException; + List reopenFiles(List fileSpecs, ReopenFilesOptions opts) throws P4JavaException; /** * Integrate ("merge") from one Perforce filespec to another. The semantics @@ -637,11 +591,7 @@ List reopenFiles(List fileSpecs, ReopenFilesOptions opts) * connected. * @throws AccessException if the Perforce server denies access to the caller */ - - List integrateFiles(int changeListId, boolean showActionsOnly, - IntegrationOptions integOpts, String branchSpec, - IFileSpec fromFile, IFileSpec toFile) - throws ConnectionException, AccessException; + List integrateFiles(int changeListId, boolean showActionsOnly, IntegrationOptions integOpts, String branchSpec, IFileSpec fromFile, IFileSpec toFile) throws ConnectionException, AccessException; /** * Integrate ("merge") from one Perforce filespec to another. The semantics @@ -659,16 +609,14 @@ List integrateFiles(int changeListId, boolean showActionsOnly, * @throws P4JavaException if an error occurs processing this method and its parameters * @see com.perforce.p4java.option.client.IntegrateFilesOptions */ - - List integrateFiles(IFileSpec fromFile, IFileSpec toFile, String branchSpec, - IntegrateFilesOptions opts) throws P4JavaException; + List integrateFiles(IFileSpec fromFile, IFileSpec toFile, String branchSpec, IntegrateFilesOptions opts) throws P4JavaException; /** * Integrate one set of files (the 'source') into another (the 'target'). * The semantics of Perforce integrate are complex and are not explained here; * please consult the main Perforce documentation for file integrations and * the IntegrateFilesOptions Javdoc comments for details of the less-commonly-used - * options.

+ * options. *

* Note that depending on the specific options passed-in the fromFile can be * null or one file spec; the toFiles list can be null, one or more file specs. @@ -680,17 +628,15 @@ List integrateFiles(IFileSpec fromFile, IFileSpec toFile, String bran * @throws P4JavaException if an error occurs processing this method and its parameters. * @since 2011.2 */ - - List integrateFiles(IFileSpec fromFile, List toFiles, - IntegrateFilesOptions opts) throws P4JavaException; + List integrateFiles(IFileSpec fromFile, List toFiles, IntegrateFilesOptions opts) throws P4JavaException; /** - * Automatically resolve the results of a previousPerforce file integration.

+ * Automatically resolve the results of a previousPerforce file integration. *

* Note that this is currently a very limited version of the full Perforce resolve feature, * corresponding only to (some of) the various auto-resolve features, meaning this method * will never invoke (or need to invoke) end user interaction. More extensive versions - * of the resolve command will be surfaced as needed.

+ * of the resolve command will be surfaced as needed. *

* This method notionally returns an IFileSpec, as it's closely * related to the integ method and shares many of its return values, but @@ -703,7 +649,7 @@ List integrateFiles(IFileSpec fromFile, List toFiles, * case, since the info messages do NOT correspond one-to-one with the input * file specs that caused the messages, consumers need to explicitly search each * returned info message string for the relevant file path or name. This is an - * unfortunate artifact of the Perforce server's implementation of this command.

+ * unfortunate artifact of the Perforce server's implementation of this command. *

* Note: results and behavior are undefined if clashing or inconsistent options * are used with this method. In general, the behavior of (e.g.) setting both @@ -733,19 +679,15 @@ List integrateFiles(IFileSpec fromFile, List toFiles, * connected. * @throws AccessException if the Perforce server denies access to the caller */ - - List resolveFilesAuto(List fileSpecs, boolean safeMerge, - boolean acceptTheirs, boolean acceptYours, boolean showActionsOnly, - boolean forceResolve) - throws ConnectionException, AccessException; + List resolveFilesAuto(List fileSpecs, boolean safeMerge, boolean acceptTheirs, boolean acceptYours, boolean showActionsOnly, boolean forceResolve) throws ConnectionException, AccessException; /** - * Automatically resolve the results of a previousPerforce file integration.

+ * Automatically resolve the results of a previousPerforce file integration. *

* Note that this is currently a very limited version of the full Perforce resolve feature, * corresponding only to (some of) the various auto-resolve features, meaning this method * will never invoke (or need to invoke) end user interaction. More extensive versions - * of the resolve command will be surfaced as needed.

+ * of the resolve command will be surfaced as needed. *

* This method notionally returns an IFileSpec, as it's closely * related to the integ method and shares many of its return values, but @@ -758,7 +700,7 @@ List resolveFilesAuto(List fileSpecs, boolean safeMerge, * case, since the info messages do NOT correspond one-to-one with the input * file specs that caused the messages, consumers need to explicitly search each * returned info message string for the relevant file path or name. This is an - * unfortunate artifact of the Perforce server's implementation of this command.

+ * unfortunate artifact of the Perforce server's implementation of this command. *

* Note: results and behavior are undefined if clashing or inconsistent options * are used with this method. In general, the behavior of (e.g.) setting both @@ -777,13 +719,11 @@ List resolveFilesAuto(List fileSpecs, boolean safeMerge, * @throws P4JavaException if an error occurs processing this method and its parameters * @see com.perforce.p4java.option.client.ResolveFilesAutoOptions */ - - List resolveFilesAuto(List fileSpecs, ResolveFilesAutoOptions opts) - throws P4JavaException; + List resolveFilesAuto(List fileSpecs, ResolveFilesAutoOptions opts) throws P4JavaException; /** * Resolve a file integration by using the contents of the sourceStream InputStream - * as the resolve result.

+ * as the resolve result. *

* Note that this method assumes that the target and source resolve makes * sense, and does little or no sanity- or error-checking. In particular, it @@ -791,13 +731,13 @@ List resolveFilesAuto(List fileSpecs, ResolveFilesAutoOpti * make sense or not; you should check the getHowResolved() method on the * returned filespec to ensure that it did what you expected (typically this * means checking that it was resolved using the "edit from" resolution rather - * than, say "ignored").

+ * than, say "ignored"). *

* Use of this method will normally result in an integration edit record * in the target file's history whether you've actually done an edit or not, so * it is up to the consumer to weed out the various straight copy resolve cases * and only use this for cases of more complex merges that actually did involve - * an edit (in reality or not).

+ * an edit (in reality or not). *

* Note that the IFileSpec returned will generally not have a * valid depot or client file paths -- you must use the toFile and fromFile methods @@ -812,13 +752,11 @@ List resolveFilesAuto(List fileSpecs, ResolveFilesAutoOpti * @throws RequestException if the Perforce server encounters an error during * its processing of the request */ - - IFileSpec resolveFile(IFileSpec targetFile, InputStream sourceStream) - throws ConnectionException, RequestException, AccessException; + IFileSpec resolveFile(IFileSpec targetFile, InputStream sourceStream) throws ConnectionException, RequestException, AccessException; /** * Resolve a file integration by using the contents of the sourceStream InputStream - * as the resolve result.

+ * as the resolve result. *

* Note that this method assumes that the target and source resolve makes * sense, and does little or no sanity- or error-checking. In particular, it @@ -826,13 +764,13 @@ IFileSpec resolveFile(IFileSpec targetFile, InputStream sourceStream) * make sense or not; you should check the getHowResolved() method on the * returned filespec to ensure that it did what you expected (typically this * means checking that it was resolved using the "edit from" resolution rather - * than, say "ignored").

+ * than, say "ignored"). *

* Use of this method will normally result in an integration edit record * in the target file's history whether you've actually done an edit or not, so * it is up to the consumer to weed out the various straight copy resolve cases * and only use this for cases of more complex merges that actually did involve - * an edit (in reality or not).

+ * an edit (in reality or not). *

* Note that the IFileSpec returned will generally not have a * valid depot or client file paths -- you must use the toFile and fromFile methods @@ -850,20 +788,17 @@ IFileSpec resolveFile(IFileSpec targetFile, InputStream sourceStream) * @throws RequestException if the Perforce server encounters an error during * its processing of the request */ - - IFileSpec resolveFile(IFileSpec targetFile, InputStream sourceStream, boolean useTextualMerge, - int startFromRev, int endFromRev) - throws ConnectionException, RequestException, AccessException; + IFileSpec resolveFile(IFileSpec targetFile, InputStream sourceStream, boolean useTextualMerge, int startFromRev, int endFromRev) throws ConnectionException, RequestException, AccessException; /** - * Automatically resolve the results of a previous Perforce file integration.

+ * Automatically resolve the results of a previous Perforce file integration. * Allows for resolving Streams. *

* Note that this is currently a very limited version of the full Perforce resolve feature, * corresponding only to (some of) the various auto-resolve features, meaning this method * will never invoke (or need to invoke) end user interaction. More extensive versions - * of the resolve command will be surfaced as needed.

- * + * of the resolve command will be surfaced as needed. + *

* Note: results and behavior are undefined if clashing or inconsistent options * are used with this method. In general, the behavior of (e.g.) setting both * acceptYours and acceptTheirs true will be whatever the Perforce server makes @@ -878,8 +813,7 @@ IFileSpec resolveFile(IFileSpec targetFile, InputStream sourceStream, boolean us * @throws P4JavaException if an error occurs processing this method and its parameters * @since 2021.2 */ - String resolveStreamAuto(ResolveFilesAutoOptions opts) - throws P4JavaException; + String resolveStreamAuto(ResolveFilesAutoOptions opts) throws P4JavaException; /** * Return a list of files resolved but not submitted for this client. Note that @@ -895,9 +829,7 @@ String resolveStreamAuto(ResolveFilesAutoOptions opts) * connected. * @throws AccessException if the Perforce server denies access to the caller */ - - List resolvedFiles(List fileSpecs, boolean showBaseRevision) - throws ConnectionException, AccessException; + List resolvedFiles(List fileSpecs, boolean showBaseRevision) throws ConnectionException, AccessException; /** * Return a list of files resolved but not submitted for this client. Note that @@ -911,19 +843,17 @@ List resolvedFiles(List fileSpecs, boolean showBaseRevisio * @throws P4JavaException if an error occurs processing this method and its parameters * @see com.perforce.p4java.option.client.ResolvedFilesOptions */ - - List resolvedFiles(List fileSpecs, ResolvedFilesOptions opts) - throws P4JavaException; + List resolvedFiles(List fileSpecs, ResolvedFilesOptions opts) throws P4JavaException; /** - * Lock an opened file against changelist submission.

+ * Lock an opened file against changelist submission. *

* The open files named are locked in the Perforce depot, preventing any * user other than the current user on the current client from * submitting changes to the files. If a file is already locked * then the lock request is rejected. If no file specs are given * then lock all files currently open in the changelist number given - * if it is IChangelist.DEFAULT or > 0.

+ * if it is IChangelist.DEFAULT or > 0. *

* Note that the file specs returned are only partially filled out; the * Perforce server seems to only return path information for this command. @@ -936,19 +866,17 @@ List resolvedFiles(List fileSpecs, ResolvedFilesOptions op * connected. * @throws AccessException if the Perforce server denies access to the caller */ - - List lockFiles(List fileSpecs, int changeListId) - throws ConnectionException, AccessException; + List lockFiles(List fileSpecs, int changeListId) throws ConnectionException, AccessException; /** - * Lock an opened file against changelist submission.

+ * Lock an opened file against changelist submission. *

* The open files named are locked in the Perforce depot, preventing any * user other than the current user on the current client from * submitting changes to the files. If a file is already locked * then the lock request is rejected. If no file specs are given * then lock all files currently open in the changelist number given - * if it is IChangelist.DEFAULT or > 0.

+ * if it is IChangelist.DEFAULT or > 0. *

* Note that the file specs returned are only partially filled out; the * Perforce server seems to only return path information for this command. @@ -959,17 +887,15 @@ List lockFiles(List fileSpecs, int changeListId) * @throws P4JavaException if an error occurs processing this method and its parameters * @see com.perforce.p4java.option.client.LockFilesOptions */ - - List lockFiles(List fileSpecs, LockFilesOptions opts) - throws P4JavaException; + List lockFiles(List fileSpecs, LockFilesOptions opts) throws P4JavaException; /** - * Release locked files but leave them open.

+ * Release locked files but leave them open. *

* If the files are open in a specific pending changelist other than * 'default', then the changeListId parameter is required to specify the * pending changelist. If no file name is given then all files in the - * designated changelist are unlocked.

+ * designated changelist are unlocked. *

* Note that the file specs returned are only partially filled out; the * Perforce server seems to only return path information for this command. @@ -984,12 +910,10 @@ List lockFiles(List fileSpecs, LockFilesOptions opts) * connected. * @throws AccessException if the Perforce server denies access to the caller */ - - List unlockFiles(List fileSpecs, int changeListId, boolean force) - throws ConnectionException, AccessException; + List unlockFiles(List fileSpecs, int changeListId, boolean force) throws ConnectionException, AccessException; /** - * Release locked files but leave them open.

+ * Release locked files but leave them open. *

* Note that the file specs returned are only partially filled out; the * Perforce server seems to only return path information for this command. @@ -999,26 +923,24 @@ List unlockFiles(List fileSpecs, int changeListId, boolean * @return non-null but possibly-empty list of unlocked file specs or errors * @throws P4JavaException if an error occurs processing this method and its parameters */ - - List unlockFiles(List fileSpecs, UnlockFilesOptions opts) - throws P4JavaException; + List unlockFiles(List fileSpecs, UnlockFilesOptions opts) throws P4JavaException; /** * Return a list of files that differ in some (arbitrarily complex) * way from depot. See the help documentation for the p4 diff command * using the "-sx" (-sa, -sl, etc.) options for a full discussion - * of the options used below.

+ * of the options used below. *

* Note that this method returns lists of files, and is not useful - * to get the diffs themselves (at least not directly).

+ * to get the diffs themselves (at least not directly). *

* Note that the diff status returned for the unopenedWithStatus option - * is retrievable from the filespec with the getDiffStatus() method.

+ * is retrievable from the filespec with the getDiffStatus() method. *

* Note that you must have at least one of the various "-s" options set * to true. * - * @param maxFiles + * @param maxFiles max files * @param fileSpecs candidate file specs; may be null. * @param diffNonTextFiles include non-text files in the diff lists * @param openedDifferentMissing corresponds to the "-sa" option for the p4 command line. @@ -1034,23 +956,19 @@ List unlockFiles(List fileSpecs, UnlockFilesOptions opts) * its processing of the request * @throws AccessException if the Perforce server denies access to the caller */ - - List getDiffFiles(List fileSpecs, int maxFiles, boolean diffNonTextFiles, - boolean openedDifferentMissing, boolean openedForIntegrate, boolean unopenedMissing, - boolean unopenedDifferent, boolean unopenedWithStatus, boolean openedSame) - throws ConnectionException, RequestException, AccessException; + List getDiffFiles(List fileSpecs, int maxFiles, boolean diffNonTextFiles, boolean openedDifferentMissing, boolean openedForIntegrate, boolean unopenedMissing, boolean unopenedDifferent, boolean unopenedWithStatus, boolean openedSame) throws ConnectionException, RequestException, AccessException; /** * Return a list of files that differ in some (arbitrarily complex) * way from depot. See the help documentation for the p4 diff command * using the "-sx" (-sa, -sl, etc.) options for a full discussion - * of the options used below.

+ * of the options used below. *

* Note that this method returns lists of files, and is not useful - * to get the diffs themselves (at least not directly).

+ * to get the diffs themselves (at least not directly). *

* Note that the diff status returned for the unopenedWithStatus option - * is retrievable from the filespec with the getDiffStatus() method.

+ * is retrievable from the filespec with the getDiffStatus() method. *

* Note that you must have at least one of the various "-s" options set * to true. @@ -1060,9 +978,7 @@ List getDiffFiles(List fileSpecs, int maxFiles, boolean di * @return non-null but possibly-empty list of qualifying filepecs. * @throws P4JavaException if an error occurs processing this method and its parameters */ - - List getDiffFiles(List fileSpecs, GetDiffFilesOptions opts) - throws P4JavaException; + List getDiffFiles(List fileSpecs, GetDiffFilesOptions opts) throws P4JavaException; /** * Shelve files in a changelist. @@ -1078,9 +994,7 @@ List getDiffFiles(List fileSpecs, GetDiffFilesOptions opts * @throws P4JavaException if an error occurs processing this method and its parameters * @see com.perforce.p4java.option.client.ShelveFilesOptions */ - - List shelveFiles(List fileSpecs, int changelistId, ShelveFilesOptions opts) - throws P4JavaException; + List shelveFiles(List fileSpecs, int changelistId, ShelveFilesOptions opts) throws P4JavaException; /** * Unshelve file(s) from a shelf. @@ -1094,9 +1008,7 @@ List shelveFiles(List fileSpecs, int changelistId, ShelveF * server's response * @throws P4JavaException if an error occurs processing this method and its parameters */ - - List unshelveFiles(List fileSpecs, int sourceChangelistId, - int targetChangelistId, UnshelveFilesOptions opts) throws P4JavaException; + List unshelveFiles(List fileSpecs, int sourceChangelistId, int targetChangelistId, UnshelveFilesOptions opts) throws P4JavaException; /** * Update/replace/delete shelved file(s) from a pending changelist. @@ -1117,13 +1029,10 @@ List unshelveFiles(List fileSpecs, int sourceChangelistId, * its processing of the request * @throws AccessException if the Perforce server denies access to the caller */ - List shelveChangelist(int changelistId, - List fileSpecs, boolean forceUpdate, boolean replace, - boolean discard) throws ConnectionException, RequestException, - AccessException; + List shelveChangelist(int changelistId, List fileSpecs, boolean forceUpdate, boolean replace, boolean discard) throws ConnectionException, RequestException, AccessException; /** - * Shelve the file(s) in a pending changelist.

+ * Shelve the file(s) in a pending changelist. *

* This performs a 'p4 shelve -i' command when called. * @@ -1136,8 +1045,7 @@ List shelveChangelist(int changelistId, * its processing of the request * @throws AccessException if the Perforce server denies access to the caller */ - List shelveChangelist(IChangelist list) - throws ConnectionException, RequestException, AccessException; + List shelveChangelist(IChangelist list) throws ConnectionException, RequestException, AccessException; /** * Unshelve file(s) from a shelved changelist @@ -1156,10 +1064,7 @@ List shelveChangelist(IChangelist list) * its processing of the request * @throws AccessException if the Perforce server denies access to the caller */ - List unshelveChangelist(int shelveChangelistId, - List fileSpecs, int clientChangelistId, - boolean forceOverwrite, boolean previewOnly) - throws ConnectionException, RequestException, AccessException; + List unshelveChangelist(int shelveChangelistId, List fileSpecs, int clientChangelistId, boolean forceOverwrite, boolean previewOnly) throws ConnectionException, RequestException, AccessException; /** * Submit a shelved changelist without transferring files or modifying the @@ -1172,7 +1077,7 @@ List unshelveChangelist(int shelveChangelistId, * be open in any workspace at the same change number. Client submit options * (ie revertUnchanged, etc) will be ignored. If the submit is successful, * the shelved change and files are cleaned up, and are no longer available - * to be unshelved or submitted.

+ * to be unshelved or submitted. *

* This performs a 'p4 submit -e shelvedChange#' command when called. * @@ -1187,7 +1092,7 @@ List unshelveChangelist(int shelveChangelistId, /** * Schedule resolve and integration actions to make the target file identical to * the source file based only on the differences between the two (i.e. ignoring - * prior integration history).

+ * prior integration history). *

* Corresponds to the 'p4 copy' command. * @@ -1199,11 +1104,10 @@ List unshelveChangelist(int shelveChangelistId, * @throws P4JavaException if an error occurs processing this method and its parameters. * @since 2011.1 */ - List copyFiles(IFileSpec fromFile, IFileSpec toFile, String branchSpec, - CopyFilesOptions opts) throws P4JavaException; + List copyFiles(IFileSpec fromFile, IFileSpec toFile, String branchSpec, CopyFilesOptions opts) throws P4JavaException; /** - * Copies one set of files (the 'source') into another (the 'target').

+ * Copies one set of files (the 'source') into another (the 'target'). *

* Note that depending on the specific options passed-in the fromFile can be * null or one file spec; the toFiles list can be null, one or more file specs. @@ -1217,15 +1121,14 @@ List copyFiles(IFileSpec fromFile, IFileSpec toFile, String branchSpe * @throws P4JavaException if an error occurs processing this method and its parameters. * @since 2011.2 */ - List copyFiles(IFileSpec fromFile, List toFiles, - CopyFilesOptions opts) throws P4JavaException; + List copyFiles(IFileSpec fromFile, List toFiles, CopyFilesOptions opts) throws P4JavaException; /** * Merges changes from one set of files (the 'source') into another (the 'target'). * It is a simplified form of the 'p4 integrate' command. The semantics of * Perforce merges are complex and are not explained here; please consult * the main Perforce documentation for file merges and the MergeFilesOptions - * Javdoc comments for details of the less-commonly-used options.

+ * Javdoc comments for details of the less-commonly-used options. *

* Note that depending on the specific options passed-in the fromFile can be * null or one file spec; the toFiles list can be null, one or more file specs. @@ -1238,20 +1141,20 @@ List copyFiles(IFileSpec fromFile, List toFiles, * @throws P4JavaException if an error occurs processing this method and its parameters * @since 2011.2 */ - - List mergeFiles(IFileSpec fromFile, List toFiles, - MergeFilesOptions opts) throws P4JavaException; + List mergeFiles(IFileSpec fromFile, List toFiles, MergeFilesOptions opts) throws P4JavaException; /** * Open files for add, delete, and/or edit to reconcile client with workspace - * changes made outside of Perforce.

+ * changes made outside of Perforce. *

* 'p4 reconcile' finds unopened files in a client's workspace and detects the - * following:

+ * following: + *

+ * 1. files in depot missing from workspace, but still on have list. *

- * 1. files in depot missing from workspace, but still on have list.

- * 2. files on workspace that are not in depot.

- * 3. files modified in workpace that are not opened for edit.

+ * 2. files on workspace that are not in depot. + *

+ * 3. files modified in workpace that are not opened for edit. *

* By default, the files matching each condition above in the path are reconciled * by opening files for delete (scenario 1), add (scenario 2), and/or edit (scenario 3). @@ -1269,19 +1172,20 @@ List mergeFiles(IFileSpec fromFile, List toFiles, * @see com.perforce.p4java.option.client.ReconcileFilesOptions * @since 2012.2 */ - List reconcileFiles(List fileSpecs, ReconcileFilesOptions opts) - throws P4JavaException; + List reconcileFiles(List fileSpecs, ReconcileFilesOptions opts) throws P4JavaException; /** * Open files for add, delete, and/or edit to reconcile client with workspace - * changes made outside of Perforce.

+ * changes made outside of Perforce. *

* 'p4 reconcile' finds unopened files in a client's workspace and detects the - * following:

+ * following: + *

+ * 1. files in depot missing from workspace, but still on have list. + *

+ * 2. files on workspace that are not in depot. *

- * 1. files in depot missing from workspace, but still on have list.

- * 2. files on workspace that are not in depot.

- * 3. files modified in workpace that are not opened for edit.

+ * 3. files modified in workpace that are not opened for edit. *

* By default, the files matching each condition above in the path are reconciled * by opening files for delete (scenario 1), add (scenario 2), and/or edit (scenario 3). @@ -1303,13 +1207,12 @@ List reconcileFiles(List fileSpecs, ReconcileFilesOptions * @see com.perforce.p4java.option.client.ReconcileFilesOptions * @since 2012.3 */ - void reconcileFiles(List fileSpecs, ReconcileFilesOptions opts, IStreamingCallback callback, int key) - throws P4JavaException; + void reconcileFiles(List fileSpecs, ReconcileFilesOptions opts, IStreamingCallback callback, int key) throws P4JavaException; /** * Branches a set of files (the 'source') into another depot location (the * 'target') in a single step. The new files are created immediately, without - * requiring a 'p4 submit' or a client workspace.

+ * requiring a 'p4 submit' or a client workspace. *

* Note that depending on the specific options passed-in the fromFile can be * null or one file spec; the toFiles list can be null, one or more file specs. @@ -1323,16 +1226,15 @@ void reconcileFiles(List fileSpecs, ReconcileFilesOptions opts, IStre * @throws P4JavaException if an error occurs processing this method and its parameters. * @since 2012.3 */ - List populateFiles(IFileSpec fromFile, List toFiles, - PopulateFilesOptions opts) throws P4JavaException; + List populateFiles(IFileSpec fromFile, List toFiles, PopulateFilesOptions opts) throws P4JavaException; /** * Gets the repos mapped within the client's view. * * @return list of repos - * @throws ConnectionException - * @throws RequestException - * @throws AccessException + * @throws ConnectionException on error + * @throws RequestException on error + * @throws AccessException on error * @since 2017.1 */ List getRepos() throws ConnectionException, RequestException, AccessException; @@ -1351,7 +1253,7 @@ List populateFiles(IFileSpec fromFile, List toFiles, * @param fileSpecs List of File specs * @param options List options * @return ListData - * @throws P4JavaException + * @throws P4JavaException on error * @since 2017.2 */ ListData getListData(List fileSpecs, ListOptions options) throws P4JavaException; @@ -1363,9 +1265,9 @@ List populateFiles(IFileSpec fromFile, List toFiles, * @param parentView NOINHERIT or INHERIT * @param sourceComments If true add inline source comments to ViewMaps when changing the ParentView field * from inherit to noinherit. - * @return - * @throws P4JavaException + * @return response + * @throws P4JavaException on error * @since 2021.2 */ - String setStreamParentView(IStreamSummary.ParentView parentView, boolean sourceComments) throws P4JavaException ; + String setStreamParentView(IStreamSummary.ParentView parentView, boolean sourceComments) throws P4JavaException; } diff --git a/src/main/java/com/perforce/p4java/client/IClientSummary.java b/src/main/java/com/perforce/p4java/client/IClientSummary.java index 76677bb..8ca1c6f 100644 --- a/src/main/java/com/perforce/p4java/client/IClientSummary.java +++ b/src/main/java/com/perforce/p4java/client/IClientSummary.java @@ -1,5 +1,5 @@ /** - * + * */ package com.perforce.p4java.client; @@ -13,123 +13,144 @@ * metadata and associated operations, without providing client * views or actual client-related operations. Corresponds closely to * the information retruned by a "p4 clients" command.

- * + * * Lightweight IClientSummary objects are typically returned from client list * operations such as IServer.getClientList; further use of these specs for * heavier-weight operations (etc.) requires getting the full client * (IClient) object from the server via an explicit getClient() or similar * operation.

- * + * * Note that field setter methods defined below have local effect only, and in order to * update the corresponding client on the Perforce server, you would need to create a * corresponding full IClient object and update that object on the server. - * + * * "Pure" IClientSummary objects (those implementing just the IClientSummary interface) are * complete but are not refreshable or updateable (full IClient objects, on the other * hand, are complete, refreshable, and updateable). */ public interface IClientSummary extends IServerResource { - + /** * Defines what options are available or set (or whatever) for a specific Perforce Client.

- * + * * Perforce client options are described in more detail elsewhere in the Perforce documentation, * but the individual method descriptions below attempt to give the general idea... */ - + public interface IClientOptions { boolean isAllWrite(); + void setAllWrite(boolean allWrite); + boolean isClobber(); + void setClobber(boolean clobber); + boolean isCompress(); + void setCompress(boolean compress); + boolean isLocked(); + void setLocked(boolean locked); + boolean isModtime(); + void setModtime(boolean modtime); + boolean isRmdir(); + void setRmdir(boolean rmdir); - }; - + } + + ; + /** * Defines the options to be used when submitting Perforce changelists associated * with this Perforce client. Note that the options here are mutually-exclusive, * but it's left up to users and / or implementors to enforce this (the standard * implementation enforces this under normal circumstances).

- * + * * Perforce changelist submit options are described in more detail elsewhere in the * Perforce documentation, but the individual method descriptions below attempt to give * the general idea... */ - + public interface IClientSubmitOptions { - + /** * REOPEN - +reopen */ String REOPEN = "+reopen"; - + /** * SUBMIT_UNCHANGED - submitunchanged */ String SUBMIT_UNCHANGED = "submitunchanged"; - + /** * SUBMIT_UNCHANGED_REOPEN - submitunchanged+reopen */ String SUBMIT_UNCHANGED_REOPEN = SUBMIT_UNCHANGED + REOPEN; - + /** * LEAVE_UNCHANGED - leaveunchanged */ String LEAVE_UNCHANGED = "leaveunchanged"; - + /** * LEAVE_UNCHANGED_REOPEN - leaveunchanged+reopen */ String LEAVE_UNCHANGED_REOPEN = LEAVE_UNCHANGED + REOPEN; - + /** * REVERT_UNCHANGED - revertunchanged */ String REVERT_UNCHANGED = "revertunchanged"; - + /** * REVERT_UNCHANGED_REOPEN - revertunchanged+reopen */ String REVERT_UNCHANGED_REOPEN = REVERT_UNCHANGED + REOPEN; - + boolean isSubmitunchanged(); + void setSubmitunchanged(boolean submitunchanged); + boolean isSubmitunchangedReopen(); + void setSubmitunchangedReopen(boolean submitunchangedReopen); + boolean isRevertunchanged(); + void setRevertunchanged(boolean revertunchanged); + boolean isRevertunchangedReopen(); + void setRevertunchangedReopen(boolean revertunchangedReopen); + boolean isLeaveunchanged(); + void setLeaveunchanged(boolean leaveunchanged); + boolean isLeaveunchangedReopen(); + void setLeaveunchangedReopen(boolean leaveunchangedReopen); - }; - + } + /** * Defines the line end options available for text files. */ - public enum ClientLineEnd { - LOCAL, - UNIX, - MAC, - WIN, - SHARE; - + LOCAL, UNIX, MAC, WIN, SHARE; + /** * A slightly looser valueOf(String) + * + * @param str String + * @return client line-end type */ - public static ClientLineEnd getValue(String str) { if (str != null) { for (ClientLineEnd le : ClientLineEnd.values()) { @@ -138,248 +159,234 @@ public static ClientLineEnd getValue(String str) { } } } - + return null; } - }; - + } + /** * Get the name of this client. - * + * * @return the name of this client, if set or known; null otherwise. */ - String getName(); - + /** * Set the name of this client. - * + * * @param name new client name. */ void setName(String name); - + /** * Get the date the client's specification was last modified. - * + * * @return the date the client's specification was last modified, * or null if not known. */ - Date getUpdated(); - + /** * Set the client's updated date / time. - * + * * @param updated new updated date. */ void setUpdated(Date updated); - + /** * Gets the date this client was last used in any way. Note that this * is a server-side date and does not reflect client-side usage. - * + * * @return the date this client was last used in any way, or * null if not known. */ - Date getAccessed(); - + /** * Set the client's accessed date / time. - * + * * @param accessed new accessed date. */ void setAccessed(Date accessed); - + /** * Get the name of the owner of this Perforce client. - * + * * @return the name of the owner of this Perforce client, if known; * null otherwise. */ - String getOwnerName(); - + /** * Set the name of the owner of this client. - * + * * @param ownerName the name of the owner of this Perforce client. */ void setOwnerName(String ownerName); - + /** * Returns the name of the associated host, if any. - * + * * @return the name of the associated host, if any; null otherwise. */ - String getHostName(); - + /** * Set the name of the associated host. - * + * * @param hostName new host name. */ void setHostName(String hostName); - + /** * Returns a short description of the Perforce server client. - * + * * @return the short description of the client, or null if no such * description is available. */ - String getDescription(); - + /** * Set the description associated with this client. - * + * * @param description new description string. */ void setDescription(String description); - + /** * Returns the root of this Perforce client. - * + * * @return the root of this client, or null if no such root is available. */ - String getRoot(); - + /** * Set the root of this client. - * + * * @param root new client root. */ void setRoot(String root); - + /** * Get the alternate roots associated with this Perforce client, * if any. - * + * * @return list of alternate roots if they exist; null otherwise. */ - List getAlternateRoots(); - + /** * Set the alternate roots associated with this Perforce client. - * + * * @param alternateRoots new alternate roots list. Note that order * within the list is significant. */ void setAlternateRoots(List alternateRoots); - + /** * Get the line end options for this client. - * + * * @return ClientLineEnd representing the line end options for this client. */ - ClientLineEnd getLineEnd(); - + /** * Set the line end options for this client. - * + * * @param lineEnd ClientLineEnd representing the line end options for this client. */ void setLineEnd(ClientLineEnd lineEnd); - + /** * Get the Perforce client options associated with this client. - * + * * @return non-null options */ - IClientOptions getOptions(); - + /** * Set the client options associated with this client. - * + * * @param options new options. */ void setOptions(IClientOptions options); - + /** * Get the Perforce client changelist submit options associated with this client. - * + * * @return non-null changelist submit options */ - IClientSubmitOptions getSubmitOptions(); - + /** * Set the client submit options for this client. - * + * * @param submitOptions new client submit options. */ void setSubmitOptions(IClientSubmitOptions submitOptions); - + /** * Get the stream's path in a stream depot, of the form //depotname/streamname, * to which this client's view will be dedicated. - * + * * @return the stream's path in a stream depot of this client, or null if this * is not a stream client. */ - String getStream(); - + /** * Set the stream's path in a stream depot, of the form //depotname/streamname, * to which this client's view will be dedicated. - * + * * @param stream new stream's path in a stream depot of this client. */ void setStream(String stream); - + /** * Convenience method to check if this is a stream client + * + * @return true, if stream */ boolean isStream(); - + /** * Get the server id associated with this client. - * + * * @return the server id associated with this client, or null if this * client has no associated server id. */ - String getServerId(); - + /** * Set the server id of this client. - * + * * @param serverId new server id for this client. */ - void setServerId(String serverId); /** * Get the changelist id associated with this dynamically generated * back-in-time stream client. - * + * * @return the changelist id associated with this dynamically generated * back-in-time stream client, or IChangelist.UNKNOWN if this is not * a dynamically generated back-in-time stream client. */ - int getStreamAtChange(); /** * Set the changelist id associated with this dynamically generated * back-in-time stream client. - * + * * @param streamAtChange * new changelist id associated with this dynamically generated * back-in-time stream client. */ - void setStreamAtChange(int streamAtChange); - + /** * Return the "unloaded" status for this client. - * + * * @return true iff the client is unloaded. */ boolean isUnloaded(); diff --git a/src/main/java/com/perforce/p4java/client/delegator/IWhereDelegator.java b/src/main/java/com/perforce/p4java/client/delegator/IWhereDelegator.java index 218087d..7ce2092 100644 --- a/src/main/java/com/perforce/p4java/client/delegator/IWhereDelegator.java +++ b/src/main/java/com/perforce/p4java/client/delegator/IWhereDelegator.java @@ -1,6 +1,5 @@ package com.perforce.p4java.client.delegator; -import com.perforce.p4java.client.IClient; import com.perforce.p4java.core.file.IFileSpec; import com.perforce.p4java.exception.AccessException; import com.perforce.p4java.exception.ConnectionException; @@ -11,10 +10,10 @@ public interface IWhereDelegator { /** * For each of the passed-in file specs, show how the named file maps through - * the client view.

+ * the client view. *

* Note that this method will return an empty list unless the client is the - * IServer object's current client.

+ * IServer object's current client. *

* The returned IFiles contain all three of the depot, client, and local * file paths of the corresponding fileSpec array element where appropriate, or the @@ -31,16 +30,14 @@ public interface IWhereDelegator { * connected. * @throws AccessException if the Perforce server denies access to the caller */ - - List where(List fileSpecs) - throws ConnectionException, AccessException; + List where(List fileSpecs) throws ConnectionException, AccessException; /** * For each of the passed-in file specs, show how the named file maps through - * the client view.

+ * the client view. *

* Note that this method will return an empty list unless the client is the - * IServer object's current client.

+ * IServer object's current client. *

* The returned IFiles contain all three of the depot, client, and local * file paths of the corresponding fileSpec array element where appropriate, or the @@ -48,7 +45,7 @@ List where(List fileSpecs) * main exception to this is the case when no filespecs are given (i.e. the fileSpecs * array is null or empty), when the mappings for '...' (all files in the current directory * and below) are returned (if they exist). - * + *

* Assumes depot syntax is used for original path. * * @param fileSpecs a list of Perforce file specifications; can be empty or even @@ -56,7 +53,5 @@ List where(List fileSpecs) * @return a non-null (but possibly empty) list of IFileSpec for the input * filespecs. */ - List localWhere(List fileSpecs); - } diff --git a/src/main/java/com/perforce/p4java/common/base/P4JavaExceptions.java b/src/main/java/com/perforce/p4java/common/base/P4JavaExceptions.java index e522b69..95b8312 100644 --- a/src/main/java/com/perforce/p4java/common/base/P4JavaExceptions.java +++ b/src/main/java/com/perforce/p4java/common/base/P4JavaExceptions.java @@ -1,10 +1,5 @@ package com.perforce.p4java.common.base; -import static com.perforce.p4java.common.base.StringHelper.format; - -import java.io.IOException; -import java.lang.reflect.Field; - import com.perforce.p4java.common.function.Function; import com.perforce.p4java.common.function.FunctionWithException; import com.perforce.p4java.exception.AccessException; @@ -16,7 +11,10 @@ import com.perforce.p4java.exception.P4JavaException; import com.perforce.p4java.exception.ProtocolError; import com.perforce.p4java.exception.RequestException; -import org.apache.commons.lang3.StringUtils; + +import java.io.IOException; + +import static com.perforce.p4java.common.base.StringHelper.format; /** * @author Sean Shou @@ -28,11 +26,13 @@ private P4JavaExceptions() { /* util */ } /** * If the check expression fails; then ConnectionException will throw * with given error message message + * + * @param expression expression + * @param message message + * @param args args + * @throws ConnectionException on error */ - public static void throwConnectionExceptionIfConditionFails( - final boolean expression, - final String message, - final Object... args) throws ConnectionException { + public static void throwConnectionExceptionIfConditionFails(final boolean expression, final String message, final Object... args) throws ConnectionException { if (!expression) { String exceptionMessage = format(message, args); @@ -57,6 +57,11 @@ public static void throwConnectionException(Throwable cause, String message, Obj /** * If the check expression fails; then ConnectionException will throw * with given error message message + * + * @param expression expression + * @param message message + * @param args args + * @throws ProtocolError on error */ public static void throwProtocolErrorIfConditionFails(boolean expression, String message, Object... args) throws ProtocolError { if (!expression) { @@ -68,6 +73,11 @@ public static void throwProtocolErrorIfConditionFails(boolean expression, String /** * If the check expression fails; then ConnectionException will throw * with given error message message + * + * @param expression expression + * @param message message + * @param args args + * @throws P4JavaError on error */ public static void throwP4JavaErrorIfConditionFails(boolean expression, String message, Object... args) throws P4JavaError { if (!expression) { @@ -89,6 +99,11 @@ public static void throwP4JavaError(String message, Object... args) throws P4Jav /** * If the check expression fails; then ConnectionException will throw * with given error message message + * + * @param expression expression + * @param message message + * @param args args + * @throws OptionsException on error */ public static void throwOptionsExceptionIfConditionFails(boolean expression, String message, Object... args) throws OptionsException { if (!expression) { @@ -114,6 +129,12 @@ public static void throwOptionsException(String message, Object... args) throws /** * If the check expression fails; then ConnectionException will throw * with given error message message + * + * @param expression expression + * @param codeString codeString + * @param message message + * @param args args + * @throws RequestException on error */ public static void throwRequestExceptionIfConditionFails(boolean expression, String codeString, String message, Object... args) throws RequestException { if (!expression) { @@ -125,11 +146,13 @@ public static void throwRequestExceptionIfConditionFails(boolean expression, Str /** * If the check expression fails; then ConnectionException will throw * with given error message message + * + * @param expression expression + * @param message message + * @param args args + * @throws RequestException on error */ - public static void throwRequestExceptionIfConditionFails( - final boolean expression, - final String message, - final Object... args) throws RequestException { + public static void throwRequestExceptionIfConditionFails(final boolean expression, final String message, final Object... args) throws RequestException { if (!expression) { String exceptionMessage = format(message, args); @@ -137,23 +160,22 @@ public static void throwRequestExceptionIfConditionFails( } } - public static void throwRequestExceptionIfPerforceServerVersionOldThanExpected( - final boolean expression, - final String message, - final Object... args) throws RequestException { + public static void throwRequestExceptionIfPerforceServerVersionOldThanExpected(final boolean expression, final String message, final Object... args) throws RequestException { if (!expression) { String exceptionMessage = format(message, args); - throw new RequestException( - exceptionMessage, - MessageGenericCode.EV_UPGRADE, - MessageSeverityCode.E_FAILED); + throw new RequestException(exceptionMessage, MessageGenericCode.EV_UPGRADE, MessageSeverityCode.E_FAILED); } } /** * If the check expression fails; then ConnectionException will throw * with given error message message + * + * @param expression expression + * @param message message + * @param args args + * @throws AccessException on error */ public static void throwAccessExceptionIfConditionFails(boolean expression, String message, Object... args) throws AccessException { if (!expression) { diff --git a/src/main/java/com/perforce/p4java/common/base/P4ResultMapUtils.java b/src/main/java/com/perforce/p4java/common/base/P4ResultMapUtils.java index eaba2da..32e6420 100644 --- a/src/main/java/com/perforce/p4java/common/base/P4ResultMapUtils.java +++ b/src/main/java/com/perforce/p4java/common/base/P4ResultMapUtils.java @@ -35,6 +35,9 @@ public static String parseCode0ErrorString(@Nonnull Map map) { } /** + * @param map map + * @param key key + * @return value * @throws NumberFormatException if the string does not contain a parsable integer. */ public static int parseInt(@Nonnull Map map, String key) { @@ -42,6 +45,9 @@ public static int parseInt(@Nonnull Map map, String key) { } /** + * @param map map + * @param key key + * @return value * @throws NumberFormatException if the string does not contain a parsable integer. */ public static long parseLong(@Nonnull Map map, String key) { diff --git a/src/main/java/com/perforce/p4java/common/function/Function.java b/src/main/java/com/perforce/p4java/common/function/Function.java index 6a89758..ac22cd8 100644 --- a/src/main/java/com/perforce/p4java/common/function/Function.java +++ b/src/main/java/com/perforce/p4java/common/function/Function.java @@ -8,15 +8,16 @@ * * @param the type of the input to the function * @param the type of the result of the function - * apiNote: It will be replace by jdk-api if p4java use jdk1.8 in future. + * apiNote: It will be replace by jdk-api if p4java use jdk1.8 in future. */ public interface Function { - /** - * Applies this function to the given argument. - * - * @param t the function argument - * @return the function result - */ - R apply(T t) throws RequestException; + /** + * Applies this function to the given argument. + * + * @param t the function argument + * @return the function result + * @throws RequestException on error + */ + R apply(T t) throws RequestException; } diff --git a/src/main/java/com/perforce/p4java/core/CoreFactory.java b/src/main/java/com/perforce/p4java/core/CoreFactory.java index 2e9797d..fbd6ebc 100644 --- a/src/main/java/com/perforce/p4java/core/CoreFactory.java +++ b/src/main/java/com/perforce/p4java/core/CoreFactory.java @@ -1,11 +1,8 @@ /** - * + * */ package com.perforce.p4java.core; -import java.util.List; -import java.util.Map; - import com.perforce.p4java.client.IClient; import com.perforce.p4java.exception.NullPointerError; import com.perforce.p4java.exception.P4JavaException; @@ -18,43 +15,46 @@ import com.perforce.p4java.impl.mapbased.client.Client; import com.perforce.p4java.server.IOptionsServer; +import java.util.List; +import java.util.Map; + /** * A lightweight factory class with convenience methods for * creating common P4Java objects using the default implementation * classes with common default values.

- * + * * Note that this is really just a useful convenience wrapper * for the standard static factory methods on each core implementation * class, but the point of this class is that users do not * typically have to deal with implementation classes * directly at all.

- * + * * Each method typically includes a boolean createOnServer * parameter, which, if true, tries to create the object * (Client, Changelist, whatever...) on the server as well. - * + * * @since 2011.1 */ public class CoreFactory { /** * Create a new client local object and optionally also create it on the server.

- * + * * Only the fields corresponding to the parameters here can be explicitly set * on creation; all others are given defaults that can be changed * or added later. These defaults are as given for the default Client * and ClientSummary constructors; exceptions include the client's user * name, which is set to server.getUserName (which may cause issues later * down the line if that wasn't set).

- * + * * Note: users of this method are responsible for ensuring that the client you're asking * to be created does not already exist -- if it does exist, this method will succeed, * but the result will be an updated version of the existing client on the server, which * may not be what you wanted.

- * + * * Note: this does not set the server's current client to the returned value; * you have to do that yourself... - * + * * @param server non-null IOptionsServer to be associated with the client. * @param name non-null client name. * @param description if not null, the client description field to be used; if null, @@ -71,37 +71,37 @@ public class CoreFactory { * returned client will in this case be the IClient corresponding * to the on-server client (if the creation succeeded...). * @throws P4JavaException if anything went wrong during creation on the server. + * @return IClient */ - public static IClient createClient(IOptionsServer server, String name, String description, - String root, String[] paths, boolean createOnServer) throws P4JavaException { - + public static IClient createClient(IOptionsServer server, String name, String description, String root, String[] paths, boolean createOnServer) throws P4JavaException { + Client client = Client.newClient(server, name, description, root, paths); - + if (client == null) { throw new NullPointerError("null client object returned from Client.newClient method"); } - + if (!createOnServer) { return client; } - + // server is usable and not null -- otherwise we'd have had a NullPointerError // in Client.newClient() ... - + @SuppressWarnings("unused") // used for debugging String createString = server.createClient(client); return server.getClient(name); } - + /** * Create a new changelist object locally and optionally also create * it on the server using the passed-in client for default values.

- * + * * The changelist's user field will be set to the current user; other * fields and semantics are as given in the Changelist implementation * class static factory methods which are called directly through this * method.

- * + * * @param client non-null client to be associated with the changelist; this * client object must contain a valid server field if * createOnServer is true. @@ -114,24 +114,23 @@ public static IClient createClient(IOptionsServer server, String name, String de * @throws P4JavaException if anything went wrong during object creation * on the server. */ - - public static IChangelist createChangelist(IClient client, String description, - boolean createOnServer) throws P4JavaException { + + public static IChangelist createChangelist(IClient client, String description, boolean createOnServer) throws P4JavaException { Changelist changelist = Changelist.newChangelist(client, description); - + if (!createOnServer) { return changelist; } - + // server is usable and not null -- otherwise we'd have had a NullPointerError // in the static method above ... - + return client.createChangelist(changelist); } - + /** * Simple convenience factory method to create a new local or in-server job. - * + * * @param server non-null server to be associated with the job. * @param map non-null job fields map. * @param createOnServer if true, create the job on the server, otherwise @@ -140,8 +139,7 @@ public static IChangelist createChangelist(IClient client, String description, * @throws P4JavaException if anything went wrong during object creation * on the server. */ - public static IJob createJob(IOptionsServer server, Map map, - boolean createOnServer) throws P4JavaException { + public static IJob createJob(IOptionsServer server, Map map, boolean createOnServer) throws P4JavaException { if (!createOnServer) { return Job.newJob(server, map); } else { @@ -149,17 +147,17 @@ public static IJob createJob(IOptionsServer server, Map map, throw new NullPointerError("null server passed to Factory.createJob()"); } return server.createJob(map); - } + } } - + /** * Create a new ILabel object locally and optionally on the server.

- * + * * Note: users of this method are responsible for ensuring that the label you're asking * to be created does not already exist -- if it does exist, this method will succeed, * but the result will be an updated version of the existing label on the server, which * may not be what you wanted.

- * + * * @param server non-null server to be associated with this label. * @param name non-null label name. * @param description if not null, use this as the label's description field; @@ -172,31 +170,30 @@ public static IJob createJob(IOptionsServer server, Map map, * @throws P4JavaException if anything went wrong during object creation * on the server. */ - public static ILabel createLabel(IOptionsServer server, String name, String description, - String[] mapping, boolean createOnServer) throws P4JavaException { + public static ILabel createLabel(IOptionsServer server, String name, String description, String[] mapping, boolean createOnServer) throws P4JavaException { ILabel label = Label.newLabel(server, name, description, mapping); - + if (!createOnServer) { return label; } - + server.createLabel(label); - + return server.getLabel(name); } - + /** * Create a new IUser object locally and optionally on the server.

- * + * * Note: users of this method are responsible for ensuring that the user you're asking * to be created does not already exist -- if it does exist, this method will succeed, * but the result will be an updated version of the existing user on the server, which * may not be what you wanted.

- * + * * Note also that if createOnServer is true, user creation will fail on the server * unless you have the right to create the new user -- this method uses the equivalent * of 'p4 user -f' under the covers. - * + * * @param server server to be associated with this user; must not be null if * createOnServer is true. * @param name non-null user name. @@ -209,30 +206,29 @@ public static ILabel createLabel(IOptionsServer server, String name, String desc * @throws P4JavaException if anything went wrong during object creation * on the server. */ - public static IUser createUser(IOptionsServer server, String name, String email, String fullName, - String password, boolean createOnServer) throws P4JavaException { + public static IUser createUser(IOptionsServer server, String name, String email, String fullName, String password, boolean createOnServer) throws P4JavaException { IUser user = User.newUser(name, email, fullName, password); - + if (!createOnServer) { return user; } - + if (server == null) { throw new NullPointerException("null server passed to Factory.createUser()"); } server.createUser(user, true); return server.getUser(name); } - + /** * Create a new user group locally and / or on the server, using "sensible" default * values for non-parameters.

- * + * * Note: users of this method are responsible for ensuring that the user group you're asking * to be created does not already exist -- if it does exist, this method will succeed, * but the result will be an updated version of the existing user grup on the server, which * may not be what you wanted.

- * + * * @param server server to be associated with this user group; must not be null if * createOnServer is true. * @param name non-null user group name. @@ -243,30 +239,29 @@ public static IUser createUser(IOptionsServer server, String name, String email, * @throws P4JavaException if anything went wrong during object creation * on the server. */ - public static IUserGroup createUserGroup(IOptionsServer server, String name, - List users, boolean createOnServer) throws P4JavaException { + public static IUserGroup createUserGroup(IOptionsServer server, String name, List users, boolean createOnServer) throws P4JavaException { IUserGroup group = UserGroup.newUserGroup(name, users); - + if (!createOnServer) { return group; } - + if (server == null) { throw new NullPointerException("null server passed to Factory.createUserGroup()"); } server.createUserGroup(group, null); return server.getUserGroup(name); } - + /** * Create a new branch spec locally and / or on the server with default values for * non-parameter fields.

- * + * * Note: users of this method are responsible for ensuring that the spec you're asking * to be created does not already exist -- if it does exist, this method will succeed, * but the result will be an updated version of the existing branch spec on the server, which * may not be what you wanted.

- * + * * @param server non-null server to be associated with the new branch spec. * @param name non-null branch spec name. * @param description if not null, used as the new branc spec's description field; @@ -281,14 +276,13 @@ public static IUserGroup createUserGroup(IOptionsServer server, String name, * @throws P4JavaException if anything went wrong during object creation * on the server. */ - public static IBranchSpec newBranchSpec(IOptionsServer server, String name, String description, - String[] branches, boolean createOnServer) throws P4JavaException { + public static IBranchSpec newBranchSpec(IOptionsServer server, String name, String description, String[] branches, boolean createOnServer) throws P4JavaException { IBranchSpec branchSpec = BranchSpec.newBranchSpec(server, name, description, branches); if (!createOnServer) { return branchSpec; } - + server.createBranchSpec(branchSpec); return server.getBranchSpec(name); } diff --git a/src/main/java/com/perforce/p4java/core/IBranchMapping.java b/src/main/java/com/perforce/p4java/core/IBranchMapping.java index e4c7617..9bc3332 100644 --- a/src/main/java/com/perforce/p4java/core/IBranchMapping.java +++ b/src/main/java/com/perforce/p4java/core/IBranchMapping.java @@ -1,5 +1,5 @@ /** - * + * */ package com.perforce.p4java.core; @@ -7,29 +7,37 @@ * Defines an individual Perforce branch view mapping between a source path * and a target path. */ - public interface IBranchMapping extends IMapEntry { + /** * Get a branch view entry's "source" spec; this corresponds * to the left entry of the associated mapping. + * + * @return LHS branch mapping */ String getSourceSpec(); - + /** * Set a branch view entry's "source" spec; this corresponds * to the left entry of the associated mapping. + * + * @param sourceSpec LHS branch mapping */ void setSourceSpec(String sourceSpec); - + /** * Get a branch view entry's "target" spec; this corresponds * to the right entry of the associated mapping. + * + * @return RHS branch mapping */ String getTargetSpec(); - + /** * Set a branch view entry's "target" spec; this corresponds * to the right entry of the associated mapping. + * + * @param targeSpec RHS branch mapping */ void setTargetSpec(String targeSpec); -}; +} diff --git a/src/main/java/com/perforce/p4java/core/IBranchSpec.java b/src/main/java/com/perforce/p4java/core/IBranchSpec.java index 8dd4efa..801ff28 100644 --- a/src/main/java/com/perforce/p4java/core/IBranchSpec.java +++ b/src/main/java/com/perforce/p4java/core/IBranchSpec.java @@ -6,23 +6,25 @@ /** * Defines a full Perforce branch specification for use in Perforce integrate (merge) - * commands.

- * - * Full branch specs in the current implementation are always complete. + * commands. + *

+ * Full branch specs in the current implementation are always complete. */ - public interface IBranchSpec extends IBranchSpecSummary { - + /** - * Return the view map associated with this branch spec.

+ * Return the view map associated with this branch spec. + *

+ * + * @return branch mapping */ ViewMap getBranchView(); - + /** * Set the the view map associated with this branch spec. This will not change * the associated branch spec on the Perforce server unless you * arrange for the update to server. - * + * * @param branchView new view mappings for the branch. */ void setBranchView(ViewMap branchView); diff --git a/src/main/java/com/perforce/p4java/core/IBranchSpecSummary.java b/src/main/java/com/perforce/p4java/core/IBranchSpecSummary.java index ae1564b..8dabea7 100644 --- a/src/main/java/com/perforce/p4java/core/IBranchSpecSummary.java +++ b/src/main/java/com/perforce/p4java/core/IBranchSpecSummary.java @@ -21,31 +21,37 @@ public interface IBranchSpecSummary extends IServerResource { /** * Get the name of this branch. + * @return name */ String getName(); /** * Get the name of the user who created this branch. + * @return owner */ String getOwnerName(); /** * Get the date specification was last modified. + * @return date */ Date getUpdated(); /** * Get the date of the last 'integrate' using this branch. + * @return date */ Date getAccessed(); /** * Get the branch's description (if any). + * @return description */ String getDescription(); /** * Return true if the branch spec is locked. + * @return true if locked */ boolean isLocked(); diff --git a/src/main/java/com/perforce/p4java/core/IChangelist.java b/src/main/java/com/perforce/p4java/core/IChangelist.java index 7ecef72..b295c58 100644 --- a/src/main/java/com/perforce/p4java/core/IChangelist.java +++ b/src/main/java/com/perforce/p4java/core/IChangelist.java @@ -214,6 +214,7 @@ List getFiles(boolean refresh) * the stream, in order to release the underlying io resources. Failure to do this * may leave temporary files lying around or cause inefficient memory usage. * + * @param diffType diff type * @return InputStream onto the diff stream. Note that * while this stream will not be null, it may be empty. * @throws ConnectionException if the Perforce server is unreachable or is not diff --git a/src/main/java/com/perforce/p4java/core/IChangelistSummary.java b/src/main/java/com/perforce/p4java/core/IChangelistSummary.java index b33be33..67f4809 100644 --- a/src/main/java/com/perforce/p4java/core/IChangelistSummary.java +++ b/src/main/java/com/perforce/p4java/core/IChangelistSummary.java @@ -1,16 +1,16 @@ /** - * + * */ package com.perforce.p4java.core; -import java.util.Date; - import com.perforce.p4java.Log; +import java.util.Date; + /** * Defines the methods and operations available on Perforce * changelist summaries returned from the server.

- * + * * Changelist summaries are typically returned from the server's * changelist list methods (e.g. getChangelists) and normally * contain only the fields returned by the Perforce "p4 changes" @@ -18,27 +18,27 @@ * and allow only "local" field setter and getter operations. For * full changelist functionality, use the IChangelist interface * that extends this interface.

- * + * * Unextended IChangelistSummary objects are complete, and neither * refreshable nor updateable. */ public interface IChangelistSummary { - + /** * Defines the visibility of the changelist. Corresponds to the * server 2010.2 release 'type' field in changelists. - * + * * @since 2011.1 */ public enum Visibility { - PUBLIC, - RESTRICTED, - UNKNOWN; - + PUBLIC, RESTRICTED, UNKNOWN; + /** * Return a suitable Visibility type as inferred from the passed-in * string, which is assumed to be the string form of a Visibility type. * Otherwise return the UNKNOWN type + * @param str str + * @return Visibility */ public static Visibility fromString(String str) { if (str == null) { @@ -48,145 +48,140 @@ public static Visibility fromString(String str) { try { return Visibility.valueOf(str.toUpperCase()); } catch (IllegalArgumentException iae) { - Log.error("Bad conversion attempt in Visibility.fromString; string: " - + str + "; message: " + iae.getMessage()); + Log.error("Bad conversion attempt in Visibility.fromString; string: " + str + "; message: " + iae.getMessage()); Log.exception(iae); return UNKNOWN; } } - }; - + } + + ; + /** * Return the Perforce changelist's ID. - * + * * @return changelist ID, or UNKNOWN if unknown or not yet allocated. */ - int getId(); - + /** * Return the description associated with this changelist. - * + * * @return textual changelist description, or null if no such description. */ - String getDescription(); - + /** * Set the description string for this changelist. - * + * * @param newDescription non-null new description string. * @return the old description string. */ - String setDescription(String newDescription); - + /** * Get the status of this changelist, if known. - * + * * @return IChangelistStatus status, or null if not known. */ - ChangelistStatus getStatus(); - + /** * Get the date the changelist was created or last updated. - * + * * @return the date the changelist was created or last updated, or null * if unknown. */ - Date getDate(); - + /** * Get the ID of the Perforce client workspace associated with this changelist. - * + * * @return the ID of the client associated with this changelist, or null if not known. */ String getClientId(); - + /** * Get the user name of the user associated with this changelist. - * + * * @return the user name of the user associated with this changelist, * or null if no such name exists or can be determined. */ - String getUsername(); - + /** * Set the changelist ID. Will not cause the associated changelist to * be updated on the Perforce server without a suitable update being performed. - * + * * @param id new changelist ID. */ void setId(int id); - + /** * Set the client ID. Will not cause the associated changelist to * be updated on the Perforce server without a suitable update being performed. - * + * * @param clientId new client ID. */ void setClientId(String clientId); - + /** * Set the changelist owner ID. Will not cause the associated changelist to * be updated on the Perforce server without a suitable update being performed. - * + * * @param username new owner's user name. */ void setUsername(String username); - + /** * Set the changelist status. Will not cause the associated changelist to * be updated on the Perforce server without a suitable update being performed. - * - * @param status + * + * @param status status */ void setStatus(ChangelistStatus status); - + /** * Set the changelist date. Will not cause the associated changelist to * be updated on the Perforce server without a suitable update being performed. - * + * * @param date new changelist date */ void setDate(Date date); - + /** * Does this changelist contain at least one shelved file? - * + * * This only applies to changelists whose {@link #getStatus()} is * {@link ChangelistStatus#PENDING} and that have been returned as * IChangelistSummary objects. The value here is unreliable for * full IChangelist objects returned from getChangelist, etc. - * + * * @return - true if changelist contains shelved files, false otherwise */ boolean isShelved(); - + /** * Set the shelved status of of this changelist (see isShelved()). - * + * * @param shelved new shelved value. */ void setShelved(boolean shelved); - + /** * Get the visibility associated with this changelist. May be null if no * visibility is associated with this changelist. - * + * * @since 2011.1 * @return possibly-null visibility. */ Visibility getVisibility(); - + /** * Set the visibility associated with this changelist. - * + * * @since 2011.1 - * @param visibility + * @param visibility visability */ void setVisibility(Visibility visibility); diff --git a/src/main/java/com/perforce/p4java/core/IDepot.java b/src/main/java/com/perforce/p4java/core/IDepot.java index 88dc42f..477b383 100644 --- a/src/main/java/com/perforce/p4java/core/IDepot.java +++ b/src/main/java/com/perforce/p4java/core/IDepot.java @@ -11,31 +11,24 @@ /** * Provides an interface onto, and a set of methods to access a specific * Perforce depot contained in a Perforce server. See the main Perforce documentation - * and help system for a full discussion of depots and associated metadata and usage models.

- * + * and help system for a full discussion of depots and associated metadata and usage models. + *

* IDepot objects are not updateable or refreshable, and are currently "complete" in all * implementations. There are no setter methods here as depots are intentionally read-only * in P4Java. */ - public interface IDepot extends IServerResource { - + public enum DepotType { - LOCAL, - REMOTE, - SPEC, - STREAM, - ARCHIVE, - UNLOAD, - TANGENT, - EXTENSION, - GRAPH, - UNKNOWN; - + LOCAL, REMOTE, SPEC, STREAM, ARCHIVE, UNLOAD, TANGENT, EXTENSION, GRAPH, UNKNOWN; + /** * Return a suitable Depot type as inferred from the passed-in * string, which is assumed to be the string form of a Depot type. * Otherwise return the UNKNOWN type + * + * @param str str + * @return DepotType */ public static DepotType fromString(String str) { if (str == null) { @@ -45,51 +38,64 @@ public static DepotType fromString(String str) { try { return DepotType.valueOf(str.toUpperCase()); } catch (IllegalArgumentException iae) { - Log.error("Bad conversion attempt in DepotType.fromString; string: " - + str + "; message: " + iae.getMessage()); + Log.error("Bad conversion attempt in DepotType.fromString; string: " + str + "; message: " + iae.getMessage()); Log.exception(iae); return UNKNOWN; } } - }; - + } + /** * Get the name of the depot. + * + * @return name */ String getName(); - + /** * Get the Perforce user name of the depot's owner. + * + * @return owner */ String getOwnerName(); - + /** * Get the date the depot was last modified. + * + * @return date */ Date getModDate(); - + /** * Get the description associated with this depot. + * + * @return description */ String getDescription(); - + /** * Get the type of this depot. + * + * @return type */ DepotType getDepotType(); - + /** * For remote depots, return the (remote) address of the depot; for other * types of depot, will return null. + * + * @return address */ String getAddress(); - + /** * For spec depots, the optional suffix to be used for generated paths. The * default is '.p4s'. + * + * @return suffix */ String getSuffix(); - + /** * For stream depots, the optional depth to be used for stream paths in the * depot, where depth equates to the number of slashes following the depot @@ -97,23 +103,29 @@ public static DepotType fromString(String str) { * created. The default is '1', matching the traditional stream name. For * example, "//stream_test/1". This value may not be updated once streams or * archive data exist within the depot. + * + * @return stream depth */ String getStreamDepth(); /** * Get the depot's path translation information. + * + * @return mapped location */ String getMap(); /** * For spec depots, the optional description of which specs should be saved, * as one or more patterns. See example below. - * + * *

 	 * //spec/...
 	 * -//spec/user/qa-*
 	 * -//spec/client/qa-*
 	 * 
+ * + * @return view mapping */ ViewMap getSpecMap(); } diff --git a/src/main/java/com/perforce/p4java/core/IExtension.java b/src/main/java/com/perforce/p4java/core/IExtension.java index 526e0dc..41a8d18 100644 --- a/src/main/java/com/perforce/p4java/core/IExtension.java +++ b/src/main/java/com/perforce/p4java/core/IExtension.java @@ -103,46 +103,64 @@ public interface IExtension extends IServerResource, IExtensionSummary { /** * Set the description of the Extension being configured. + * + * @param extDescription description */ void setExtDescription(String extDescription); /** * Set maximum seconds the Extension may be run. + * + * @param extMaxScriptTime time */ void setExtMaxScriptTime(String extMaxScriptTime); /** * Set maximum megabytes the Extension may use. + * + * @param extMaxScriptMem memory */ void setExtMaxScriptMem(String extMaxScriptMem); /** * Set the user who created this Extension config. - **/ + * + * @param owner owner + */ void setOwner(String owner); /** * Set update time for the Extension config spec. + * + * @param update date */ void setUpdate(String update); /** * Set the description of this Extension config. + * + * @param description description */ void setDescription(String description); /** * Set the extension config. + * + * @param extConfig config map */ void setExtConfig(Map extConfig); /** * Set groups whose members may configure the Extension. - **/ + * + * @param extAllowedGroups groups + */ void setExtAllowedGroups(List extAllowedGroups); /** * Set Perforce user account for the Extension to use. + * + * @param extP4USER Perforce user */ void setExtP4USER(String extP4USER); @@ -152,6 +170,8 @@ public interface IExtension extends IServerResource, IExtensionSummary { * the instance of the Extension will append execution traces to * a log file named '.p4-debug-tracing.txt' in the Extension data * directory. + * + * @param extDebug debug */ void setExtDebug(String extDebug); } diff --git a/src/main/java/com/perforce/p4java/core/IFileLineMatch.java b/src/main/java/com/perforce/p4java/core/IFileLineMatch.java index 5729e92..c997218 100644 --- a/src/main/java/com/perforce/p4java/core/IFileLineMatch.java +++ b/src/main/java/com/perforce/p4java/core/IFileLineMatch.java @@ -30,11 +30,11 @@ enum MatchType { /** * Get a match type enumeration for the specified server value. - * + *

* The returned value will be {@link MatchType#MATCH} when the * serverValue specified is null. - * - * @param serverValue + * + * @param serverValue serverValue * @return type */ public static MatchType fromServerString(String serverValue) { @@ -49,35 +49,35 @@ public static MatchType fromServerString(String serverValue) { /** * Get depot file path of match - * + * * @return depot file path */ String getDepotFile(); /** * Get revision number of match - * + * * @return revision number */ int getRevision(); /** * Get line text of match - * + * * @return line text */ String getLine(); /** * Get line number of match - * + * * @return line number */ int getLineNumber(); /** * Get match type - * + * * @return - type */ MatchType getType(); diff --git a/src/main/java/com/perforce/p4java/core/IJob.java b/src/main/java/com/perforce/p4java/core/IJob.java index ad44caf..d806664 100644 --- a/src/main/java/com/perforce/p4java/core/IJob.java +++ b/src/main/java/com/perforce/p4java/core/IJob.java @@ -3,8 +3,6 @@ */ package com.perforce.p4java.core; -import java.util.Map; - import com.perforce.p4java.exception.AccessException; import com.perforce.p4java.exception.ConnectionException; import com.perforce.p4java.exception.RequestException; @@ -15,55 +13,55 @@ * by an associated IJobSpec interface, which should be used to fully interpret * and work with jobs for a specific server. This particular interface (IJob) * is really intended to let a consumer get a summary list only; further details may - * need to be retrieved from the jobspec and associated elements and interfaces.

- * + * need to be retrieved from the jobspec and associated elements and interfaces. + *

* Note that what constitutes the job ID and description may not always even be accurate, * as it's intuited under the covers using a few shopworn rules of thumb. In any case, * the list is returned in the order returned from the Perforce server, and the raw fields - * map is assumed to contain authoritative field values.

- * + * map is assumed to contain authoritative field values. + *

* IJob objects are currently always complete, are updateable, but not refreshable. Setter * methods below will not affect the corresponding job on the Perforce server unless * an update is performed. - * - * */ - public interface IJob extends IServerResource { /** * get job name + * * @return job name */ String getId(); /** * set job name - * @param id + * + * @param id id */ void setId(String id); - + String getDescription(); + void setDescription(String description); - + IJobSpec getJobSpec(); + void setJobSpec(IJobSpec jobSpec); /** * Update the underlying Perforce job associated with this object in - * the Perforce server.

- * + * the Perforce server. + *

* Basically a convenience method for IServer.updateJob(job). - * - * @deprecated use the IServerResource update method instead if possible. - * + * * @return possibly-null Perforce server-generated status resulting from operation. * @throws ConnectionException if the Perforce server is unreachable or is not - * connected. - * @throws RequestException if the Perforce server encounters an error during - * its processing of the request - * @throws AccessException if the Perforce server denies access to the caller + * connected. + * @throws RequestException if the Perforce server encounters an error during + * its processing of the request + * @throws AccessException if the Perforce server denies access to the caller + * @deprecated use the IServerResource update method instead if possible. */ - + String updateOnServer() throws ConnectionException, RequestException, AccessException; } diff --git a/src/main/java/com/perforce/p4java/core/ILabel.java b/src/main/java/com/perforce/p4java/core/ILabel.java index e5a3daf..77b1af3 100644 --- a/src/main/java/com/perforce/p4java/core/ILabel.java +++ b/src/main/java/com/perforce/p4java/core/ILabel.java @@ -10,100 +10,97 @@ /** * Defines and describes a Perforce label. See the main Perforce - * documentation for label usage and semantics.

- * + * documentation for label usage and semantics. + *

* ILabel objects are complete and updateable only if they come from the * IServer.getLabel() method (or are hand-crafted); label objects from other sources * are not complete or completable, and nor are they refreshable. Setter methods - * defined below affect only local values unless a suitable update is done.

+ * defined below affect only local values unless a suitable update is done. */ public interface ILabel extends ILabelSummary { - + /** * Get the view mapping for this label. Note that only the * left hand side (the depot path) of a mapping is used for labels - * and will be valid here.

- * + * and will be valid here. + *

* Note also that this method will only return the actual view * mapping a label if the label object was returned from the IServer's * getLabel() method (this is due to limitations in the underlying * implementation). - * + * * @return non-null but possibly empty list of IClientViewMapping - * mappings for this label. + * mappings for this label. */ ViewMap getViewMapping(); - + /** * Set the view mapping for this label. Note that only the * left hand side (the depot path) of a mapping is used for labels * and will be valid here. - * + * * @param viewMapping list of IClientViewMapping mappings for this label. */ void setViewMapping(ViewMap viewMapping); - + /** * Update (or even create) this label on the associated Perforce server, * if that server has been set for this label. Will throw a suitable * RequestException if the label is not associated with a server, * either as the result of being returned from a server earlier, or * as the result of an explicit call on the underlying implementation - * object.

- * + * object. + *

* Note that you should only call this method on "full" labels, i.e. * those returned from an explicit single call to IServer.getLabel() * or those created by hand; calling this on a label returned from the * getLabelList() method may cause the associated in-server label to lose * its view mapping. - * - * @deprecated use update() instead. - * + * * @return the string message resulting from the update * @throws ConnectionException if the Perforce server is unreachable or is not - * connected. - * @throws RequestException if the Perforce server encounters an error during - * its processing of the request - * @throws AccessException if the Perforce server denies access to the caller + * connected. + * @throws RequestException if the Perforce server encounters an error during + * its processing of the request + * @throws AccessException if the Perforce server denies access to the caller + * @deprecated use update() instead. */ - String updateOnServer() - throws ConnectionException, RequestException, AccessException; - + String updateOnServer() throws ConnectionException, RequestException, AccessException; + /** * Update (or even create) this label on the associated Perforce server, * if that server has been set for this label. Will throw a suitable * RequestException if the label is not associated with a server, * either as the result of being returned from a server earlier, or * as the result of an explicit call on the underlying implementation - * object.

- * + * object. + *

* Note that you should only call this method on complete labels, i.e. * those returned from an explicit single call to IServer.getLabel() * or those created by hand; calling this on a label returned from the * getLabelList() method will result in a UnimplementedError being * thrown. - * + * * @throws ConnectionException if the Perforce server is unreachable or is not - * connected. - * @throws RequestException if the Perforce server encounters an error during - * its processing of the request - * @throws AccessException if the Perforce server denies access to the caller - * + * connected. + * @throws RequestException if the Perforce server encounters an error during + * its processing of the request + * @throws AccessException if the Perforce server denies access to the caller */ - + void update() throws ConnectionException, RequestException, AccessException; - + /** * Get the Perforce server object associated with this label. - * + * * @return possibly-null IServer object associated with this label. */ IServer getServer(); - + /** * Set the Perforce server object associated with this label. - * + * * @param server possibly-null IServer object to be associated with this label. */ void setServer(IServer server); diff --git a/src/main/java/com/perforce/p4java/core/ILabelMapping.java b/src/main/java/com/perforce/p4java/core/ILabelMapping.java index cd4d15a..97ca79b 100644 --- a/src/main/java/com/perforce/p4java/core/ILabelMapping.java +++ b/src/main/java/com/perforce/p4java/core/ILabelMapping.java @@ -1,12 +1,12 @@ /** - * + * */ package com.perforce.p4java.core; /** * Extends IMapEntry to provide a Perforce label-specific * view map entry type.

- * + * * Perforce label views define only the left side of the mapping as * significant, so we only supply that here, but users are quite * free to use the superclass right side methods to do what they @@ -14,16 +14,20 @@ */ public interface ILabelMapping extends IMapEntry { - + /** * Get a label view entry's "source" spec; this corresponds * to the left entry of the associated mapping. + * + * @return LHS mapping */ String getViewMapping(); - + /** * Set a branch view entry's "source" spec; this corresponds * to the left entry of the associated mapping. + * + * @param entry LHS entry */ void setViewMapping(String entry); } diff --git a/src/main/java/com/perforce/p4java/core/ILabelSummary.java b/src/main/java/com/perforce/p4java/core/ILabelSummary.java index 4394811..9df20c8 100644 --- a/src/main/java/com/perforce/p4java/core/ILabelSummary.java +++ b/src/main/java/com/perforce/p4java/core/ILabelSummary.java @@ -1,5 +1,5 @@ /** - * + * */ package com.perforce.p4java.core; @@ -12,133 +12,132 @@ * and do not support server-side operations against them. For the * full Perforce label object functionality, see ILabel, which * extends this interface.

- * + * * ILabelSummary objects are complete and neither refreshable nor updateable.

- * - * See the main Perforce documentation for label usage and semantics.

+ * + * See the main Perforce documentation for label usage and semantics. */ - public interface ILabelSummary extends IServerResource { - + /** * Get the label's name (the label's label, so to speak). - * + * * @return possibly-null label name (should only be null if the underlying label * object has just been created on the client and has no server-side * counterpart yet). */ String getName(); - + /** * Set the label's name. - * + * * @param name the label's (new) name. */ void setName(String name); - + /** * Get the name of the owner of this label. - * + * * @return possibly-null owner name. */ String getOwnerName(); - + /** * Set the name of the owner of this label. - * + * * @param ownerName the new owner name. */ void setOwnerName(String ownerName); - + /** * Get the date and time the label specification was last updated. - * + * * @return possibly-null Date */ Date getLastUpdate(); - + /** * Set the date and time the label specification was last updated. - * + * * @param lastUpdate Date last updated. */ void setLastUpdate(Date lastUpdate); - + /** * Get the date and time of the last 'labelsync' or use of '@label' * on this label. - * + * * @return possibly-null Date */ Date getLastAccess(); - + /** * Set the date and time of the last 'labelsync' or use of '@label' * on this label. - * + * * @param lastAccess new last access date. */ void setLastAccess(Date lastAccess); - + /** * Get the description associated with this label. - * + * * @return possibly-null description string. */ String getDescription(); - + /** * Set the description associated with this label. - * + * * @param description new label description string. */ void setDescription(String description); - + /** * Return the "locked/unlocked" status for this label. - * + * * @return true iff the label is locked else it is unlocked. */ boolean isLocked(); - + /** * Set the "locked/unlocked" status for this label. - * + * * @param locked true iff the label is locked else it is unlocked. */ void setLocked(boolean locked); - + /** * Return the "autoreload/noautoreload" status for this label. - * + * * @return true iff the label is "autoreload" else it is "noautoreload". */ boolean isAutoReload(); - + /** * Set the "autoreload/noautoreload" status for this label. - * + * * @param autoreload true iff the label is "autoreload" else it is "noautoreload". */ void setAutoReload(boolean autoreload); /** * Get the optional revision specification for this label. - * + * * @return possibly-null revision spec string. */ String getRevisionSpec(); - + /** * Set the optional revision specification for this label. - * + * * @param revisionSpec new revision spec string */ void setRevisionSpec(String revisionSpec); /** * Return the "unloaded" status for this label. - * + * * @return true iff the label is unloaded. */ boolean isUnloaded(); diff --git a/src/main/java/com/perforce/p4java/core/IMapEntry.java b/src/main/java/com/perforce/p4java/core/IMapEntry.java index 06c8b45..c9ff7f5 100644 --- a/src/main/java/com/perforce/p4java/core/IMapEntry.java +++ b/src/main/java/com/perforce/p4java/core/IMapEntry.java @@ -1,5 +1,5 @@ /** - * + * */ package com.perforce.p4java.core; @@ -8,7 +8,7 @@ * "left" values to "right" values, where the semantics and * usage of "left" and "right" depends on the specific type of view * (e.g. left may be "depot", right "client").

- * + * * Note that the left and right strings are pure paths -- they do * not contain (or should not contain) any leading include / exclude * prefixes except where this is explicitly allowed (e.g. the special @@ -16,9 +16,9 @@ */ public interface IMapEntry { - + int ORDER_UNKNOWN = -1; - + /** * Defines the specific type of a given view map entry. */ @@ -29,24 +29,24 @@ enum EntryType { * the map includes this path and its children. */ INCLUDE(""), - + /** * Specifies this is an "exclude" mapping; this means that * the map excludes this path and its children. */ EXCLUDE("-"), - /** - * Specifies this is an "overlay" mapping; this means that - * the map overlays this path and its children. - */ - OVERLAY("+"), - - /** - * Specifies this is an "ditto" mapping; this means that - * the map duplicates this path and its children. - */ - DITTO("&"); + /** + * Specifies this is an "overlay" mapping; this means that + * the map overlays this path and its children. + */ + OVERLAY("+"), + + /** + * Specifies this is an "ditto" mapping; this means that + * the map duplicates this path and its children. + */ + DITTO("&"); private final String symbol; @@ -64,18 +64,20 @@ public String getSymbol() { * string, which is assumed to be a Perforce view map path string. * If str is null, or no such EntryType can be inferred, * returns null. + * @param str str + * @return EntryType */ public static EntryType fromString(String str) { if (str == null) { return null; } - for(IMapEntry.EntryType type : IMapEntry.EntryType.values()) { + for (IMapEntry.EntryType type : IMapEntry.EntryType.values()) { // skip over the INCLUDE type as there is no symbol to match - if(type.equals(INCLUDE)) { + if (type.equals(INCLUDE)) { continue; } - if(str.startsWith(type.getSymbol())) { + if (str.startsWith(type.getSymbol())) { return type; } } @@ -84,7 +86,7 @@ public static EntryType fromString(String str) { return INCLUDE; } - + /** * Return a more useful string than "EXCLUDE" or "OVERLAY", i.e. * return "-" or "+" respectively. Returns the empty string @@ -93,13 +95,15 @@ public static EntryType fromString(String str) { public String toString() { return getSymbol(); } - }; - + } + + ; + /** * Get the order of this entry in the entry list, if known. Returns * ORDER_UNKNOWN if the order is unknown or this entry is not currently * associated with a map. - * + * * @return ORDER_UNKNOWN or current order. */ int getOrder(); @@ -108,131 +112,134 @@ public String toString() { * Set the order of this entry in the entry list. Note that this method * has no effect on the actual order within an entry whatsoever, and is * provided for symmetry and for implementation initialization reasons only. - * + * * @param position new order */ void setOrder(int position); - + /** * Return the view map type of this entry. - * + * * @return possibly-null EntryType */ - EntryType getType(); - - /** - * Set this entry's type. - * - * @param type new entry type. May be null. - */ - void setType(EntryType type); - - /** - * Get the "left" entry for this mapping; equivalent to - * getLeft(false). - * - * @return possibly-null left mapping entry. - */ - String getLeft(); - - /** - * Get the "left" entry for this mapping. Will not include - * any prefixes. If quoteBlanks is true and the left string - * contains spaces or tabs the entire string is returned - * surrounded by quote characters. - * - * @param quoteBlanks if true, and the left string - * contains spaces or tabs the entire string is returned - * surrounded by quote characters. - * @return possibly-null left mapping entry. - */ - String getLeft(boolean quoteBlanks); - - /** - * Set the "left" entry for this mapping. Will strip off - * any exclude (etc.) prefix before assigning it. - * - * @param left possibly-null new left mapping entry - */ - void setLeft(String left); - - /** - * Get the "right" entry for this mapping; equivalent to - * getRight(false). - * - * @return possibly-null right mapping entry. - */ - String getRight(); - - /** - * Get the "right" entry for this mapping. Will not include - * any prefixes. If quoteBlanks is true and the right string - * contains spaces or tabs the entire string is returned - * surrounded by quote characters. - * - * @param quoteBlanks if true, and the right string - * contains spaces or tabs the entire string is returned - * surrounded by quote characters. - * @return possibly-null right mapping entry. - */ - String getRight(boolean quoteBlanks); - - /** - * Set the "right" entry for this mapping. Will strip off - * any exclude (etc.) prefix before assigning it. - * - * @param right possibly-null new right mapping entry - */ - void setRight(String right); - - - /** - * Get the "comment" entry for this mapping; equivalent to - * getComment(false). - * - * @return possibly-null comment mapping entry. - */ - String getComment(); - - /** - * Get the "comment" entry for this mapping. Will not include - * any prefixes. If quoteBlanks is true and the comment string - * contains spaces or tabs the entire string is returned - * surrounded by quote characters. - * - * @param quoteBlanks if true, and the comment string - * contains spaces or tabs the entire string is returned - * surrounded by quote characters. - * @return possibly-null comment mapping entry. - */ - String getComment(boolean quoteBlanks); - - /** - * Set the "comment" entry for this mapping. Will strip off - * any exclude (etc.) prefix before assigning it. - * - * @param comment possibly-null new comment mapping entry - */ - void setComment(String comment); - - /** - * Alias for toString(" ", false). - */ - String toString(); - - /** - * Return a canonical String representation of this entry. This - * is in the form [type prefix]leftpath[specstring]rightpath, e.g. - * "-//depot/dev/test/... //clientname/newpath/..."

- * - * If the passed-in string is null, the left and right strings - * (if they exist) will be concatenated into one long separator-less - * string.

- * - * If the quoteBlanks parameter is true, if either or both the left - * or right entries contain spaces, the entries are quoted in full, i.e. - * the mapping //depot/test/space test 01/... //depot/test/space test 02/... - * becomes "//depot/test/space test 01/..." "//depot/test/space test 02/...". - */ - String toString(String sepString, boolean quoteBlanks); + EntryType getType(); + + /** + * Set this entry's type. + * + * @param type new entry type. May be null. + */ + void setType(EntryType type); + + /** + * Get the "left" entry for this mapping; equivalent to + * getLeft(false). + * + * @return possibly-null left mapping entry. + */ + String getLeft(); + + /** + * Get the "left" entry for this mapping. Will not include + * any prefixes. If quoteBlanks is true and the left string + * contains spaces or tabs the entire string is returned + * surrounded by quote characters. + * + * @param quoteBlanks if true, and the left string + * contains spaces or tabs the entire string is returned + * surrounded by quote characters. + * @return possibly-null left mapping entry. + */ + String getLeft(boolean quoteBlanks); + + /** + * Set the "left" entry for this mapping. Will strip off + * any exclude (etc.) prefix before assigning it. + * + * @param left possibly-null new left mapping entry + */ + void setLeft(String left); + + /** + * Get the "right" entry for this mapping; equivalent to + * getRight(false). + * + * @return possibly-null right mapping entry. + */ + String getRight(); + + /** + * Get the "right" entry for this mapping. Will not include + * any prefixes. If quoteBlanks is true and the right string + * contains spaces or tabs the entire string is returned + * surrounded by quote characters. + * + * @param quoteBlanks if true, and the right string + * contains spaces or tabs the entire string is returned + * surrounded by quote characters. + * @return possibly-null right mapping entry. + */ + String getRight(boolean quoteBlanks); + + /** + * Set the "right" entry for this mapping. Will strip off + * any exclude (etc.) prefix before assigning it. + * + * @param right possibly-null new right mapping entry + */ + void setRight(String right); + + + /** + * Get the "comment" entry for this mapping; equivalent to + * getComment(false). + * + * @return possibly-null comment mapping entry. + */ + String getComment(); + + /** + * Get the "comment" entry for this mapping. Will not include + * any prefixes. If quoteBlanks is true and the comment string + * contains spaces or tabs the entire string is returned + * surrounded by quote characters. + * + * @param quoteBlanks if true, and the comment string + * contains spaces or tabs the entire string is returned + * surrounded by quote characters. + * @return possibly-null comment mapping entry. + */ + String getComment(boolean quoteBlanks); + + /** + * Set the "comment" entry for this mapping. Will strip off + * any exclude (etc.) prefix before assigning it. + * + * @param comment possibly-null new comment mapping entry + */ + void setComment(String comment); + + /** + * Alias for toString(" ", false). + */ + String toString(); + + /** + * Return a canonical String representation of this entry. This + * is in the form [type prefix]leftpath[specstring]rightpath, e.g. + * "-//depot/dev/test/... //clientname/newpath/..."

+ * + * If the passed-in string is null, the left and right strings + * (if they exist) will be concatenated into one long separator-less + * string.

+ * + * If the quoteBlanks parameter is true, if either or both the left + * or right entries contain spaces, the entries are quoted in full, i.e. + * the mapping //depot/test/space test 01/... //depot/test/space test 02/... + * becomes "//depot/test/space test 01/..." "//depot/test/space test 02/...". + * @param sepString separator string + * @param quoteBlanks quotes if spaces are used + * @return formatted string + */ + String toString(String sepString, boolean quoteBlanks); } diff --git a/src/main/java/com/perforce/p4java/core/IRepo.java b/src/main/java/com/perforce/p4java/core/IRepo.java index 68c4423..e900ec9 100644 --- a/src/main/java/com/perforce/p4java/core/IRepo.java +++ b/src/main/java/com/perforce/p4java/core/IRepo.java @@ -6,26 +6,36 @@ public interface IRepo extends IServerResource { /** * Get the repo's name. + * + * @return name */ String getName(); /** * Get the Perforce user name of the repo's owner. + * + * @return owner */ String getOwnerName(); /** * Get the date the repo was created. + * + * @return date */ Date getCreatedDate(); /** * Get the date the repo was last pushed. + * + * @return date */ Date getPushedDate(); /** * Get the description associated with this repo. + * + * @return description */ String getDescription(); @@ -36,15 +46,33 @@ public interface IRepo extends IServerResource { */ void setDescription(String description); + /** + * @return fork + */ String getForkedFrom(); + /** + * @param forkedFrom fork + */ void setForkedFrom(String forkedFrom); + /** + * @return branch + */ String getDefaultBranch(); + /** + * @param defaultBranch branch + */ void setDefaultBranch(String defaultBranch); + /** + * @return mirror + */ String getMirroredFrom(); + /** + * @param mirroredFrom mirror + */ void setMirroredFrom(String mirroredFrom); } diff --git a/src/main/java/com/perforce/p4java/core/IReviewSubscription.java b/src/main/java/com/perforce/p4java/core/IReviewSubscription.java index e43f533..07fa782 100644 --- a/src/main/java/com/perforce/p4java/core/IReviewSubscription.java +++ b/src/main/java/com/perforce/p4java/core/IReviewSubscription.java @@ -15,12 +15,14 @@ public interface IReviewSubscription extends IMapEntry { /** * Get the review subscription. + * @return subscription */ String getSubscription(); /** * Set the review subscription. + * @param subscription subscription */ void setSubscription(String subscription); } diff --git a/src/main/java/com/perforce/p4java/core/IServerResource.java b/src/main/java/com/perforce/p4java/core/IServerResource.java index 4f02d80..5d654e8 100644 --- a/src/main/java/com/perforce/p4java/core/IServerResource.java +++ b/src/main/java/com/perforce/p4java/core/IServerResource.java @@ -14,136 +14,133 @@ /** * Defines methods available on all participating objects returned from * P4Java server and client methods that represent server-side objects - * such as changelists, jobs, etc.

- * + * such as changelists, jobs, etc. + *

* The general intention here is to allow the underlying P4Java plumbing * to use lightweight metadata-only objects where possible (or full-strength * objects only partially-implemented or filled-out), and allow the consumer - * to determine the status of the underlying object and act accordingly.

- * + * to determine the status of the underlying object and act accordingly. + *

* This approach requires all participating P4Java interfaces to spell - * out what both "updateable" and "refreshable" mean, and whether the + * out what both "updateable" and "refreshable" mean, and whether the * associated methods are implemented or not. */ public interface IServerResource { - + /** * Returns true if the underlying object is refreshable from the Perforce - * server.

- * + * server. + *

* The details of what "refreshable" means in this context are always * object-dependent, but typically mean that "live" data and metadata * will be updated from the server. This is especially useful on objects * like changelists, where the underlying server-side data may change * often outside P4Java's control. - * + * * @return true if the underlying the object is refreshable. */ boolean canRefresh(); - + /** - * Refresh the underlying object from the Perforce server.

- * + * Refresh the underlying object from the Perforce server. + *

* The details of what "refreshable" means in this context are always * object-dependent, but typically mean that "live" data and metadata - * will be updated from the server.

- * + * will be updated from the server. + *

* The results of calling this method on objects whose canRefresh * method returns false are undefined (but will generally result in a * UnimplementedError being thrown). - * + * * @throws ConnectionException if the Perforce server is unreachable or is not - * connected. - * @throws RequestException if the Perforce server encounters an error during - * its processing of the request - * @throws AccessException if the Perforce server denies access to the caller + * connected. + * @throws RequestException if the Perforce server encounters an error during + * its processing of the request + * @throws AccessException if the Perforce server denies access to the caller */ void refresh() throws ConnectionException, RequestException, AccessException; - + /** * Returns true if the underlying object can be updated back to (or on) the * associated Perforce server. The semantics of server updates are generally * object-specific. - * + * * @return true if the underlying object can be updated back to (or on) the - * associated Perforce server + * associated Perforce server */ boolean canUpdate(); /** * Old method called used to call refresh when completing a spec. * - * @throws ConnectionException - * when there is an error talking to the Helix server - * @throws RequestException - * when there is a problem with the data provided in the request - * @throws AccessException - * when access to the branch command is not authorised + * @throws ConnectionException when there is an error talking to the Helix server + * @throws RequestException when there is a problem with the data provided in the request + * @throws AccessException when access to the branch command is not authorised */ void complete() throws ConnectionException, RequestException, AccessException; /** * Update the Perforce server object associated with the underlying P4Java object, * if possible. The semantics of server updates are generally object-specific and - * will be spelled out for each participating object.

- * + * will be spelled out for each participating object. + *

* The results of calling this method on objects whose canUpdate * method returns false are undefined (but will generally result in a * UnimplementedError being thrown). - * + * * @throws ConnectionException if the Perforce server is unreachable or is not - * connected. - * @throws RequestException if the Perforce server encounters an error during - * its processing of the request - * @throws AccessException if the Perforce server denies access to the caller + * connected. + * @throws RequestException if the Perforce server encounters an error during + * its processing of the request + * @throws AccessException if the Perforce server denies access to the caller */ void update() throws ConnectionException, RequestException, AccessException; - + /** * Force (if true) update the Perforce server object associated with the underlying * P4Java object, if possible. The semantics of server updates are generally - * object-specific and will be spelled out for each participating object.

- * + * object-specific and will be spelled out for each participating object. + *

* Note, in order to force the change it may require super user / admin privileges * to work properly. - * + *

* The results of calling this method on objects whose canUpdate * method returns false are undefined (but will generally result in a * UnimplementedError being thrown). - * + * * @param force if true, force the update of the object on the server. * @throws ConnectionException if the Perforce server is unreachable or is not - * connected. - * @throws RequestException if the Perforce server encounters an error during - * its processing of the request - * @throws AccessException if the Perforce server denies access to the caller + * connected. + * @throws RequestException if the Perforce server encounters an error during + * its processing of the request + * @throws AccessException if the Perforce server denies access to the caller */ void update(boolean force) throws ConnectionException, RequestException, AccessException; /** * Update the Perforce server object associated with the underlying P4Java object * and its options, if possible. The semantics of server updates are generally - * object-specific and will be spelled out for each participating object.

- * + * object-specific and will be spelled out for each participating object. + *

* The results of calling this method on objects whose canUpdate * method returns false are undefined (but will generally result in a * UnimplementedError being thrown). - * + * * @param opts Options object describing optional parameters; if null, no - * options are set. + * options are set. * @throws ConnectionException if the Perforce server is unreachable or is not - * connected. - * @throws RequestException if the Perforce server encounters an error during - * its processing of the request - * @throws AccessException if the Perforce server denies access to the caller + * connected. + * @throws RequestException if the Perforce server encounters an error during + * its processing of the request + * @throws AccessException if the Perforce server denies access to the caller */ void update(Options opts) throws ConnectionException, RequestException, AccessException; /** * Set the server associated with this resource. Setting this null can have * bad effects down the line... - * + * * @param server IServer to be used for refresh, update, etc. */ void setServer(IServer server); @@ -158,8 +155,9 @@ public interface IServerResource { /** * Enter Key/Pair for a spec field. - * @param field - * @param value + * + * @param field field kay + * @param value value */ void setRawField(String field, Object value); @@ -173,7 +171,7 @@ public interface IServerResource { /** * Add all elements in a map to the spec * - * @param map + * @param map field map */ void setRawFields(Map map); diff --git a/src/main/java/com/perforce/p4java/core/IStream.java b/src/main/java/com/perforce/p4java/core/IStream.java index 19e95f1..914fd98 100644 --- a/src/main/java/com/perforce/p4java/core/IStream.java +++ b/src/main/java/com/perforce/p4java/core/IStream.java @@ -37,7 +37,7 @@ public interface IExtraTag { /** * Return the view map associated with this stream. One or more mappings * that define file paths in the stream view. Each line is of the form: - * [] + * path_type view_path [depot_path] * * @return non-null list of IStreamViewMapping mappings for this stream. */ @@ -57,7 +57,7 @@ public interface IExtraTag { /** * Return the remapped view map associated with this stream. Optional; one * or more mappings that define how stream view paths are to be remapped in - * client views. Each line is of the form: + * client views. Each line is of the form: view_path_1 view_path_2 * * @return possibly-null (optional) list of IStreamRemappedMapping mappings * for this stream. @@ -89,6 +89,7 @@ public interface IExtraTag { * Set the ignored view map associated with this stream spec. This will * not change the associated stream spec on the Perforce server unless you * arrange for the update to server. + * @param ignoredView ignore view mapping */ void setIgnoredView(ViewMap ignoredView); @@ -105,6 +106,7 @@ public interface IExtraTag { * Set the automatically generated client view map associated with this * stream spec. This will not change the associated stream spec on the * Perforce server unless you arrange for the update to server. + * @param clientView client view */ void setClientView(ViewMap clientView); @@ -119,11 +121,13 @@ public interface IExtraTag { * Set the extra tags associated with this stream. This will not change * the associated stream spec on the Perforce server unless you arrange for * the update to server. + * @param extraTags extra tags */ void setExtraTags(List extraTags); /** * Set the server to type of IOptionsServer, overriding the default IServer. + * @param server server */ void setServer(IOptionsServer server); } diff --git a/src/main/java/com/perforce/p4java/core/IStreamIgnoredMapping.java b/src/main/java/com/perforce/p4java/core/IStreamIgnoredMapping.java index f117ab6..b493006 100644 --- a/src/main/java/com/perforce/p4java/core/IStreamIgnoredMapping.java +++ b/src/main/java/com/perforce/p4java/core/IStreamIgnoredMapping.java @@ -7,29 +7,30 @@ * Define (optional) a list of file or directory names to be ignored in client * views. For example: *

- * * /tmp # ignores files named 'tmp' *

* /tmp/... # ignores dirs named 'tmp' *

* .tmp # ignores file names ending in '.tmp' *

- * * Mappings in the "Ignored" field may appear in any order. Ignored names are * inherited by child stream client views. */ - public interface IStreamIgnoredMapping extends IMapEntry { /** * Get a stream ignored entry's file path; this corresponds to the left * entry of the associated mapping. + * + * @return ignore path */ String getIgnorePath(); /** * Set a stream ignored entry's left file path; this corresponds to the left * entry of the associated mapping. + * + * @param ignorePath ignore path */ void setIgnorePath(String ignorePath); -}; +} diff --git a/src/main/java/com/perforce/p4java/core/IStreamIntegrationLog.java b/src/main/java/com/perforce/p4java/core/IStreamIntegrationLog.java index 089fec8..bc6f0c1 100644 --- a/src/main/java/com/perforce/p4java/core/IStreamIntegrationLog.java +++ b/src/main/java/com/perforce/p4java/core/IStreamIntegrationLog.java @@ -2,36 +2,44 @@ /** - * StreamIntegrationLog is typically returned from the server as part of the streamlog command. - * It carries integration/branching data for perforce Stream spec + * StreamIntegrationLog is typically returned from the server as part of the streamlog command. + * It carries integration/branching data for perforce Stream spec */ public interface IStreamIntegrationLog { /** * Returns integration method: variations on merge/branch/copy/ignore/delete. * For example "branch from". + * * @return Integration type. */ String getHow(); /** * Returns String associated with the integration. + * * @return Stream path. */ String getStream(); /** * Returns field. + * + * @return field */ String getField(); /** * Returns the starting change of the from stream spec. + * + * @return start from change */ String getStartFromChange(); /** * Returns the ending change of the to stream spec. + * + * @return end from change */ String getEndFromChange(); } diff --git a/src/main/java/com/perforce/p4java/core/IStreamIntegrationStatus.java b/src/main/java/com/perforce/p4java/core/IStreamIntegrationStatus.java index d8dcb44..e957302 100644 --- a/src/main/java/com/perforce/p4java/core/IStreamIntegrationStatus.java +++ b/src/main/java/com/perforce/p4java/core/IStreamIntegrationStatus.java @@ -21,102 +21,142 @@ public interface ICachedState { /** * Get the changelist. + * + * @return change */ int getChange(); /** * Get the parent changelist. + * + * @return parent change */ int getParentChange(); /** * Get the copy parent changelist. + * + * @return copy parent */ int getCopyParent(); /** * Get the merge parent changelist. + * + * @return merge parent */ int getMergeParent(); /** * Get the merge high value changelist. + * + * @return merge high value */ int getMergeHighVal(); /** * Get the branch hash. + * + * @return branch hash */ int getBranchHash(); /** * Get the status + * + * @return status */ int getStatus(); - }; + } /** * Get the stream's path in a stream depot. + * + * @return stream */ String getStream(); /** * Get the stream's parent. + * + * @return parent */ String getParent(); /** * Get the stream's type. + * + * @return type */ IStreamSummary.Type getType(); /** * Is firmer than parent. + * + * @return if true */ boolean isFirmerThanParent(); /** * Is change flows to parent. + * + * @return if true */ boolean isChangeFlowsToParent(); /** * Is change flows from parent. + * + * @return if true */ boolean isChangeFlowsFromParent(); /** * Is integration to parent. + * + * @return if true */ boolean isIntegToParent(); /** * Get how the integration to parent was performed. + * + * @return how */ String getIntegToParentHow(); /** * Get the to result. + * + * @return to result */ String getToResult(); /** * Is integration from parent. + * + * @return if true */ boolean isIntegFromParent(); /** * Get how the integration from parent was performed. + * + * @return how */ String getIntegFromParentHow(); /** * Get the from result. + * + * @return from result */ String getFromResult(); - + /** * Get the cached states + * + * @return list of cached states */ List getCachedStates(); } diff --git a/src/main/java/com/perforce/p4java/core/IStreamRemappedMapping.java b/src/main/java/com/perforce/p4java/core/IStreamRemappedMapping.java index c8cc318..856d591 100644 --- a/src/main/java/com/perforce/p4java/core/IStreamRemappedMapping.java +++ b/src/main/java/com/perforce/p4java/core/IStreamRemappedMapping.java @@ -7,47 +7,50 @@ * Define (optional) an individual stream view path is to be remapped in client * view. Each remapped mapping is of the form: *

- * - * + * {@code } *

- * - * where and are Perforce view paths with no leading + * where {@code and } are Perforce view paths with no leading * slashes and no leading or embedded wildcards. For example: *

- * - * ... x/... + * {@code ... x/...} *

- * y/* y/z/* + * {@code y/* y/z/*} *

- * * Line ordering in the Remapped field is significant; if more than one line * remaps the same files, the later line has precedence. Remapping is inherited * by child stream client views. */ - public interface IStreamRemappedMapping extends IMapEntry { /** * Get a stream remapped entry's left remap path; this corresponds to the * left entry of the associated mapping. + * + * @return left remapped path */ String getLeftRemapPath(); /** * Set a stream remapped entry's left remap path; this corresponds to the * left entry of the associated mapping. + * + * @param leftRemapPath left remapped path */ void setLeftRemapPath(String leftRemapPath); /** * Get a stream remapped entry's right remap path; this corresponds to the * right entry of the associated mapping. + * + * @return right remapped path */ String getRightRemapPath(); /** * Set a stream remapped entry's right remap path; this corresponds to the * right entry of the associated mapping. + * + * @param rightRemapPath right remapped path */ void setRightRemapPath(String rightRemapPath); }; diff --git a/src/main/java/com/perforce/p4java/core/IStreamSummary.java b/src/main/java/com/perforce/p4java/core/IStreamSummary.java index 038721d..574fe32 100644 --- a/src/main/java/com/perforce/p4java/core/IStreamSummary.java +++ b/src/main/java/com/perforce/p4java/core/IStreamSummary.java @@ -3,28 +3,26 @@ */ package com.perforce.p4java.core; -import java.util.Date; - import com.perforce.p4java.Log; +import java.util.Date; + /** * Defines the summary Perforce stream metadata typically returned by the * getStreamSummaryList() method, corresponding to "p4 streams" and similar. *

- * * In general, stream summary information excludes the stream paths, remapped, * ignored, and no server-side operations can be performed against them; for * full stream functionality you should use the full IStream interface. *

- * * Stream summaries are complete and not refreshable or updateable. */ public interface IStreamSummary extends IServerResource { /** * Types of streams include 'mainline', 'release', 'development', 'virtual' - * and 'task'. The default is 'development'.

- * + * and 'task'. The default is 'development'. + *

* Defines the role of a stream: A 'mainline' may not have a parent. A * 'virtual' stream is not a stream but an alternate view of its parent * stream. The 'development' and 'release' streams have controlled flow. Can @@ -34,17 +32,15 @@ public interface IStreamSummary extends IServerResource { * unloaded. */ public enum Type { - MAINLINE, - RELEASE, - DEVELOPMENT, - VIRTUAL, - TASK, - UNKNOWN; + MAINLINE, RELEASE, DEVELOPMENT, VIRTUAL, TASK, UNKNOWN; /** * Return a suitable Stream type as inferred from the passed-in * string, which is assumed to be the string form of a Stream type. * Otherwise return the UNKNOWN Stream type + * + * @param str str + * @return Type */ public static Type fromString(String str) { if (str == null) { @@ -54,8 +50,7 @@ public static Type fromString(String str) { try { return Type.valueOf(str.toUpperCase()); } catch (IllegalArgumentException iae) { - Log.error("Bad conversion attempt in Type.fromString; string: " - + str + "; message: " + iae.getMessage()); + Log.error("Bad conversion attempt in Type.fromString; string: " + str + "; message: " + iae.getMessage()); Log.exception(iae); return UNKNOWN; } @@ -65,53 +60,50 @@ public static Type fromString(String str) { public String toString() { return this.name().toLowerCase(); } - }; - - /** - * ParentView: 'inherit' or 'noinherit'. Defines whether the stream - * inherits a view from its parent. - */ - public enum ParentView { - INHERIT, - NOINHERIT; - - public static ParentView fromString(String str) { - if (str == null) { - return null; - } - - try { - return ParentView.valueOf(str.toUpperCase()); - } catch (IllegalArgumentException iae) { - Log.error("Bad conversion attempt in ParentView.fromString; string: " - + str + "; message: " + iae.getMessage()); - Log.exception(iae); - return null; - } - } - - @Override - public String toString() { - return this.name().toLowerCase(); - } - }; + } + + ; + + /** + * ParentView: 'inherit' or 'noinherit'. Defines whether the stream + * inherits a view from its parent. + */ + public enum ParentView { + INHERIT, NOINHERIT; + + public static ParentView fromString(String str) { + if (str == null) { + return null; + } + + try { + return ParentView.valueOf(str.toUpperCase()); + } catch (IllegalArgumentException iae) { + Log.error("Bad conversion attempt in ParentView.fromString; string: " + str + "; message: " + iae.getMessage()); + Log.exception(iae); + return null; + } + } + + @Override + public String toString() { + return this.name().toLowerCase(); + } + } /** * Stream options are flags to configure stream behavior. *

- * * unlocked (default) / locked: Indicates whether the stream spec is locked * against modifications. If locked, the spec may not be deleted, and only * its owner may modify it. *

- * * allsubmit (default) / ownersubmit: Indicates whether all users or only * the of the stream may submit changes to the stream path. - * + *

* toparent (default) / notoparent: Indicates whether integration from the * stream to its parent is expected to occur. *

- * * fromparent (default) / nofromparent: Indicates whether integration to the * stream from its parent is expected to occur. */ @@ -135,93 +127,119 @@ public interface IOptions { boolean isMergeAny(); void setMergeAny(boolean mergeAny); - }; + } /** * Get the stream's path in a stream depot. + * + * @return stream path */ String getStream(); /** * Get the alternate name of the stream. + * + * @return name */ String getName(); /** * Get the name of the user who created this stream. + * + * @return owner */ String getOwnerName(); /** * Get the date specification was last modified. + * + * @return date */ Date getUpdated(); /** * Get the date of the last 'integrate' using this stream. + * + * @return date */ Date getAccessed(); /** * Get the stream's description (if any). + * + * @return description */ String getDescription(); /** * Get the stream's parent. + * + * @return parent */ String getParent(); - + /** * Get the stream type + * + * @return type */ Type getType(); - /** - * Get the stream parentView - */ - ParentView getParentView(); + /** + * Get the stream parentView + * + * @return parent view + */ + ParentView getParentView(); /** * Get the stream options + * + * @return options */ IOptions getOptions(); /** * Is firmer than parent. + * + * @return if true */ boolean isFirmerThanParent(); /** * Is change flows to parent. + * + * @return if true */ boolean isChangeFlowsToParent(); /** * Is change flows from parent. + * + * @return if true */ boolean isChangeFlowsFromParent(); /** * Get the stream's base parent. + * + * @return parent base */ String getBaseParent(); - + /** * Set the stream's path. This will not change the associated stream spec on * the Perforce server unless you arrange for the update to server. - * - * @param stream - * new stream's path + * + * @param stream new stream's path */ void setStream(String stream); /** * Set the name of this stream. This will not change the associated stream * spec on the Perforce server unless you arrange for the update to server. - * - * @param name - * new stream spec name + * + * @param name new stream spec name */ void setName(String name); @@ -229,27 +247,24 @@ public interface IOptions { * Set the owner's name for this stream. This will not change the associated * stream spec on the Perforce server unless you arrange for the update to * server. - * - * @param ownerName - * new owner's name + * + * @param ownerName new owner's name */ void setOwnerName(String ownerName); /** * Set the last-updated date. This generally has no effect on the associated * Perforce server version of this spec. - * - * @param updated - * new updated date. + * + * @param updated new updated date. */ void setUpdated(Date updated); /** * Set the last-accessed date. This generally has no effect on the * associated Perforce server version of this spec. - * - * @param accessed - * new accessed date. + * + * @param accessed new accessed date. */ void setAccessed(Date accessed); @@ -257,74 +272,75 @@ public interface IOptions { * Set the stream spec description. This will not change the associated * stream spec on the Perforce server unless you arrange for the update to * server. - * - * @param description - * new description string. + * + * @param description new description string. */ void setDescription(String description); /** * Set the stream parent. This will not change the associated stream spec on * the Perforce server unless you arrange for the update to server. - * - * @param parent - * new stream parent. + * + * @param parent new stream parent. */ void setParent(String parent); /** * Set the stream type. This will not change the associated stream spec on * the Perforce server unless you arrange for the update to server. - * - * @param type - * new stream type. + * + * @param type new stream type. */ void setType(Type type); - /** - * Set the stream parentView. This will not change the associated stream spec on - * the Perforce server unless you arrange for the update to server. - * - * @param parentView new stream parentView. - */ - void setParentView(ParentView parentView); + /** + * Set the stream parentView. This will not change the associated stream spec on + * the Perforce server unless you arrange for the update to server. + * + * @param parentView new stream parentView. + */ + void setParentView(ParentView parentView); /** * Set the stream options. This will not change the associated stream spec * on the Perforce server unless you arrange for the update to server. - * - * @param options - * new stream options. + * + * @param options new stream options. */ void setOptions(IOptions options); /** * Set (true/false) the stream is firmer than parent. + * + * @param firmerThanParent if true */ void setFirmerThanParent(boolean firmerThanParent); /** * Set (true/false) the stream's change flows to parent. + * + * @param changeFlowsToParent if true */ void setChangeFlowsToParent(boolean changeFlowsToParent); /** * Set (true/false) the stream's change flows from parent. + * + * @param changeFlowsFromParent if true */ void setChangeFlowsFromParent(boolean changeFlowsFromParent); /** * Set the stream base parent. This will not change the associated stream * spec on the Perforce server unless you arrange for the update to server. - * - * @param baseParent - * new stream base parent. + * + * @param baseParent new stream base parent. */ void setBaseParent(String baseParent); - + /** * Return the "unloaded" status for this stream. - * + * * @return true iff the stream is unloaded. */ boolean isUnloaded(); diff --git a/src/main/java/com/perforce/p4java/core/IStreamViewMapping.java b/src/main/java/com/perforce/p4java/core/IStreamViewMapping.java index 4210ce9..f8c3ede 100644 --- a/src/main/java/com/perforce/p4java/core/IStreamViewMapping.java +++ b/src/main/java/com/perforce/p4java/core/IStreamViewMapping.java @@ -7,61 +7,47 @@ * Defines an individual file path in the stream view. Each view mapping is of * the form: *

- * - * [] + * {@code []} *

- * - * where is a single keyword, is a file path with no - * leading slashes, and the optional is a file path beginning with - * '//'. Both and may contain trailing wildcards, but + * where {@code } is a single keyword, {@code } is a file path with no + * leading slashes, and the optional {@code } is a file path beginning with + * '//'. Both {@code } and {@code } may contain trailing wildcards, but * no leading or embedded wildcards. Lines in the Paths field may appear in any - * order. A duplicated overrides its preceding entry. + * order. A duplicated {@code } overrides its preceding entry. *

- * * Paths are inherited by child stream views. A child stream's paths can * downgrade the inherited view, but not upgrade it. (For instance, a child * stream can downgrade a shared path to an isolated path, but it can't upgrade - * an isolated path to a shared path.) Note that is relevant only - * when is 'import' or 'import+'. + * an isolated path to a shared path.) Note that {@code } is relevant only + * when {@code } is 'import' or 'import+'. */ - public interface IStreamViewMapping extends IMapEntry { /** * Defines the possible path types. *

- * - * share: will be included in client views and in branch views. + * share: {@code } will be included in client views and in branch views. * Files in this path are accessible to workspaces, can be submitted to the * stream, and can be integrated with the parent stream. *

- * - * isolate: will be included in client views but not in branch + * isolate: {@code } will be included in client views but not in branch * views. Files in this path are accessible to workspaces, can be submitted * to the stream, but are not integratable with the parent stream. *

- * - * import: will be included in client views but not in branch + * import: {@code } will be included in client views but not in branch * views. Files in this path are mapped as in the parent stream's view (the - * default) or to (optional); they are accessible to + * default) or to {@code } (optional); they are accessible to * workspaces, but can not be submitted or integrated to the stream. *

- * - * exclude: will be excluded from client views and branch views. + * exclude: {@code } will be excluded from client views and branch views. * Files in this path are not accessible to workspaces, and can't be * submitted or integrated to the stream. - *

*/ public enum PathType { - SHARE("share"), - ISOLATE("isolate"), - IMPORT("import"), - IMPORTPLUS("import+"), - EXCLUDE("exclude"), - UNKNOWN("unknown"); - + SHARE("share"), ISOLATE("isolate"), IMPORT("import"), IMPORTPLUS("import+"), EXCLUDE("exclude"), UNKNOWN("unknown"); + private String type = null; - + private PathType(String type) { this.type = type; } @@ -71,14 +57,17 @@ public String getValue() { } @Override - public String toString() { - return this.getValue(); - } - + public String toString() { + return this.getValue(); + } + /** * Return a suitable Path type as inferred from the passed-in * string, which is assumed to be the string form of a Path type. * Otherwise return the UNKNOWN type + * + * @param str str + * @return PathType */ public static PathType fromString(String str) { if (str != null) { @@ -91,51 +80,65 @@ public static PathType fromString(String str) { } return null; } - }; + } + + ; /** * Get the stream view path type + * + * @return path type */ PathType getPathType(); /** * Set a stream view path type + * + * @param pathType path type */ void setPathType(PathType pathType); /** * Get a stream view entry's view path; this corresponds to the left entry * of the associated mapping. + * + * @return view path */ String getViewPath(); /** * Set a stream view entry's view path; this corresponds to the left entry * of the associated mapping. + * + * @param viewPath view path */ void setViewPath(String viewPath); /** * Get a stream view entry's optional depot path; this corresponds to the * right entry of the associated mapping. + * + * @return depot path */ String getDepotPath(); /** * Set a stream view entry's optional depot path; this corresponds to the * right entry of the associated mapping. + * + * @param depotPath depot path */ void setDepotPath(String depotPath); /** * Return a canonical String representation of this entry. This * is in the form [type prefix]leftpath[specstring]rightpath, e.g. - * "-//depot/dev/test/... //clientname/newpath/..."

- * + * "-//depot/dev/test/... //clientname/newpath/..." + *

* If the passed-in string is null, the left and right strings * (if they exist) will be concatenated into one long separator-less - * string.

- * + * string. + *

* If the quoteBlanks parameter is true, if either or both the left * or right entries contain spaces, the entries are quoted in full, i.e. * the mapping //depot/test/space test 01/... //depot/test/space test 02/... diff --git a/src/main/java/com/perforce/p4java/core/IStreamlog.java b/src/main/java/com/perforce/p4java/core/IStreamlog.java index 1364aa6..660c152 100644 --- a/src/main/java/com/perforce/p4java/core/IStreamlog.java +++ b/src/main/java/com/perforce/p4java/core/IStreamlog.java @@ -5,13 +5,12 @@ /** * Defines the methods and operations available on Perforce - * streamlogs returned from the server.

+ * streamlogs returned from the server. *

* Streamlogs are typically returned from the server's streamlog * methods (e.g. getStreamlog) and normally contain only * the fields returned by the Perforce "p4 streamlog" command. */ - public interface IStreamlog { /** @@ -74,6 +73,7 @@ public interface IStreamlog { /** * Return Integration history associated with changelist. + * * @return List of hash maps describing integrations. */ List getStreamIntegList(); diff --git a/src/main/java/com/perforce/p4java/core/IUser.java b/src/main/java/com/perforce/p4java/core/IUser.java index c3ae665..b358f79 100644 --- a/src/main/java/com/perforce/p4java/core/IUser.java +++ b/src/main/java/com/perforce/p4java/core/IUser.java @@ -1,5 +1,5 @@ /** - * + * */ package com.perforce.p4java.core; @@ -10,37 +10,38 @@ /** * Defines a full Perforce user object. See the main * Perforce documentation for full usage and semantics.

- * + * * IUser objects are complete and updateable only if they come from the * IServer.getUser() method (or are hand-crafted); user objects from other sources * are not complete or completable, and nor are they refreshable. Setter methods * defined below or on the superclass affect only local values unless a suitable - * update is done.

+ * update is done. */ - public interface IUser extends IUserSummary { String getPassword(); + void setPassword(String password); - + String getJobView(); + void setJobView(String jobView); - + ViewMap getReviewSubscriptions(); + void setReviewSubscriptions(ViewMap subs); - + /** * Updates this user on the Perforce server; if force is * true, force the change (requires super user / admin * privileges to work properly). This method is supplied * in addition to the normal IServerRespurce.update() method * since that method is always called with force set to false. - * + * * @throws ConnectionException if the Perforce server is unreachable or is not * connected. * @throws RequestException if the Perforce server encounters an error during * its processing of the request * @throws AccessException if the Perforce server denies access to the caller */ - void update(boolean force) - throws ConnectionException, RequestException, AccessException; + void update(boolean force) throws ConnectionException, RequestException, AccessException; } diff --git a/src/main/java/com/perforce/p4java/core/IUserGroup.java b/src/main/java/com/perforce/p4java/core/IUserGroup.java index 046d41c..83f4325 100644 --- a/src/main/java/com/perforce/p4java/core/IUserGroup.java +++ b/src/main/java/com/perforce/p4java/core/IUserGroup.java @@ -8,22 +8,22 @@ /** * Defines Perforce user group attributes and methods. See the main Perforce * documentation for a full detailed description of Perforce user groups and - * the associated methods defined below.

- * + * the associated methods defined below. + *

* The IUserGroup interface and implementation objects are somewhat unusual * in the P4Java object menagerie in that they do not have corresponding summary * objects due to the way the Perforce server handles and communicates * Perforce user groups. This may change in the future, but in general, * with caveats noted below and elsewhere, IUserGroup objects are complete, - * updateable, and refreshable, and (as explained) have no summary versions.

- * + * updateable, and refreshable, and (as explained) have no summary versions. + *

* Note that the getSubgroups() method is not guaranteed to return correct * values for IUserGroup objects returned from the getUserGroupList; you * normally have to get the group definition from getUserGroup to see the * list of that group's sub groups (this is a Perforce server limitation). * Conversely, the isSubGroup() method only works for a user group object - * returned by the list version of the get group(s) commands.

- * + * returned by the list version of the get group(s) commands. + *

* Setter methods defined below only have local effect unless an object * update is performed. */ @@ -34,7 +34,7 @@ public interface IUserGroup extends IServerResource { * or password timeout) is unset. */ int UNSET = 0; - + /** * Used to signal that a specific user group max value (eg. MaxScanRows * or password timeout) is unlimited. @@ -45,50 +45,64 @@ public interface IUserGroup extends IServerResource { * Used as a default value in MaxOpenFiles, for backwards compatibility with old servers. */ int UNDEFINED = -Integer.MAX_VALUE; - + /** * Get the group's name. + * + * @return name */ String getName(); - + /** * Set the group's name. + * + * @param name name */ void setName(String name); - + /** * Get the maximum number of results returned for queries by members * of this group. + * + * @return max results */ int getMaxResults(); - + /** * Set the maximum number of results returned for queries by members * of this group. + * + * @param maxResults max results */ void setMaxResults(int maxResults); - + /** * Get the maximum number of scan rows returned for queries by members * of this group. + * + * @return max rows */ int getMaxScanRows(); - + /** * Set the maximum number of scan rows returned for queries by members * of this group. + * + * @param maxScanRows max rows */ void setMaxScanRows(int maxScanRows); - + /** * Get the maximum lock time for queries by members of this group. - * @return max lock time - milliseconds + * + * @return max lock time - milliseconds */ int getMaxLockTime(); - + /** * Set the maximum lock time for queries by members of this group. - * @param maxLockTimeOfMilliSeconds - milliseconds + * + * @param maxLockTimeOfMilliSeconds - milliseconds */ void setMaxLockTime(int maxLockTimeOfMilliSeconds); @@ -102,85 +116,101 @@ public interface IUserGroup extends IServerResource { /** * Set maximum files that can be opened by members of this group. * - * @param maxOpenFiles + * @param maxOpenFiles max open files */ void setMaxOpenFiles(int maxOpenFiles); - + /** * Get the timeout value for commands by members of this group. - * @return seconds + * + * @return seconds */ int getTimeout(); - + /** * Set the timeout value for commands by members of this group. - * @param timeoutOfSeconds - seconds + * + * @param timeoutOfSeconds - seconds */ void setTimeout(int timeoutOfSeconds); - + /** * Get the password timeout value associated with this user group. - * - * @return max password time out - seconds - * + * + * @return max password time out - seconds * @since 2011.1 */ int getPasswordTimeout(); - + /** * Set the password timeout value associated with this user group. - * - * @param passwordTimeoutOfSeconds - seconds - * + * + * @param passwordTimeoutOfSeconds - seconds * @since 2011.1 */ void setPasswordTimeout(int passwordTimeoutOfSeconds); - + /** - * Return true if this group is a sub group of another group on this server.

- * + * Return true if this group is a sub group of another group on this server. + *

* Note that this method will always return false on an IUserGroup object * retrieved from the IServer.getUserGroup() method (this is a restriction * imposed by the Perforce server). + * + * @return if true */ boolean isSubGroup(); - + /** - * Set whether this group is a sub group of another group on this server.

+ * Set whether this group is a sub group of another group on this server. + * + * @param subGroup sub group */ void setSubGroup(boolean subGroup); - + /** * Get the list of known subgroups of this groups. Will be null or empty if * no subgroups exist or if this user group object was returned from the IServer * getUserGroupList method. + * + * @return subgroups */ List getSubgroups(); - + /** * Set the list of known subgroups of this groups. + * + * @param subgroups list of subgroups */ void setSubgroups(List subgroups); - + /** * Get a list of owner names for this group. Will be null or empty if this group has * no owners. + * + * @return owners */ List getOwners(); - + /** * Set the list of owner names for this group. + * + * @param owners list of owners */ void setOwners(List owners); - + /** * Get a list of user names for this group. Will be null or empty if this group has * no users. + * + * @return list of users */ List getUsers(); - + /** * Set the list of user names for this group. + * + * @param users users */ void setUsers(List users); } diff --git a/src/main/java/com/perforce/p4java/core/IUserSummary.java b/src/main/java/com/perforce/p4java/core/IUserSummary.java index 4a2263e..b84d063 100644 --- a/src/main/java/com/perforce/p4java/core/IUserSummary.java +++ b/src/main/java/com/perforce/p4java/core/IUserSummary.java @@ -3,123 +3,129 @@ */ package com.perforce.p4java.core; -import java.util.Date; - import com.perforce.p4java.Log; +import java.util.Date; + /** * Defines a Perforce user summary as returned from an IServer * getUsers method and similar. IUserSummary objects contain * only the summary information returned by the p4 users * command; to get the full user information from the server, * use the IUser interface returned from getUser, etc. - * + *

* Fields and methods below are basically self-explanatory * and more detailed documentation can be found in the main * p4 documentation. Note that any or all of these methods - * are allowed to return null.

- * - * IUserSummary objects are complete and neither refreshable nor updateable.

+ * are allowed to return null. + *

+ * IUserSummary objects are complete and neither refreshable nor updateable. */ - - public interface IUserSummary extends IServerResource { - /** - * Describes the type (service or standard) of this user. - * - * @since 2011.1 - */ - public enum UserType { - STANDARD, - OPERATOR, - SERVICE, - UNKNOWN; - - /** - * Return a suitable User type as inferred from the passed-in - * string, which is assumed to be the string form of a User type. - * Otherwise return the UNKNOWN type - */ - public static UserType fromString(String str) { - if (str == null) { - return null; - } - - try { - return UserType.valueOf(str.toUpperCase()); - } catch (IllegalArgumentException iae) { - Log.error("Bad conversion attempt in UserType.fromString; string: " - + str + "; message: " + iae.getMessage()); - Log.exception(iae); - return UNKNOWN; - } - } - }; - - String getLoginName(); - void setLoginName(String loginName); - - Date getUpdate(); - void setUpdate(Date update); - - Date getAccess(); - void setAccess(Date access); - - String getFullName(); - void setFullName(String fullName); - - String getEmail(); - void setEmail(String email); - - /** - * Get the UserType associated with this user. May return - * null if no type was set. - * - * @since 2011.1 - */ - UserType getType(); - - /** - * Set the UserType associated with this user. - * - * @since 2011.1 - */ - void setType(UserType type); - - /** - * Get the date the ticket associated with this summary user expires.

- * - * This field will only be non-null if a) the user summary object - * it's a part of was retrieved using the IOptionsServer.getUsers method - * with the GetUsersOptions().setExtendedOutput option set to true; - * b) the caller was a super-user or admin; and, c) the Perforce - * server was 2011.1 or above. In all other cases the value - * of this field is either null or not reliable. - * - * This is a read-only field synthesized by the Perforce server, and - * can not be meaningfully set in the client. - * - * @since 2011.1 - * @return possibly-null Date object. - */ - Date getTicketExpiration(); - - /** - * Get the date the password associated with this summary user expires.

- * - * This field will only be non-null if a) the user summary object - * it's a part of was retrieved using the IOptionsServer.getUsers method - * with the GetUsersOptions().setExtendedOutput option set to true; - * b) the caller was a super-user or admin; and, c) the Perforce - * server was 2011.1 or above. In all other cases the value - * of this field is either null or not reliable. - * - * This is a read-only field synthesized by the Perforce server, and - * can not be meaningfully set in the client. - * - * @since 2011.1 - * @return possibly-null Date object. - */ - Date getPasswordChange(); + /** + * Describes the type (service or standard) of this user. + * + * @since 2011.1 + */ + public enum UserType { + STANDARD, OPERATOR, SERVICE, UNKNOWN; + + /** + * Return a suitable User type as inferred from the passed-in + * string, which is assumed to be the string form of a User type. + * Otherwise return the UNKNOWN type + * + * @param str str + * @return UserType + */ + public static UserType fromString(String str) { + if (str == null) { + return null; + } + + try { + return UserType.valueOf(str.toUpperCase()); + } catch (IllegalArgumentException iae) { + Log.error("Bad conversion attempt in UserType.fromString; string: " + str + "; message: " + iae.getMessage()); + Log.exception(iae); + return UNKNOWN; + } + } + } + + ; + + String getLoginName(); + + void setLoginName(String loginName); + + Date getUpdate(); + + void setUpdate(Date update); + + Date getAccess(); + + void setAccess(Date access); + + String getFullName(); + + void setFullName(String fullName); + + String getEmail(); + + void setEmail(String email); + + /** + * Get the UserType associated with this user. May return + * null if no type was set. + * + * @return user type + * @since 2011.1 + */ + UserType getType(); + + /** + * Set the UserType associated with this user. + * + * @param type type + * @since 2011.1 + */ + void setType(UserType type); + + /** + * Get the date the ticket associated with this summary user expires. + *

+ * This field will only be non-null if a) the user summary object + * it's a part of was retrieved using the IOptionsServer.getUsers method + * with the GetUsersOptions().setExtendedOutput option set to true; + * b) the caller was a super-user or admin; and, c) the Perforce + * server was 2011.1 or above. In all other cases the value + * of this field is either null or not reliable. + *

+ * This is a read-only field synthesized by the Perforce server, and + * can not be meaningfully set in the client. + * + * @return possibly-null Date object. + * @since 2011.1 + */ + Date getTicketExpiration(); + + /** + * Get the date the password associated with this summary user expires. + *

+ * This field will only be non-null if a) the user summary object + * it's a part of was retrieved using the IOptionsServer.getUsers method + * with the GetUsersOptions().setExtendedOutput option set to true; + * b) the caller was a super-user or admin; and, c) the Perforce + * server was 2011.1 or above. In all other cases the value + * of this field is either null or not reliable. + *

+ * This is a read-only field synthesized by the Perforce server, and + * can not be meaningfully set in the client. + * + * @return possibly-null Date object. + * @since 2011.1 + */ + Date getPasswordChange(); } diff --git a/src/main/java/com/perforce/p4java/core/ViewMap.java b/src/main/java/com/perforce/p4java/core/ViewMap.java index 599f937..f9a88f2 100644 --- a/src/main/java/com/perforce/p4java/core/ViewMap.java +++ b/src/main/java/com/perforce/p4java/core/ViewMap.java @@ -1,5 +1,5 @@ /** - * + * */ package com.perforce.p4java.core; @@ -19,11 +19,11 @@ * normally used in Perforce clients, labels, branches, etc., to map one type * of path (a depot path, for example) to a different type of path (e.g. a * client path).

- * + * * View maps work in a manner that's described in the main Perforce documentation * for the basic client view, but in summary, map entries can be inclusive, * exclusive, or overlays, and map entry order is (of course) deeply significant.

- * + * * This implementation of view maps does not (yet) include advanced Perforce * functionality (such as translation or testing the map to see whether a * path is mapped or not), but future versions will; the emphasis here is on @@ -38,7 +38,7 @@ public enum MapDirection { } protected List entryList = null; - + /** * Default constructor. Creates a new ViewMap with an * empty (but not null) entry list. @@ -46,20 +46,20 @@ public enum MapDirection { public ViewMap() { this.entryList = new ArrayList(); } - + /** * Constructs a new ViewMap from the passed-in entry list. The passed-in * list is inspected for consistency before being used. - * + * * @param entryList non-null (but possibly-empty) entry list. */ public ViewMap(List entryList) { checkEntryList(entryList); this.entryList = entryList; } - + /** - * Return the number of elements in the associated entry list. + * @return the number of elements in the associated entry list. */ public int getSize() { return this.entryList.size(); @@ -70,7 +70,7 @@ public int getSize() { * if order is out of bounds. The order field of the deleted entry * will be set to ORDER_UNKNOWN; the order fields of any entries * "below" the deletion will be updated with their new order. - * + * * @param position order of entry to be deleted */ public synchronized void deleteEntry(int position) { @@ -84,15 +84,16 @@ public synchronized void deleteEntry(int position) { /** * Get the map entry at the specified position. Will throw a P4JavaError * if order is out of bounds. - * + * * @param position list position to use + * @return map entry */ public synchronized E getEntry(int position) { - if ((position < 0) || (position >=this.entryList.size())) { + if ((position < 0) || (position >= this.entryList.size())) { throw new P4JavaError("Position out of range: " + position + "; list size: " + this.entryList.size()); } - + E entry = this.entryList.get(position); if (entry == null) { throw new NullPointerError("Null entry in ViewMap list"); @@ -105,7 +106,7 @@ public synchronized E getEntry(int position) { /** * Get the entry list associated with this view map. - * + * * @return non-null entry list */ public List getEntryList() { @@ -115,7 +116,7 @@ public List getEntryList() { /** * Add a map new entry at the end of the view map. The value of the entry's * order field will be set to the order in the entry list. - * + * * @param entry non-null map entry. */ public synchronized void addEntry(E entry) { @@ -129,12 +130,12 @@ public synchronized void addEntry(E entry) { /** * Set (replace) a specific map position.

- * + * * Will throw a P4JavaError if order is out of bounds or if the new entry * is null. The value of the entry's order field will be set to the * order in the entry list; the value of the replaced entry's * order field will be set to ORDER_UNKNOWN. - * + * * @param position list order of replacement * @param entry non-null replacement entry */ @@ -154,21 +155,22 @@ public synchronized void setEntry(int position, E entry) { /** * Set the entry list associated with this view map. - * + * * @param entryList non-null entry list */ public void setEntryList(List entryList) { checkEntryList(entryList); this.entryList = entryList; } - + /** * Do some sanity checks on the passed-in entry list. This includes * checking for null list, null entries, and whether each entry's order * field matches its actual order in the list. Throws NullPointerError * or P4JavaError as appropriate. + * + * @param entryList list of entries */ - public synchronized void checkEntryList(List entryList) { if (entryList == null) { throw new NullPointerError( @@ -188,7 +190,7 @@ public synchronized void checkEntryList(List entryList) { } } } - + /** * Update the entry list entry positions after an update by reassigning entry-internal * positions as appropriate. @@ -218,12 +220,12 @@ public Iterator iterator() { */ public String translate(String from, MapDirection dir) { MapTable mt = new MapTable(); - for(E i : this) { + for (E i : this) { mt.insert(i.getLeft(), i.getRight(), i.getType() == IMapEntry.EntryType.EXCLUDE ? MapFlag.MfUnmap : - i.getType() == IMapEntry.EntryType.OVERLAY ? MapFlag.MfRemap : - i.getType() == IMapEntry.EntryType.DITTO ? MapFlag.MfAndmap : - MapFlag.MfMap); + i.getType() == IMapEntry.EntryType.OVERLAY ? MapFlag.MfRemap : + i.getType() == IMapEntry.EntryType.DITTO ? MapFlag.MfAndmap : + MapFlag.MfMap); } MapWrap mw = mt.translate(dir == MapDirection.MapLeftRight ? MapTableT.LHS : MapTableT.RHS, from); return mw != null ? mw.getTo() : null; diff --git a/src/main/java/com/perforce/p4java/core/file/FileDiff.java b/src/main/java/com/perforce/p4java/core/file/FileDiff.java index b09efca..ea9b623 100644 --- a/src/main/java/com/perforce/p4java/core/file/FileDiff.java +++ b/src/main/java/com/perforce/p4java/core/file/FileDiff.java @@ -3,6 +3,11 @@ */ package com.perforce.p4java.core.file; +import com.perforce.p4java.core.IFileDiff; +import com.perforce.p4java.impl.generic.core.file.FileSpec; + +import java.util.Map; + import static com.perforce.p4java.common.base.P4ResultMapUtils.parseString; import static com.perforce.p4java.impl.mapbased.rpc.func.RpcFunctionMapKey.DEPOT_FILE; import static com.perforce.p4java.impl.mapbased.rpc.func.RpcFunctionMapKey.REV; @@ -11,81 +16,77 @@ import static com.perforce.p4java.impl.mapbased.rpc.func.RpcFunctionMapKey.TYPE2; import static org.apache.commons.lang3.StringUtils.isNotBlank; -import java.util.Map; - -import com.perforce.p4java.core.IFileDiff; -import com.perforce.p4java.impl.generic.core.file.FileSpec; - /** * @author Kevin Sawicki (ksawicki@perforce.com) */ public class FileDiff implements IFileDiff { - private Status status = null; - private String file1 = null; - private String file2 = null; - private int revision1 = -1; - private int revision2 = -1; - private String type1 = null; - private String type2 = null; - - /** - * Create a new file diff with the values from the specified map - */ - public FileDiff(final Map map) { - String depotFile1 = parseString(map, DEPOT_FILE); - if (isNotBlank(depotFile1)) { - file1 = depotFile1; - revision1 = FileSpec.getRevFromString(parseString(map, REV)); - type1 = parseString(map, TYPE); - } - - String depotFile2 = parseString(map, DEPOT_FILE + "2"); - if (isNotBlank(depotFile2)) { - file2 = depotFile2; - revision2 = FileSpec.getRevFromString(parseString(map, REV + "2")); - type2 = parseString(map, TYPE2); - } - status = Status.fromString(parseString(map, STATUS)); - } - - @Override - public Status getStatus() { - return status; - } - - @Override - - public String getDepotFile1() { - return file1; - } - - @Override - - public String getDepotFile2() { - return file2; - } - - @Override - - public int getRevision1() { - return revision1; - } - - @Override - - public int getRevision2() { - return revision2; - } - - @Override - - public String getFileType1() { - return type1; - } - - @Override - public String getFileType2() { - return type2; - } + private Status status = null; + private String file1 = null; + private String file2 = null; + private int revision1 = -1; + private int revision2 = -1; + private String type1 = null; + private String type2 = null; + + /** + * Create a new file diff with the values from the specified map + * @param map map + */ + public FileDiff(final Map map) { + String depotFile1 = parseString(map, DEPOT_FILE); + if (isNotBlank(depotFile1)) { + file1 = depotFile1; + revision1 = FileSpec.getRevFromString(parseString(map, REV)); + type1 = parseString(map, TYPE); + } + + String depotFile2 = parseString(map, DEPOT_FILE + "2"); + if (isNotBlank(depotFile2)) { + file2 = depotFile2; + revision2 = FileSpec.getRevFromString(parseString(map, REV + "2")); + type2 = parseString(map, TYPE2); + } + status = Status.fromString(parseString(map, STATUS)); + } + + @Override + public Status getStatus() { + return status; + } + + @Override + + public String getDepotFile1() { + return file1; + } + + @Override + + public String getDepotFile2() { + return file2; + } + + @Override + + public int getRevision1() { + return revision1; + } + + @Override + + public int getRevision2() { + return revision2; + } + + @Override + + public String getFileType1() { + return type1; + } + + @Override + public String getFileType2() { + return type2; + } } diff --git a/src/main/java/com/perforce/p4java/core/file/FileSpecBuilder.java b/src/main/java/com/perforce/p4java/core/file/FileSpecBuilder.java index b1438f1..84c1c7c 100644 --- a/src/main/java/com/perforce/p4java/core/file/FileSpecBuilder.java +++ b/src/main/java/com/perforce/p4java/core/file/FileSpecBuilder.java @@ -45,9 +45,9 @@ public static List makeFileSpecList(@Nullable List filePaths) /** * Given an array of file paths (which might include revision or label specs, etc.), * return a corresponding list of file specs. Returns null if filePaths is null; skips - * any null element of the array.

+ * any null element of the array. *

- * NOTE: use the 'FileSpecBuilder.makeFileSpecList(List pathList)' method if + * NOTE: use the {@code 'FileSpecBuilder.makeFileSpecList(List pathList)'} method if * you have a very large amount of file paths. The method with the 'List' parameter * is more memory efficient, since an array keeps data in a contiguous chunk of memory. * @@ -66,6 +66,30 @@ public static List makeFileSpecList(String... filePaths) { return fileSpecs; } + /** + * Given a list of file paths which include special characters like #, @, % or * in the file path, + * replaces the special characters (%, @, # or *) with their numeric values and returns a corresponding + * list of file specs. + * + * @param filePaths multiple file path strings + * @return non-null list of filespecs + */ + public static List makeFileSpecListSpecialChars(String... filePaths) { + List fileSpecs = new ArrayList<>(); + if (filePaths != null) { + for (String path : filePaths) { + if (isNotBlank(path)) { + path = path.replaceAll("%", "%25"); + path = path.replaceAll("@", "%40"); + path = path.replaceAll("#", "%23"); + path = path.replaceAll("\\*", "%2A"); + fileSpecs.add(new FileSpec(path)); + } + } + } + return fileSpecs; + } + /** * Given a list of file specs, return a list of the valid file specs in that list. * "Valid" here means a) non-null, and b) getOpStatus() returns VALID. diff --git a/src/main/java/com/perforce/p4java/core/file/FileStatAncilliaryOptions.java b/src/main/java/com/perforce/p4java/core/file/FileStatAncilliaryOptions.java index 49616c3..96b953e 100644 --- a/src/main/java/com/perforce/p4java/core/file/FileStatAncilliaryOptions.java +++ b/src/main/java/com/perforce/p4java/core/file/FileStatAncilliaryOptions.java @@ -16,112 +16,126 @@ public class FileStatAncilliaryOptions { - private boolean allRevs = false; // -Of - private boolean fileSizeDigest = false; // -Ol - private boolean bothPathTypes = false; // -Op - private boolean pendingIntegrationRecs = false; // -Or - private boolean excludeLocalPath = false; // -Os - private boolean showAttributes = false; // -Oa - private boolean showHexAttributes = false; // -Oae - - public FileStatAncilliaryOptions() { - } - - public FileStatAncilliaryOptions(boolean allRevs, - boolean fileSizeDigest, boolean bothPathTypes, - boolean pendingIntegrationRecs, boolean excludeLocalPath) { - this.allRevs = allRevs; - this.fileSizeDigest = fileSizeDigest; - this.bothPathTypes = bothPathTypes; - this.pendingIntegrationRecs = pendingIntegrationRecs; - this.excludeLocalPath = excludeLocalPath; - } - - /** - * Return a list of strings, one element for each enabled option. - * - * @return non-null but possibly-empty list of strings. - */ - public List toStrings() { - List retVal = new ArrayList(); - - if (this.isAllRevs()) { - retVal.add("-Of"); - } - if (this.isFileSizeDigest()) { - retVal.add("-Ol"); - } - if (this.isBothPathTypes()) { - retVal.add("-Op"); - } - if (this.isPendingIntegrationRecs()) { - retVal.add("-Or"); - } - if (this.isExcludeLocalPath()) { - retVal.add("-Os"); - } - if (this.isShowHexAttributes()) { - retVal.add("-Oae"); - } else if (this.isShowAttributes()) { - retVal.add("-Oa"); - } - - return retVal; - } - - public boolean isAllRevs() { - return allRevs; - } - public void setAllRevs(boolean allRevs) { - this.allRevs = allRevs; - } - public boolean isFileSizeDigest() { - return fileSizeDigest; - } - public void setFileSizeDigest(boolean fileSizeDigest) { - this.fileSizeDigest = fileSizeDigest; - } - public boolean isBothPathTypes() { - return bothPathTypes; - } - public void setBothPathTypes(boolean bothPathTypes) { - this.bothPathTypes = bothPathTypes; - } - public boolean isPendingIntegrationRecs() { - return pendingIntegrationRecs; - } - public void setPendingIntegrationRecs(boolean pendingIntegrationRecs) { - this.pendingIntegrationRecs = pendingIntegrationRecs; - } - public boolean isExcludeLocalPath() { - return excludeLocalPath; - } - public void setExcludeLocalPath(boolean excludeLocalPath) { - this.excludeLocalPath = excludeLocalPath; - } - - /** - * @since 2011.1 - */ - public boolean isShowAttributes() { - return showAttributes; - } - /** - * @since 2011.1 - */ - public void setShowAttributes(boolean showAttributes) { - this.showAttributes = showAttributes; - } - /** - * @since 2011.1 - */ - public boolean isShowHexAttributes() { - return showHexAttributes; - } - /** - * @since 2011.1 - */ - public void setShowHexAttributes(boolean showHexAttributes) { - this.showHexAttributes = showHexAttributes; - } + private boolean allRevs = false; // -Of + private boolean fileSizeDigest = false; // -Ol + private boolean bothPathTypes = false; // -Op + private boolean pendingIntegrationRecs = false; // -Or + private boolean excludeLocalPath = false; // -Os + private boolean showAttributes = false; // -Oa + private boolean showHexAttributes = false; // -Oae + + public FileStatAncilliaryOptions() { + } + + public FileStatAncilliaryOptions(boolean allRevs, boolean fileSizeDigest, boolean bothPathTypes, boolean pendingIntegrationRecs, boolean excludeLocalPath) { + this.allRevs = allRevs; + this.fileSizeDigest = fileSizeDigest; + this.bothPathTypes = bothPathTypes; + this.pendingIntegrationRecs = pendingIntegrationRecs; + this.excludeLocalPath = excludeLocalPath; + } + + /** + * Return a list of strings, one element for each enabled option. + * + * @return non-null but possibly-empty list of strings. + */ + public List toStrings() { + List retVal = new ArrayList(); + + if (this.isAllRevs()) { + retVal.add("-Of"); + } + if (this.isFileSizeDigest()) { + retVal.add("-Ol"); + } + if (this.isBothPathTypes()) { + retVal.add("-Op"); + } + if (this.isPendingIntegrationRecs()) { + retVal.add("-Or"); + } + if (this.isExcludeLocalPath()) { + retVal.add("-Os"); + } + if (this.isShowHexAttributes()) { + retVal.add("-Oae"); + } else if (this.isShowAttributes()) { + retVal.add("-Oa"); + } + + return retVal; + } + + public boolean isAllRevs() { + return allRevs; + } + + public void setAllRevs(boolean allRevs) { + this.allRevs = allRevs; + } + + public boolean isFileSizeDigest() { + return fileSizeDigest; + } + + public void setFileSizeDigest(boolean fileSizeDigest) { + this.fileSizeDigest = fileSizeDigest; + } + + public boolean isBothPathTypes() { + return bothPathTypes; + } + + public void setBothPathTypes(boolean bothPathTypes) { + this.bothPathTypes = bothPathTypes; + } + + public boolean isPendingIntegrationRecs() { + return pendingIntegrationRecs; + } + + public void setPendingIntegrationRecs(boolean pendingIntegrationRecs) { + this.pendingIntegrationRecs = pendingIntegrationRecs; + } + + public boolean isExcludeLocalPath() { + return excludeLocalPath; + } + + public void setExcludeLocalPath(boolean excludeLocalPath) { + this.excludeLocalPath = excludeLocalPath; + } + + /** + * @since 2011.1 + * @return showAttributes + */ + public boolean isShowAttributes() { + return showAttributes; + } + + /** + * @param showAttributes showAttributes + * @since 2011.1 + */ + public void setShowAttributes(boolean showAttributes) { + this.showAttributes = showAttributes; + } + + /** + * @since 2011.1 + * @return showHexAttributes + */ + public boolean isShowHexAttributes() { + return showHexAttributes; + } + + /** + * @param showHexAttributes showHexAttributes + * @since 2011.1 + */ + public void setShowHexAttributes(boolean showHexAttributes) { + this.showHexAttributes = showHexAttributes; + } } diff --git a/src/main/java/com/perforce/p4java/core/file/IFileAnnotation.java b/src/main/java/com/perforce/p4java/core/file/IFileAnnotation.java index f4e9947..a2d8e81 100644 --- a/src/main/java/com/perforce/p4java/core/file/IFileAnnotation.java +++ b/src/main/java/com/perforce/p4java/core/file/IFileAnnotation.java @@ -1,5 +1,5 @@ /** - * + * */ package com.perforce.p4java.core.file; @@ -12,51 +12,50 @@ */ public interface IFileAnnotation { - + /** - * Get the lower version or change number for the associated annotation. + * @return the lower version or change number for the associated annotation. */ int getLower(); - + /** - * Get the upper version or change number for the associated annotation. + * @return the upper version or change number for the associated annotation. */ int getUpper(); - + /** - * Get the line being annotated. This will not include the associated newline + * @return the line being annotated. This will not include the associated newline * character or any line ending processing, but may include any embedded carriage - * return characters if they exist.

- * + * return characters if they exist. + *

* The returned line will never be null, but may be empty. */ String getLine(); - + /** - * Get the line being annotated, with optional line ending processing based on + * @param processLineEndings if true, and if a client is associated with this + * annotation (i.e. it was created by one of the IServer or IFileSpec + * annotation methods, and a client was associated with the server at the + * time the IServer or IFileSpec call was made), the returned string will + * attempt to honor client line end settings where possible; if there are no + * available settings, the local line ending is appended. If processLineEndings + * is not true, the results are identical to calling the no-argument getLine method. + * @return the line being annotated, with optional line ending processing based on * client settings (if available). This method is aimed mostly at P4Eclipse and other * specialized usage where file content lines need to be matched or compared * with sync'd file contents (etc.), and may not be particularly useful for general - * users: when in doubt, use the simple getLine() method instead.

- * + * users: when in doubt, use the simple getLine() method instead. + *

* The returned line will never be null, but may be empty. - * - * @param processLineEndings if true, and if a client is associated with this - * annotation (i.e. it was created by one of the IServer or IFileSpec - * annotation methods, and a client was associated with the server at the - * time the IServer or IFileSpec call was made), the returned string will - * attempt to honor client line end settings where possible; if there are no - * available settings, the local line ending is appended. If processLineEndings - * is not true, the results are identical to calling the no-argument getLine method. */ String getLine(boolean processLineEndings); - + /** - * Get the associated depot path for this annotation, if one is available. + * @return the associated depot path for this annotation, if one is available. * May be null in certain (very unusual) circumstances. */ String getDepotPath(); - + /** * Get a list of all contributing integration annotations for this annotation, * if such a list exists. In the absence of the use of the GetFileAnnotationsOptions @@ -65,19 +64,18 @@ public interface IFileAnnotation { * IFileAnnotation objects representing the contributing integrations. These * IFileAnnotation objects will have a non-negative ordering (see getOrdering()), * and null line data. - * + * * @since 2011.1 * @return possibly-null list of contributing integrations. */ List getAllIntegrations(); - + /** - * Get the ordering of this annotation in the associated allIntegrations + * @return the ordering of this annotation in the associated allIntegrations * list, if it exists. If the returned value is -1, this annotation is not * part of an integrations list (and is therefore a data annotation). - * + * * @since 2011.1 */ - int getOrdering(); } diff --git a/src/main/java/com/perforce/p4java/core/file/IFileOperationResult.java b/src/main/java/com/perforce/p4java/core/file/IFileOperationResult.java index 0449264..eed36b2 100644 --- a/src/main/java/com/perforce/p4java/core/file/IFileOperationResult.java +++ b/src/main/java/com/perforce/p4java/core/file/IFileOperationResult.java @@ -1,5 +1,5 @@ /** - * + * */ package com.perforce.p4java.core.file; @@ -8,89 +8,97 @@ /** * Defines the broadest operations available on file specs returned * from Perforce file operations.

- * + * * IFileOperationResult is the base interface for the IFileSpec family of * interfaces, and is used to signal and store the synchronous error returns * from methods that return file specs and lists of file specs. This is needed * due to the Perforce server's penchant for returning info and error messages * intertwined with "normal" file specs; this interface can be used to determine * the status of a specific returned file spec.

- * + * * In general, if an IFileOperationResult object has been returned from a server * or client (etc.) method, the getOpStatus() method will indicate whether the * associated values are "valid" (i.e. were filled-in or whatever by the underlying * server) or represent an error or informational event. In the latter cases, * the getStatusMessage() method returns the associated server message, and the * other fields in the file spec are not guaranteed to contain useful values.

- * + * * Note that although IFileOperationResult extends the IServerResource interface, current * implementations are not refreshable, updateable, or completable through that interface, * and isComplete() will currently always return true. */ public interface IFileOperationResult extends IServerResource { - + /** * Return the particular Perforce operation status associated with the * specific Perforce file spec operation. - * + * * @return non-null FileSpecOpStatus for the specific file spec return. */ FileSpecOpStatus getOpStatus(); - + /** * Return the status message associated with the operation (this may be an * error or informational message, depending on the operation). Will only be * meaningful if the associated op status returned by getOpStatus() is neither * UNKNOWN nor VALID. - * + * * @return possibly-null Perforce operation message. */ String getStatusMessage(); - + /** * Get the Perforce severity code associated with the operation result. Will only * be meaningful if the associated op status returned by getOpStatus() is neither * UNKNOWN nor VALID. - * + * * @return integer severity code. */ int getSeverityCode(); - + /** * Get the Perforce generic code associated with the operation result. Will only * be meaningful if the associated op status returned by getOpStatus() is neither * UNKNOWN nor VALID. - * + * * @return integer generic code. */ int getGenericCode(); - + /** * Get the Perforce raw code associated with the operation result. Will only * be meaningful if the associated op status returned by getOpStatus() is neither * UNKNOWN nor VALID, and the status was set as the result of a server-side issue. + * + * @return raw code */ int getRawCode(); - + /** * Get the Perforce 'unqieu' code associated with the operation result. Will only * be meaningful if the associated op status returned by getOpStatus() is neither * UNKNOWN nor VALID, and the status was set as the result of a server-side issue. + * + * @return 'unqieu' code */ int getUniqueCode(); - + /** * Get the Perforce sub system code associated with the operation result. Will only * be meaningful if the associated op status returned by getOpStatus() is neither * UNKNOWN nor VALID, and the status was set as the result of a server-side issue. + * + * @return sub system code */ int getSubSystem(); - + /** * Get the Perforce 'sub' code associated with the operation result. Will only * be meaningful if the associated op status returned by getOpStatus() is neither * UNKNOWN nor VALID, and the status was set as the result of a server-side issue. + * + * @return 'sub' code */ int getSubCode(); } diff --git a/src/main/java/com/perforce/p4java/core/file/IFileRevisionData.java b/src/main/java/com/perforce/p4java/core/file/IFileRevisionData.java index 7606e3a..6b56d91 100644 --- a/src/main/java/com/perforce/p4java/core/file/IFileRevisionData.java +++ b/src/main/java/com/perforce/p4java/core/file/IFileRevisionData.java @@ -15,47 +15,47 @@ public interface IFileRevisionData { /** - * Get the revision ID associated with this revision. + * @return the revision ID associated with this revision. */ int getRevision(); /** - * Get the changelist ID associated with this revision. + * @return the changelist ID associated with this revision. */ int getChangelistId(); /** - * Get the file action associated with this revision. + * @return the file action associated with this revision. */ FileAction getAction(); /** - * Get the date associated with this revision. + * @return the date associated with this revision. */ Date getDate(); /** - * Get the Perforce user name associated with this revision. + * @return the Perforce user name associated with this revision. */ String getUserName(); /** - * Get the Perforce file type string associated with this revision. + * @return the Perforce file type string associated with this revision. */ String getFileType(); /** - * Get the description string associated with this revision. + * @return the description string associated with this revision. */ String getDescription(); /** - * Get the depot file name associated with this revision. + * @return the depot file name associated with this revision. */ String getDepotFileName(); /** - * Get the client file name associated with this revision. + * @return the client file name associated with this revision. */ String getClientName(); diff --git a/src/main/java/com/perforce/p4java/core/file/IFileSize.java b/src/main/java/com/perforce/p4java/core/file/IFileSize.java index 043bb35..1ea6085 100644 --- a/src/main/java/com/perforce/p4java/core/file/IFileSize.java +++ b/src/main/java/com/perforce/p4java/core/file/IFileSize.java @@ -12,63 +12,75 @@ */ public interface IFileSize { - /** - * Get the depot file. - */ - String getDepotFile(); + /** + * @return the depot file. + */ + String getDepotFile(); - /** - * Set the depot file. - */ - void setDepotFile(String depotFile); + /** + * Set the depot file. + * + * @param depotFile depotFile + */ + void setDepotFile(String depotFile); - /** - * Get the file revision ID. - */ - long getRevisionId(); + /** + * @return the file revision ID. + */ + long getRevisionId(); - /** - * Set the file revision ID. - */ - void setRevisionId(long revisionId); + /** + * Set the file revision ID. + * + * @param revisionId revisionId + */ + void setRevisionId(long revisionId); - /** - * Get the file size. - */ - long getFileSize(); + /** + * @return the file size. + */ + long getFileSize(); - /** - * Set the file size. - */ - void setFileSize(long fileSize); + /** + * Set the file size. + * + * @param fileSize fileSize + */ + void setFileSize(long fileSize); - /** - * Get the path. - */ - String getPath(); + /** + * @return the path. + */ + String getPath(); - /** - * Set the path. - */ - void setPath(String path); + /** + * Set the path. + * + * @param path path + */ + void setPath(String path); - /** - * Get the file count. - */ - long getFileCount(); + /** + * @return the file count. + */ + long getFileCount(); - /** - * Set the file count. - */ - void setFileCount(long fileCount); + /** + * Set the file count. + * + * @param fileCount fileCount + */ + void setFileCount(long fileCount); - /** - * Get the shelved changelist ID. - */ - long getChangelistId(); + /** + * @return the shelved changelist ID. + */ + long getChangelistId(); - /** - * Set the shelved changelist ID. - */ - void setChangelistId(long changeListId); + /** + * Set the shelved changelist ID. + * + * @param changeListId changeListId + */ + void setChangelistId(long changeListId); } diff --git a/src/main/java/com/perforce/p4java/core/file/IFileSpec.java b/src/main/java/com/perforce/p4java/core/file/IFileSpec.java index 41af851..705444b 100644 --- a/src/main/java/com/perforce/p4java/core/file/IFileSpec.java +++ b/src/main/java/com/perforce/p4java/core/file/IFileSpec.java @@ -23,15 +23,15 @@ * Defines the basic set of information and operations on a Perforce file * under P4Java, and performs as the common currency for a lot of file-list * based methods, usually encapsulated as Java lists as both input and output - * for common server and client file-based methods such as where, sync, add, etc.

- * + * for common server and client file-based methods such as where, sync, add, etc. + *

* The various IFileSpec methods generally correspond closely to the similarly-named * fields or attributes given in the general Perforce documentation, and will not * be discussed in great detail here. Note that many of them are only set in response * to a specific server or client method call, and, in general, only the file's path needs * to be set to be usable as input to these methods. Conversely, some of the fields - * defined below are only relevant for integration actions, resolve results, etc.

- * + * defined below are only relevant for integration actions, resolve results, etc. + *

* The main complexity in this interface is the variety of file spec paths and associated * gubbins: in general, a Perforce file specification can have all four or none of * depot, client, and local paths plus an "original" path (see below) valid (or some @@ -42,341 +42,400 @@ * used as the preferred path for operations (but see below). File specs may not * even have original paths, and / or may have all four path types set, depending on * the circumstances of the file spec's creation and subsequent history. - * + *

* Additionally, the getPreferedPath() method allows a user to retrieve the "correct" - * path based on a simple set of rules if you've lost track of which path is valid.

- * + * path based on a simple set of rules if you've lost track of which path is valid. + *

* IFileSpec may be extended for other uses (see e.g. IExtendedFileSpec as used - * by the IServer.getExtendedFiles() method.

- * + * by the IServer.getExtendedFiles() method. + *

* Note that although IFileSpec (indirectly) extends the IServerResource interface, current * implementations are not refreshable, updateable, or completable, and isComplete() will - * currently always return true.

- * + * currently always return true. + *

* Note also that the field setter methods below have local effect only. */ - public interface IFileSpec extends IFileOperationResult { - + /** * Value that signals that no Perforce file revision is (currently) - * associated with a file spec.

- * + * associated with a file spec. + *

* Note that this is distinct from specifying "#none" or "#0" explicitly, * which is dealt with by the NONE_FILE_REVISION below. */ final int NO_FILE_REVISION = -1; - + /** * String representation for the NO_FILE_REVISION value. */ final String NO_REVISION_STRING = ""; - + /** * Value used to signal "none" file revision explicitly. Note that * this is distinct from leaving a FileSpec's revision unspecified * with NO_FILE_REVISION. */ final int NONE_REVISION = 0; - + /** * The string used by the Perforce server to signal no revision specified. */ final String NONE_REVISION_STRING = "none"; - + /** * The symbolic value used to signal the head revision. */ final int HEAD_REVISION = -17; - + /** * The string used by the Perforce server to signal a head revision. */ final String HEAD_REVISION_STRING = "head"; - + /** * The symbolic value used to signal the "have" revision. */ final int HAVE_REVISION = -18; - + /** * The string used by the Perforce server to signal a "have" revision. */ final String HAVE_REVISION_STRING = "have"; - + /** * Get the specific depot, client, local, or original Perforce file path * associated with this file spec. Will be null if no such path exists * for this file spec. - * + * * @param pathType if null or PathType.ORIGINAL, return the original - * path for this file spec, otherwise return the specified - * path for this file spec. + * path for this file spec, otherwise return the specified + * path for this file spec. * @return possibly-null file path */ FilePath getPath(PathType pathType); - + /** * Set a Perforce file path associated with this file spec. If path or * path.getPathType() is null, the passed-in path type is assumed * to be ORIGINAL. - * + * * @param path candidate file path; may be null. */ void setPath(FilePath path); - + /** * Convenience method for setPath(new FilePath(PathType.ORIGINAL, pathStr)); + * + * @param pathStr path */ - void setOriginalPath(String pathStr); - + /** * Convenience method for setPath(new FilePath(PathType.DEPOT, pathStr)); + * + * @param pathStr path */ void setDepotPath(String pathStr); - + /** * Convenience method for setPath(new FilePath(PathType.CLIENT, pathStr)); + * + * @param pathStr path */ void setClientPath(String pathStr); - + /** * Convenience method for setPath(new FilePath(PathType.LOCAL, pathStr)); + * + * @param pathStr path */ void setLocalPath(String pathStr); - + /** * Get an annotated string representation of a Perforce file * path associated with this Perforce file spec. "Annotated" in * this context means any known Perforce version / changelist (etc.) * information is appended in standard Perforce format to the end of the * returned string. - * + * * @param pathType if null or PathType.ORIGINAL, return the original - * path for this file spec, otherwise return the specified - * path for this file spec. + * path for this file spec, otherwise return the specified + * path for this file spec. * @return possibly-null annotated Perforce file path string representation. */ - String getAnnotatedPathString(PathType pathType); - + /** * Get the unannotated path string for this Perforce file. - * + * * @param pathType if null or PathType.ORIGINAL, return the original - * path for this file spec, otherwise return the specified - * path for this file spec. + * path for this file spec, otherwise return the specified + * path for this file spec. * @return possibly-null non-annotated Perforce file path string representation. */ String getPathString(PathType pathType); - + /** * Set a specific Perforce file path for this file spec from a passed-in * string. Any file revision / changelist (etc.) information appended to * the pathStr parameter is stripped off before the path is set. - * + * * @param pathType if null or PathType.ORIGINAL, sets the original - * path for this file spec, otherwise sets the specified - * path for this file spec. - * @param pathStr possibly-null, possibly-annotated path string + * path for this file spec, otherwise sets the specified + * path for this file spec. + * @param pathStr possibly-null, possibly-annotated path string */ void setPathFromString(PathType pathType, String pathStr); - + /** * Convenience method for getPath(ORIGINAL). + * + * @return path */ FilePath getOriginalPath(); - + /** * Convenience method for getPathString(ORIGINAL). + * + * @return path */ String getOriginalPathString(); - + /** * Convenience method for getPath(DEPOT). + * + * @return depot path */ FilePath getDepotPath(); - + /** * Convenience method for getPathString(DEPOT). + * + * @return depot path */ String getDepotPathString(); - + /** * Convenience method for getPath(CLIENT). + * + * @return client path */ FilePath getClientPath(); - + /** * Convenience method for getPathString(CLIENT). + * + * @return client path */ String getClientPathString(); - + /** * Convenience method for getPath(LOCAL). + * + * @return local path */ FilePath getLocalPath(); - + /** * Convenience method for getPathString(LOCAL). + * + * @return local path */ String getLocalPathString(); - + /** - * Get the start revision for this file spec, if any. Returns + * @return the start revision for this file spec, if any. Returns * NO_FILE_REVISION if the revision hasn't been set or is unknown. */ int getStartRevision(); - + /** * Set the start revision for this file spec. + * + * @param rev revision */ void setStartRevision(int rev); - + /** * Get the end revision for this file spec, if any. Returns * NO_FILE_REVISION if the revision hasn't been set or is unknown. + * + * @return revision */ int getEndRevision(); - + /** * Set the end revision for this file spec. + * + * @param rev revision */ void setEndRevision(int rev); - + /** * Get the ID of the changelist associated with this file spec. Returns * IChangelist.UNKNOWN if no changelist ID has been set. + * + * @return change */ int getChangelistId(); - + /** * Set the changelist ID for this file spec. + * + * @param id change */ void setChangelistId(int id); - + /** * Get the Perforce date of this file spec. Returns null if no date has been set. + * + * @return date */ Date getDate(); - + /** * Set the date for this file spec. + * + * @param date date */ void setDate(Date date); - + /** - * Returns true if the associated file has been locked. + * @return true if the associated file has been locked. */ boolean isLocked(); - + /** * Set the locked status for this file spec. + * + * @param locked locked */ void setLocked(boolean locked); - + /** * Get the diff status for this file spec. + * + * @return diff status */ String getDiffStatus(); - + /** * Set the diff status for this file spec. + * + * @param status status */ void setDiffStatus(String status); - + /** - * Get the resolve type for this file spec. + * @return the resolve type for this file spec. */ String getResolveType(); - + /** * Set the resolve type for this file spec. + * + * @param resolveType resolve type */ void setResolveType(String resolveType); /** - * Get the content resolve type for this file spec. + * @return the content resolve type for this file spec. */ String getContentResolveType(); - + /** * Set the content resolve type for this file spec. + * + * @param contentResolveType contentResolveType */ void setContentResolveType(String contentResolveType); - + /** - * Get the shelved change for this file spec. + * @return the shelved change for this file spec. */ int getShelvedChange(); - + /** * Set the shelved change for this file spec. + * + * @param shelvedChange shelvedChange */ void setShelvedChange(int shelvedChange); /** - * Returns the file action associated with this file, if any. Returns + * @return the file action associated with this file, if any. Returns * null if no such action has been set. */ FileAction getAction(); - + /** * Set the file action for this file spec. + * + * @param action action */ void setAction(FileAction action); - + /** - * Get the label string associated with this file spec, if any. Returns + * @return the label string associated with this file spec, if any. Returns * null if no such label string has been set. */ String getLabel(); - + /** * Set the label associated with this file spec. + * + * @param label label */ void setLabel(String label); - + /** - * Returns the file type string for this file spec, or null if not known. + * @return the file type string for this file spec, or null if not known. */ String getFileType(); - + /** * Set the file type for this file spec. + * + * @param type type */ void setFileType(String type); - + /** - * Return the Perforce user name of the file's owner, or null if this + * @return the Perforce user name of the file's owner, or null if this * is not set or known. */ String getUserName(); - + /** * Set the Perforce user name for this file spec. + * + * @param userName userName */ void setUserName(String userName); - + /** - * Return the name of the client associated with this file spec, or null + * @return the name of the client associated with this file spec, or null * if not set or known. */ String getClientName(); - + /** * Set the Perforce client name for this file spec. + * + * @param clientName clientName */ void setClientName(String clientName); - + /** - * Return if this file spec is not mapped. + * @return if this file spec is not mapped. */ boolean isUnmap(); - + /** * Set the unmap status value for this file spec. + * + * @param unmap unmap */ void setUnmap(boolean unmap); @@ -384,352 +443,360 @@ public interface IFileSpec extends IFileOperationResult { * Get the "preferred" path for this file spec. A file spec's preferred * path is defined to be the path specified (in order) the original path, * the depot path, the client path, or the local path.

- * + * * @return possibly-null preferred path */ - FilePath getPreferredPath(); - + /** * Get the annotated "preferred" path string for this file spec. A file spec's preferred * path is defined to be the path specified by (in order) the original path, * the depot path, the client path, or the local path. This method * appends any relevant revision / changelist (etc.) information to the * path string if it exists.

- * + * * @return possibly-null annotated preferred path string. */ - String getAnnotatedPreferredPathString(); - + /** * Get the (unannotated) "preferred" path string for this file spec. A file spec's preferred * path is defined to be the path specified by (in order) the original path, * the depot path, the client path, or the local path. - * + * * @return possibly-null annotated preferred path string. */ String getPreferredPathString(); - + /** * Useful alias for getPreferredPathString(). */ String toString(); - + // IFileSpec methods: - + /** - * Get the file this file spec was integrated from if any. Returns null + * @return the file this file spec was integrated from if any. Returns null * if no such file. */ String getFromFile(); - + /** * Set the from file for this file spec. + * + * @param pathStr pathStr */ void setFromFile(String pathStr); - + /** - * Return the end "from" revision of the last integration, if any. + * @return the end "from" revision of the last integration, if any. */ int getEndFromRev(); - + /** * Set the end from revision for this file spec. + * + * @param rev rev */ void setEndFromRev(int rev); - + /** - * Return the start "from" revision of the last integration, if any. + * @return the start "from" revision of the last integration, if any. */ int getStartFromRev(); - + /** * Set the end from revision for this file spec. + * + * @param rev rev */ void setStartFromRev(int rev); - + /** - * Get the "to" file for the integration, if it exists. Returns null + * @return the "to" file for the integration, if it exists. Returns null * otherwise. */ String getToFile(); - + /** * Set the to file for this file spec. + * + * @param pathStr pathStr */ void setToFile(String pathStr); - + /** - * Return the start "to" revision of the last integration, if any. + * @return the start "to" revision of the last integration, if any. */ int getStartToRev(); - + /** * Set the start to revision for this file spec. + * + * @param rev rev */ void setStartToRev(int rev); - + /** - * Return the end "from" revision of the last integration, if any. + * @return the end "from" revision of the last integration, if any. */ int getEndToRev(); - + /** * Set the end to revision for this file spec. + * + * @param rev rev */ void setEndToRev(int rev); - + /** - * Return a string representation of how the last resolve happened. + * @return a string representation of how the last resolve happened. * Returns null if unknown or not relevant. */ String getHowResolved(); - + /** * Set the "how resolved" string for this file spec. + * + * @param howStr howStr */ void setHowResolved(String howStr); - + /** - * Get the work revision. + * @return the work revision. */ int getWorkRev(); - + /** * Set the work revision for this file spec. + * + * @param rev rev */ void setWorkRev(int rev); - + /** - * Get the other action. Returns null if no such action. + * @return the other action. Returns null if no such action. */ FileAction getOtherAction(); - + /** * Set the other action for this file spec. + * + * @param action action */ void setOtherAction(FileAction action); - + /** - * Get the base revision as reported by integ -o or equivalent. This + * @return the base revision as reported by integ -o or equivalent. This * may be NO_FILE_REVISION if no base revision exists. */ int getBaseRev(); - + /** * Set the base revision on this object. Makes no sense for * general users to call this. + * + * @param rev rev */ void setBaseRev(int rev); - + /** - * Get the base name as reported by integ -o or equivalent. This + * @return the base name as reported by integ -o or equivalent. This * may be null if no base name exists. */ String getBaseName(); - + /** * Set the base name on this object. Makes no sense for * general users to call this. + * + * @param basename basename */ void setBaseName(String basename); /** - * Get the base file as reported by resolve -o or equivalent. This + * @return the base file as reported by resolve -o or equivalent. This * may be null if no base file exists. */ String getBaseFile(); - + /** * Set the base file on this object. Makes no sense for * general users to call this. + * + * @param basefile basefile */ void setBaseFile(String basefile); /** - * Get the revision history of this Perforce file.

- * + * Get the revision history of this Perforce file. + *

* Note that the revision history returned may contain more than one file * if the includeInherited option is true; this is why the return is a map - * (keyed on depot file path) of revision lists rather than a simple list.

- * + * (keyed on depot file path) of revision lists rather than a simple list. + *

* Behavior is undefined if both longOutput and truncatedLongOutput are true. If both * are false, a short form of the description (prepared by the server) is returned. - * - * @param maxRevs if positive, return at most maxRev revisions for this file. - * @param includeInherited if true, causes inherited file history to be returned as well. - * @param longOutput if true, return the full descriptions associated with each revision + * + * @param maxRevs if positive, return at most maxRev revisions for this file. + * @param contentHistory if true, return the content history + * @param includeInherited if true, causes inherited file history to be returned as well. + * @param longOutput if true, return the full descriptions associated with each revision * @param truncatedLongOutput if true, return only the first 250 characters of each description. * @return a non-null map of lists of the revision data for the file. * @throws ConnectionException if the Perforce server is unreachable or is not - * connected. - * @throws RequestException if the Perforce server encounters an error during - * its processing of the request - * @throws AccessException if the Perforce server denies access to the caller - */ - - Map> getRevisionHistory(int maxRevs, - boolean contentHistory, boolean includeInherited, boolean longOutput, - boolean truncatedLongOutput) - throws ConnectionException, RequestException, AccessException; - - /** - * Get the revision history of this Perforce file.

- * + * connected. + * @throws RequestException if the Perforce server encounters an error during + * its processing of the request + * @throws AccessException if the Perforce server denies access to the caller + */ + Map> getRevisionHistory(int maxRevs, boolean contentHistory, boolean includeInherited, boolean longOutput, boolean truncatedLongOutput) throws ConnectionException, RequestException, AccessException; + + /** + * Get the revision history of this Perforce file. + *

* Note that the revision history returned may contain more than one file * if the includeInherited option is true; this is why the return is a map - * (keyed on depot file path) of revision lists rather than a simple list.

- * - * Behavior is undefined if both longOutput and truncatedLongOutput are true in the + * (keyed on depot file path) of revision lists rather than a simple list. + *

+ * Behavior is undefined if both longOutput and truncatedLongOutput are true in the * passed-in GetRevisionHistory object. If both are false, a short form of the description * (prepared by the server) is returned. - * + * * @param opts GetChangelistDiffs object describing optional parameters; if null, no - * options are set. + * options are set. * @return a non-null map of lists of the revision data for the file. * @throws P4JavaException if any error occurs in the processing of this method. */ - - Map> getRevisionHistory(GetRevisionHistoryOptions opts) - throws P4JavaException; - + Map> getRevisionHistory(GetRevisionHistoryOptions opts) throws P4JavaException; + /** * Get the file annotations associated with this file. - * - * @param wsOptions DiffType describing the white space option to be used; if null, - * use default (no options), otherwise must be one of the whitespace - * options defined by the isWsOption method on DiffType. - * @param allResults if true, include both deleted files and lines no longer present - * at the head revision + * + * @param wsOptions DiffType describing the white space option to be used; if null, + * use default (no options), otherwise must be one of the whitespace + * options defined by the isWsOption method on DiffType. + * @param allResults if true, include both deleted files and lines no longer present + * at the head revision * @param useChangeNumbers if true, annotate with change numbers rather than - * revision numbers with each line - * @param followBranches if true, follow branches. + * revision numbers with each line + * @param followBranches if true, follow branches. * @return non-null (but possibly-empty) list of IFileAnnotation objects representing - * this file's version annotations. + * this file's version annotations. * @throws ConnectionException if the Perforce server is unreachable or is not - * connected. - * @throws RequestException if the Perforce server encounters an error during - * its processing of the request - * @throws AccessException if the Perforce server denies access to the caller + * connected. + * @throws RequestException if the Perforce server encounters an error during + * its processing of the request + * @throws AccessException if the Perforce server denies access to the caller */ - List getAnnotations(DiffType wsOptions, boolean allResults, - boolean useChangeNumbers, boolean followBranches) - throws ConnectionException, RequestException, AccessException; - + List getAnnotations(DiffType wsOptions, boolean allResults, boolean useChangeNumbers, boolean followBranches) throws ConnectionException, RequestException, AccessException; + /** * Get the file annotations associated with this file. - * + * * @param opts GetFileAnnotations object describing optional parameters; if null, no - * options are set. + * options are set. * @return non-null (but possibly-empty) list of IFileAnnotation objects representing - * this file's version annotations. + * this file's version annotations. * @throws P4JavaException if any error occurs in the processing of this method. */ List getAnnotations(GetFileAnnotationsOptions opts) throws P4JavaException; - + /** * Get the contents of this specific Perforce file revision from the Perforce * depot as an InputStream. Note that the contents are retrieved from the * depot, not from the (possibly-changed) local Perforce client workspace copy). * This method is basically a convenience wrapper for the IServer.getFileContents() - * method.

- * + * method. + *

* You should close the InputStream after use in order to release any underlying * stream-related resources. Failure to do this may lead to the proliferation of * temp files or long-term memory wastage or even leaks. - * + * * @param noHeaderLine if true, suppresses the initial line that displays the file name - * and revision + * and revision * @return a non-null but possibly-empty InputStream onto the file's contents. * @throws ConnectionException if the Perforce server is unreachable or is not - * connected. - * @throws RequestException if the Perforce server encounters an error during - * its processing of the request - * @throws AccessException if the Perforce server denies access to the caller + * connected. + * @throws RequestException if the Perforce server encounters an error during + * its processing of the request + * @throws AccessException if the Perforce server denies access to the caller */ - - public InputStream getContents(boolean noHeaderLine) - throws ConnectionException, RequestException, AccessException; - + public InputStream getContents(boolean noHeaderLine) throws ConnectionException, RequestException, AccessException; + /** * Get the contents of this specific Perforce file revision from the Perforce * depot as an InputStream. Note that the contents are retrieved from the * depot, not from the (possibly-changed) local Perforce client workspace copy). * This method is basically a convenience wrapper for the IOptionsServer.getFileContents() - * method.

- * + * method. + *

* You should close the InputStream after use in order to release any underlying * stream-related resources. Failure to do this may lead to the proliferation of * temp files or long-term memory wastage or even leaks. - * + * * @param opts GetFileContents object describing optional parameters; if null, no - * options are set. + * options are set. * @return a non-null but possibly-empty InputStream onto the file's contents. * @throws P4JavaException if any error occurs in the processing of this method. */ - public InputStream getContents(GetFileContentsOptions opts) throws P4JavaException; - + /** - * Move this file if it's already opened for edit or add (the fromFile) to the destination - * file (the toFile). A file can be moved many times before it is submitted; + * Move this file if it's already opened for edit or add (the fromFile) to the destination + * file (the toFile). A file can be moved many times before it is submitted; * moving it back to its original location will reopen it for edit. The full * semantics of this operation (which can be confusing) are found in the - * main 'p4 help' documentation.

- * + * main 'p4 help' documentation. + *

* Note that the status of this file once the move has been performed may be * indeterminate; you should discard this file and use the file returned, - * if any, or at least test this file's status.

- * + * if any, or at least test this file's status. + *

* Note that this operation is not supported on servers earlier than 2009.1; * any attempt to use this on earlier servers will result in a RequestException * with a suitable message. Similarly, not all underlying IServer implementations * will work with this either, and will also result in a suitable RequestException. - * + * * @param changelistId if not IChangelist.UNKNOWN, the files are opened in the numbered - * pending changelist instead of the 'default' changelist. - * @param listOnly if true, don't actually perform the move, just return what would - * happen if the move was performed + * pending changelist instead of the 'default' changelist. + * @param listOnly if true, don't actually perform the move, just return what would + * happen if the move was performed * @param noClientMove if true, bypasses the client file rename. See main IServer - * moveFiles comments for restrictions. - * @param fileType if not null, the file is reopened as that filetype. - * @param toFile the target file. + * moveFiles comments for restrictions. + * @param fileType if not null, the file is reopened as that filetype. + * @param toFile the target file. * @return list of IFileSpec objects representing the results of this move * @throws ConnectionException if the Perforce server is unreachable or is not - * connected. - * @throws RequestException if the Perforce server encounters an error during - * its processing of the request - * @throws AccessException if the Perforce server denies access to the caller - */ - - List move(int changelistId, boolean listOnly, boolean noClientMove, - String fileType, IFileSpec toFile) - throws ConnectionException, RequestException, AccessException; - - /** - * Move this file if it's already opened for edit or add (the fromFile) to the destination - * file (the toFile). A file can be moved many times before it is submitted; + * connected. + * @throws RequestException if the Perforce server encounters an error during + * its processing of the request + * @throws AccessException if the Perforce server denies access to the caller + */ + List move(int changelistId, boolean listOnly, boolean noClientMove, String fileType, IFileSpec toFile) throws ConnectionException, RequestException, AccessException; + + /** + * Move this file if it's already opened for edit or add (the fromFile) to the destination + * file (the toFile). A file can be moved many times before it is submitted; * moving it back to its original location will reopen it for edit. The full * semantics of this operation (which can be confusing) are found in the - * main 'p4 help' documentation.

- * + * main 'p4 help' documentation. + *

* Note that the status of this file once the move has been performed may be * indeterminate; you should discard this file and use the file returned, - * if any, or at least test this file's status.

- * + * if any, or at least test this file's status. + *

* Note that this operation is not supported on servers earlier than 2009.1; * any attempt to use this on earlier servers will result in a RequestException * with a suitable message. Similarly, not all underlying IServer implementations * will work with this either, and will also result in a suitable RequestException. - * + * * @param toFile the target file. - * @param opts GetFileContents object describing optional parameters; if null, no - * options are set. + * @param opts GetFileContents object describing optional parameters; if null, no + * options are set. * @return list of IFileSpec objects representing the results of this move. * @throws P4JavaException if any error occurs in the processing of this method. */ - List move(IFileSpec toFile, MoveFileOptions opts) throws P4JavaException; String getRepoName(); diff --git a/src/main/java/com/perforce/p4java/core/file/IObliterateResult.java b/src/main/java/com/perforce/p4java/core/file/IObliterateResult.java index 1ee7a28..59c1730 100644 --- a/src/main/java/com/perforce/p4java/core/file/IObliterateResult.java +++ b/src/main/java/com/perforce/p4java/core/file/IObliterateResult.java @@ -14,42 +14,42 @@ public interface IObliterateResult { /** - * Get the list of filespecs purged + * @return the list of filespecs purged */ List getFileSpecs(); /** - * Get the number of integration records added + * @return the number of integration records added */ int getIntegrationRecAdded(); /** - * Get the number of integration records deleted + * @return the number of integration records deleted */ int getLabelRecDeleted(); /** - * Get the number of client records deleted + * @return the number of client records deleted */ int getClientRecDeleted(); /** - * Get the number of integration records deleted + * @return the number of integration records deleted */ int getIntegrationRecDeleted(); /** - * Get the number of working records deleted + * @return the number of working records deleted */ int getWorkingRecDeleted(); /** - * Get the number of revision records deleted + * @return the number of revision records deleted */ int getRevisionRecDeleted(); /** - * Is report only + * @return true, if report only */ boolean isReportOnly(); } diff --git a/src/main/java/com/perforce/p4java/core/file/IRevisionIntegrationData.java b/src/main/java/com/perforce/p4java/core/file/IRevisionIntegrationData.java index 882f862..256e487 100644 --- a/src/main/java/com/perforce/p4java/core/file/IRevisionIntegrationData.java +++ b/src/main/java/com/perforce/p4java/core/file/IRevisionIntegrationData.java @@ -7,28 +7,28 @@ * Used to specify Perforce file integration data in short form * for specific file revisions. Unbranched / unmerged / unintegrated * (etc.) files do not commonly have any such data; others may - * contain it, but this is not guaranteed. + * contain it, but this is not guaranteed. */ public interface IRevisionIntegrationData { - + /** - * Get the file this integration was from. + * @return the file this integration was from. */ String getFromFile(); - + /** - * Get the end revision used in the integration. + * @return the end revision used in the integration. */ int getEndFromRev(); - + /** - * Get the start revision used in the integration. + * @return the start revision used in the integration. */ int getStartFromRev(); - + /** - * Get a string description of what happened in the integration. + * @return a string description of what happened in the integration. */ String getHowFrom(); } diff --git a/src/main/java/com/perforce/p4java/env/ClientTunableSettings.java b/src/main/java/com/perforce/p4java/env/ClientTunableSettings.java index 489f4cd..0bf6a4d 100644 --- a/src/main/java/com/perforce/p4java/env/ClientTunableSettings.java +++ b/src/main/java/com/perforce/p4java/env/ClientTunableSettings.java @@ -19,6 +19,7 @@ private ClientTunableSettings() { /* util */ } * Set to 0 to prevent writing utf8 files BOM * Set to 1 to write utf8 files with a BOM - default * Set to 2 to write utf8 BOM only on Windows + * @return true, if UTF8 BOM needed */ //TODO: sshou should implement read it from 'p4envrio' with server:port prefix as well public static boolean needWriteUtf8Bom() { diff --git a/src/main/java/com/perforce/p4java/env/PerforceEnvironment.java b/src/main/java/com/perforce/p4java/env/PerforceEnvironment.java index 5da8120..e232efc 100644 --- a/src/main/java/com/perforce/p4java/env/PerforceEnvironment.java +++ b/src/main/java/com/perforce/p4java/env/PerforceEnvironment.java @@ -13,7 +13,7 @@ public class PerforceEnvironment { public static final String P4USER = "P4USER"; public static final String P4PASSWD = "P4PASSWD"; public static final String P4CLIENT = "P4CLIENT"; - + public static final String P4HOST = "P4HOST"; public static final String P4CHARSET = "P4CHARSET"; public static final String P4TICKETS = "P4TICKETS"; @@ -25,7 +25,7 @@ public class PerforceEnvironment { // Default P4ENVIRO file path public static final String DEFAULT_P4ENVIRO_FILE = System.getProperty("user.home") + "/.p4enviro"; - + public static String getP4Port() { return System.getenv(P4PORT); } @@ -68,6 +68,8 @@ public static String getP4Config() { /** * If not set and return the default P4ENVIRO file path. + * + * @return P4ENVIRO */ public static String getP4Enviro() { if (System.getenv(P4ENVIRO) != null) { diff --git a/src/main/java/com/perforce/p4java/exception/ClientError.java b/src/main/java/com/perforce/p4java/exception/ClientError.java index 5a29fdc..08cf3cd 100644 --- a/src/main/java/com/perforce/p4java/exception/ClientError.java +++ b/src/main/java/com/perforce/p4java/exception/ClientError.java @@ -21,7 +21,7 @@ public ClientError() { /** * Create a P4Java client error * - * @param message + * @param message message */ public ClientError(String message) { super(message); @@ -30,7 +30,7 @@ public ClientError(String message) { /** * Create a P4Java client error * - * @param cause + * @param cause cause */ public ClientError(Throwable cause) { super(cause); @@ -39,8 +39,8 @@ public ClientError(Throwable cause) { /** * Create a P4Java client error * - * @param message - * @param cause + * @param message message + * @param cause cause */ public ClientError(String message, Throwable cause) { super(message, cause); diff --git a/src/main/java/com/perforce/p4java/exception/RequestException.java b/src/main/java/com/perforce/p4java/exception/RequestException.java index 0ef067c..7bccaf5 100644 --- a/src/main/java/com/perforce/p4java/exception/RequestException.java +++ b/src/main/java/com/perforce/p4java/exception/RequestException.java @@ -1,5 +1,5 @@ /** - * + * */ package com.perforce.p4java.exception; @@ -12,7 +12,7 @@ * a semantics error in the request. Note that this is not the same as a * connection exception, which is typically signaled when the Perforce server * itself can't be reached.

- * + * * RequestExceptions coming back from the server have a non-zero rawCode field * that is set to the corresponding raw code value sent from the server; this * code normally requires processing for use by callers, who typically want to @@ -24,18 +24,18 @@ * set to meaningful values here (in fact, all RequestExceptions constructed 'under * the covers' in the RPC layer will do what they can to get meaningful value for * these other fields, but this is not guaranteed)...

- * + * * Note that if you set the raw code yourself using the accessor methods, you are * required to also set the other fields to appropriate values yourself; failure * to do this will cause a lot of confusion up the chain, as the subsidiary codes are * only calculated once. The setCodes method is provided to make this easy.

- * + * * See the MessageSeverityCode and MessageGenericCode definitions for suitable help * with those types of code. */ public class RequestException extends P4JavaException { - + private static final long serialVersionUID = 1L; private int rawCode = 0; private int severityCode = 0; @@ -59,12 +59,12 @@ public RequestException(String message) { public RequestException(Throwable cause) { super(cause); } - + public RequestException(String message, int rawCode) { super(message); setCodes(rawCode); } - + public RequestException(String message, String codeString) { super(message); if (codeString != null) { @@ -75,31 +75,31 @@ public RequestException(String message, String codeString) { } } } - + public RequestException(String message, int genericCode, int severityCode) { super(message); this.genericCode = genericCode; this.severityCode = severityCode; } - + public RequestException(Throwable cause, int genericCode, int severityCode) { super(cause); this.genericCode = genericCode; this.severityCode = severityCode; } - + public RequestException(String message, Throwable cause, int genericCode, int severityCode) { super(message, cause); this.genericCode = genericCode; this.severityCode = severityCode; } - + /** * Set the raw code and associated subsidiary codes according to * the passed-in values. If you only have the raw code from the server, * this is probably the easiest and least error-prone way to set the * request exception codes. - * + * * @param rawCode raw code from the server. * @return 'this' for chaining. */ @@ -121,12 +121,9 @@ public void setSeverityCode(int severityCode) { public void setGenericCode(int genericCode) { this.genericCode = genericCode; } - + public String getDisplayString() { - return "" + (this.genericCode != 0 ? "Generic: " + this.genericCode : "") - + (this.severityCode != 0 ? " Severity: " + this.severityCode + "; " : "") - + this.getMessage() - + (this.getCause() != null ? this.getCause() : ""); + return "" + (this.genericCode != 0 ? "Generic: " + this.genericCode : "") + (this.severityCode != 0 ? " Severity: " + this.severityCode + "; " : "") + this.getMessage() + (this.getCause() != null ? this.getCause() : ""); } public int getUniqueCode() { @@ -160,6 +157,7 @@ public void setSubSystem(int subSystem) { /** * Get the Perforce severity code associated with this exception, if any. * See the MessageSeverityCode Javadocs for an explanation of these codes. + * @return code */ public int getSeverityCode() { return this.severityCode; @@ -168,6 +166,7 @@ public int getSeverityCode() { /** * Get the Perforce generic code associated with this exception, if any. * See the MessageSGenericCode Javadocs for an explanation of these codes. + * @return code */ public int getGenericCode() { return this.genericCode; diff --git a/src/main/java/com/perforce/p4java/impl/generic/admin/DbSchema.java b/src/main/java/com/perforce/p4java/impl/generic/admin/DbSchema.java index 732046a..c0a989f 100644 --- a/src/main/java/com/perforce/p4java/impl/generic/admin/DbSchema.java +++ b/src/main/java/com/perforce/p4java/impl/generic/admin/DbSchema.java @@ -1,21 +1,21 @@ /** - * + * */ package com.perforce.p4java.impl.generic.admin; +import com.perforce.p4java.Log; +import com.perforce.p4java.admin.IDbSchema; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import com.perforce.p4java.Log; -import com.perforce.p4java.admin.IDbSchema; - /** * Simple default implementation class for the IDbSchema interface. */ public class DbSchema implements IDbSchema { - + private String name = null; private int version = NOVERSION; private List> columnMetadata = null; @@ -28,20 +28,25 @@ public DbSchema() { /** * Construct a DbSchema using explicit field values. + * + * @param name name + * @param version version + * @param columnMetadata columnMetadata */ - public DbSchema(String name, int version, - List> columnMetadata) { + public DbSchema(String name, int version, List> columnMetadata) { this.name = name; this.version = version; this.columnMetadata = columnMetadata; } - + /** - * Construct a DbSchema from a map returned by the Perforce server.

- * + * Construct a DbSchema from a map returned by the Perforce server. + *

* Don't use this unless you know the correct format of the maps and you either * got the map directly from the server or you cobbled together something * suitable yourself. No real error- or sanity-checking is done here. + * + * @param map map data */ public DbSchema(Map map) { if (map != null) { @@ -49,7 +54,7 @@ public DbSchema(Map map) { this.name = (String) map.get("table"); this.version = new Integer((String) map.get("version")); this.columnMetadata = new ArrayList>(); - + String columnName = null; for (int i = 0; (columnName = (String) map.get("name" + i)) != null; i++) { Map colMap = new HashMap(); diff --git a/src/main/java/com/perforce/p4java/impl/generic/admin/ProtectionEntry.java b/src/main/java/com/perforce/p4java/impl/generic/admin/ProtectionEntry.java index 142a93e..040ff2c 100644 --- a/src/main/java/com/perforce/p4java/impl/generic/admin/ProtectionEntry.java +++ b/src/main/java/com/perforce/p4java/impl/generic/admin/ProtectionEntry.java @@ -22,17 +22,14 @@ /** * Default IProtectionEntry implementation class. *

- * * Note that the order of this protection entry in the protections table is part * of the protection entry key when pass to the server for updating the * protections table. *

- * * When exclusionary mappings are used, order is relevant: the exclusionary * mapping overrides any matching protections listed above it in the table. No * matter what access level is being denied in the exclusionary protection, all * the access levels for the matching users, files, and IP addresses are denied. - *

* *

  * Protections0: super user p4java * //depot/...
@@ -45,235 +42,238 @@
 
 public class ProtectionEntry extends MapEntry implements IProtectionEntry {
 
-  /**
-   * The protection mode for this entry. The permission level or right being
-   * granted or denied. Each permission level includes all the permissions
-   * above it, except for 'review'. Each permission only includes the specific
-   * right and no lesser rights. This approach enables you to deny individual
-   * rights without having to re-grant lesser rights. Modes prefixed by '='
-   * are rights. All other modes are permission levels.
-   */
-  private String mode = null;
-
-  /**
-   * If true, this protection entry applies to a group.
-   */
-  private boolean group = false;
-
-  /**
-   * The IP address of a client host; can include wildcards.
-   */
-  private String host = null;
-
-  /**
-   * A Perforce group or user name; can include wildcards.
-   */
-  private String name = null;
-
-  /**
-   * Default constructor -- sets all fields to null, zero, or false.
-   */
-  public ProtectionEntry() {
-    super();
-  }
-
-  /**
-   * Explicit-value constructor.
-   */
-  public ProtectionEntry(final int order,
-                         final String mode,
-                         final boolean group,
-                         final String host,
-                         final String name,
-                         final String path,
-                         final boolean pathExcluded) {
-
-    super(order, null);
-
-    this.mode = mode;
-    this.group = group;
-    this.host = host;
-    this.name = name;
-    if (isNotBlank(path)) {
-      String[] entries = parseViewMappingString(quoteWhitespaceString(path));
-      type = EntryType.fromString(entries[0]);
-      left = stripTypePrefix(entries[0]);
-      right = entries[1];
-    }
-    left = quoteWhitespaceString(left);
-
-    if (pathExcluded) {
-      type = EntryType.EXCLUDE;
-    }
-  }
-
-  /**
-   * Constructs a ProtectionEntry from the passed-in map; this map
-   * must have come from a Perforce IServer method call or it may fail.
-   * If map is null, equivalent to calling the default constructor.
-   */
-
-  public ProtectionEntry(final Map map,
-                         final int order) {
-    super(order, null);
-
-    if (nonNull(map)) {
-      host = parseString(map, HOST);
-      String pathStr = parseString(map, DEPOT_FILE);
-      if (isNotBlank(pathStr)) {
-        String[] entries = parseViewMappingString(quoteWhitespaceString(pathStr));
-        type = EntryType.fromString(entries[0]);
-        left = stripTypePrefix(entries[0]);
-        right = entries[1];
-      }
-      left = quoteWhitespaceString(left);
-      mode = parseString(map, PERM);
-      name = parseString(map, USER);
-
-      group = map.containsKey(IS_GROUP);
-      if (map.containsKey(UNMAP)) {
-        type = EntryType.EXCLUDE;
-      }
-    }
-  }
-
-  @Override
-  public String getHost() {
-    return host;
-  }
-
-  @Override
-
-  public String getMode() {
-    return mode;
-  }
-
-  @Override
-
-  public String getName() {
-    return name;
-  }
-
-  @Override
-
-  public String getPath() {
-    if (isPathExcluded()) {
-      return addExclude(left);
-    } else if (type == EntryType.OVERLAY) {
-      return addOverlay(left);
-    } else {
-      return left;
-    }
-  }
-
-  @Override
-
-  public boolean isGroup() {
-    return this.group;
-  }
-
-  @Override
-
-  public void setGroup(boolean group) {
-    this.group = group;
-  }
-
-  @Override
-
-  public void setHost(String host) {
-    this.host = host;
-  }
-
-  @Override
-
-  public void setMode(String mode) {
-    this.mode = mode;
-  }
-
-  @Override
-
-  public void setName(String name) {
-    this.name = name;
-  }
-
-  @Override
-
-  public void setPath(String path) {
-    left = quoteWhitespaceString(path);
-  }
-
-  @Override
-
-  public boolean isPathExcluded() {
-    return type == EntryType.EXCLUDE;
-  }
-
-  @Override
-
-  public void setPathExcluded(boolean pathExcluded) {
-    if (pathExcluded) {
-      type = EntryType.EXCLUDE;
-    }
-  }
-
-  /**
-   * Add exclude ('-') to a string. If it is a double quoted string, add the
-   * exclude immediately after the first double quote char.
-   *
-   * @param str with quotes
-   * @return exclude in quoted str
-   */
-  private String addExclude(String str) {
-    return buildDiffSyntaxString(str, "-");
-  }
-
-  /**
-   * Add overlay ('+') to a string. If it is a double quoted string, add the
-   * overlay immediately after the first double quote char.
-   *
-   * @param str with quotes
-   * @return overlay in quoted str
-   */
-  private String addOverlay(String str) {
-    return buildDiffSyntaxString(str, "+");
-  }
-
-  private String buildDiffSyntaxString(String str, String syntax) {
-    if (isNotBlank(str)) {
-      if (str.startsWith("\"")) {
-        str = "\"" + syntax + str.substring(1);
-      } else {
-        str = syntax + str;
-      }
-    }
-    return str;
-  }
-
-  /**
-   * Returns string representation of the protection entry.
-   *
-   * @return the string representation of the protection entry
-   */
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    if (isNotBlank(mode)) {
-      sb.append(mode);
-    }
-    if (isGroup()) {
-      sb.append(SPACE).append("group");
-    } else {
-      sb.append(SPACE).append(USER);
-    }
-    if (isNotBlank(name)) {
-      sb.append(SPACE).append(name);
-    }
-    if (isNotBlank(host)) {
-      sb.append(SPACE).append(host);
-    }
-    if (isNotBlank(left)) {
-      sb.append(SPACE).append(getPath());
-    }
-    return sb.toString();
-  }
+	/**
+	 * The protection mode for this entry. The permission level or right being
+	 * granted or denied. Each permission level includes all the permissions
+	 * above it, except for 'review'. Each permission only includes the specific
+	 * right and no lesser rights. This approach enables you to deny individual
+	 * rights without having to re-grant lesser rights. Modes prefixed by '='
+	 * are rights. All other modes are permission levels.
+	 */
+	private String mode = null;
+
+	/**
+	 * If true, this protection entry applies to a group.
+	 */
+	private boolean group = false;
+
+	/**
+	 * The IP address of a client host; can include wildcards.
+	 */
+	private String host = null;
+
+	/**
+	 * A Perforce group or user name; can include wildcards.
+	 */
+	private String name = null;
+
+	/**
+	 * Default constructor -- sets all fields to null, zero, or false.
+	 */
+	public ProtectionEntry() {
+		super();
+	}
+
+	/**
+	 * Explicit-value constructor.
+	 *
+	 * @param order        order
+	 * @param mode         mode
+	 * @param group        group
+	 * @param host         host
+	 * @param name         name
+	 * @param path         path
+	 * @param pathExcluded pathExcluded
+	 */
+	public ProtectionEntry(final int order, final String mode, final boolean group, final String host, final String name, final String path, final boolean pathExcluded) {
+
+		super(order, null);
+
+		this.mode = mode;
+		this.group = group;
+		this.host = host;
+		this.name = name;
+		if (isNotBlank(path)) {
+			String[] entries = parseViewMappingString(quoteWhitespaceString(path));
+			type = EntryType.fromString(entries[0]);
+			left = stripTypePrefix(entries[0]);
+			right = entries[1];
+		}
+		left = quoteWhitespaceString(left);
+
+		if (pathExcluded) {
+			type = EntryType.EXCLUDE;
+		}
+	}
+
+	/**
+	 * Constructs a ProtectionEntry from the passed-in map; this map
+	 * must have come from a Perforce IServer method call or it may fail.
+	 * If map is null, equivalent to calling the default constructor.
+	 *
+	 * @param map   map
+	 * @param order order
+	 */
+	public ProtectionEntry(final Map map, final int order) {
+		super(order, null);
+
+		if (nonNull(map)) {
+			host = parseString(map, HOST);
+			String pathStr = parseString(map, DEPOT_FILE);
+			if (isNotBlank(pathStr)) {
+				String[] entries = parseViewMappingString(quoteWhitespaceString(pathStr));
+				type = EntryType.fromString(entries[0]);
+				left = stripTypePrefix(entries[0]);
+				right = entries[1];
+			}
+			left = quoteWhitespaceString(left);
+			mode = parseString(map, PERM);
+			name = parseString(map, USER);
+
+			group = map.containsKey(IS_GROUP);
+			if (map.containsKey(UNMAP)) {
+				type = EntryType.EXCLUDE;
+			}
+		}
+	}
+
+	@Override
+	public String getHost() {
+		return host;
+	}
+
+	@Override
+
+	public String getMode() {
+		return mode;
+	}
+
+	@Override
+
+	public String getName() {
+		return name;
+	}
+
+	@Override
+
+	public String getPath() {
+		if (isPathExcluded()) {
+			return addExclude(left);
+		} else if (type == EntryType.OVERLAY) {
+			return addOverlay(left);
+		} else {
+			return left;
+		}
+	}
+
+	@Override
+
+	public boolean isGroup() {
+		return this.group;
+	}
+
+	@Override
+
+	public void setGroup(boolean group) {
+		this.group = group;
+	}
+
+	@Override
+
+	public void setHost(String host) {
+		this.host = host;
+	}
+
+	@Override
+
+	public void setMode(String mode) {
+		this.mode = mode;
+	}
+
+	@Override
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	@Override
+
+	public void setPath(String path) {
+		left = quoteWhitespaceString(path);
+	}
+
+	@Override
+
+	public boolean isPathExcluded() {
+		return type == EntryType.EXCLUDE;
+	}
+
+	@Override
+
+	public void setPathExcluded(boolean pathExcluded) {
+		if (pathExcluded) {
+			type = EntryType.EXCLUDE;
+		}
+	}
+
+	/**
+	 * Add exclude ('-') to a string. If it is a double quoted string, add the
+	 * exclude immediately after the first double quote char.
+	 *
+	 * @param str with quotes
+	 * @return exclude in quoted str
+	 */
+	private String addExclude(String str) {
+		return buildDiffSyntaxString(str, "-");
+	}
+
+	/**
+	 * Add overlay ('+') to a string. If it is a double quoted string, add the
+	 * overlay immediately after the first double quote char.
+	 *
+	 * @param str with quotes
+	 * @return overlay in quoted str
+	 */
+	private String addOverlay(String str) {
+		return buildDiffSyntaxString(str, "+");
+	}
+
+	private String buildDiffSyntaxString(String str, String syntax) {
+		if (isNotBlank(str)) {
+			if (str.startsWith("\"")) {
+				str = "\"" + syntax + str.substring(1);
+			} else {
+				str = syntax + str;
+			}
+		}
+		return str;
+	}
+
+	/**
+	 * Returns string representation of the protection entry.
+	 *
+	 * @return the string representation of the protection entry
+	 */
+	@Override
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		if (isNotBlank(mode)) {
+			sb.append(mode);
+		}
+		if (isGroup()) {
+			sb.append(SPACE).append("group");
+		} else {
+			sb.append(SPACE).append(USER);
+		}
+		if (isNotBlank(name)) {
+			sb.append(SPACE).append(name);
+		}
+		if (isNotBlank(host)) {
+			sb.append(SPACE).append(host);
+		}
+		if (isNotBlank(left)) {
+			sb.append(SPACE).append(getPath());
+		}
+		return sb.toString();
+	}
 }
diff --git a/src/main/java/com/perforce/p4java/impl/generic/admin/ProtectionsTable.java b/src/main/java/com/perforce/p4java/impl/generic/admin/ProtectionsTable.java
index d49d1d8..8fad9c1 100644
--- a/src/main/java/com/perforce/p4java/impl/generic/admin/ProtectionsTable.java
+++ b/src/main/java/com/perforce/p4java/impl/generic/admin/ProtectionsTable.java
@@ -26,20 +26,21 @@ public ProtectionsTable() {
 	
 	/**
 	 * Explicit-value constructor.
+	 * @param entries protections
 	 */
 	public ProtectionsTable(List entries) {
 		this.entries = entries;
 	}
 	
 	/**
-	 * @see com.perforce.p4java.admin.IProtectionTable#getEntries()
+	 * @see com.perforce.p4java.admin.IProtectionsTable#getEntries()
 	 */
 	public List getEntries() {
 		return this.entries;
 	}
 
 	/**
-	 * @see com.perforce.p4java.admin.IProtectionTable#setEntries(java.util.List)
+	 * @see com.perforce.p4java.admin.IProtectionsTable#setEntries(java.util.List)
 	 */
 	public void setEntries(List entries) {
 		this.entries = entries;
diff --git a/src/main/java/com/perforce/p4java/impl/generic/admin/TriggerEntry.java b/src/main/java/com/perforce/p4java/impl/generic/admin/TriggerEntry.java
index c159931..ee4f264 100644
--- a/src/main/java/com/perforce/p4java/impl/generic/admin/TriggerEntry.java
+++ b/src/main/java/com/perforce/p4java/impl/generic/admin/TriggerEntry.java
@@ -18,7 +18,6 @@
  * Note that the order of this trigger entry in the triggers table is part of
  * the trigger entry key when pass to the server for updating the triggers
  * table.
- * 

* *

  * Triggers0 example1 change-submit //depot/... "echo %changelist%"
@@ -75,6 +74,12 @@ public TriggerEntry() {
 
 	/**
 	 * Explicit-value constructor.
+	 *
+	 * @param order       order
+	 * @param name        name
+	 * @param triggerType triggerType
+	 * @param path        path
+	 * @param command     command
 	 */
 	public TriggerEntry(int order, String name, TriggerType triggerType, String path, String command) {
 		super(order, null);
@@ -88,6 +93,9 @@ public TriggerEntry(int order, String name, TriggerType triggerType, String path
 	/**
 	 * Constructs a TriggerEntry from the passed-in trigger as a string and its
 	 * order.
+	 *
+	 * @param triggerEntry triggerEntry
+	 * @param order        order
 	 */
 	public TriggerEntry(String triggerEntry, int order) {
 		if (triggerEntry != null) {
diff --git a/src/main/java/com/perforce/p4java/impl/generic/admin/TriggersTable.java b/src/main/java/com/perforce/p4java/impl/generic/admin/TriggersTable.java
index 0feeb3a..0d93e8c 100644
--- a/src/main/java/com/perforce/p4java/impl/generic/admin/TriggersTable.java
+++ b/src/main/java/com/perforce/p4java/impl/generic/admin/TriggersTable.java
@@ -26,6 +26,7 @@ public TriggersTable() {
 
 	/**
 	 * Explicit-value constructor.
+	 * @param entries triggers
 	 */
 	public TriggersTable(List entries) {
 		this.entries = entries;
diff --git a/src/main/java/com/perforce/p4java/impl/generic/client/ClientLineEnding.java b/src/main/java/com/perforce/p4java/impl/generic/client/ClientLineEnding.java
index 5dc66f7..9a76399 100644
--- a/src/main/java/com/perforce/p4java/impl/generic/client/ClientLineEnding.java
+++ b/src/main/java/com/perforce/p4java/impl/generic/client/ClientLineEnding.java
@@ -3,13 +3,13 @@
  */
 package com.perforce.p4java.impl.generic.client;
 
-import java.util.Arrays;
-import java.util.Map;
-
 import com.perforce.p4java.impl.mapbased.rpc.func.helper.StringHelper;
 import com.perforce.p4java.impl.mapbased.rpc.sys.RpcLineEndFilterOutputStream;
 import com.perforce.p4java.impl.mapbased.rpc.sys.RpcPerforceFileType;
 
+import java.util.Arrays;
+import java.util.Map;
+
 /**
  * Defines the various line ending mappings needed
  * for text files in the transfer between client and server.

@@ -20,212 +20,218 @@ public enum ClientLineEnding { - FST_L_LOCAL, // LineTypeLocal - FST_L_LF, // LineTypeRaw - FST_L_CR, // LineTypeCr - FST_L_CRLF, // LineTypeCrLf - FST_L_LFCRLF, // LineTypeLfcrlf - FST_L_LF_UTF_16BE, // LineTypeRaw - FST_L_CR_UTF_16BE, // LineTypeCr - FST_L_CRLF_UTF_16BE, // LineTypeCrLf - FST_L_LFCRLF_UTF_16BE, // LineTypeLfcrlf - FST_L_LF_UTF_16LE, // LineTypeRaw - FST_L_CR_UTF_16LE, // LineTypeCr - FST_L_CRLF_UTF_16LE, // LineTypeCrLf - FST_L_LFCRLF_UTF_16LE; // LineTypeLfcrlf - - /** - * The key for the system-wide line separator. - */ - public static final String LINESEP_PROPS_KEY = "line.separator"; - - /** - * The local line end string, as retrieved from the system - * properties. The JVM apparently guarantees that this is - * accurate.... - */ - public static final String localLineEndStr = - System.getProperty(LINESEP_PROPS_KEY, "\n"); - - /** - * What the Perforce server uses internally to signal line end. - * Not coincidentally, the same as the Unix, Linux, and Mac OS X - * line end byte. - */ - public static final byte PERFORCE_SERVER_LINE_END_BYTE = '\n'; - - public static final byte[] FST_L_LOCAL_BYTES = localLineEndStr.getBytes(); - public static final char FST_L_LF_CHAR = '\n'; - public static final char FST_L_CR_CHAR = '\r'; - public static final byte[] FST_L_LF_BYTES = new byte[]{'\n'}; - public static final byte[] FST_L_CR_BYTES = new byte[]{'\r'}; - public static final byte[] FST_L_CRLF_BYTES = new byte[]{'\r', '\n'}; - public static final byte[] FST_L_LFCRLF_BYTES = new byte[]{'\n', '\r', '\n'}; // ?? - HR - - public static final byte[] FST_L_LF_UTF_16BE_BYTES = new byte[]{(byte) 0x00, '\n'}; - public static final byte[] FST_L_CR_UTF_16BE_BYTES = new byte[]{(byte) 0x00, '\r'}; - public static final byte[] FST_L_CRLF_UTF_16BE_BYTES = new byte[]{(byte) 0x00, '\r', (byte) 0x00, '\n'}; - public static final byte[] FST_L_LFCRLF_UTF_16BE_BYTES = new byte[]{(byte) 0x00, '\n', (byte) 0x00, '\r', (byte) 0x00, '\n'}; - - public static final byte[] FST_L_LF_UTF_16LE_BYTES = new byte[]{'\n', (byte) 0x00}; - public static final byte[] FST_L_CR_UTF_16LE_BYTES = new byte[]{'\r', (byte) 0x00}; - public static final byte[] FST_L_CRLF_UTF_16LE_BYTES = new byte[]{'\r', (byte) 0x00, '\n', (byte) 0x00}; - public static final byte[] FST_L_LFCRLF_UTF_16LE_BYTES = new byte[]{'\n', (byte) 0x00, '\r', (byte) 0x00, '\n', (byte) 0x00}; - - public static final boolean CONVERT_TEXT = !Arrays.equals(FST_L_LOCAL_BYTES, FST_L_LF_BYTES); - - /** - * Decode the file's actual or intended line ending type from the passed-in - * string. The line ending stuff is usually the second char (if it exists), - * but that may be overridden if the associated file type is a raw text - * type (usually something to do with merges or diff / resolve, apparently), - * in which case we return FST_L_LF.

- * - * Hence the anomalous-looking second parameter here.... - */ - - public static ClientLineEnding decodeFromServerString(String str, - RpcPerforceFileType fileType) { - - if ((fileType != null) && (fileType == RpcPerforceFileType.FST_RTEXT)) { - return FST_L_LF; // See comments above... this overrides everything - } - - if (str == null) { - return FST_L_LOCAL; - } - - // Copied wholesale from the C++ API... - - // fileType [ lineType [ uncompress ] ] - - int tl = 0; - - if (str.length() >= 2) { - tl = StringHelper.hexcharToInt(str.charAt(1)); - } - - switch (tl) { - case 0x1: - return FST_L_LF; - case 0x2: - return FST_L_CR; - case 0x3: - return FST_L_CRLF; - case 0x4: - return FST_L_LFCRLF; - - default: - return FST_L_LOCAL; - } - } - - - /** - * Determine whether we really need to translate newlines. Since the - * server stores them internally as "\n" characters, we only need to - * translate on systems where that's not the default -- currently - * win and mac, but we use the system prop just to be sure... - */ - // TODO: should use charset - public static boolean needsLineEndFiltering(ClientLineEnding lineEndSpec) { - if (lineEndSpec != null) { - switch (lineEndSpec) { - case FST_L_LOCAL: - if (!localLineEndStr.equals( - RpcLineEndFilterOutputStream.P4SERVER_LINSEP_STR)) { - return true; - } - break; - - case FST_L_LF: - break; - - case FST_L_CR: - case FST_L_CRLF: - case FST_L_LFCRLF: - - case FST_L_LF_UTF_16BE: - case FST_L_CR_UTF_16BE: - case FST_L_CRLF_UTF_16BE: - case FST_L_LFCRLF_UTF_16BE: - - case FST_L_LF_UTF_16LE: - case FST_L_CR_UTF_16LE: - case FST_L_CRLF_UTF_16LE: - case FST_L_LFCRLF_UTF_16LE: - - return true; - } - } - return false; - } - - /** - * Return the byte array corresponding to the client line ending. - * The default is {@link #FST_L_LOCAL_BYTES}. - */ - - public static byte[] getLineEndBytes(ClientLineEnding lineEndSpec) { - if (lineEndSpec != null) { - switch (lineEndSpec) { - case FST_L_LOCAL: - return FST_L_LOCAL_BYTES; - - case FST_L_LF: - return FST_L_LF_BYTES; - - case FST_L_CR: - return FST_L_CR_BYTES; - - case FST_L_CRLF: - return FST_L_CRLF_BYTES; - - case FST_L_LFCRLF: - return FST_L_LFCRLF_BYTES; - - case FST_L_LF_UTF_16BE: - return FST_L_LF_UTF_16BE_BYTES; - - case FST_L_CR_UTF_16BE: - return FST_L_CR_UTF_16BE_BYTES; - - case FST_L_CRLF_UTF_16BE: - return FST_L_CRLF_UTF_16BE_BYTES; - - case FST_L_LFCRLF_UTF_16BE: - return FST_L_LFCRLF_UTF_16BE_BYTES; - - case FST_L_LF_UTF_16LE: - return FST_L_LF_UTF_16LE_BYTES; - - case FST_L_CR_UTF_16LE: - return FST_L_CR_UTF_16LE_BYTES; - - case FST_L_CRLF_UTF_16LE: - return FST_L_CRLF_UTF_16LE_BYTES; - - case FST_L_LFCRLF_UTF_16LE: - return FST_L_LFCRLF_UTF_16LE_BYTES; - } - } - return FST_L_LOCAL_BYTES; - } - - /** - * Convert the line endings for any string found in the map to the - * {@link #FST_L_LF_BYTES} values from {@link #localLineEndStr}. The - * conversion will be done in place. - */ - public static void convertMap(Map map) { - if (map != null) { - String convertTo = new String(FST_L_LF_BYTES); - for (Map.Entry entry : map.entrySet()) { - if (entry.getValue() instanceof String) { - String value = ((String) entry.getValue()).replace(localLineEndStr, convertTo); - map.put(entry.getKey(), value); - } - } - } - } + FST_L_LOCAL, // LineTypeLocal + FST_L_LF, // LineTypeRaw + FST_L_CR, // LineTypeCr + FST_L_CRLF, // LineTypeCrLf + FST_L_LFCRLF, // LineTypeLfcrlf + FST_L_LF_UTF_16BE, // LineTypeRaw + FST_L_CR_UTF_16BE, // LineTypeCr + FST_L_CRLF_UTF_16BE, // LineTypeCrLf + FST_L_LFCRLF_UTF_16BE, // LineTypeLfcrlf + FST_L_LF_UTF_16LE, // LineTypeRaw + FST_L_CR_UTF_16LE, // LineTypeCr + FST_L_CRLF_UTF_16LE, // LineTypeCrLf + FST_L_LFCRLF_UTF_16LE; // LineTypeLfcrlf + + /** + * The key for the system-wide line separator. + */ + public static final String LINESEP_PROPS_KEY = "line.separator"; + + /** + * The local line end string, as retrieved from the system + * properties. The JVM apparently guarantees that this is + * accurate.... + */ + public static final String localLineEndStr = System.getProperty(LINESEP_PROPS_KEY, "\n"); + + /** + * What the Perforce server uses internally to signal line end. + * Not coincidentally, the same as the Unix, Linux, and Mac OS X + * line end byte. + */ + public static final byte PERFORCE_SERVER_LINE_END_BYTE = '\n'; + + public static final byte[] FST_L_LOCAL_BYTES = localLineEndStr.getBytes(); + public static final char FST_L_LF_CHAR = '\n'; + public static final char FST_L_CR_CHAR = '\r'; + public static final byte[] FST_L_LF_BYTES = new byte[]{'\n'}; + public static final byte[] FST_L_CR_BYTES = new byte[]{'\r'}; + public static final byte[] FST_L_CRLF_BYTES = new byte[]{'\r', '\n'}; + public static final byte[] FST_L_LFCRLF_BYTES = new byte[]{'\n', '\r', '\n'}; // ?? - HR + + public static final byte[] FST_L_LF_UTF_16BE_BYTES = new byte[]{(byte) 0x00, '\n'}; + public static final byte[] FST_L_CR_UTF_16BE_BYTES = new byte[]{(byte) 0x00, '\r'}; + public static final byte[] FST_L_CRLF_UTF_16BE_BYTES = new byte[]{(byte) 0x00, '\r', (byte) 0x00, '\n'}; + public static final byte[] FST_L_LFCRLF_UTF_16BE_BYTES = new byte[]{(byte) 0x00, '\n', (byte) 0x00, '\r', (byte) 0x00, '\n'}; + + public static final byte[] FST_L_LF_UTF_16LE_BYTES = new byte[]{'\n', (byte) 0x00}; + public static final byte[] FST_L_CR_UTF_16LE_BYTES = new byte[]{'\r', (byte) 0x00}; + public static final byte[] FST_L_CRLF_UTF_16LE_BYTES = new byte[]{'\r', (byte) 0x00, '\n', (byte) 0x00}; + public static final byte[] FST_L_LFCRLF_UTF_16LE_BYTES = new byte[]{'\n', (byte) 0x00, '\r', (byte) 0x00, '\n', (byte) 0x00}; + + public static final boolean CONVERT_TEXT = !Arrays.equals(FST_L_LOCAL_BYTES, FST_L_LF_BYTES); + + /** + * Decode the file's actual or intended line ending type from the passed-in + * string. The line ending stuff is usually the second char (if it exists), + * but that may be overridden if the associated file type is a raw text + * type (usually something to do with merges or diff / resolve, apparently), + * in which case we return FST_L_LF. + *

+ * Hence the anomalous-looking second parameter here.... + * + * @param str line ending string + * @param fileType file type + * @return Client line-ending + */ + public static ClientLineEnding decodeFromServerString(String str, RpcPerforceFileType fileType) { + + if ((fileType != null) && (fileType == RpcPerforceFileType.FST_RTEXT)) { + return FST_L_LF; // See comments above... this overrides everything + } + + if (str == null) { + return FST_L_LOCAL; + } + + // Copied wholesale from the C++ API... + + // fileType [ lineType [ uncompress ] ] + + int tl = 0; + + if (str.length() >= 2) { + tl = StringHelper.hexcharToInt(str.charAt(1)); + } + + switch (tl) { + case 0x1: + return FST_L_LF; + case 0x2: + return FST_L_CR; + case 0x3: + return FST_L_CRLF; + case 0x4: + return FST_L_LFCRLF; + + default: + return FST_L_LOCAL; + } + } + + /** + * Determine whether we really need to translate newlines. Since the + * server stores them internally as "\n" characters, we only need to + * translate on systems where that's not the default -- currently + * win and mac, but we use the system prop just to be sure... + * + * @param lineEndSpec client line-ending + * @return true if line-ending filtering is required + */ + // TODO: should use charset + public static boolean needsLineEndFiltering(ClientLineEnding lineEndSpec) { + if (lineEndSpec != null) { + switch (lineEndSpec) { + case FST_L_LOCAL: + if (!localLineEndStr.equals(RpcLineEndFilterOutputStream.P4SERVER_LINSEP_STR)) { + return true; + } + break; + + case FST_L_LF: + break; + + case FST_L_CR: + case FST_L_CRLF: + case FST_L_LFCRLF: + + case FST_L_LF_UTF_16BE: + case FST_L_CR_UTF_16BE: + case FST_L_CRLF_UTF_16BE: + case FST_L_LFCRLF_UTF_16BE: + + case FST_L_LF_UTF_16LE: + case FST_L_CR_UTF_16LE: + case FST_L_CRLF_UTF_16LE: + case FST_L_LFCRLF_UTF_16LE: + + return true; + } + } + return false; + } + + /** + * Return the byte array corresponding to the client line ending. + * The default is {@link #FST_L_LOCAL_BYTES}. + * + * @param lineEndSpec client line-ending + * @return bytes + */ + public static byte[] getLineEndBytes(ClientLineEnding lineEndSpec) { + if (lineEndSpec != null) { + switch (lineEndSpec) { + case FST_L_LOCAL: + return FST_L_LOCAL_BYTES; + + case FST_L_LF: + return FST_L_LF_BYTES; + + case FST_L_CR: + return FST_L_CR_BYTES; + + case FST_L_CRLF: + return FST_L_CRLF_BYTES; + + case FST_L_LFCRLF: + return FST_L_LFCRLF_BYTES; + + case FST_L_LF_UTF_16BE: + return FST_L_LF_UTF_16BE_BYTES; + + case FST_L_CR_UTF_16BE: + return FST_L_CR_UTF_16BE_BYTES; + + case FST_L_CRLF_UTF_16BE: + return FST_L_CRLF_UTF_16BE_BYTES; + + case FST_L_LFCRLF_UTF_16BE: + return FST_L_LFCRLF_UTF_16BE_BYTES; + + case FST_L_LF_UTF_16LE: + return FST_L_LF_UTF_16LE_BYTES; + + case FST_L_CR_UTF_16LE: + return FST_L_CR_UTF_16LE_BYTES; + + case FST_L_CRLF_UTF_16LE: + return FST_L_CRLF_UTF_16LE_BYTES; + + case FST_L_LFCRLF_UTF_16LE: + return FST_L_LFCRLF_UTF_16LE_BYTES; + } + } + return FST_L_LOCAL_BYTES; + } + + /** + * Convert the line endings for any string found in the map to the + * {@link #FST_L_LF_BYTES} values from {@link #localLineEndStr}. The + * conversion will be done in place. + * + * @param map map spec + */ + public static void convertMap(Map map) { + if (map != null) { + String convertTo = new String(FST_L_LF_BYTES); + for (Map.Entry entry : map.entrySet()) { + if (entry.getValue() instanceof String) { + String value = ((String) entry.getValue()).replace(localLineEndStr, convertTo); + map.put(entry.getKey(), value); + } + } + } + } } diff --git a/src/main/java/com/perforce/p4java/impl/generic/client/ClientOptions.java b/src/main/java/com/perforce/p4java/impl/generic/client/ClientOptions.java index 820b9ff..b5cae79 100644 --- a/src/main/java/com/perforce/p4java/impl/generic/client/ClientOptions.java +++ b/src/main/java/com/perforce/p4java/impl/generic/client/ClientOptions.java @@ -1,5 +1,5 @@ /** - * + * */ package com.perforce.p4java.impl.generic.client; @@ -10,25 +10,31 @@ */ public class ClientOptions implements IClientOptions { - + private boolean allWrite = false; private boolean clobber = false; private boolean compress = false; private boolean locked = false; private boolean modtime = false; private boolean rmdir = false; - + /** * Default constructor; sets all fields to false. */ public ClientOptions() { } - + /** * Explicit-value constructor. + * + * @param allWrite allWrite + * @param clobber clobber + * @param compress compress + * @param locked locked + * @param modtime modtime + * @param rmdir rmdir */ - public ClientOptions(boolean allWrite, boolean clobber, - boolean compress, boolean locked, boolean modtime, boolean rmdir) { + public ClientOptions(boolean allWrite, boolean clobber, boolean compress, boolean locked, boolean modtime, boolean rmdir) { this.allWrite = allWrite; this.clobber = clobber; this.compress = compress; @@ -36,14 +42,16 @@ public ClientOptions(boolean allWrite, boolean clobber, this.modtime = modtime; this.rmdir = rmdir; } - + /** * Attempts to construct a ClientOptions object from a typical p4 cmd options string, * e.g. "noallwrite noclobber nocompress unlocked nomodtime normdir". If optionsString * is null, this is equivalent to calling the default constructor. + * + * @param optionsString options */ public ClientOptions(String optionsString) { - + if (optionsString != null) { String opts[] = optionsString.split(" "); for (String str : opts) { @@ -70,49 +78,53 @@ public ClientOptions(String optionsString) { * constructor. */ public String toString() { - return - (this.allWrite ? "allwrite" : "noallwrite") + - (this.clobber ? " clobber" : " noclobber") + - (this.compress ? " compress" : " nocompress") + - (this.locked ? " locked" : " nolocked") + - (this.modtime ? " modtime" : " nomodtime") + - (this.rmdir ? " rmdir" : " normdir") - ; - } - + return (this.allWrite ? "allwrite" : "noallwrite") + (this.clobber ? " clobber" : " noclobber") + (this.compress ? " compress" : " nocompress") + (this.locked ? " locked" : " nolocked") + (this.modtime ? " modtime" : " nomodtime") + (this.rmdir ? " rmdir" : " normdir"); + } + public boolean isAllWrite() { return allWrite; } + public void setAllWrite(boolean allWrite) { this.allWrite = allWrite; } + public boolean isClobber() { return clobber; } + public void setClobber(boolean clobber) { this.clobber = clobber; } + public boolean isCompress() { return compress; } + public void setCompress(boolean compress) { this.compress = compress; } + public boolean isLocked() { return locked; } + public void setLocked(boolean locked) { this.locked = locked; } + public boolean isModtime() { return modtime; } + public void setModtime(boolean modtime) { this.modtime = modtime; } + public boolean isRmdir() { return rmdir; } + public void setRmdir(boolean rmdir) { this.rmdir = rmdir; } diff --git a/src/main/java/com/perforce/p4java/impl/generic/client/ClientSubmitOptions.java b/src/main/java/com/perforce/p4java/impl/generic/client/ClientSubmitOptions.java index c524c9d..7d94e1d 100644 --- a/src/main/java/com/perforce/p4java/impl/generic/client/ClientSubmitOptions.java +++ b/src/main/java/com/perforce/p4java/impl/generic/client/ClientSubmitOptions.java @@ -1,5 +1,5 @@ /** - * + * */ package com.perforce.p4java.impl.generic.client; @@ -12,35 +12,37 @@ */ public class ClientSubmitOptions implements IClientSubmitOptions { - + private boolean submitunchanged = false; private boolean submitunchangedReopen = false; private boolean revertunchanged = false; private boolean revertunchangedReopen = false; private boolean leaveunchanged = false; private boolean leaveunchangedReopen = false; - + /** * Default constructor; sets all fields to false. */ public ClientSubmitOptions() { } - + /** * Attempts to construct a ClientSubmitOptions object from a typical p4 cmd options string, * e.g. "revertunchanged+reopen", or from a map returned from the * server (where it's more commonly in the format "revertunchangedReopen". - * If optString is null, this is equivalent to calling the default constructor.

- * + * If optString is null, this is equivalent to calling the default constructor. + *

* Note that the optString parser is fairly permissive in what it will accept; * for example, the string "submitunchanged submitunchanged+reopen" is accepted * just fine even though it's a little redundant, and no real attempt is made to * enforce the mutual exclusivity of the options. + * + * @param optString options */ public ClientSubmitOptions(String optString) { if (optString != null) { String opts[] = optString.split(" "); - + for (String str : opts) { if (str.equalsIgnoreCase(SUBMIT_UNCHANGED)) { this.submitunchanged = true; @@ -61,17 +63,24 @@ public ClientSubmitOptions(String optString) { } } } - + /** * Explicit-value constructor. Note that nonsensical constructs * like submitunchanged = false and submitunchangedReopen = true * are accepted silently; also, no attempt is made to enforce * mutual exclusivity here. + * + * @param submitunchanged submitunchanged + * @param submitunchangedReopen submitunchangedReopen + * @param revertunchanged revertunchanged + * @param revertunchangedReopen revertunchangedReopen + * @param leaveunchanged leaveunchanged + * @param leaveunchangedReopen leaveunchangedReopen */ public ClientSubmitOptions(boolean submitunchanged, - boolean submitunchangedReopen, boolean revertunchanged, - boolean revertunchangedReopen, boolean leaveunchanged, - boolean leaveunchangedReopen) { + boolean submitunchangedReopen, boolean revertunchanged, + boolean revertunchangedReopen, boolean leaveunchanged, + boolean leaveunchangedReopen) { this.submitunchanged = submitunchanged; this.submitunchangedReopen = submitunchangedReopen; this.revertunchanged = revertunchanged; @@ -79,7 +88,7 @@ public ClientSubmitOptions(boolean submitunchanged, this.leaveunchanged = leaveunchanged; this.leaveunchangedReopen = leaveunchangedReopen; } - + /** * Return a Perforce-standard representation of these options. * This string is in the same format as used by the @@ -95,52 +104,63 @@ public String toString() { public boolean isSubmitunchanged() { return submitunchanged; } + public void setSubmitunchanged(boolean submitunchanged) { resetOptions(); this.submitunchanged = submitunchanged; } + public boolean isSubmitunchangedReopen() { return submitunchangedReopen; } + public void setSubmitunchangedReopen(boolean submitunchangedReopen) { resetOptions(); this.submitunchangedReopen = submitunchangedReopen; } + public boolean isRevertunchanged() { return revertunchanged; } + public void setRevertunchanged(boolean revertunchanged) { resetOptions(); this.revertunchanged = revertunchanged; } + public boolean isRevertunchangedReopen() { return revertunchangedReopen; } + public void setRevertunchangedReopen(boolean revertunchangedReopen) { resetOptions(); this.revertunchangedReopen = revertunchangedReopen; } + public boolean isLeaveunchanged() { return leaveunchanged; } + public void setLeaveunchanged(boolean leaveunchanged) { resetOptions(); this.leaveunchanged = leaveunchanged; } + public boolean isLeaveunchangedReopen() { return leaveunchangedReopen; } + public void setLeaveunchangedReopen(boolean leaveunchangedReopen) { resetOptions(); this.leaveunchangedReopen = leaveunchangedReopen; } - + protected void resetOptions() { this.leaveunchanged = false; this.leaveunchangedReopen = false; this.revertunchanged = false; this.revertunchangedReopen = false; - this.submitunchanged = false; + this.submitunchanged = false; this.submitunchangedReopen = false; } } diff --git a/src/main/java/com/perforce/p4java/impl/generic/client/ClientView.java b/src/main/java/com/perforce/p4java/impl/generic/client/ClientView.java index 57d428c..fa8785c 100644 --- a/src/main/java/com/perforce/p4java/impl/generic/client/ClientView.java +++ b/src/main/java/com/perforce/p4java/impl/generic/client/ClientView.java @@ -1,15 +1,15 @@ /** - * + * */ package com.perforce.p4java.impl.generic.client; -import java.util.List; - import com.perforce.p4java.client.IClient; import com.perforce.p4java.client.IClientViewMapping; import com.perforce.p4java.core.ViewMap; import com.perforce.p4java.impl.generic.core.MapEntry; +import java.util.List; + /** * Simple default generic implementation class for the IClientView and * associated IClientViewMapping interfaces. Relies heavily @@ -17,68 +17,85 @@ */ public class ClientView extends ViewMap { - + /** * Simple extension of the basic MapEntry class to provide convenience * methods based on "depot" and "client" rather than "left" and "right". */ public static class ClientViewMapping extends MapEntry implements IClientViewMapping { - + public static final int NO_MAP_ORDER = MapEntry.ORDER_UNKNOWN; - + /** * Default constructor. Sets all fields to null or false. */ public ClientViewMapping() { super(); } - + /** * Constructs a new view mapping by calling the superclass's * corresponding constructor. + * + * @param order order + * @param mappingString mappingString */ public ClientViewMapping(int order, String mappingString) { super(order, mappingString); } - + /** * Constructs a new view mapping by calling the superclass's * corresponding constructor. + * + * @param order order + * @param depotSpec depotSpec + * @param client client */ public ClientViewMapping(int order, String depotSpec, String client) { super(order, depotSpec, client); } - + /** * Constructs a new view mapping by calling the superclass's * corresponding constructor. + * + * @param order order + * @param type type + * @param depotSpec depotSpec + * @param clientSpec clientSpec */ public ClientViewMapping(int order, EntryType type, String depotSpec, String clientSpec) { super(order, type, depotSpec, clientSpec); } - + public String getDepotSpec() { return this.left; } + public String getDepotSpec(boolean quoteBlanks) { return this.getLeft(quoteBlanks); } + public void setDepotSpec(String depotSpec) { this.left = depotSpec; } + public String getClient() { return this.right; } + public void setClient(String client) { this.right = client; } + public String getClient(boolean quoteBlanks) { return this.getRight(quoteBlanks); } } private IClient client = null; - + /** * Default constructor; simply calls the superclass * default constructor and sets this.client to null. @@ -86,9 +103,12 @@ public String getClient(boolean quoteBlanks) { public ClientView() { super(); } - + /** * Construct a ClientView from the passed-in client and mapping list. + * + * @param client client + * @param mapping mapping */ public ClientView(IClient client, List mapping) { super(mapping); @@ -98,13 +118,15 @@ public ClientView(IClient client, List mapping) { /** * Get the client object (not path) associated with this view, if any. + * @return Client object */ public IClient getClient() { return this.client; } - + /** * Set the client object (not path) associated with this view, if any. + * @param client Client object */ public void setClient(IClient client) { this.client = client; diff --git a/src/main/java/com/perforce/p4java/impl/generic/core/BranchSpec.java b/src/main/java/com/perforce/p4java/impl/generic/core/BranchSpec.java index dd53c00..cb99617 100644 --- a/src/main/java/com/perforce/p4java/impl/generic/core/BranchSpec.java +++ b/src/main/java/com/perforce/p4java/impl/generic/core/BranchSpec.java @@ -3,9 +3,6 @@ */ package com.perforce.p4java.impl.generic.core; -import java.util.Date; -import java.util.Map; - import com.perforce.p4java.Log; import com.perforce.p4java.core.IBranchMapping; import com.perforce.p4java.core.IBranchSpec; @@ -19,36 +16,39 @@ import com.perforce.p4java.server.IOptionsServer; import com.perforce.p4java.server.IServer; +import java.util.Date; +import java.util.Map; + /** * Simple default implementation class for the IBranchSpec interface. */ public class BranchSpec extends BranchSpecSummary implements IBranchSpec { - + protected ViewMap branchView = null; - + /** * Default description for use in newBranchSpec method when no explicit * description is given. */ public static final String DEFAULT_DESCRIPTION = "New branchspec created by P4Java"; - + /** * Simple factory / convenience method for creating a new local BranchSpec object * with defult values. - * - * @param server non-null server to be associated with the new branch spec. - * @param name non-null branch spec name. + * + * @param server non-null server to be associated with the new branch spec. + * @param name non-null branch spec name. * @param description if not null, used as the new branc spec's description field; - * if null, uses the BranchSpec.DEFAULT_DESCRIPTION field. - * @param branches if not null, use this as the list of branch spec - * paths, in the order given, and according to the format in - * MapEntry.parseViewMappingString; unlike many other core object - * factory methods, this one does not default if null. + * if null, uses the BranchSpec.DEFAULT_DESCRIPTION field. + * @param branches if not null, use this as the list of branch spec + * paths, in the order given, and according to the format in + * MapEntry.parseViewMappingString; unlike many other core object + * factory methods, this one does not default if null. * @return new local BranchSpec object. */ public static BranchSpec newBranchSpec(IOptionsServer server, String name, String description, - String[] branches) { + String[] branches) { if (name == null) { throw new NullPointerError("null branch spec name in BranchSpec.newBranchSpec()"); } @@ -58,9 +58,9 @@ public static BranchSpec newBranchSpec(IOptionsServer server, String name, Strin if (branches == null) { throw new NullPointerError("null branch view in BranchSpec.newBranchSpec()"); } - + ViewMap branchView = new ViewMap(); - + int i = 0; for (String mapping : branches) { if (mapping == null) { @@ -69,42 +69,49 @@ public static BranchSpec newBranchSpec(IOptionsServer server, String name, Strin branchView.addEntry(new BranchViewMapping(i, mapping)); i++; } - + return new BranchSpec( - name, - server.getUserName(), - description == null ? BranchSpec.DEFAULT_DESCRIPTION : description, - false, - null, - null, - branchView - ); + name, + server.getUserName(), + description == null ? BranchSpec.DEFAULT_DESCRIPTION : description, + false, + null, + null, + branchView + ); } - + /** * Simple default implementation of the IViewMapping interface. */ - + static public class BranchViewMapping extends MapEntry implements IBranchMapping { - + /** * Default constructor -- calls super() only. */ public BranchViewMapping() { super(); } - + /** * Explicit value constructor -- calls super(order, sourceSpec, targetSpec). + * + * @param order order + * @param sourceSpec source spec + * @param targetSpec target spec */ public BranchViewMapping(int order, String sourceSpec, - String targetSpec) { + String targetSpec) { super(order, sourceSpec, targetSpec); } - + /** * Construct a mapping from the passed-in string, which is assumed * to be in the format described in MapEntry.parseViewString(String). + * + * @param order order + * @param viewString view string */ public BranchViewMapping(int order, String viewString) { super(order, viewString); @@ -116,18 +123,21 @@ public BranchViewMapping(int order, String viewString) { public String getSourceSpec() { return this.left; } + /** * @see com.perforce.p4java.core.IBranchMapping#setSourceSpec(java.lang.String) */ public void setSourceSpec(String sourceSpec) { this.left = sourceSpec; } + /** * @see com.perforce.p4java.core.IBranchMapping#getTargetSpec() */ public String getTargetSpec() { return this.right; } + /** * @see com.perforce.p4java.core.IBranchMapping#setTargetSpec(java.lang.String) */ @@ -135,22 +145,29 @@ public void setTargetSpec(String targetSpec) { this.right = targetSpec; } } - + /** * Default constructor. All fields set to null or false. */ public BranchSpec() { super(); } - + /** * Construct a new BranchSpec from explicit field values. + * + * @param name name + * @param ownerName owner + * @param description description + * @param locked if locked + * @param accessed date + * @param updated date + * @param branchView view mapping */ - public BranchSpec(String name, - String ownerName, String description, boolean locked, - Date accessed, Date updated, - ViewMap branchView) { + String ownerName, String description, boolean locked, + Date accessed, Date updated, + ViewMap branchView) { this.accessed = accessed; this.updated = updated; this.name = name; @@ -162,14 +179,17 @@ public BranchSpec(String name, /** * Construct a BranchSpec from a map passed back from the Perforce - * server in response to a getBranchSpec command. + * server in response to a getBranchSpec command. + * + * @param map spec map + * @param server server */ public BranchSpec(Map map, IServer server) { super(map, false); - + this.server = server; this.branchView = new ViewMap(); - + if (map != null) { String key = MapKeys.VIEW_KEY; for (int i = 0; ; i++) { @@ -178,52 +198,53 @@ public BranchSpec(Map map, IServer server) { } else if (map.get(key + i) != null) { try { String[] matchStrs = MapEntry.parseViewMappingString((String) map.get(key + i)); - + this.branchView.getEntryList().add(new BranchViewMapping(i, matchStrs[0], matchStrs[1])); - + } catch (Throwable thr) { Log.error("Unexpected exception in BranchSpec map-based constructor: " - + thr.getLocalizedMessage()); + + thr.getLocalizedMessage()); Log.exception(thr); } } } } } - + /** * Construct a new BranchSpec from the passed-in summary branch spec. If * the summary is null, this is equivalent to calling the default BranchSpec * constructor; otherwise after name initialization a refresh() is done on the * new (empty) BranchSpec. - * + * + * @param summary summary object * @throws ConnectionException if the Perforce server is unreachable or is not - * connected. - * @throws RequestException if the Perforce server encounters an error during - * its processing of the request - * @throws AccessException if the Perforce server denies access to the caller + * connected. + * @throws RequestException if the Perforce server encounters an error during + * its processing of the request + * @throws AccessException if the Perforce server denies access to the caller */ - + public BranchSpec(IBranchSpecSummary summary) - throws ConnectionException, RequestException, AccessException { + throws ConnectionException, RequestException, AccessException { super(false); this.branchView = new ViewMap(); if (summary != null) { this.setName(summary.getName()); - + if (this.getName() != null) { this.refresh(); } } } - + private void updateFlags() { } /** * This method will refresh by getting the complete branch model. If this * refresh is successful then this branch will be marked as complete. - * + * * @see com.perforce.p4java.impl.generic.core.ServerResource#refresh() */ public void refresh() throws ConnectionException, RequestException, @@ -245,7 +266,7 @@ public void refresh() throws ConnectionException, RequestException, } updateFlags(); } - + /** * @see com.perforce.p4java.impl.generic.core.ServerResource#update() diff --git a/src/main/java/com/perforce/p4java/impl/generic/core/BranchSpecSummary.java b/src/main/java/com/perforce/p4java/impl/generic/core/BranchSpecSummary.java index ea8b74a..831ce51 100644 --- a/src/main/java/com/perforce/p4java/impl/generic/core/BranchSpecSummary.java +++ b/src/main/java/com/perforce/p4java/impl/generic/core/BranchSpecSummary.java @@ -1,16 +1,16 @@ /** - * + * */ package com.perforce.p4java.impl.generic.core; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Map; - import com.perforce.p4java.Log; import com.perforce.p4java.core.IBranchSpecSummary; import com.perforce.p4java.impl.mapbased.MapKeys; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Map; + /** * Default implementation class for the IBranchSpecSummary interface. */ @@ -23,31 +23,41 @@ public class BranchSpecSummary extends ServerResource implements IBranchSpecSumm protected String ownerName = null; protected String description = null; protected boolean locked = false; - + /** * Default constructor -- sets all fields to null or false. */ public BranchSpecSummary() { } - + /** * Default constructor; same as no-argument default constructor, * except that it sets the ServerResource superclass fields appropriately * for summary only (everything false) or full branch spec (updateable and * refreshable). + * + * @param summaryOnly summary only (everything false) or full branch spec */ public BranchSpecSummary(boolean summaryOnly) { super(!summaryOnly, !summaryOnly); } - + /** * Explicit-value constructor. If summaryOnly is true, refreshable * and updeateable are set true in the ServerResource superclass, otherwise * they're set false. + * + * @param summaryOnly summary only (everything false) or full branch spec + * @param accessed date + * @param updated date + * @param name name + * @param ownerName owner + * @param description description + * @param locked locked */ public BranchSpecSummary(boolean summaryOnly, Date accessed, - Date updated, String name, String ownerName, String description, - boolean locked) { + Date updated, String name, String ownerName, String description, + boolean locked) { super(!summaryOnly, !summaryOnly); this.accessed = accessed; this.updated = updated; @@ -56,15 +66,17 @@ public BranchSpecSummary(boolean summaryOnly, Date accessed, this.description = description; this.locked = locked; } - + /** * Construct a BranchSpecSummary from a map returned by the Perforce server. If * summaryOnly is true, this map was returned by the IServer getBranchSummaryList * or similar summary-only method; otherwise it's assumed to be the full branch * spec.

- * + * * If map is null, this is equivalent to calling the default summaryOnly-argument * constructor. + * @param map spec map + * @param summaryOnly summary only (everything false) or full branch spec */ public BranchSpecSummary(Map map, boolean summaryOnly) { super(!summaryOnly, !summaryOnly); @@ -80,11 +92,11 @@ public BranchSpecSummary(Map map, boolean summaryOnly) { this.name = (String) map.get(MapKeys.BRANCH_KEY); if (map.containsKey(MapKeys.UPDATE_KEY)) { this.updated = new SimpleDateFormat(DATE_FORMAT).parse( - (String) map.get(MapKeys.UPDATE_KEY)); + (String) map.get(MapKeys.UPDATE_KEY)); } if (map.containsKey(MapKeys.ACCESS_KEY)) { this.accessed = new SimpleDateFormat(DATE_FORMAT).parse( - (String) map.get(MapKeys.ACCESS_KEY)); + (String) map.get(MapKeys.ACCESS_KEY)); } } catch (Throwable thr) { Log.warn("Unexpected exception in BranchSpecSummary constructor: " @@ -92,7 +104,7 @@ public BranchSpecSummary(Map map, boolean summaryOnly) { Log.exception(thr); } } - + this.description = (String) map.get(MapKeys.DESCRIPTION_KEY); this.ownerName = (String) map.get(MapKeys.OWNER_KEY); String opts = (String) map.get(MapKeys.OPTIONS_KEY); @@ -101,73 +113,84 @@ public BranchSpecSummary(Map map, boolean summaryOnly) { } } } - + /** * @see com.perforce.p4java.core.IBranchSpecSummary#getAccessed() */ public Date getAccessed() { return accessed; } + /** * @see com.perforce.p4java.core.IBranchSpecSummary#setAccessed(java.util.Date) */ public void setAccessed(Date accessed) { this.accessed = accessed; } + /** * @see com.perforce.p4java.core.IBranchSpecSummary#getUpdated() */ public Date getUpdated() { return updated; } + /** * @see com.perforce.p4java.core.IBranchSpecSummary#setUpdated(java.util.Date) */ public void setUpdated(Date updated) { this.updated = updated; } + /** * @see com.perforce.p4java.core.IBranchSpecSummary#getName() */ public String getName() { return name; } + /** * @see com.perforce.p4java.core.IBranchSpecSummary#setName(java.lang.String) */ public void setName(String name) { this.name = name; } + /** * @see com.perforce.p4java.core.IBranchSpecSummary#getOwnerName() */ public String getOwnerName() { return ownerName; } + /** * @see com.perforce.p4java.core.IBranchSpecSummary#setOwnerName(java.lang.String) */ public void setOwnerName(String ownerName) { this.ownerName = ownerName; } + /** * @see com.perforce.p4java.core.IBranchSpecSummary#getDescription() */ public String getDescription() { return description; } + /** * @see com.perforce.p4java.core.IBranchSpecSummary#setDescription(java.lang.String) */ public void setDescription(String description) { this.description = description; } + /** * @see com.perforce.p4java.core.IBranchSpecSummary#isLocked() */ public boolean isLocked() { return locked; } + /** * @see com.perforce.p4java.core.IBranchSpecSummary#setLocked(boolean) */ diff --git a/src/main/java/com/perforce/p4java/impl/generic/core/Changelist.java b/src/main/java/com/perforce/p4java/impl/generic/core/Changelist.java index 01988a0..5ad903d 100644 --- a/src/main/java/com/perforce/p4java/impl/generic/core/Changelist.java +++ b/src/main/java/com/perforce/p4java/impl/generic/core/Changelist.java @@ -26,6 +26,7 @@ import com.perforce.p4java.impl.mapbased.server.Parameters; import com.perforce.p4java.impl.mapbased.server.Server; import com.perforce.p4java.impl.mapbased.server.cmd.ResultListBuilder; +import com.perforce.p4java.impl.mapbased.server.cmd.ResultMapParser; import com.perforce.p4java.option.Options; import com.perforce.p4java.option.changelist.SubmitOptions; import com.perforce.p4java.option.server.ChangelistOptions; @@ -63,7 +64,7 @@ public class Changelist extends ChangelistSummary implements IChangelist { * Return a new local Changelist object with default values. Default values * for all fields not mentioned in the parameter list are as given for the * default Changelist and ChangelistSummary default constructors; the main - * exception is the user name, which is filled in with the current user name.

+ * exception is the user name, which is filled in with the current user name. *

* Note that this object is a local object only -- you must subsequently call * the client's createChangelist method to also create it on the server (or use @@ -75,29 +76,18 @@ public class Changelist extends ChangelistSummary implements IChangelist { * Changelist.DEFAULT_DESCRIPTION. * @return new local Changelist object. */ - public static Changelist newChangelist(IServer server, String clientName, - String description) { + public static Changelist newChangelist(IServer server, String clientName, String description) { if (server == null) { throw new NullPointerError("null server passed to Changelist.newChangelist"); } if (!(server instanceof Server)) { - throw new P4JavaError( - "IOptionsServer passed to Changelist.newChangelist does not implement 'Server' class"); + throw new P4JavaError("IOptionsServer passed to Changelist.newChangelist does not implement 'Server' class"); } if (clientName == null) { throw new NullPointerError("null client name passed to Changelist.newChangelist"); } - return new Changelist( - IChangelist.UNKNOWN, - clientName, - server.getUserName(), - ChangelistStatus.NEW, - null, - description == null ? DEFAULT_DESCRIPTION : description, - false, - (Server) server - ); + return new Changelist(IChangelist.UNKNOWN, clientName, server.getUserName(), ChangelistStatus.NEW, null, description == null ? DEFAULT_DESCRIPTION : description, false, (Server) server); } /** @@ -119,15 +109,14 @@ public static Changelist newChangelist(IClient client, String description) { throw new NullPointerError("null client passed to Changelist.newChangelist"); } if (client.getServer() == null) { - throw new NullPointerError( - "client has no server associated with it in Changelist.newChangelist"); + throw new NullPointerError("client has no server associated with it in Changelist.newChangelist"); } return newChangelist(client.getServer(), client.getName(), description); } /** - * Default constructor; calls default superclass constructor.

+ * Default constructor; calls default superclass constructor. *

* Actual users of this constructor need to ensure that the super-super-class * ServeResource fields are set appropriately after calling this constructor. @@ -137,16 +126,23 @@ public Changelist() { } /** - * Construct a changelist implementation given an explicit set of initial field values.

+ * Construct a changelist implementation given an explicit set of initial field values. *

* This constructor requires a Server object as its serverImpl parameter; * note that any server object returned by the ServerFactory will work, as long * as it's downcast to Server. If it doesn't cast cleanly, then it is not * suitable for use here. + * + * @param id id + * @param clientId client + * @param username user name + * @param status status + * @param date date + * @param description description + * @param shelved shelved + * @param serverImpl server */ - public Changelist(int id, String clientId, String username, - ChangelistStatus status, Date date, String description, - boolean shelved, Server serverImpl) { + public Changelist(int id, String clientId, String username, ChangelistStatus status, Date date, String description, boolean shelved, Server serverImpl) { super(false, true, true, true, serverImpl); this.id = id; this.clientId = clientId; @@ -159,16 +155,24 @@ public Changelist(int id, String clientId, String username, } /** - * Construct a changelist implementation given an explicit set of initial field values.

+ * Construct a changelist implementation given an explicit set of initial field values. *

* This constructor requires a Server object as its serverImpl parameter; * note that any server object returned by the ServerFactory will work, as long * as it's downcast to Server. If it doesn't cast cleanly, then it is not * suitable for use here. + * + * @param id id + * @param clientId client + * @param username user name + * @param status status + * @param date date + * @param description description + * @param shelved shelved + * @param serverImpl server + * @param visibility visibility */ - public Changelist(int id, String clientId, String username, - ChangelistStatus status, Date date, String description, - boolean shelved, Server serverImpl, Visibility visibility) { + public Changelist(int id, String clientId, String username, ChangelistStatus status, Date date, String description, boolean shelved, Server serverImpl, Visibility visibility) { super(false, true, true, true, serverImpl); this.id = id; this.clientId = clientId; @@ -184,22 +188,24 @@ public Changelist(int id, String clientId, String username, /** * Construct a new Changelist using the passed-in changelist as a template. * If summary and server are not null and refresh is true, perform a refresh - * from the Perforce server to initialize the full changelist.

+ * from the Perforce server to initialize the full changelist. *

* If changelist is null, this is equivalent to calling the default constructor. * + * @param summary summary + * @param server server + * @param refresh refresh * @throws ConnectionException if the Perforce server is unreachable or is not connected. * @throws RequestException if the Perforce server encounters an error during its processing of * the request * @throws AccessException if the Perforce server denies access to the caller */ - public Changelist(IChangelistSummary summary, IOptionsServer server, boolean refresh) - throws ConnectionException, RequestException, AccessException { + public Changelist(IChangelistSummary summary, IOptionsServer server, boolean refresh) throws ConnectionException, RequestException, AccessException { super(summary); super.setRefreshable(true); super.updateable = true; super.server = server; - //Set server impl if specified server is an impl + // Set server impl if specified server is an impl if (server instanceof Server) { this.serverImpl = server; } @@ -209,20 +215,22 @@ public Changelist(IChangelistSummary summary, IOptionsServer server, boolean ref } @Deprecated - public Changelist(IChangelistSummary summary, IServer server, boolean refresh) - throws ConnectionException, RequestException, AccessException { - this(summary, (IOptionsServer)server, refresh); + public Changelist(IChangelistSummary summary, IServer server, boolean refresh) throws ConnectionException, RequestException, AccessException { + this(summary, (IOptionsServer) server, refresh); } /** * Construct a changelist impl from the passed-in map and serverImpl parameters. * Calls super(map, false, serverImpl) and additionally sets job ids associated - * with this changelist, if any.

+ * with this changelist, if any. *

* This constructor requires a Server object as its serverImpl parameter; * note that any server object returned by the ServerFactory will work, as long * as it's downcast to Server. If it doesn't cast cleanly, then it is not * suitable for use here. + * + * @param map map + * @param serverImpl server */ public Changelist(Map map, IOptionsServer serverImpl) { super(map, false, serverImpl); @@ -249,7 +257,7 @@ public Changelist(Map map, IOptionsServer serverImpl) { @Deprecated public Changelist(Map map, IServer serverImpl) { - this(map, (IOptionsServer)serverImpl); + this(map, (IOptionsServer) serverImpl); } /** @@ -324,15 +332,11 @@ public void setServerImpl(Server serverImpl) { this.serverImpl = serverImpl; } - public List getFiles(boolean refresh) - throws ConnectionException, RequestException, - AccessException { + public List getFiles(boolean refresh) throws ConnectionException, RequestException, AccessException { return getFiles(refresh, false); } - public List getFiles(boolean refresh, boolean bypassServer) - throws ConnectionException, RequestException, - AccessException { + public List getFiles(boolean refresh, boolean bypassServer) throws ConnectionException, RequestException, AccessException { if (!refresh && (this.fileSpecs != null)) { return this.fileSpecs; @@ -346,8 +350,7 @@ public List getFiles(boolean refresh, boolean bypassServer) } if (this.serverImpl == null) { - throw new RequestException( - "Changelist not associated with a Perforce server"); + throw new RequestException("Changelist not associated with a Perforce server"); } // We need to special-case the default changelist: @@ -356,8 +359,7 @@ public List getFiles(boolean refresh, boolean bypassServer) // Use the "opened" command and list all files for this client // in the default changelist. This can be expensive... (HR) - List openList = this.serverImpl.getOpenedFiles( - null, false, this.clientId, 0, 0); + List openList = this.serverImpl.getOpenedFiles(null, false, this.clientId, 0, 0); List defList = new ArrayList(); if (openList != null) { for (IFileSpec fSpec : openList) { @@ -374,15 +376,11 @@ public List getFiles(boolean refresh, boolean bypassServer) return this.fileSpecs; } - public List getExtendedFiles(boolean refresh) - throws ConnectionException, RequestException, - AccessException { + public List getExtendedFiles(boolean refresh) throws ConnectionException, RequestException, AccessException { return getExtendedFiles(refresh, false); } - public List getExtendedFiles(boolean refresh, boolean bypassServer) - throws ConnectionException, RequestException, - AccessException { + public List getExtendedFiles(boolean refresh, boolean bypassServer) throws ConnectionException, RequestException, AccessException { if (!refresh && (this.extendedFileSpecs != null)) { return this.extendedFileSpecs; @@ -396,8 +394,7 @@ public List getExtendedFiles(boolean refresh, boolean bypassS } if (this.serverImpl == null) { - throw new RequestException( - "Changelist not associated with a Perforce server"); + throw new RequestException("Changelist not associated with a Perforce server"); } // We need to special-case the default changelist: @@ -406,13 +403,12 @@ public List getExtendedFiles(boolean refresh, boolean bypassS // Use the "opened" command and list all files for this client // in the default changelist. This can be expensive... (HR) - List openList = this.serverImpl.getOpenedFiles( - null, false, this.clientId, 0, 0); + List openList = this.serverImpl.getOpenedFiles(null, false, this.clientId, 0, 0); List defList = new ArrayList<>(); if (openList != null) { for (IFileSpec fSpec : openList) { if (fSpec.getChangelistId() == IChangelist.DEFAULT) { - defList.add((ExtendedFileSpec)fSpec); + defList.add((ExtendedFileSpec) fSpec); } } } @@ -427,8 +423,7 @@ public List getExtendedFiles(boolean refresh, boolean bypassS /** * @see com.perforce.p4java.core.IChangelist#getDiffs(com.perforce.p4java.core.file.DiffType) */ - public InputStream getDiffs(DiffType diffType) - throws ConnectionException, RequestException, AccessException { + public InputStream getDiffs(DiffType diffType) throws ConnectionException, RequestException, AccessException { if (this.serverImpl == null) { throw new RequestException("Changelist not associated with a Perforce server"); } @@ -450,8 +445,7 @@ public InputStream getDiffsStream(GetChangelistDiffsOptions opts) throws P4JavaE * @see com.perforce.p4java.core.IChangelist#getJobIds() */ - public List getJobIds() - throws ConnectionException, RequestException, AccessException { + public List getJobIds() throws ConnectionException, RequestException, AccessException { List idList = new ArrayList(); // Don't do this if we're a new (or unknown) changelist: @@ -478,8 +472,7 @@ public List getJobIds() /** * @see com.perforce.p4java.core.IChangelist#getCachedJobIdList() */ - public List getCachedJobIdList() - throws ConnectionException, RequestException, AccessException { + public List getCachedJobIdList() throws ConnectionException, RequestException, AccessException { if (this.jobIds != null) { return this.jobIds; } @@ -491,8 +484,7 @@ public List getCachedJobIdList() * @see com.perforce.p4java.core.IChangelist#getJobs() */ - public List getJobs() - throws ConnectionException, RequestException, AccessException { + public List getJobs() throws ConnectionException, RequestException, AccessException { List idList = getJobIds(); List jobList = new ArrayList(); @@ -510,13 +502,9 @@ public List getJobs() * @see com.perforce.p4java.core.IChangelist#submit(boolean, java.util.List, java.lang.String) */ - public List submit(boolean reOpen, List jobIds, String jobStatus) - throws ConnectionException, RequestException, AccessException { + public List submit(boolean reOpen, List jobIds, String jobStatus) throws ConnectionException, RequestException, AccessException { try { - return submit(new SubmitOptions() - .setJobIds(jobIds) - .setJobStatus(jobStatus) - .setReOpen(reOpen)); + return submit(new SubmitOptions().setJobIds(jobIds).setJobStatus(jobStatus).setReOpen(reOpen)); } catch (ConnectionException exc) { throw exc; } catch (AccessException exc) { @@ -538,11 +526,7 @@ public List submit(SubmitOptions opts) throws P4JavaException { } Map inMap = getInMap(opts); - List> retMaps = this.serverImpl.execMapCmdList( - CmdSpec.SUBMIT, - Parameters.processParameters( - opts, null, "-i", this.serverImpl), - inMap); + List> retMaps = this.serverImpl.execMapCmdList(CmdSpec.SUBMIT, Parameters.processParameters(opts, null, "-i", this.serverImpl), inMap); List fileList = new ArrayList(); @@ -556,8 +540,7 @@ public List submit(SubmitOptions opts) throws P4JavaException { if (map.get("submittedChange") != null) { this.id = new Integer((String) map.get("submittedChange")); this.status = ChangelistStatus.SUBMITTED; - fileList.add(new FileSpec(FileSpecOpStatus.INFO, - "Submitted as change " + this.id)); + fileList.add(new FileSpec(FileSpecOpStatus.INFO, "Submitted as change " + this.id)); } else if (map.get("locked") != null) { // disregard this message for now -- FIXME -- HR } else { @@ -580,20 +563,13 @@ public void submit(SubmitOptions opts, IStreamingCallback callback, int key) thr } Map inMap = getInMap(opts); - this.serverImpl.execStreamingMapCommand( - CmdSpec.SUBMIT.toString(), - Parameters.processParameters( - opts, null, "-i", this.serverImpl), - inMap, - callback, - key); + this.serverImpl.execStreamingMapCommand(CmdSpec.SUBMIT.toString(), Parameters.processParameters(opts, null, "-i", this.serverImpl), inMap, callback, key); } /** * @see com.perforce.p4java.core.IChangelist#submit(boolean) */ - public List submit(boolean reOpen) - throws ConnectionException, RequestException, AccessException { + public List submit(boolean reOpen) throws ConnectionException, RequestException, AccessException { return submit(reOpen, null, null); } @@ -613,7 +589,7 @@ private Map getInMap(SubmitOptions opts) throws P4JavaException inMap.put("User", this.username); inMap.put("Description", this.description); - if (this.changelistStream != null){ + if (this.changelistStream != null) { inMap.put("Stream", this.changelistStream); } @@ -663,8 +639,7 @@ private Map getInMap(SubmitOptions opts) throws P4JavaException return inMap; } - public void refresh() - throws ConnectionException, RequestException, AccessException { + public void refresh() throws ConnectionException, RequestException, AccessException { // Basically, just ask the server about us and fill in the blanks... (and what // a waste of a perfectly good IChangelist object :-) ). if (this.serverImpl == null) { @@ -725,14 +700,11 @@ public void update(Options opts) throws ConnectionException, RequestException, A } try { - List> retMaps = this.serverImpl.execMapCmdList(CmdSpec.CHANGE, - Parameters.processParameters( - opts, null, new String[]{"-i"}, this.serverImpl), - InputMapper.map(this)); + List> retMaps = this.serverImpl.execMapCmdList(CmdSpec.CHANGE, Parameters.processParameters(opts, null, new String[]{"-i"}, this.serverImpl), InputMapper.map(this)); if (retMaps != null) { for (Map map : retMaps) { - this.serverImpl.handleErrorStr(map); + ResultMapParser.handleErrorStr(map); } } } catch (ConnectionException exc) { @@ -748,9 +720,10 @@ public void update(Options opts) throws ConnectionException, RequestException, A /** * @see com.perforce.p4java.core.IChangelist#updateOnServer(boolean) + * @deprecated use update optionally followed by refresh() */ - public void updateOnServer(boolean refresh) - throws ConnectionException, RequestException, AccessException { + @Deprecated + public void updateOnServer(boolean refresh) throws ConnectionException, RequestException, AccessException { this.update(); if (refresh) { this.refresh(); diff --git a/src/main/java/com/perforce/p4java/impl/generic/core/ChangelistSummary.java b/src/main/java/com/perforce/p4java/impl/generic/core/ChangelistSummary.java index 9b8ad42..0f27798 100644 --- a/src/main/java/com/perforce/p4java/impl/generic/core/ChangelistSummary.java +++ b/src/main/java/com/perforce/p4java/impl/generic/core/ChangelistSummary.java @@ -1,13 +1,8 @@ /** - * + * */ package com.perforce.p4java.impl.generic.core; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Map; - import com.perforce.p4java.Log; import com.perforce.p4java.core.ChangelistStatus; import com.perforce.p4java.core.IChangelist; @@ -15,6 +10,11 @@ import com.perforce.p4java.impl.mapbased.MapKeys; import com.perforce.p4java.server.IServer; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Map; + /** * Default implementation of the IChangelistSummary interface. */ @@ -22,7 +22,7 @@ public class ChangelistSummary extends ServerResource implements IChangelistSummary { protected static final String DATE_FORMAT = "yyyy/MM/dd HH:mm:ss"; - + protected int id = IChangelist.UNKNOWN; protected String clientId = null; protected String username = null; @@ -39,22 +39,35 @@ public class ChangelistSummary extends ServerResource implements IChangelistSumm */ public ChangelistSummary() { } - + /** * Explicit-value pass-through constructor for the ServerResource fields. Usually * used by IChangelistSummary extensions. + * + * @param complete complete + * @param completable completable + * @param refreshable refreshable + * @param updateable updateable + * @param server server */ public ChangelistSummary(boolean complete, boolean completable, - boolean refreshable, boolean updateable, IServer server) { + boolean refreshable, boolean updateable, IServer server) { super(refreshable, updateable, server); } - + /** * Explicit-value constructor; calls the default ServerResource constructor. + * @param id id + * @param clientId client + * @param username user name + * @param status status + * @param date date + * @param description description + * @param shelved shelved */ public ChangelistSummary(int id, String clientId, String username, - ChangelistStatus status, Date date, String description, - boolean shelved) { + ChangelistStatus status, Date date, String description, + boolean shelved) { this.id = id; this.clientId = clientId; this.username = username; @@ -63,12 +76,13 @@ public ChangelistSummary(int id, String clientId, String username, this.description = description; this.shelved = shelved; } - + /** * Construct a new ChangelistSummary from the passed-in summary. If summary * is null, this is equivalent to calling the default constructor. + * + * @param summary summary object */ - public ChangelistSummary(IChangelistSummary summary) { if (summary != null) { this.id = summary.getId(); @@ -80,14 +94,17 @@ public ChangelistSummary(IChangelistSummary summary) { this.shelved = summary.isShelved(); } } - + /** * Convenience constructor, equivalent to this(map, summaryOnly, null). + * + * @param map spec map + * @param summaryOnly summary only */ public ChangelistSummary(Map map, boolean summaryOnly) { this(map, summaryOnly, null); } - + /** * Construct a ChangelistSummary from a suitable map returned from * the Perforce server. If map is null, this is equivalent to calling @@ -97,10 +114,14 @@ public ChangelistSummary(Map map, boolean summaryOnly) { * the map is assumed to come from a full changelist command and the * superclass fields are also set appropriately for the full changelist. * The server parameter is ignored for summaryOnly objects.

- * + * * Note that map keys returned from the Perforce server are sometimes different * for summary fields and full fields, so you have to be clear about where the * map came from to get accurate results. + * + * @param map spec map + * @param summaryOnly summary only + * @param server server */ public ChangelistSummary(Map map, boolean summaryOnly, IServer server) { super(); @@ -109,7 +130,7 @@ public ChangelistSummary(Map map, boolean summaryOnly, IServer s try { // Note use of lower-case keys here; this is the only // place lower-case fields are used for this... - + this.id = new Integer((String) map.get("change")); this.clientId = (String) map.get("client"); this.username = (String) map.get("user"); @@ -130,7 +151,7 @@ public ChangelistSummary(Map map, boolean summaryOnly, IServer s this.server = server; this.refreshable = true; this.updateable = true; - + try { String idString = (String) map.get(MapKeys.CHANGE_KEY); @@ -147,11 +168,11 @@ public ChangelistSummary(Map map, boolean summaryOnly, IServer s this.clientId = (String) map.get(MapKeys.CLIENT_KEY); this.username = (String) map.get(MapKeys.USER_KEY); this.status = ChangelistStatus.fromString((String) map.get(MapKeys.STATUS_KEY)); - + // Note that this is about the only place that Perforce sends // an actual formatted date string back; everywhere else it's // a long; here it's in the yyyy/mm/dd hh:mm:ss format -- HR. - + String dateStr = (String) map.get(MapKeys.DATE_KEY); if (dateStr == null) { this.date = new Date(); @@ -163,7 +184,7 @@ public ChangelistSummary(Map map, boolean summaryOnly, IServer s + pe.getLocalizedMessage()); } } - + this.description = (String) map.get(MapKeys.DESCRIPTION_KEY); if (map.containsKey("Type")) { this.visibility = Visibility.fromString(((String) map.get("Type")).toUpperCase()); @@ -281,7 +302,9 @@ public void setShelved(boolean shelved) { /** * @see com.perforce.p4java.core.IChangelistSummary#getVisibility() */ - public Visibility getVisibility() { return visibility; } + public Visibility getVisibility() { + return visibility; + } /** * @see com.perforce.p4java.core.IChangelistSummary#setVisibility(com.perforce.p4java.core.IChangelistSummary.Visibility) @@ -291,9 +314,11 @@ public void setVisibility(Visibility visibility) { } /** - // * @see com.perforce.p4java.core.IChangelistSummary#getChangelistStream() + // * @see com.perforce.p4java.core.IChangelistSummary#getChangelistStream() */ - public String getChangelistStream() { return changelistStream; } + public String getChangelistStream() { + return changelistStream; + } } diff --git a/src/main/java/com/perforce/p4java/impl/generic/core/DefaultParallelSync.java b/src/main/java/com/perforce/p4java/impl/generic/core/DefaultParallelSync.java index c6a91e6..42ca085 100644 --- a/src/main/java/com/perforce/p4java/impl/generic/core/DefaultParallelSync.java +++ b/src/main/java/com/perforce/p4java/impl/generic/core/DefaultParallelSync.java @@ -30,11 +30,11 @@ public DefaultParallelSync() { *

* Invocation of this method spawns the threads required to support parallelism * - * @param cmdEnv - * @param threads - * @param flags - * @param args - * @return + * @param cmdEnv command env + * @param threads threads + * @param flags flags + * @param args arguments + * @return true if no error */ @Override public boolean transmit(CommandEnv cmdEnv, int threads, HashMap flags, ArrayList args) { @@ -56,14 +56,14 @@ public boolean transmit(CommandEnv cmdEnv, int threads, HashMap /** * Helper method which creates a Runnable that performs the sync * - * @param cmdEnv - * @param thread - * @param flags - * @param args - * @return + * @param cmdEnv command env + * @param thread (not used) + * @param flags (not used) + * @param args list arguments + * @return runnable thread */ private Runnable createRunnable(final CommandEnv cmdEnv, int thread, - HashMap flags, final List args) { + HashMap flags, final List args) { class RunnableSync implements Runnable { @Override @@ -104,10 +104,10 @@ public void run() { } /** - * Handles results on a per thread basis + * Handles results on a per-thread basis * - * @param results - * @param cmdEnv + * @param results results map + * @param cmdEnv command environment */ private synchronized void handleResults(Map[] results, CommandEnv cmdEnv) { if (results != null) { diff --git a/src/main/java/com/perforce/p4java/impl/generic/core/Extension.java b/src/main/java/com/perforce/p4java/impl/generic/core/Extension.java index d4f325e..3c378a3 100644 --- a/src/main/java/com/perforce/p4java/impl/generic/core/Extension.java +++ b/src/main/java/com/perforce/p4java/impl/generic/core/Extension.java @@ -9,6 +9,7 @@ import java.util.List; import java.util.Map; import java.util.StringTokenizer; +import java.util.stream.Collectors; public class Extension extends ExtensionSummary implements IExtension { /** @@ -78,8 +79,9 @@ public Extension(Map map) { } Object extAllowedGroups = map.get(MapKeys.EXTENSION_GROUPS_KEY); - if (extAllowedGroups != null) { - this.extAllowedGroups = (List) extAllowedGroups; + if (extAllowedGroups instanceof List) { + List unknown = (List) extAllowedGroups; + this.extAllowedGroups = unknown.stream().map(String::valueOf).collect(Collectors.toList()); } this.extP4USER = (String) map.get(MapKeys.EXTENSION_P4USER_KEY); diff --git a/src/main/java/com/perforce/p4java/impl/generic/core/FileLineMatch.java b/src/main/java/com/perforce/p4java/impl/generic/core/FileLineMatch.java index 887b90e..817eb5f 100644 --- a/src/main/java/com/perforce/p4java/impl/generic/core/FileLineMatch.java +++ b/src/main/java/com/perforce/p4java/impl/generic/core/FileLineMatch.java @@ -20,64 +20,72 @@ * Implementation class of the {@link IFileLineMatch} interface */ public class FileLineMatch implements IFileLineMatch { - protected String file = null; - protected int revision = -1; - protected int lineNumber = -1; - protected String line = null; - protected MatchType type = MatchType.MATCH; + protected String file = null; + protected int revision = -1; + protected int lineNumber = -1; + protected String line = null; + protected MatchType type = MatchType.MATCH; - /** - * Explicit-value constructor; sets all fields to null or -1, type to MatchType.MATCH. - */ - public FileLineMatch(final String file, - final int revision, - final String line, - final MatchType type) { - this.file = file; - this.revision = revision; - this.line = line; - this.type = type; - } + /** + * Explicit-value constructor; sets all fields to null or -1, type to MatchType.MATCH. + * + * @param file file + * @param revision revision + * @param line line + * @param type type + */ + public FileLineMatch(final String file, + final int revision, + final String line, + final MatchType type) { + this.file = file; + this.revision = revision; + this.line = line; + this.type = type; + } - public FileLineMatch(Map map) { - if (nonNull(map)) { - file = parseString(map, DEPOT_FILE); - revision = FileSpec.getRevFromString(parseString(map, REV)); - if (nonNull(map.get("line"))) { - try { - lineNumber = parseInt(map, "line"); - } catch (NumberFormatException exc) { - Log.warn("NumberFormatException in FileLineMatch map-based constructor: %s", - exc.getLocalizedMessage()); - } - } - line = parseString(map, "matchedLine"); - type = MatchType.fromServerString(parseString(map, TYPE)); - } - } + /** + * @param map map + */ + public FileLineMatch(Map map) { + if (nonNull(map)) { + file = parseString(map, DEPOT_FILE); + revision = FileSpec.getRevFromString(parseString(map, REV)); + if (nonNull(map.get("line"))) { + try { + lineNumber = parseInt(map, "line"); + } catch (NumberFormatException exc) { + Log.warn("NumberFormatException in FileLineMatch map-based constructor: %s", + exc.getLocalizedMessage()); + } + } + line = parseString(map, "matchedLine"); + type = MatchType.fromServerString(parseString(map, TYPE)); + } + } - @Override - public String getDepotFile() { - return file; - } + @Override + public String getDepotFile() { + return file; + } - @Override - public String getLine() { - return line; - } + @Override + public String getLine() { + return line; + } - @Override - public int getRevision() { - return revision; - } + @Override + public int getRevision() { + return revision; + } - @Override - public int getLineNumber() { - return lineNumber; - } + @Override + public int getLineNumber() { + return lineNumber; + } - @Override - public MatchType getType() { - return type; - } + @Override + public MatchType getType() { + return type; + } } diff --git a/src/main/java/com/perforce/p4java/impl/generic/core/InputMapper.java b/src/main/java/com/perforce/p4java/impl/generic/core/InputMapper.java index dec9cf3..212c5ba 100644 --- a/src/main/java/com/perforce/p4java/impl/generic/core/InputMapper.java +++ b/src/main/java/com/perforce/p4java/impl/generic/core/InputMapper.java @@ -24,10 +24,7 @@ import com.perforce.p4java.core.IMapEntry; import com.perforce.p4java.core.IReviewSubscription; import com.perforce.p4java.core.IStream; -import com.perforce.p4java.core.IStreamIgnoredMapping; -import com.perforce.p4java.core.IStreamRemappedMapping; import com.perforce.p4java.core.IStreamSummary; -import com.perforce.p4java.core.IStreamViewMapping; import com.perforce.p4java.core.IUser; import com.perforce.p4java.core.IUserGroup; import com.perforce.p4java.core.ViewMap; @@ -76,7 +73,7 @@ private static Map> getDefaultMaps(IServer serve * Map a P4Java changelist to an IServer input map. * * @param change candidate changelist - * @param allowUnknownFiles + * @param allowUnknownFiles unknown files? * @return non-null map suitable for use with execMapCmd */ @@ -346,7 +343,7 @@ public static Map map(IUserGroup group) { groupMap.put(MapKeys.TIMEOUT_KEY, getUGValue(group.getTimeout())); groupMap.put(MapKeys.MAXSCANROWS_KEY, getUGValue(group.getMaxScanRows())); groupMap.put(MapKeys.MAXLOCKTIME_KEY, getUGValue(group.getMaxLockTime())); - if (group.getMaxOpenFiles() != -Integer.MAX_VALUE){ + if (group.getMaxOpenFiles() != -Integer.MAX_VALUE) { groupMap.put(MapKeys.MAXOPENFILES_KEY, getUGValue(group.getMaxOpenFiles())); } groupMap.put(MapKeys.PASSWORD_TIMEOUT_KEY, getUGValue(group.getPasswordTimeout())); @@ -490,9 +487,10 @@ public static Map map(IProtectionsTable protectionsTable) { * Map a P4Java stream object to an IServer input map. * * @param stream candidate stream + * @param server server * @return non-null map suitable for use with execMapCmd + * @throws P4JavaException on error */ - public static Map map(IStream stream, IServer server) throws P4JavaException { Map streamMap = new HashMap(); if (stream == null) { @@ -539,7 +537,6 @@ public static Map map(IStream stream, IServer server) throws P4J * @param triggersTable table - list of trigger entries * @return non-null map suitable for use with execMapCmd */ - public static Map map(ITriggersTable triggersTable) { Map triggersMap = new HashMap(); diff --git a/src/main/java/com/perforce/p4java/impl/generic/core/Job.java b/src/main/java/com/perforce/p4java/impl/generic/core/Job.java index 829b13b..e8968d0 100644 --- a/src/main/java/com/perforce/p4java/impl/generic/core/Job.java +++ b/src/main/java/com/perforce/p4java/impl/generic/core/Job.java @@ -3,12 +3,6 @@ */ package com.perforce.p4java.impl.generic.core; -import static org.apache.commons.lang3.StringUtils.isBlank; -import static org.apache.commons.lang3.StringUtils.isNotBlank; - -import java.util.HashMap; -import java.util.Map; - import com.perforce.p4java.core.IJob; import com.perforce.p4java.core.IJobSpec; import com.perforce.p4java.exception.AccessException; @@ -17,176 +11,182 @@ import com.perforce.p4java.server.IServer; import org.apache.commons.lang3.Validate; +import java.util.Map; + +import static org.apache.commons.lang3.StringUtils.isBlank; +import static org.apache.commons.lang3.StringUtils.isNotBlank; + /** * Simple generic default implementation class for the IJob interface. */ public class Job extends ServerResource implements IJob { - /** - * The max description length for "short" or summary descriptions - */ - public static int SHORT_DESCR_LENGTH = 128; - - /* it's read only */ - private String jobName = null; - //private Map rawFields = new HashMap<>(6); - private String description = null; - private IJobSpec jobSpec = null; - private static final String[] DESCRIPTION_FIELD_IDS = {"Description", "description", "Desc"}; - private static final String[] JOB_ID_FIELD_IDS = {"Job", "job", "JobId"}; - - /** - * Simple factory method for creating a new Job class. - * - * @param server non-null IServer to be associated with this job. - * @param map non-null fields map for the job to be created. - * @return new Job object - */ - public static Job newJob(IServer server, Map map) { - Validate.notNull(server, "null server passed to Job.newJob()"); - Validate.notNull(map, "null map passed to Job.newJob()"); - return new Job(server, map); - } - - public Job(IServer server, Map map) { - this(server, map, false); - } - - public Job(IServer server, Map map, boolean longDescriptions) { - super(true, true); - this.server = server; - - // Now try to retrieve a handful of "standard" fields - // if we can... - if (map != null) { - jobName = getJobIdString(map); - description = getDescriptionString(map, longDescriptions); - - // Remove the 'specFormatted' field. - // See job072366 for more detail. - map.remove("specFormatted"); - // Assign the raw fields + /** + * The max description length for "short" or summary descriptions + */ + public static int SHORT_DESCR_LENGTH = 128; + + /* it's read only */ + private String jobName = null; + //private Map rawFields = new HashMap<>(6); + private String description = null; + private IJobSpec jobSpec = null; + private static final String[] DESCRIPTION_FIELD_IDS = {"Description", "description", "Desc"}; + private static final String[] JOB_ID_FIELD_IDS = {"Job", "job", "JobId"}; + + /** + * Simple factory method for creating a new Job class. + * + * @param server non-null IServer to be associated with this job. + * @param map non-null fields map for the job to be created. + * @return new Job object + */ + public static Job newJob(IServer server, Map map) { + Validate.notNull(server, "null server passed to Job.newJob()"); + Validate.notNull(map, "null map passed to Job.newJob()"); + return new Job(server, map); + } + + public Job(IServer server, Map map) { + this(server, map, false); + } + + public Job(IServer server, Map map, boolean longDescriptions) { + super(true, true); + this.server = server; + + // Now try to retrieve a handful of "standard" fields + // if we can... + if (map != null) { + jobName = getJobIdString(map); + description = getDescriptionString(map, longDescriptions); + + // Remove the 'specFormatted' field. + // See job072366 for more detail. + map.remove("specFormatted"); + // Assign the raw fields setRawFields(map); - } - } - - /** - * This method will refresh by getting the complete job model. If this - * refresh is successful then this job will be marked as complete. - */ - @Override - public void refresh() throws ConnectionException, RequestException, AccessException { - IServer refreshServer = server; - String refreshId = jobName; - if (refreshServer != null && refreshId != null) { - IJob refreshedJob = refreshServer.getJob(refreshId); - if (refreshedJob != null) { - description = refreshedJob.getDescription(); - if (refreshedJob.getRawFields() != null) { + } + } + + /** + * This method will refresh by getting the complete job model. If this + * refresh is successful then this job will be marked as complete. + */ + @Override + public void refresh() throws ConnectionException, RequestException, AccessException { + IServer refreshServer = server; + String refreshId = jobName; + if (refreshServer != null && refreshId != null) { + IJob refreshedJob = refreshServer.getJob(refreshId); + if (refreshedJob != null) { + description = refreshedJob.getDescription(); + if (refreshedJob.getRawFields() != null) { setRawFields(refreshedJob.getRawFields()); - } else { + } else { clearRawFields(); - } - } - } - } - - /** - *

- * NOTE: do not use this method if the server field has not been set. - */ - @Override - public String updateOnServer() - throws ConnectionException, RequestException, AccessException { - - Validate.notNull(server, "Null server field in Job.updateOnServer"); - return server.updateJob(this); - } - - @Override - public void update() throws ConnectionException, RequestException, AccessException { - server.updateJob(this); - } - - public String getDescription() { - return description; - } - - /** - * get job name - * - * @return - */ - public String getId() { - return jobName; - } - - public IJobSpec getJobSpec() { - return jobSpec; - } - - /** - * Set job name - * @param id job name - */ - public void setId(String id) { - this.jobName = id; - //addOrUpdateRawFieldValue(JOB_ID_FIELD_IDS, id); - } - - public void setDescription(String description) { - this.description = description; - addOrUpdateRawFieldValue(DESCRIPTION_FIELD_IDS, description); - } - - private void addOrUpdateRawFieldValue(String[] possibleKeys, Object value) { - boolean isPresent = false; - for (String possibleKey : possibleKeys) { - if (hasRawField(possibleKey)) { + } + } + } + } + + /** + * @deprecated use update() instead. + */ + @Deprecated + @Override + public String updateOnServer() + throws ConnectionException, RequestException, AccessException { + + Validate.notNull(server, "Null server field in Job.updateOnServer"); + return server.updateJob(this); + } + + @Override + public void update() throws ConnectionException, RequestException, AccessException { + server.updateJob(this); + } + + public String getDescription() { + return description; + } + + /** + * get job name + * + * @return id + */ + public String getId() { + return jobName; + } + + public IJobSpec getJobSpec() { + return jobSpec; + } + + /** + * Set job name + * + * @param id job name + */ + public void setId(String id) { + this.jobName = id; + //addOrUpdateRawFieldValue(JOB_ID_FIELD_IDS, id); + } + + public void setDescription(String description) { + this.description = description; + addOrUpdateRawFieldValue(DESCRIPTION_FIELD_IDS, description); + } + + private void addOrUpdateRawFieldValue(String[] possibleKeys, Object value) { + boolean isPresent = false; + for (String possibleKey : possibleKeys) { + if (hasRawField(possibleKey)) { setRawField(possibleKey, value); - isPresent = true; - break; - } - } + isPresent = true; + break; + } + } - if (!isPresent) { - String firstKey = possibleKeys[0]; + if (!isPresent) { + String firstKey = possibleKeys[0]; setRawField(firstKey, value); - } - } - - public void setJobSpec(IJobSpec jobSpec) { - this.jobSpec = jobSpec; - } - - protected String getJobIdString(Map map) { - String candidate = (String) map.get(JOB_ID_FIELD_IDS[0]); - - if (isBlank(candidate)) { - candidate = (String) map.get(JOB_ID_FIELD_IDS[1]); - if (isBlank(candidate)) { - candidate = (String) map.get(JOB_ID_FIELD_IDS[2]); - } - } - - return candidate; - } - - protected String getDescriptionString(Map map, boolean longDescriptions) { - String candidate = (String) map.get(DESCRIPTION_FIELD_IDS[0]); - - if (isBlank(candidate)) { - candidate = (String) map.get(DESCRIPTION_FIELD_IDS[1]); - if (isBlank(candidate)) { - candidate = (String) map.get(DESCRIPTION_FIELD_IDS[2]); - } - } - - if (isNotBlank(candidate) - && !longDescriptions - && (candidate.length() > SHORT_DESCR_LENGTH)) { - return candidate.substring(0, SHORT_DESCR_LENGTH - 1); - } - return candidate; - } + } + } + + public void setJobSpec(IJobSpec jobSpec) { + this.jobSpec = jobSpec; + } + + protected String getJobIdString(Map map) { + String candidate = (String) map.get(JOB_ID_FIELD_IDS[0]); + + if (isBlank(candidate)) { + candidate = (String) map.get(JOB_ID_FIELD_IDS[1]); + if (isBlank(candidate)) { + candidate = (String) map.get(JOB_ID_FIELD_IDS[2]); + } + } + + return candidate; + } + + protected String getDescriptionString(Map map, boolean longDescriptions) { + String candidate = (String) map.get(DESCRIPTION_FIELD_IDS[0]); + + if (isBlank(candidate)) { + candidate = (String) map.get(DESCRIPTION_FIELD_IDS[1]); + if (isBlank(candidate)) { + candidate = (String) map.get(DESCRIPTION_FIELD_IDS[2]); + } + } + + if (isNotBlank(candidate) + && !longDescriptions + && (candidate.length() > SHORT_DESCR_LENGTH)) { + return candidate.substring(0, SHORT_DESCR_LENGTH - 1); + } + return candidate; + } } diff --git a/src/main/java/com/perforce/p4java/impl/generic/core/Label.java b/src/main/java/com/perforce/p4java/impl/generic/core/Label.java index d776fbe..f55c588 100644 --- a/src/main/java/com/perforce/p4java/impl/generic/core/Label.java +++ b/src/main/java/com/perforce/p4java/impl/generic/core/Label.java @@ -113,6 +113,9 @@ public LabelMapping() { * Explicit value constructor -- calls super(order, labelMapping). * Note that this probably won't do what you expect it to if * there's more than one element in the subscription. + * + * @param order order + * @param labelMapping mapping */ public LabelMapping(int order, String labelMapping) { super(order, labelMapping); @@ -146,8 +149,16 @@ public Label() { /** * Explicit-value constructor. Generally useful for constructing new * label implementations. + * + * @param name name + * @param ownerName owner + * @param lastAccess date + * @param lastUpdate date + * @param description description + * @param revisionSpec revision + * @param locked locked + * @param viewMapping view mapping */ - public Label(String name, String ownerName, Date lastAccess, Date lastUpdate, String description, String revisionSpec, boolean locked, ViewMap viewMapping) { @@ -166,11 +177,13 @@ public Label(String name, String ownerName, Date lastAccess, * Construct a new Label from the map passed back from the * IServer's getLabel method or from a similar map, and the current * server object (if any). Will not work properly with the map returned - * from the server getLabelSummaryList method.

+ * from the server getLabelSummaryList method. *

* If the map is null, this is equivalent to calling the default constructor. + * + * @param map spec map + * @param server server */ - public Label(Map map, IServer server) { super(false); @@ -245,15 +258,17 @@ public Label(Map map, IServer server) { /** * Given an ILabelSummary object, construct a new Label object from it. This * implementation simply gets the label on the Perforce server with the same - * name as the labelSummary's name by using the Label.refresh() object.

+ * name as the labelSummary's name by using the Label.refresh() object. *

* If labelSummary is null this is equivalent to calling the default constructor; * otherwise all LabelSummary fields are copied, and if labelSummary.getName() is * not null, the refresh() is performed. * * @param labelSummary possibly-null ILabelSummary object. + * @throws ConnectionException on error + * @throws RequestException on error + * @throws AccessException on error */ - public Label(ILabelSummary labelSummary) throws ConnectionException, RequestException, AccessException { super(false); @@ -299,7 +314,9 @@ public void refresh() throws ConnectionException, RequestException, /** * @see com.perforce.p4java.core.ILabel#updateOnServer() + * @deprecated use update() instead. */ + @Deprecated public String updateOnServer() throws ConnectionException, RequestException, AccessException { diff --git a/src/main/java/com/perforce/p4java/impl/generic/core/LabelSummary.java b/src/main/java/com/perforce/p4java/impl/generic/core/LabelSummary.java index 7c30fe2..c52934a 100644 --- a/src/main/java/com/perforce/p4java/impl/generic/core/LabelSummary.java +++ b/src/main/java/com/perforce/p4java/impl/generic/core/LabelSummary.java @@ -1,25 +1,25 @@ /** - * + * */ package com.perforce.p4java.impl.generic.core; -import java.util.Date; -import java.util.Map; - import com.perforce.p4java.Log; import com.perforce.p4java.core.ILabelSummary; import com.perforce.p4java.impl.mapbased.MapKeys; +import java.util.Date; +import java.util.Map; + /** * Default implementation of the ILabelSumamry interface. */ public class LabelSummary extends ServerResource implements ILabelSummary { - + protected static final String LOCKED_VALUE = "locked"; protected static final String UNLOCKED_VALUE = "unlocked"; protected static final String AUTORELOAD_VALUE = "autoreload"; protected static final String NOAUTORELOAD_VALUE = "noautoreload"; - + protected String name = null; protected String ownerName = null; protected Date lastAccess = null; @@ -29,33 +29,35 @@ public class LabelSummary extends ServerResource implements ILabelSummary { protected boolean locked = false; protected boolean unloaded = false; protected boolean autoreload = false; - + /** * Default constructor -- set all fields to null or false. */ public LabelSummary() { super(false, false); } - - + + /** * Construct an empty LabelSummary and appropriately initialize * the ServerResource superclass fields according to whether this * summary a summary only or part of the full Label class. + * @param summaryOnly summary only */ public LabelSummary(boolean summaryOnly) { super(!summaryOnly, !summaryOnly); } - + /** * Construct a LabelSummary from a map returned from the Perforce server's * getLabelSummaryList.

- * + * * If the map is null, this is equivalent to calling the default constructor. + * @param map spec map */ public LabelSummary(Map map) { super(false, false); - + if (map != null) { try { this.name = (String) map.get(MapKeys.LABEL_LC_KEY); @@ -93,7 +95,7 @@ public LabelSummary(Map map) { } } catch (Throwable thr) { Log.error("Unexpected exception in LabelSummary constructor: " - + thr.getLocalizedMessage()); + + thr.getLocalizedMessage()); Log.exception(thr); } } diff --git a/src/main/java/com/perforce/p4java/impl/generic/core/MapEntry.java b/src/main/java/com/perforce/p4java/impl/generic/core/MapEntry.java index 0f68f29..24cf2f8 100644 --- a/src/main/java/com/perforce/p4java/impl/generic/core/MapEntry.java +++ b/src/main/java/com/perforce/p4java/impl/generic/core/MapEntry.java @@ -35,6 +35,10 @@ public MapEntry() { * Construct a suitable MapEntry from the passed-in arguments, inferring * the entry type from any suitable prefixes on the passed-in left string. * Left and right strings have any type prefixes stripped from them. + * + * @param order order + * @param left left mapping + * @param right right mapping */ public MapEntry(int order, String left, String right) { this.order = order; @@ -52,6 +56,11 @@ public MapEntry(int order, String left, String right) { /** * Explicit-value constructor. Left and right strings have any type * prefixes stripped from them before being assigned to the new entry. + * + * @param order order + * @param type type + * @param left left mapping + * @param right right mapping */ public MapEntry(int order, EntryType type, String left, String right) { this.order = order; @@ -72,6 +81,9 @@ public MapEntry(int order, EntryType type, String left, String right) { * is in the format specified by parseViewString (below). If the passed-in string * is null, only the order field is set; the other fields are set to null or * ORDER_UNKNOWN. + * + * @param order order + * @param mappingStr mapping */ public MapEntry(int order, String mappingStr) { this.order = order; @@ -87,6 +99,8 @@ public MapEntry(int order, String mappingStr) { /** * Copy constructor. Constructs a new MapEntry from the passed-in version. * If entry is null, this is equivalent to calling the default constructor. + * + * @param entry map entry */ public MapEntry(IMapEntry entry) { if (entry != null) { @@ -254,6 +268,9 @@ public String toString() { * Strip any Perforce entry type prefix from the passed-in string. If the * string is null, this returns null; if there's no such prefix, the original * string is returned. + * + * @param str prefix + * @return formatted string */ public static String stripTypePrefix(final String str) { if (str == null) { diff --git a/src/main/java/com/perforce/p4java/impl/generic/core/ReviewSubscription.java b/src/main/java/com/perforce/p4java/impl/generic/core/ReviewSubscription.java index 063e010..c387332 100644 --- a/src/main/java/com/perforce/p4java/impl/generic/core/ReviewSubscription.java +++ b/src/main/java/com/perforce/p4java/impl/generic/core/ReviewSubscription.java @@ -21,6 +21,9 @@ public ReviewSubscription() { * Explicit value constructor -- calls super(order, subscription). * Note that this probably won't do what you expect it to if * there's more than one element in the subscription. + * + * @param order order + * @param subscription subscription */ public ReviewSubscription(int order, String subscription) { super(order, subscription); diff --git a/src/main/java/com/perforce/p4java/impl/generic/core/ServerResource.java b/src/main/java/com/perforce/p4java/impl/generic/core/ServerResource.java index da674a2..7d837e9 100644 --- a/src/main/java/com/perforce/p4java/impl/generic/core/ServerResource.java +++ b/src/main/java/com/perforce/p4java/impl/generic/core/ServerResource.java @@ -19,7 +19,7 @@ import java.util.Map; /** - * Abstract implementation class for the IServerResource interface.

+ * Abstract implementation class for the IServerResource interface. *

* Implementations of interfaces that extend IServerResource should * use this as a superclass unless there are good reasons not to. @@ -57,6 +57,8 @@ protected ServerResource() { /** * Sets complete to true, completable, refreshable, and * updateable to false, and server to the passed-in value. + * + * @param server server */ protected ServerResource(IServer server) { this.server = server; @@ -64,6 +66,9 @@ protected ServerResource(IServer server) { /** * Explicit some-value constructor; sets server to null. + * + * @param refreshable refreshable + * @param updateable updateable */ protected ServerResource(boolean refreshable, boolean updateable) { this(refreshable, updateable, null); @@ -71,6 +76,10 @@ protected ServerResource(boolean refreshable, boolean updateable) { /** * Explicit all-value constructor. + * + * @param refreshable refreshable + * @param updateable updateable + * @param server server */ protected ServerResource( boolean refreshable, boolean updateable, IServer server) { @@ -132,7 +141,7 @@ public void update(Options opts) throws ConnectionException, RequestException, A /** * Set the resource as refreshable * - * @param refreshable + * @param refreshable true if refreshable */ public void setRefreshable(boolean refreshable) { this.refreshable = refreshable; @@ -216,5 +225,5 @@ protected String parseComment(String line){ } */ - + } diff --git a/src/main/java/com/perforce/p4java/impl/generic/core/Stream.java b/src/main/java/com/perforce/p4java/impl/generic/core/Stream.java index d8e4be1..78d1124 100644 --- a/src/main/java/com/perforce/p4java/impl/generic/core/Stream.java +++ b/src/main/java/com/perforce/p4java/impl/generic/core/Stream.java @@ -64,6 +64,10 @@ public ExtraTag() { /** * Explicit-value constructor. + * + * @param name name + * @param type type + * @param value value */ public ExtraTag(String name, String type, String value) { if (name == null) { @@ -81,26 +85,44 @@ public ExtraTag(String name, String type, String value) { this.value = value; } + /** + * @return name + */ public String getName() { return this.name; } + /** + * @param name name + */ public void setName(String name) { this.name = name; } + /** + * @return type + */ public String getType() { return this.type; } + /** + * @param type type + */ public void setType(String type) { this.type = type; } + /** + * @return value + */ public String getValue() { return this.value; } + /** + * @param value value + */ public void setValue(String value) { this.value = value; } @@ -109,6 +131,18 @@ public void setValue(String value) { /** * Simple factory / convenience method for creating a new local Stream * object with defult values. + * + * @param server server + * @param streamPath stream path + * @param type type + * @param parentStreamPath parent stream + * @param name name + * @param description description + * @param options options + * @param viewPaths view paths + * @param remappedPaths remapped paths + * @param ignoredPaths ignored paths + * @return stream object */ public static Stream newStream(IOptionsServer server, String streamPath, String type, String parentStreamPath, String name, @@ -139,11 +173,10 @@ public static Stream newStream(IOptionsServer server, String streamPath, * @param options flags to configure stream behavior: allsubmit/ownersubmit * [un]locked [no]toparent [no]fromparent mergedown/mergeany. * @param viewPaths one or more lines that define file paths in the stream view. - * Each line is of the form: - * [] + * Each line is of the form: path_type view_path depot_path * @param remappedPaths optional; one or more lines that define how stream view paths * are to be remapped in client views. Each line is of the form: - * + * view_path_1 view_path_2 * @param ignoredPaths optional; a list of file or directory names to be ignored in * client views. For example: * /tmp # ignores files named 'tmp' @@ -273,6 +306,11 @@ public StreamViewMapping() { /** * Explicit value constructor -- calls super(order, target, targetSpec). + * + * @param order order + * @param pathType path type + * @param viewPath view path + * @param depotPath depot path */ public StreamViewMapping(int order, PathType pathType, String viewPath, String depotPath) { @@ -286,6 +324,9 @@ public StreamViewMapping(int order, PathType pathType, String viewPath, /** * Construct a mapping from the passed-in string, which is assumed to be * in the format. + * + * @param order order + * @param rawViewString raw view string */ public StreamViewMapping(int order, String rawViewString) { this.order = order; @@ -350,7 +391,7 @@ public void setDepotPath(String depotPath) { @Override public String toString(String sepString, boolean quoteBlanks) { - String returnedString = super.toString(sepString, quoteBlanks); + String returnedString = super.toString(sepString, quoteBlanks); if (this.getPathType() != null) { return this.getPathType().getValue() + " " + returnedString; } @@ -374,6 +415,10 @@ public StreamRemappedMapping() { /** * Explicit value constructor -- calls super(order, target, targetSpec). + * + * @param order order + * @param leftRemapPath left remapped path + * @param rightRemapPath right remapped path */ public StreamRemappedMapping(int order, String leftRemapPath, String rightRemapPath) { @@ -383,6 +428,9 @@ public StreamRemappedMapping(int order, String leftRemapPath, /** * Construct a mapping from the passed-in string, which is assumed to be * in the format described in MapEntry.parseViewString(String). + * + * @param order order + * @param viewString view string */ public StreamRemappedMapping(int order, String viewString) { super(order, viewString); @@ -434,6 +482,9 @@ public StreamIgnoredMapping() { /** * Explicit value constructor -- calls super(order, target, targetSpec). + * + * @param order order + * @param ignorePath ignore path */ public StreamIgnoredMapping(int order, String ignorePath) { super(order, ignorePath, null); @@ -463,6 +514,19 @@ public Stream() { /** * Construct a new Stream from explicit field values. + * + * @param stream stream + * @param type type + * @param parent parent + * @param accessed accessed + * @param updated updated + * @param name name + * @param description description + * @param ownerName ownerName + * @param options options + * @param streamView streamView + * @param remappedView remappedView + * @param ignoredView ignoredView */ public Stream(String stream, Type type, String parent, Date accessed, Date updated, String name, String description, String ownerName, @@ -476,6 +540,20 @@ public Stream(String stream, Type type, String parent, Date accessed, /** * Construct a new Stream from explicit field values. + * + * @param stream stream + * @param type type + * @param parent parent + * @param accessed accessed + * @param updated updated + * @param name name + * @param description description + * @param ownerName ownerName + * @param options options + * @param streamView streamView + * @param remappedView remappedView + * @param ignoredView ignoredView + * @param clientView clientView */ public Stream(String stream, Type type, String parent, Date accessed, Date updated, String name, String description, String ownerName, @@ -502,6 +580,9 @@ public Stream(String stream, Type type, String parent, Date accessed, /** * Construct a Stream from a map passed back from the Perforce server in * response to a getStream command. + * + * @param map spec map + * @param server server */ public Stream(Map map, IServer server) { super(map, false); @@ -579,7 +660,7 @@ public Stream(Map map, IServer server) { remappedMap.setLeft(matchStrs[0]); remappedMap.setRight(matchStrs[1]); } - }catch (Throwable thr) { + } catch (Throwable thr) { Log.error("Unexpected exception in Stream map-based constructor: " + thr.getLocalizedMessage()); Log.exception(thr); @@ -611,7 +692,7 @@ public Stream(Map map, IServer server) { ignoreMap.setOrder(i); ignoreMap.setLeft(matchStrs[0]); } - }catch (Throwable thr) { + } catch (Throwable thr) { Log.error("Unexpected exception in Stream map-based constructor: " + thr.getLocalizedMessage()); Log.exception(thr); @@ -663,6 +744,7 @@ public Stream(Map map, IServer server) { * constructor; otherwise after name initialization a refresh() is done on * the new (empty) Stream. * + * @param summary summary class * @throws ConnectionException if the Perforce server is unreachable or is not connected. * @throws RequestException if the Perforce server encounters an error during its * processing of the request @@ -698,7 +780,7 @@ public void refresh() throws ConnectionException, RequestException, AccessExcept try { IStream refreshedStream = refreshServer.getStream(refreshStreamPath); if (refreshedStream != null) { - if(refreshedStream.getRawFields() != null) { + if (refreshedStream.getRawFields() != null) { setRawFields(refreshedStream.getRawFields()); } else { clearRawFields(); diff --git a/src/main/java/com/perforce/p4java/impl/generic/core/StreamIntegrationStatus.java b/src/main/java/com/perforce/p4java/impl/generic/core/StreamIntegrationStatus.java index 27371b3..a85f41d 100644 --- a/src/main/java/com/perforce/p4java/impl/generic/core/StreamIntegrationStatus.java +++ b/src/main/java/com/perforce/p4java/impl/generic/core/StreamIntegrationStatus.java @@ -3,16 +3,16 @@ */ package com.perforce.p4java.impl.generic.core; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - import com.perforce.p4java.Log; import com.perforce.p4java.core.IChangelist; import com.perforce.p4java.core.IStreamIntegrationStatus; import com.perforce.p4java.core.IStreamSummary; import com.perforce.p4java.core.IStreamSummary.Type; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + /** * Default implementation class for the IStreamIntegrationStatus interface. */ @@ -49,9 +49,17 @@ public static class CachedState implements ICachedState { /** * Explicit-value all-fields constructor. + * + * @param change change + * @param parentChange parentChange + * @param copyParent copyParent + * @param mergeParent mergeParent + * @param mergeHighVal mergeHighVal + * @param branchHash branchHash + * @param status status */ public CachedState(int change, int parentChange, int copyParent, - int mergeParent, int mergeHighVal, int branchHash, int status) { + int mergeParent, int mergeHighVal, int branchHash, int status) { this.change = change; this.parentChange = parentChange; @@ -121,14 +129,29 @@ public int getStatus() { /** * Explicit-value all-fields constructor. + * + * @param stream stream + * @param parent parent + * @param type type + * @param parentType parentType + * @param firmerThanParent firmerThanParent + * @param changeFlowsToParent changeFlowsToParent + * @param changeFlowsFromParent changeFlowsFromParent + * @param integToParent integToParent + * @param integToParentHow integToParentHow + * @param toResult toResult + * @param integFromParent integFromParent + * @param integFromParentHow integFromParentHow + * @param fromResult fromResult + * @param cachedStates cachedStates */ public StreamIntegrationStatus(String stream, String parent, - IStreamSummary.Type type, IStreamSummary.Type parentType, - boolean firmerThanParent, boolean changeFlowsToParent, - boolean changeFlowsFromParent, boolean integToParent, - String integToParentHow, String toResult, boolean integFromParent, - String integFromParentHow, String fromResult, - List cachedStates) { + IStreamSummary.Type type, IStreamSummary.Type parentType, + boolean firmerThanParent, boolean changeFlowsToParent, + boolean changeFlowsFromParent, boolean integToParent, + String integToParentHow, String toResult, boolean integFromParent, + String integFromParentHow, String fromResult, + List cachedStates) { this.stream = stream; this.parent = parent; this.type = type; @@ -147,6 +170,8 @@ public StreamIntegrationStatus(String stream, String parent, /** * Constructor for use with maps passed back from the Perforce server only. + * + * @param map spec map */ public StreamIntegrationStatus(Map map) { if (map != null) { diff --git a/src/main/java/com/perforce/p4java/impl/generic/core/StreamSummary.java b/src/main/java/com/perforce/p4java/impl/generic/core/StreamSummary.java index 5663d8b..d3402fc 100644 --- a/src/main/java/com/perforce/p4java/impl/generic/core/StreamSummary.java +++ b/src/main/java/com/perforce/p4java/impl/generic/core/StreamSummary.java @@ -33,6 +33,11 @@ public Options() { /** * Explicit-value constructor. + * + * @param ownerSubmit ownerSubmit + * @param locked locked + * @param noToParent noToParent + * @param noFromParent noFromParent */ public Options(boolean ownerSubmit, boolean locked, boolean noToParent, boolean noFromParent) { this(ownerSubmit, locked, noToParent, noFromParent, false); @@ -40,6 +45,12 @@ public Options(boolean ownerSubmit, boolean locked, boolean noToParent, boolean /** * Explicit-value constructor. + * + * @param ownerSubmit ownerSubmit + * @param locked locked + * @param noToParent noToParent + * @param noFromParent noFromParent + * @param mergeAny mergeAny */ public Options(boolean ownerSubmit, boolean locked, boolean noToParent, boolean noFromParent, boolean mergeAny) { setOwnerSubmit(ownerSubmit); @@ -55,6 +66,8 @@ public Options(boolean ownerSubmit, boolean locked, boolean noToParent, boolean * "allsubmit/ownersubmit, [un]locked, [no]toparent, [no]fromparent". If * optionsString is null, this is equivalent to calling the default * constructor. + * + * @param optionsString options */ public Options(String optionsString) { if (optionsString == null) { @@ -82,49 +95,75 @@ public Options(String optionsString) { * optionsString) constructor. */ public String toString() { - return (isOwnerSubmit() ? "ownersubmit" : "allsubmit") - + (isLocked() ? " locked" : " unlocked") - + (isNoToParent() ? " notoparent" : " toparent") - + (isNoFromParent() ? " nofromparent" : " fromparent") - + (isMergeAny() ? " mergeany" : " mergedown"); + return (isOwnerSubmit() ? "ownersubmit" : "allsubmit") + (isLocked() ? " locked" : " unlocked") + (isNoToParent() ? " notoparent" : " toparent") + (isNoFromParent() ? " nofromparent" : " fromparent") + (isMergeAny() ? " mergeany" : " mergedown"); } + /** + * @return owner if true + */ public boolean isOwnerSubmit() { return ownerSubmit; } + /** + * @param ownerSubmit owner if true + */ public void setOwnerSubmit(boolean ownerSubmit) { this.ownerSubmit = ownerSubmit; } + /** + * @return if true + */ public boolean isLocked() { return locked; } + /** + * @param locked if true + */ public void setLocked(boolean locked) { this.locked = locked; } + /** + * @return if true + */ public boolean isNoToParent() { return noToParent; } + /** + * @param noToParent if true + */ public void setNoToParent(boolean noToParent) { this.noToParent = noToParent; } + /** + * @return if true + */ public boolean isNoFromParent() { return noFromParent; } + /** + * @param noFromParent if true + */ public void setNoFromParent(boolean noFromParent) { this.noFromParent = noFromParent; } + /** + * @return if true + */ public boolean isMergeAny() { return mergeAny; } + /** + * @param mergeAny if true + */ public void setMergeAny(boolean mergeAny) { this.mergeAny = mergeAny; } @@ -142,6 +181,7 @@ public StreamSummary() { * Default constructor; same as no-argument default constructor, except that * it sets the ServerResource superclass fields appropriately for summary * only (everything false) or full stream spec (updateable and refreshable). + * @param summaryOnly if true */ public StreamSummary(boolean summaryOnly) { super(!summaryOnly, !summaryOnly); @@ -151,10 +191,19 @@ public StreamSummary(boolean summaryOnly) { * Explicit-value constructor. If summaryOnly is true, refreshable and * updeateable are set true in the ServerResource superclass, otherwise * they're set false. - */ - public StreamSummary(boolean summaryOnly, String stream, Date accessed, - Date updated, String name, String ownerName, String description, - String parent, Type type, Options options) { + * + * @param summaryOnly summaryOnly + * @param stream stream + * @param accessed accessed + * @param updated updated + * @param name name + * @param ownerName ownerName + * @param description description + * @param parent parent + * @param type type + * @param options options + */ + public StreamSummary(boolean summaryOnly, String stream, Date accessed, Date updated, String name, String ownerName, String description, String parent, Type type, Options options) { super(!summaryOnly, !summaryOnly); setStream(stream); setAccessed(accessed); @@ -176,6 +225,8 @@ public StreamSummary(boolean summaryOnly, String stream, Date accessed, * * If map is null, this is equivalent to calling the default * summaryOnly-argument constructor. + * @param map spec map + * @param summaryOnly if true */ public StreamSummary(Map map, boolean summaryOnly) { super(!summaryOnly, !summaryOnly); diff --git a/src/main/java/com/perforce/p4java/impl/generic/core/Streamlog.java b/src/main/java/com/perforce/p4java/impl/generic/core/Streamlog.java index 6ec0ccf..e20284a 100644 --- a/src/main/java/com/perforce/p4java/impl/generic/core/Streamlog.java +++ b/src/main/java/com/perforce/p4java/impl/generic/core/Streamlog.java @@ -37,6 +37,9 @@ public Streamlog() { /** * Construct a Streamlog implementation, by parsing a map returned by the server. * Streamlog is a single change per Stream, sorted by order, to create array. + * + * @param map spec map + * @param order order */ public Streamlog(Map map, int order) { if (map == null) { diff --git a/src/main/java/com/perforce/p4java/impl/generic/core/User.java b/src/main/java/com/perforce/p4java/impl/generic/core/User.java index 09eb508..53fc2cf 100644 --- a/src/main/java/com/perforce/p4java/impl/generic/core/User.java +++ b/src/main/java/com/perforce/p4java/impl/generic/core/User.java @@ -3,9 +3,6 @@ */ package com.perforce.p4java.impl.generic.core; -import java.util.Date; -import java.util.Map; - import com.perforce.p4java.Log; import com.perforce.p4java.core.IReviewSubscription; import com.perforce.p4java.core.IUser; @@ -15,22 +12,25 @@ import com.perforce.p4java.exception.RequestException; import com.perforce.p4java.server.IServer; +import java.util.Date; +import java.util.Map; + /** * Simple default IUser implementation class. */ public class User extends UserSummary implements IUser { - + private String password = null; private String jobView = null; private ViewMap reviewSubscriptions = null; - + /** * Simple convenience factory method to create a new local User object * with default (null) jobView and reviewSubscriptions fields. - * - * @param name non-null user name. - * @param email user's email address. + * + * @param name non-null user name. + * @param email user's email address. * @param fullName user's full name. * @param password user's password (usually ignored). * @return new local user object. @@ -38,7 +38,7 @@ public class User extends UserSummary implements IUser { public static User newUser(String name, String email, String fullName, String password) { return new User(name, email, fullName, null, null, password, null, null); } - + /** * Default constructor -- sets all summary and extended * fields to null. @@ -48,25 +48,44 @@ public User() { /** * Explicit-value constructor. + * + * @param loginName loginName + * @param email email + * @param fullName fullName + * @param access access + * @param update update + * @param password password + * @param jobView jobView + * @param reviewSubscriptions reviewSubscriptions */ - + public User(String loginName, String email, String fullName, - Date access, Date update, String password, String jobView, - ViewMap reviewSubscriptions) { + Date access, Date update, String password, String jobView, + ViewMap reviewSubscriptions) { super(loginName, email, fullName, access, update); this.password = password; this.jobView = jobView; this.reviewSubscriptions = reviewSubscriptions; } - + /** * Explicit-value constructor. + * + * @param loginName loginName + * @param email email + * @param fullName fullName + * @param access access + * @param update update + * @param password password + * @param jobView jobView + * @param type type + * @param reviewSubscriptions reviewSubscriptions */ - + public User(String loginName, String email, String fullName, - Date access, Date update, String password, String jobView, - UserType type, - ViewMap reviewSubscriptions) { + Date access, Date update, String password, String jobView, + UserType type, + ViewMap reviewSubscriptions) { super(loginName, email, fullName, access, update, type); this.password = password; this.jobView = jobView; @@ -78,22 +97,25 @@ public User(String loginName, String email, String fullName, * is assumed to come from a suitable call on IServer; if * the map is null this is equivalent to calling the * default constructor. + * + * @param map spec map + * @param server server */ public User(Map map, IServer server) { super(map, false); this.server = server; if (map != null) { final String JOBVIEW_KEY = "JobView"; - final String PASSWORD_KEY = "Password"; // FIXME: check this... -- HR. + final String PASSWORD_KEY = "Password"; // FIXME: check this... -- HR. final String REVIEW_KEY_PFX = "Reviews"; // Only concerned about the Reviews*, JobView, and Password // keys here: - + try { this.jobView = (String) map.get(JOBVIEW_KEY); this.password = (String) map.get(PASSWORD_KEY); - + for (int i = 0; map.containsKey(REVIEW_KEY_PFX + i); i++) { if (this.reviewSubscriptions == null) { this.reviewSubscriptions = new ViewMap(); @@ -150,12 +172,12 @@ public ViewMap getReviewSubscriptions() { public void setReviewSubscriptions(ViewMap reviewSubscriptions) { this.reviewSubscriptions = reviewSubscriptions; } - + /** * @see com.perforce.p4java.impl.generic.core.ServerResource#refresh() */ public void refresh() throws ConnectionException, RequestException, - AccessException { + AccessException { IServer refreshServer = this.server; String refreshName = this.getLoginName(); if (refreshServer != null && refreshName != null) { @@ -172,15 +194,15 @@ public void refresh() throws ConnectionException, RequestException, } } } - + /** * @see com.perforce.p4java.impl.generic.core.ServerResource#update() */ public void update() - throws ConnectionException, RequestException, AccessException { + throws ConnectionException, RequestException, AccessException { this.server.updateUser(this, false); } - + public void update(boolean force) throws ConnectionException, RequestException, AccessException { this.server.updateUser(this, true); } diff --git a/src/main/java/com/perforce/p4java/impl/generic/core/UserGroup.java b/src/main/java/com/perforce/p4java/impl/generic/core/UserGroup.java index 359e53e..dac2c9e 100644 --- a/src/main/java/com/perforce/p4java/impl/generic/core/UserGroup.java +++ b/src/main/java/com/perforce/p4java/impl/generic/core/UserGroup.java @@ -26,207 +26,208 @@ */ public class UserGroup extends ServerResource implements IUserGroup { - /** - * How the Perforce server represents an unset group value as a string. - */ - private static final String UNSET_STR = "unset"; - - /** - * How the Perforce server represents an unlimited group value as a string. - */ - private static final String UNLIMITED_STR = "unlimited"; - - private String name = null; - private int maxResults = UNSET; - private int maxScanRows = UNSET; - /* TimeUnit: milliseconds */ - private int maxLockTime = UNSET; - /* TimeUnit: seconds */ - private int timeout = UNSET; - /* TimeUnit: seconds */ - private int passwordTimeout = UNSET; - private boolean subGroup = false; - private List subgroups = new ArrayList<>(); - private List owners = new ArrayList<>(); - private List users = new ArrayList<>(); + /** + * How the Perforce server represents an unset group value as a string. + */ + private static final String UNSET_STR = "unset"; + + /** + * How the Perforce server represents an unlimited group value as a string. + */ + private static final String UNLIMITED_STR = "unlimited"; + + private String name = null; + private int maxResults = UNSET; + private int maxScanRows = UNSET; + /* TimeUnit: milliseconds */ + private int maxLockTime = UNSET; + /* TimeUnit: seconds */ + private int timeout = UNSET; + /* TimeUnit: seconds */ + private int passwordTimeout = UNSET; + private boolean subGroup = false; + private List subgroups = new ArrayList<>(); + private List owners = new ArrayList<>(); + private List users = new ArrayList<>(); private int maxOpenFiles = UNDEFINED; /** - * Simple convenience factory method to return a new local UserGroup object. - *

- * - * All fields not passed as parameters here default to the defaults applied - * by the associated default UserGroup constructor. - * - * @param name - * non-null name for the UserGroup. - * @param users - * possibly-null list of users to be associated with the group. - * @return new user group. - */ - public static UserGroup newUserGroup(@Nonnull final String name, - @Nonnull final List users) { - Validate.notNull(name); - - UserGroup group = new UserGroup(); - group.setName(name); - group.setUsers(users); - - return group; - } - - /** - * @deprecated Please use method addUser(String user) - */ - public void setUsers(List users) { - if (nonNull(users)) { - this.users.addAll(users); - } - } - - /** - * Default constructor. Sets all fields to null, UNSET, or false. Sets - * superclass IServerResource fields complete, completeable, refereable and - * updateable to true. - */ - public UserGroup() { - super(true, true); - } - - /** - * Construct a new user group impl from the passed-in map. Note that this - * map must come from the Perforce "group" command or exact equivalent; - * using a map passed back by (e.g.) the Perforce "groups" (note the plural) - * command will fail due to the way the Perforce server returns group lists - * rather than individual groups. Calling this with a null map argument is - * equivalent to calling the default constructor. - *

- * - * Sets superclass IServerResource fields complete, completeable, refereable - * and updateable to true. - */ - public UserGroup(@Nullable final Map map) { - super(true, true); - if (nonNull(map)) { - try { - name = (String) map.get(MapKeys.GROUP_KEY); - maxLockTime = parseGroupIntValue((String) map.get(MapKeys.MAXLOCKTIME_KEY)); - maxResults = parseGroupIntValue((String) map.get(MapKeys.MAXRESULTS_KEY)); - maxScanRows = parseGroupIntValue((String) map.get(MapKeys.MAXSCANROWS_KEY)); + * Simple convenience factory method to return a new local UserGroup object. + *

+ * All fields not passed as parameters here default to the defaults applied + * by the associated default UserGroup constructor. + * + * @param name non-null name for the UserGroup. + * @param users possibly-null list of users to be associated with the group. + * @return new user group. + */ + public static UserGroup newUserGroup(@Nonnull final String name, + @Nonnull final List users) { + Validate.notNull(name); + + UserGroup group = new UserGroup(); + group.setName(name); + group.setUsers(users); + + return group; + } + + /** + * @deprecated Please use method addUser(String user) + */ + public void setUsers(List users) { + if (nonNull(users)) { + this.users.addAll(users); + } + } + + /** + * Default constructor. Sets all fields to null, UNSET, or false. Sets + * superclass IServerResource fields complete, completeable, refereable and + * updateable to true. + */ + public UserGroup() { + super(true, true); + } + + /** + * Construct a new user group impl from the passed-in map. Note that this + * map must come from the Perforce "group" command or exact equivalent; + * using a map passed back by (e.g.) the Perforce "groups" (note the plural) + * command will fail due to the way the Perforce server returns group lists + * rather than individual groups. Calling this with a null map argument is + * equivalent to calling the default constructor. + *

+ * Sets superclass IServerResource fields complete, completeable, refereable + * and updateable to true. + * + * @param map spec map + */ + public UserGroup(@Nullable final Map map) { + super(true, true); + if (nonNull(map)) { + try { + name = (String) map.get(MapKeys.GROUP_KEY); + maxLockTime = parseGroupIntValue((String) map.get(MapKeys.MAXLOCKTIME_KEY)); + maxResults = parseGroupIntValue((String) map.get(MapKeys.MAXRESULTS_KEY)); + maxScanRows = parseGroupIntValue((String) map.get(MapKeys.MAXSCANROWS_KEY)); if (map.containsKey(MapKeys.MAXOPENFILES_KEY)) { maxOpenFiles = parseGroupIntValue((String) map.get(MapKeys.MAXOPENFILES_KEY)); } - timeout = parseGroupIntValue((String) map.get(MapKeys.TIMEOUT_KEY)); - passwordTimeout = parseGroupIntValue( - (String) map.get(MapKeys.PASSWORD_TIMEOUT_KEY)); - - addToListIfKeyIsNotExistInMap(users, map, MapKeys.USERS_KEY); - addToListIfKeyIsNotExistInMap(owners, map, MapKeys.OWNERS_KEY); - addToListIfKeyIsNotExistInMap(subgroups, map, MapKeys.SUBGROUPS_KEY); - } catch (Throwable thr) { - Log.warn("Unexpected exception in UserGroup constructor: %s", thr.getMessage()); - Log.exception(thr); - } - } - } - - /** - * Parse a Perforce server-side string representing a user group integer - * value (such as timeout). Copes with "unset" and "unlimited" properly. - */ - public int parseGroupIntValue(String str) { - if (isNotBlank(str)) { - if (UNSET_STR.equalsIgnoreCase(str)) { - return UNSET; - } else if (UNLIMITED_STR.equalsIgnoreCase(str)) { - return UNLIMITED; - } else { - return new Integer(str); - } - } - return UNSET; - } - - private void addToListIfKeyIsNotExistInMap(@Nonnull final List lists, - @Nonnull Map map, @Nonnull String key) { - - for (int i = 0;; i++) { - if (!map.containsKey(key + i)) { - break; - } else { - lists.add((String) map.get(key + i)); - } - } - } - - public int getMaxLockTime() { - return this.maxLockTime; - } - - public void setMaxLockTime(int maxLockTimeOfMilliSeconds) { - this.maxLockTime = maxLockTimeOfMilliSeconds; - } - - public int getMaxResults() { - return this.maxResults; - } - - public void setMaxResults(int maxResults) { - this.maxResults = maxResults; - } - - public int getMaxScanRows() { - return this.maxScanRows; - } - - public void setMaxScanRows(int maxScanRows) { - this.maxScanRows = maxScanRows; - } - - public String getName() { - return this.name; - } - - public void setName(String name) { - this.name = name; - } - - public List getOwners() { - return this.owners; - } - - public int getPasswordTimeout() { - return passwordTimeout; - } - - public void setPasswordTimeout(int passwordTimeoutOfSeconds) { - this.passwordTimeout = passwordTimeoutOfSeconds; - } - - public List getSubgroups() { - return this.subgroups; - } - - public int getTimeout() { - return this.timeout; - } - - public void setTimeout(int timeoutOfSeconds) { - this.timeout = timeoutOfSeconds; - } - - public List getUsers() { - return this.users; - } - - public boolean isSubGroup() { - return this.subGroup; - } - - public void setSubGroup(boolean subGroup) { - this.subGroup = subGroup; - } + timeout = parseGroupIntValue((String) map.get(MapKeys.TIMEOUT_KEY)); + passwordTimeout = parseGroupIntValue( + (String) map.get(MapKeys.PASSWORD_TIMEOUT_KEY)); + + addToListIfKeyIsNotExistInMap(users, map, MapKeys.USERS_KEY); + addToListIfKeyIsNotExistInMap(owners, map, MapKeys.OWNERS_KEY); + addToListIfKeyIsNotExistInMap(subgroups, map, MapKeys.SUBGROUPS_KEY); + } catch (Throwable thr) { + Log.warn("Unexpected exception in UserGroup constructor: %s", thr.getMessage()); + Log.exception(thr); + } + } + } + + /** + * Parse a Perforce server-side string representing a user group integer + * value (such as timeout). Copes with "unset" and "unlimited" properly. + * + * @param str string + * @return value + */ + public int parseGroupIntValue(String str) { + if (isNotBlank(str)) { + if (UNSET_STR.equalsIgnoreCase(str)) { + return UNSET; + } else if (UNLIMITED_STR.equalsIgnoreCase(str)) { + return UNLIMITED; + } else { + return new Integer(str); + } + } + return UNSET; + } + + private void addToListIfKeyIsNotExistInMap(@Nonnull final List lists, + @Nonnull Map map, @Nonnull String key) { + + for (int i = 0; ; i++) { + if (!map.containsKey(key + i)) { + break; + } else { + lists.add((String) map.get(key + i)); + } + } + } + + public int getMaxLockTime() { + return this.maxLockTime; + } + + public void setMaxLockTime(int maxLockTimeOfMilliSeconds) { + this.maxLockTime = maxLockTimeOfMilliSeconds; + } + + public int getMaxResults() { + return this.maxResults; + } + + public void setMaxResults(int maxResults) { + this.maxResults = maxResults; + } + + public int getMaxScanRows() { + return this.maxScanRows; + } + + public void setMaxScanRows(int maxScanRows) { + this.maxScanRows = maxScanRows; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public List getOwners() { + return this.owners; + } + + public int getPasswordTimeout() { + return passwordTimeout; + } + + public void setPasswordTimeout(int passwordTimeoutOfSeconds) { + this.passwordTimeout = passwordTimeoutOfSeconds; + } + + public List getSubgroups() { + return this.subgroups; + } + + public int getTimeout() { + return this.timeout; + } + + public void setTimeout(int timeoutOfSeconds) { + this.timeout = timeoutOfSeconds; + } + + public List getUsers() { + return this.users; + } + + public boolean isSubGroup() { + return this.subGroup; + } + + public void setSubGroup(boolean subGroup) { + this.subGroup = subGroup; + } public int getMaxOpenFiles() { return this.maxOpenFiles; @@ -236,70 +237,70 @@ public void setMaxOpenFiles(int maxOpenFiles) { this.maxOpenFiles = maxOpenFiles; } - @Override - public void refresh() throws ConnectionException, RequestException, AccessException { - IServer refreshServer = server; - String refreshName = getName(); - if (nonNull(refreshServer) && isNotBlank(refreshName)) { - IUserGroup refreshedUserGroup = refreshServer.getUserGroup(refreshName); - if (nonNull(refreshedUserGroup)) { - maxLockTime = refreshedUserGroup.getMaxLockTime(); - name = refreshedUserGroup.getName(); - maxResults = refreshedUserGroup.getMaxResults(); - maxScanRows = refreshedUserGroup.getMaxScanRows(); - owners = refreshedUserGroup.getOwners(); - subGroup = refreshedUserGroup.isSubGroup(); - timeout = refreshedUserGroup.getTimeout(); - subgroups = refreshedUserGroup.getSubgroups(); - users = refreshedUserGroup.getUsers(); - } - } - } - - @Override - public void update() throws ConnectionException, RequestException, AccessException { - server.updateUserGroup(this, false); - } - - /** - * @deprecated Please use method addSubgroup(String subgroup) - */ - public void setSubgroups(List subgroups) { - if (nonNull(subgroups)) { - this.subgroups.addAll(subgroups); - } - } - - /** - * @deprecated Please use method addOwner(String owner) - */ - public void setOwners(List owners) { - if (nonNull(owners)) { - this.owners.addAll(owners); - } - } - - public UserGroup addOwner(final String owner) { - if (isNotBlank(owner)) { - owners.add(owner); - } - - return this; - } - - public UserGroup addSubgroup(final String subgroup) { - if (isNotBlank(subgroup)) { - subgroups.add(subgroup); - } - - return this; - } - - public UserGroup addUser(final String user) { - if (isNotBlank(user)) { - users.add(user); - } - - return this; - } + @Override + public void refresh() throws ConnectionException, RequestException, AccessException { + IServer refreshServer = server; + String refreshName = getName(); + if (nonNull(refreshServer) && isNotBlank(refreshName)) { + IUserGroup refreshedUserGroup = refreshServer.getUserGroup(refreshName); + if (nonNull(refreshedUserGroup)) { + maxLockTime = refreshedUserGroup.getMaxLockTime(); + name = refreshedUserGroup.getName(); + maxResults = refreshedUserGroup.getMaxResults(); + maxScanRows = refreshedUserGroup.getMaxScanRows(); + owners = refreshedUserGroup.getOwners(); + subGroup = refreshedUserGroup.isSubGroup(); + timeout = refreshedUserGroup.getTimeout(); + subgroups = refreshedUserGroup.getSubgroups(); + users = refreshedUserGroup.getUsers(); + } + } + } + + @Override + public void update() throws ConnectionException, RequestException, AccessException { + server.updateUserGroup(this, false); + } + + /** + * @deprecated Please use method addSubgroup(String subgroup) + */ + public void setSubgroups(List subgroups) { + if (nonNull(subgroups)) { + this.subgroups.addAll(subgroups); + } + } + + /** + * @deprecated Please use method addOwner(String owner) + */ + public void setOwners(List owners) { + if (nonNull(owners)) { + this.owners.addAll(owners); + } + } + + public UserGroup addOwner(final String owner) { + if (isNotBlank(owner)) { + owners.add(owner); + } + + return this; + } + + public UserGroup addSubgroup(final String subgroup) { + if (isNotBlank(subgroup)) { + subgroups.add(subgroup); + } + + return this; + } + + public UserGroup addUser(final String user) { + if (isNotBlank(user)) { + users.add(user); + } + + return this; + } } diff --git a/src/main/java/com/perforce/p4java/impl/generic/core/UserSummary.java b/src/main/java/com/perforce/p4java/impl/generic/core/UserSummary.java index 00ed947..f44b0e9 100644 --- a/src/main/java/com/perforce/p4java/impl/generic/core/UserSummary.java +++ b/src/main/java/com/perforce/p4java/impl/generic/core/UserSummary.java @@ -1,16 +1,16 @@ /** - * + * */ package com.perforce.p4java.impl.generic.core; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Map; - import com.perforce.p4java.Log; import com.perforce.p4java.core.IUserSummary; import com.perforce.p4java.impl.mapbased.MapKeys; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Map; + /** * Default implementation class for IUserSummary interface. */ @@ -25,34 +25,43 @@ public class UserSummary extends ServerResource implements IUserSummary { protected UserType type = null; protected Date ticketExpiration = null; protected Date passwordChange = null; - + static final String DATE_FORMAT = "yyyy/MM/dd HH:mm:ss"; - + /** * Default constructor; sets all fields to null or zero. */ public UserSummary() { } - + /** * Explicit-value constructor. - */ - - public UserSummary(String loginName, String email, String fullName, - Date access, Date update) { + * + * @param loginName loginName + * @param email email + * @param fullName fullName + * @param access access + * @param update update + */ + public UserSummary(String loginName, String email, String fullName, Date access, Date update) { this.loginName = loginName; this.email = email; this.fullName = fullName; this.access = access; this.update = update; } - + /** * Explicit-value constructor. - */ - - public UserSummary(String loginName, String email, String fullName, - Date access, Date update, UserType type) { + * + * @param loginName loginName + * @param email email + * @param fullName fullName + * @param access access + * @param update update + * @param type type + */ + public UserSummary(String loginName, String email, String fullName, Date access, Date update, UserType type) { this.loginName = loginName; this.email = email; this.fullName = fullName; @@ -65,15 +74,18 @@ public UserSummary(String loginName, String email, String fullName, * Construct a UserSummary from the passed-in map and summaryOnly values. * The map must have been returned from the Perforce server in response * to a getUsers() or getUser (etc.) call; is summaryOnly is true, this - * is treated as a map that came from the getUseres method.

- * + * is treated as a map that came from the getUseres method. + *

* If map is null, this is equivalent to calling the default constructor. + * + * @param map spec map + * @param summaryOnly if true */ public UserSummary(Map map, boolean summaryOnly) { super(!summaryOnly, !summaryOnly); - + if (map != null) { - try{ + try { this.loginName = (String) map.get("User"); this.email = (String) map.get("Email"); this.fullName = (String) map.get("FullName"); @@ -81,36 +93,28 @@ public UserSummary(Map map, boolean summaryOnly) { this.type = UserType.fromString(((String) map.get(MapKeys.TYPE_KEY)).toUpperCase()); } if (summaryOnly) { - this.update = new Date(Long.parseLong((String) map - .get(MapKeys.UPDATE_KEY)) * 1000); - this.access = new Date(Long.parseLong((String) map - .get(MapKeys.ACCESS_KEY)) * 1000); + this.update = new Date(Long.parseLong((String) map.get(MapKeys.UPDATE_KEY)) * 1000); + this.access = new Date(Long.parseLong((String) map.get(MapKeys.ACCESS_KEY)) * 1000); if (map.get(MapKeys.TICKET_EXPIRATION) != null) { - this.ticketExpiration = new Date(Long.parseLong((String) map - .get(MapKeys.TICKET_EXPIRATION)) * 1000); + this.ticketExpiration = new Date(Long.parseLong((String) map.get(MapKeys.TICKET_EXPIRATION)) * 1000); } if (map.get(MapKeys.PASSWORD_CHANGE_KEY) != null) { - this.passwordChange = new Date(Long.parseLong((String) map - .get(MapKeys.PASSWORD_CHANGE_KEY)) * 1000); + this.passwordChange = new Date(Long.parseLong((String) map.get(MapKeys.PASSWORD_CHANGE_KEY)) * 1000); } } else { SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATE_FORMAT); if (map.containsKey(MapKeys.UPDATE_KEY)) { - this.update = simpleDateFormat - .parse((String) map.get(MapKeys.UPDATE_KEY)); + this.update = simpleDateFormat.parse((String) map.get(MapKeys.UPDATE_KEY)); } if (map.containsKey(MapKeys.ACCESS_KEY)) { - this.access = simpleDateFormat - .parse((String) map.get(MapKeys.ACCESS_KEY)); + this.access = simpleDateFormat.parse((String) map.get(MapKeys.ACCESS_KEY)); } if (map.get(MapKeys.PASSWORD_CHANGE_LC_KEY) != null) { - this.passwordChange = simpleDateFormat - .parse((String) map.get(MapKeys.PASSWORD_CHANGE_LC_KEY)); + this.passwordChange = simpleDateFormat.parse((String) map.get(MapKeys.PASSWORD_CHANGE_LC_KEY)); } } } catch (Throwable thr) { - Log.error("Unexpected exception in UserSummary constructor: " - + thr.getLocalizedMessage()); + Log.error("Unexpected exception in UserSummary constructor: " + thr.getLocalizedMessage()); Log.exception(thr); } } diff --git a/src/main/java/com/perforce/p4java/impl/generic/core/file/ExtendedFileSpec.java b/src/main/java/com/perforce/p4java/impl/generic/core/file/ExtendedFileSpec.java index 2a005e1..aa43fab 100644 --- a/src/main/java/com/perforce/p4java/impl/generic/core/file/ExtendedFileSpec.java +++ b/src/main/java/com/perforce/p4java/impl/generic/core/file/ExtendedFileSpec.java @@ -136,7 +136,6 @@ public ExtendedFileSpec() { * annotations, at least), try to construct a corresponding extended file * spec. *

- *

* See the corresponding FileSpec constructor for details -- this * constructor does not add any ExtendedFileSpec-specific semantics. * diff --git a/src/main/java/com/perforce/p4java/impl/generic/core/file/FileAnnotation.java b/src/main/java/com/perforce/p4java/impl/generic/core/file/FileAnnotation.java index 31a934d..da23b07 100644 --- a/src/main/java/com/perforce/p4java/impl/generic/core/file/FileAnnotation.java +++ b/src/main/java/com/perforce/p4java/impl/generic/core/file/FileAnnotation.java @@ -1,16 +1,16 @@ /** - * + * */ package com.perforce.p4java.impl.generic.core.file; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - import com.perforce.p4java.Log; import com.perforce.p4java.client.IClientSummary.ClientLineEnd; import com.perforce.p4java.core.file.IFileAnnotation; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + /** * Simple generic implementation class for IFileAnnotation interface. */ @@ -25,12 +25,17 @@ public class FileAnnotation implements IFileAnnotation { private static final String localLineEndStr = System.getProperty("line.separator", "\n"); private List contributingSources = null; private int ordering = -1; - + /** * Default all-field constructor. + * + * @param upper upper + * @param lower lower + * @param depotPath depotPath + * @param line line + * @param lineEnd lineEnd */ - public FileAnnotation(int upper, int lower, String depotPath, - String line, ClientLineEnd lineEnd) { + public FileAnnotation(int upper, int lower, String depotPath, String line, ClientLineEnd lineEnd) { this.upper = upper; this.lower = lower; this.depotPath = depotPath; @@ -38,7 +43,7 @@ public FileAnnotation(int upper, int lower, String depotPath, this.lineEnd = lineEnd; handleLineEnding(); } - + private void handleLineEnding() { // Data comes back with unwanted trailing newline; get rid of this here: if (this.line != null) { @@ -53,13 +58,17 @@ private void handleLineEnding() { } } } - + /** * Construct a suitable FileAnnotation object from the passed-in * map; this map must be in the format and use the fields returned from - * a Perforce server annotate command.

- * + * a Perforce server annotate command. + *

* Leave lineEnd null for normal use. + * + * @param map map + * @param depotPath depotPath + * @param lineEnd lineEnd */ public FileAnnotation(Map map, String depotPath, ClientLineEnd lineEnd) { if (map != null) { @@ -74,24 +83,30 @@ public FileAnnotation(Map map, String depotPath, ClientLineEnd l Log.exception(thr); } } - + this.depotPath = depotPath; // May, of course, be null... } - + /** * Create a new non-data file annotation with the passed-in parameters. + * + * @param order order + * @param depotPath depotPath + * @param upper upper + * @param lower lower */ - public FileAnnotation(int order, String depotPath, int upper, int lower) { this.ordering = order; this.depotPath = depotPath; this.upper = upper; this.lower = lower; } - + /** * Add an integration annotation to the contributingSources list. If the list * is null, a new list will be created; otherwise it's added to the end of the list. + * + * @param annotation annotation */ public void addIntegrationAnnotation(IFileAnnotation annotation) { if (annotation != null) { @@ -115,24 +130,24 @@ public String getDepotPath() { public String getLine() { return this.line; } - + /** * @see com.perforce.p4java.core.file.IFileAnnotation#getLine(boolean) */ - public String getLine(boolean processLineEndings) { + public String getLine(boolean processLineEndings) { if (processLineEndings && this.line != null && hadLineEnd) { if (lineEnd != null) { switch (lineEnd) { - case UNIX: - case SHARE: - return this.line + "\n"; - case MAC: - return this.line + "\r"; - case WIN: - return this.line + "\r\n"; - case LOCAL: - default: - return this.line + localLineEndStr; + case UNIX: + case SHARE: + return this.line + "\n"; + case MAC: + return this.line + "\r"; + case WIN: + return this.line + "\r\n"; + case LOCAL: + default: + return this.line + localLineEndStr; } } else { return this.line + localLineEndStr; @@ -140,9 +155,9 @@ public String getLine(boolean processLineEndings) { } return this.line; } - + /** - * @see com.perforce.p4java.core.file.IFileAnnotation#getContributingSources() + * @see com.perforce.p4java.core.file.IFileAnnotation#getAllIntegrations() */ public List getAllIntegrations() { return this.contributingSources; diff --git a/src/main/java/com/perforce/p4java/impl/generic/core/file/FilePath.java b/src/main/java/com/perforce/p4java/impl/generic/core/file/FilePath.java index f6af873..78206d9 100644 --- a/src/main/java/com/perforce/p4java/impl/generic/core/file/FilePath.java +++ b/src/main/java/com/perforce/p4java/impl/generic/core/file/FilePath.java @@ -62,23 +62,30 @@ public enum PathType { */ public FilePath() { } - + /** * Construct a FilePath from explicit type and path string values. If the * passed-in pathString contains version / date / changelist information, * it is stripped from the path and ignored. + * + * @param pathType pathType + * @param pathString pathString */ public FilePath(PathType pathType, String pathString) { this(pathType, pathString, false); } - + /** * Construct a FilePath from explicit type and path string values. If the - * ignoreAnnotations parameter is false and if the + * ignoreAnnotations parameter is false and if the * passed-in pathString contains version / date / changelist information, * it is stripped from the path and ignored; otherwise the pathString * parameter is used-as is (allowing for embedded "#" and "@" characters, * for instance). + * + * @param pathType pathType + * @param pathString pathString + * @param ignoreAnnotations ignoreAnnotations */ public FilePath(PathType pathType, String pathString, boolean ignoreAnnotations) { this.pathType = pathType; @@ -88,13 +95,15 @@ public FilePath(PathType pathType, String pathString, boolean ignoreAnnotations) this.pathString = PathAnnotations.stripAnnotations(pathString); } } - + /** * Annotate this path with the passed-in Perforce file metadata * annotations. If either or both this.pathString and annotations * is null, returns this.pathString. + * + * @param annotations annotations + * @return path string */ - public String annotate(PathAnnotations annotations) { if ((annotations != null) && (this.pathString != null)) { return this.pathString + annotations.toString(); @@ -102,7 +111,11 @@ public String annotate(PathAnnotations annotations) { return this.pathString; } - + + /** + * @param fileSpec file spec + * @return annotated path string + */ public String annotate(IFileSpec fileSpec) { if ((fileSpec != null) && (this.pathString != null)) { return this.pathString + new PathAnnotations(fileSpec); diff --git a/src/main/java/com/perforce/p4java/impl/generic/core/file/FileSpec.java b/src/main/java/com/perforce/p4java/impl/generic/core/file/FileSpec.java index 29a7cae..78f77a0 100644 --- a/src/main/java/com/perforce/p4java/impl/generic/core/file/FileSpec.java +++ b/src/main/java/com/perforce/p4java/impl/generic/core/file/FileSpec.java @@ -97,843 +97,841 @@ public class FileSpec extends ServerResource implements IFileSpec { - protected FileSpecOpStatus opStatus = FileSpecOpStatus.VALID; - protected String statusMessage = null; - protected int genericCode = 0; - protected int severityCode = 0; - protected int rawCode = 0; - protected int uniqueCode = 0; - protected int subCode = 0; - protected int subSystem = 0; - - protected FilePath originalPath = null; - protected FilePath depotPath = null; - protected FilePath clientPath = null; - protected FilePath localPath = null; - protected String fileType = null; - protected int startRevision = NO_FILE_REVISION; - protected int endRevision = NO_FILE_REVISION; - protected int changeListId = IChangelist.UNKNOWN; - protected String label = null; - protected Date date = null; - protected FileAction action = null; - protected String userName = null; - protected String clientName = null; - protected int baseRev = NO_FILE_REVISION; - protected String baseName = null; - protected String baseFile = null; - - protected boolean unmap = false; - - protected String repoName = null; - protected String sha = null; - protected String branch = null; - protected String blobSha = null; - protected String commitSha = null; + protected FileSpecOpStatus opStatus = FileSpecOpStatus.VALID; + protected String statusMessage = null; + protected int genericCode = 0; + protected int severityCode = 0; + protected int rawCode = 0; + protected int uniqueCode = 0; + protected int subCode = 0; + protected int subSystem = 0; + + protected FilePath originalPath = null; + protected FilePath depotPath = null; + protected FilePath clientPath = null; + protected FilePath localPath = null; + protected String fileType = null; + protected int startRevision = NO_FILE_REVISION; + protected int endRevision = NO_FILE_REVISION; + protected int changeListId = IChangelist.UNKNOWN; + protected String label = null; + protected Date date = null; + protected FileAction action = null; + protected String userName = null; + protected String clientName = null; + protected int baseRev = NO_FILE_REVISION; + protected String baseName = null; + protected String baseFile = null; + + protected boolean unmap = false; + + protected String repoName = null; + protected String sha = null; + protected String branch = null; + protected String blobSha = null; + protected String commitSha = null; protected String treeSha = null; - private String fromFile = null; - private int endFromRev = NO_FILE_REVISION; - private int startFromRev = NO_FILE_REVISION; - private String toFile = null; - private int endToRev = NO_FILE_REVISION; - private int startToRev = NO_FILE_REVISION; + private String fromFile = null; + private int endFromRev = NO_FILE_REVISION; + private int startFromRev = NO_FILE_REVISION; + private String toFile = null; + private int endToRev = NO_FILE_REVISION; + private int startToRev = NO_FILE_REVISION; - private int workRev = NO_FILE_REVISION; - private String howResolved = null; - private FileAction otherAction = null; + private int workRev = NO_FILE_REVISION; + private String howResolved = null; + private FileAction otherAction = null; - private boolean locked = false; + private boolean locked = false; - private String diffStatus = null; + private String diffStatus = null; - private String resolveType = null; + private String resolveType = null; private List resolveTypes = null; - private String contentResolveType = null; - - private int shelvedChange = IChangelist.UNKNOWN; - - protected IClient client = null; - - /** - * Default constructor. Sets all paths, labels, dates, etc. to null; - * revisions to IFileSpec.NO_FILE_REVISION; client and server references to - * null; changelist ID to IChangelist.UNKNOWN; opStatus to VALID; locked to - * false, etc. - */ - public FileSpec() { - super(false, false); - } - - /** - * Given a candidate path string (which may include version and changelist - * annotations, at least), try to construct a corresponding file spec. - *

+ private String contentResolveType = null; + + private int shelvedChange = IChangelist.UNKNOWN; + + protected IClient client = null; + + /** + * Default constructor. Sets all paths, labels, dates, etc. to null; + * revisions to IFileSpec.NO_FILE_REVISION; client and server references to + * null; changelist ID to IChangelist.UNKNOWN; opStatus to VALID; locked to + * false, etc. + */ + public FileSpec() { + super(false, false); + } + + /** + * Given a candidate path string (which may include version and changelist + * annotations, at least), try to construct a corresponding file spec. *

- * Effectively an alias for FileSpec(pathStr, true). - * + * Effectively an alias for FileSpec(pathStr, true). + * * @param pathStr candidate path string - */ + */ - public FileSpec(String pathStr) { - this(pathStr, true); - } + public FileSpec(String pathStr) { + this(pathStr, true); + } - /** - * Given a candidate path string (which may include version and changelist - * annotations, at least), try to construct a corresponding file spec. - *

+ /** + * Given a candidate path string (which may include version and changelist + * annotations, at least), try to construct a corresponding file spec. *

- * The motivation for the hasAnnotations parameter is to allow path strings - * to contain "@" and "#" characters; the downside of this that if there's - * any associated annotation info, it's not parsed at all and any such - * information must be set up manually. - * + * The motivation for the hasAnnotations parameter is to allow path strings + * to contain "@" and "#" characters; the downside of this that if there's + * any associated annotation info, it's not parsed at all and any such + * information must be set up manually. + * * @param pathStr candidate path string * @param parseAnnotations if true, attempt to parse the path string for revision - * annotations. - */ - public FileSpec(final String pathStr, final boolean parseAnnotations) { - super(false, false); - originalPath = new FilePath(PathType.ORIGINAL, pathStr); - if (parseAnnotations && isNotBlank(pathStr) - && PathAnnotations.hasPerforceAnnotations(pathStr)) { - PathAnnotations annotations = new PathAnnotations(pathStr); - startRevision = annotations.getStartRevision(); - endRevision = annotations.getEndRevision(); - changeListId = annotations.getChangelistId(); - label = annotations.getLabel(); - date = annotations.getDate(); - } - } - - /** - * Construct a FileSpec from a specific FilePath. - */ - public FileSpec(FilePath path) { - super(false, false); - setPath(path); - } - - /** - * Construct a filespec from an opstatus and error message pair. - */ - - public FileSpec(final FileSpecOpStatus status, final String errStr) { - super(false, false); - opStatus = status; - statusMessage = errStr; - } - - /** - * Construct a FileSpec from an opstatus, error message, Perforce generic - * code, and Perforce severity code. - */ - public FileSpec(final FileSpecOpStatus status, final String errStr, final int genericCode, - final int severityCode) { - - super(false, false); - opStatus = status; - statusMessage = errStr; - this.genericCode = genericCode; - this.severityCode = severityCode; - } - - /** - * Construct a new FileSpec given the op status, an error string, and a raw - * code string returned from a Perforce server. - */ - public FileSpec(final FileSpecOpStatus status, final String errStr, final String codeStr) { - super(false, false); - opStatus = status; - statusMessage = errStr; - try { - setCodes(Integer.valueOf(codeStr)); - } catch (NumberFormatException thr) { - Log.exception(thr); - } - } - - /** - * Construct a new FileSpec given the op status, an error string, and a raw - * code value returned from a Perforce server. - */ - public FileSpec(final FileSpecOpStatus status, final String errStr, final int rawCode) { - - super(false, false); - opStatus = status; - statusMessage = errStr; - setCodes(rawCode); - } - - /** - * Construct a new filespec from another filespec. In other words, - * effectively clone it by deep copy of local fields. - *

- * + * annotations. + */ + public FileSpec(final String pathStr, final boolean parseAnnotations) { + super(false, false); + originalPath = new FilePath(PathType.ORIGINAL, pathStr); + if (parseAnnotations && isNotBlank(pathStr) && PathAnnotations.hasPerforceAnnotations(pathStr)) { + PathAnnotations annotations = new PathAnnotations(pathStr); + startRevision = annotations.getStartRevision(); + endRevision = annotations.getEndRevision(); + changeListId = annotations.getChangelistId(); + label = annotations.getLabel(); + date = annotations.getDate(); + } + } + + /** + * Construct a FileSpec from a specific FilePath. + * + * @param path path + */ + public FileSpec(FilePath path) { + super(false, false); + setPath(path); + } + + /** + * Construct a filespec from an opstatus and error message pair. + * + * @param status status + * @param errStr errStr + */ + public FileSpec(final FileSpecOpStatus status, final String errStr) { + super(false, false); + opStatus = status; + statusMessage = errStr; + } + + /** + * Construct a FileSpec from an opstatus, error message, Perforce generic + * code, and Perforce severity code. + * + * @param status status + * @param errStr errStr + * @param genericCode genericCode + * @param severityCode severityCode + */ + public FileSpec(final FileSpecOpStatus status, final String errStr, final int genericCode, final int severityCode) { + + super(false, false); + opStatus = status; + statusMessage = errStr; + this.genericCode = genericCode; + this.severityCode = severityCode; + } + + /** + * Construct a new FileSpec given the op status, an error string, and a raw + * code string returned from a Perforce server. + * + * @param status status + * @param errStr errStr + * @param codeStr codeStr + */ + public FileSpec(final FileSpecOpStatus status, final String errStr, final String codeStr) { + super(false, false); + opStatus = status; + statusMessage = errStr; + try { + setCodes(Integer.valueOf(codeStr)); + } catch (NumberFormatException thr) { + Log.exception(thr); + } + } + + /** + * Construct a new FileSpec given the op status, an error string, and a raw + * code value returned from a Perforce server. + * + * @param status status + * @param errStr errStr + * @param rawCode rawCode + */ + public FileSpec(final FileSpecOpStatus status, final String errStr, final int rawCode) { + + super(false, false); + opStatus = status; + statusMessage = errStr; + setCodes(rawCode); + } + + /** + * Construct a new filespec from another filespec. In other words, + * effectively clone it by deep copy of local fields. + *

+ * * @param impl non-null existing filespec. - */ - public FileSpec(final FileSpec impl) { - super(false, false); - - Validate.notNull(impl); - - opStatus = impl.opStatus; - statusMessage = impl.statusMessage; - genericCode = impl.genericCode; - severityCode = impl.severityCode; - originalPath = impl.originalPath; - depotPath = impl.depotPath; - clientPath = impl.clientPath; - localPath = impl.localPath; - fileType = impl.fileType; - startRevision = impl.startRevision; - endRevision = impl.endRevision; - changeListId = impl.changeListId; - label = impl.label; - date = impl.date; - action = impl.action; - userName = impl.userName; - clientName = impl.clientName; - unmap = impl.unmap; - fromFile = impl.fromFile; - endFromRev = impl.endFromRev; - startFromRev = impl.startFromRev; - toFile = impl.toFile; - endToRev = impl.endToRev; - startToRev = impl.startToRev; - workRev = impl.workRev; - howResolved = impl.howResolved; - otherAction = impl.otherAction; - locked = impl.locked; - diffStatus = impl.diffStatus; - resolveType = impl.resolveType; + */ + public FileSpec(final FileSpec impl) { + super(false, false); + + Validate.notNull(impl); + + opStatus = impl.opStatus; + statusMessage = impl.statusMessage; + genericCode = impl.genericCode; + severityCode = impl.severityCode; + originalPath = impl.originalPath; + depotPath = impl.depotPath; + clientPath = impl.clientPath; + localPath = impl.localPath; + fileType = impl.fileType; + startRevision = impl.startRevision; + endRevision = impl.endRevision; + changeListId = impl.changeListId; + label = impl.label; + date = impl.date; + action = impl.action; + userName = impl.userName; + clientName = impl.clientName; + unmap = impl.unmap; + fromFile = impl.fromFile; + endFromRev = impl.endFromRev; + startFromRev = impl.startFromRev; + toFile = impl.toFile; + endToRev = impl.endToRev; + startToRev = impl.startToRev; + workRev = impl.workRev; + howResolved = impl.howResolved; + otherAction = impl.otherAction; + locked = impl.locked; + diffStatus = impl.diffStatus; + resolveType = impl.resolveType; resolveTypes = impl.resolveTypes; - contentResolveType = impl.contentResolveType; - shelvedChange = impl.shelvedChange; - server = impl.server; - client = impl.client; - baseFile = impl.baseFile; - } - - /** - * Try to construct a FileSpec from a passed-in map as returned from a - * Perforce server. Tuned to return values from the underlying map-based - * server interface, which explains the index (set this to zero for normal - * use). - */ - - public FileSpec(@Nullable final Map map, @Nonnull final IServer server, - final int index) { - - super(false, false); - if (nonNull(map)) { - setOpStatus(FileSpecOpStatus.VALID); - - String indexStr = EMPTY; - if (index >= 0) { - indexStr += index; - } - setServer(server); - if (map.containsKey(DIR + indexStr)) { - setDepotPath(new FilePath(PathType.DEPOT, parseString(map, DIR + indexStr), true)); - } - if (map.containsKey(DEPOT_FILE + indexStr)) { - setDepotPath(new FilePath(PathType.DEPOT, parseString(map, DEPOT_FILE + indexStr), - true)); - } - if (map.containsKey(CLIENT_FILE + indexStr)) { - setClientPath(new FilePath(PathType.CLIENT, - parseString(map, CLIENT_FILE + indexStr), true)); - } - if (map.containsKey(LOCAL_FILE + indexStr)) { - setLocalPath(new FilePath(PathType.LOCAL, parseString(map, LOCAL_FILE + indexStr), - true)); - } - if (map.containsKey(PATH + indexStr)) { - setLocalPath(new FilePath(PathType.LOCAL, parseString(map, PATH + indexStr), true)); - } - setFileType(parseString(map, TYPE + indexStr)); - setAction(FileAction.fromString(parseString(map, ACTION + indexStr))); - setUserName(parseString(map, USER + indexStr)); - setClientName(parseString(map, "client" + indexStr)); - String cid = parseString(map, CHANGE + indexStr); - String revStr = parseString(map, REV + indexStr); - if (revStr == null) { - // Sometimes it's the haveRev key... - revStr = parseString(map, HAVEREV + indexStr); - } - - // Get submit date from the 'time' (seconds). - // Multiply by 1000 to get the milliseconds. - if (nonNull(map.get(TIME))) { - try { - long seconds = parseLong(map, TIME); - setDate(new Date(seconds * 1000)); - } catch (NumberFormatException nfe) { - Log.error("Error parsing the '%S' in the FileSpec constructor: %s", TIME, - nfe.getLocalizedMessage()); - Log.exception(nfe); - } - } - - setLocked(nonNull(map.get(OURLOCK)) || nonNull(map.get(OTHERLOCK))); - setEndRevision(getRevFromString(revStr)); - - if (isBlank(cid)) { - setChangelistId(IChangelist.UNKNOWN); - } else if (DEFAULT.equalsIgnoreCase(cid) || DEFAULT_CHANGE.equalsIgnoreCase(cid)) { - setChangelistId(IChangelist.DEFAULT); - } else { - // Sometimes in format "change nnnnnn", sometimes just "nnnnn". - // Urgh... - int i = indexOf(cid, SPACE); - if (i < 0) { - setChangelistId(Integer.valueOf(cid)); - } else { - setChangelistId(Integer.valueOf(substring(cid, i + 1))); - } - } - - setEndFromRev(getRevFromString(parseString(map, ENDFROMREV + indexStr))); - setStartFromRev(getRevFromString(parseString(map, STARTFROMREV + indexStr))); - setWorkRev(getRevFromString(parseString(map, WORKREV + indexStr))); - - setHowResolved(parseString(map, HOW)); - setFromFile(parseString(map, FROM_FILE + indexStr)); - - setEndToRev(getRevFromString(parseString(map, END_TO_REV + indexStr))); - setStartToRev(getRevFromString(parseString(map, START_TO_REV + indexStr))); - setToFile(parseString(map, TO_FILE + indexStr)); - - setBaseRev(getRevFromString(parseString(map, BASE_REV + indexStr))); - setBaseName(parseString(map, BASENAME + indexStr)); - setBaseFile(parseString(map, BASE_FILE + indexStr)); - - setOtherAction(FileAction.fromString(parseString(map, OTHER_ACTION + indexStr))); - setDiffStatus(parseString(map, STATUS)); - - setResolveType(parseString(map, RESOLVE_TYPE)); + contentResolveType = impl.contentResolveType; + shelvedChange = impl.shelvedChange; + server = impl.server; + client = impl.client; + baseFile = impl.baseFile; + } + + /** + * Try to construct a FileSpec from a passed-in map as returned from a + * Perforce server. Tuned to return values from the underlying map-based + * server interface, which explains the index (set this to zero for normal + * use). + * + * @param map map + * @param server server + * @param index index + */ + public FileSpec(@Nullable final Map map, @Nonnull final IServer server, final int index) { + + super(false, false); + if (nonNull(map)) { + setOpStatus(FileSpecOpStatus.VALID); + + String indexStr = EMPTY; + if (index >= 0) { + indexStr += index; + } + setServer(server); + if (map.containsKey(DIR + indexStr)) { + setDepotPath(new FilePath(PathType.DEPOT, parseString(map, DIR + indexStr), true)); + } + if (map.containsKey(DEPOT_FILE + indexStr)) { + setDepotPath(new FilePath(PathType.DEPOT, parseString(map, DEPOT_FILE + indexStr), true)); + } + if (map.containsKey(CLIENT_FILE + indexStr)) { + setClientPath(new FilePath(PathType.CLIENT, parseString(map, CLIENT_FILE + indexStr), true)); + } + if (map.containsKey(LOCAL_FILE + indexStr)) { + setLocalPath(new FilePath(PathType.LOCAL, parseString(map, LOCAL_FILE + indexStr), true)); + } + if (map.containsKey(PATH + indexStr)) { + setLocalPath(new FilePath(PathType.LOCAL, parseString(map, PATH + indexStr), true)); + } + setFileType(parseString(map, TYPE + indexStr)); + setAction(FileAction.fromString(parseString(map, ACTION + indexStr))); + setUserName(parseString(map, USER + indexStr)); + setClientName(parseString(map, "client" + indexStr)); + String cid = parseString(map, CHANGE + indexStr); + String revStr = parseString(map, REV + indexStr); + if (revStr == null) { + // Sometimes it's the haveRev key... + revStr = parseString(map, HAVEREV + indexStr); + } + + // Get submit date from the 'time' (seconds). + // Multiply by 1000 to get the milliseconds. + if (nonNull(map.get(TIME))) { + try { + long seconds = parseLong(map, TIME); + setDate(new Date(seconds * 1000)); + } catch (NumberFormatException nfe) { + Log.error("Error parsing the '%S' in the FileSpec constructor: %s", TIME, nfe.getLocalizedMessage()); + Log.exception(nfe); + } + } + + setLocked(nonNull(map.get(OURLOCK)) || nonNull(map.get(OTHERLOCK))); + setEndRevision(getRevFromString(revStr)); + + if (isBlank(cid)) { + setChangelistId(IChangelist.UNKNOWN); + } else if (DEFAULT.equalsIgnoreCase(cid) || DEFAULT_CHANGE.equalsIgnoreCase(cid)) { + setChangelistId(IChangelist.DEFAULT); + } else { + // Sometimes in format "change nnnnnn", sometimes just "nnnnn". + // Urgh... + int i = indexOf(cid, SPACE); + if (i < 0) { + setChangelistId(Integer.valueOf(cid)); + } else { + setChangelistId(Integer.valueOf(substring(cid, i + 1))); + } + } + + setEndFromRev(getRevFromString(parseString(map, ENDFROMREV + indexStr))); + setStartFromRev(getRevFromString(parseString(map, STARTFROMREV + indexStr))); + setWorkRev(getRevFromString(parseString(map, WORKREV + indexStr))); + + setHowResolved(parseString(map, HOW)); + setFromFile(parseString(map, FROM_FILE + indexStr)); + + setEndToRev(getRevFromString(parseString(map, END_TO_REV + indexStr))); + setStartToRev(getRevFromString(parseString(map, START_TO_REV + indexStr))); + setToFile(parseString(map, TO_FILE + indexStr)); + + setBaseRev(getRevFromString(parseString(map, BASE_REV + indexStr))); + setBaseName(parseString(map, BASENAME + indexStr)); + setBaseFile(parseString(map, BASE_FILE + indexStr)); + + setOtherAction(FileAction.fromString(parseString(map, OTHER_ACTION + indexStr))); + setDiffStatus(parseString(map, STATUS)); + + setResolveType(parseString(map, RESOLVE_TYPE)); int r = 0; List rTypes = new ArrayList<>(); - while(map.containsKey(RESOLVE_TYPE + r)) { + while (map.containsKey(RESOLVE_TYPE + r)) { rTypes.add(parseString(map, RESOLVE_TYPE + r)); r++; } setResolveTypes(rTypes); - setContentResolveType(parseString(map, CONTENT_RESOLVE_TYPE)); - - if (map.containsKey(SHELVED_CHANGE)) { - try { - setShelvedChange(parseInt(map, SHELVED_CHANGE)); - } catch (NumberFormatException nfe) { - Log.error("Error parsing the 'shelvedChange' in the FileSpec constructor: %s", - nfe.getLocalizedMessage()); - Log.exception(nfe); - } - } - setUnmap(nonNull(map.get(UNMAP + indexStr))); - - // Graph output - setRepoName(parseString(map, REPO_NAME)); - setSha(parseString(map, SHA)); - setBranch(parseString(map, BRANCH)); - setBlobSha(parseString(map, BLOB_SHA)); - setCommitSha(parseString(map, COMMIT_SHA)); + setContentResolveType(parseString(map, CONTENT_RESOLVE_TYPE)); + + if (map.containsKey(SHELVED_CHANGE)) { + try { + setShelvedChange(parseInt(map, SHELVED_CHANGE)); + } catch (NumberFormatException nfe) { + Log.error("Error parsing the 'shelvedChange' in the FileSpec constructor: %s", nfe.getLocalizedMessage()); + Log.exception(nfe); + } + } + setUnmap(nonNull(map.get(UNMAP + indexStr))); + + // Graph output + setRepoName(parseString(map, REPO_NAME)); + setSha(parseString(map, SHA)); + setBranch(parseString(map, BRANCH)); + setBlobSha(parseString(map, BLOB_SHA)); + setCommitSha(parseString(map, COMMIT_SHA)); setTreeSha(parseString(map, TREE)); - setRepoName(parseString(map, REPO)); - } - } - - /** - * Set the various error codes for this FileSpec to a value returned from - * the server or the RPC layer. Use this if you're hand-constructing a new - * FileSpec for an error condition and you have the raw code. - */ - public FileSpec setCodes(final int rawCode) { - this.rawCode = rawCode; - subCode = (rawCode & 0x3FF); - subSystem = ((rawCode >> 10) & 0x3F); - uniqueCode = (rawCode & 0xFFFF); - genericCode = ((rawCode >> 16) & 0xFF); - severityCode = ((rawCode >> 28) & 0x00F); - return this; - } - - @Override - public FilePath getPath(@Nullable final PathType pathType) { - if (nonNull(pathType)) { - switch (pathType) { - case DEPOT: - return depotPath; - case CLIENT: - return clientPath; - case LOCAL: - return localPath; - default: - break; - } - } - - return originalPath; - } - - @Override - public void setPath(@Nullable final FilePath filePath) { - if (nonNull(filePath)) { - if (nonNull(filePath.getPathType())) { - switch (filePath.getPathType()) { - case DEPOT: - depotPath = filePath; - return; - case CLIENT: - clientPath = filePath; - return; - case LOCAL: - localPath = filePath; - return; - default: - break; - } - } - } - - originalPath = filePath; - } - - @Override - public FileAction getAction() { - return action; - } - - @Override - public int getChangelistId() { - return changeListId; - } - - @Override - public String getClientName() { - return clientName; - } - - @Override - public FilePath getClientPath() { - return getPath(PathType.CLIENT); - } - - @Override - public InputStream getContents(boolean noHeaderLine) - throws ConnectionException, RequestException, AccessException { - checkServer(); - List fList = new ArrayList<>(); - fList.add(this); - - return server.getFileContents(fList, false, noHeaderLine); - } - - @Override - public InputStream getContents(GetFileContentsOptions opts) throws P4JavaException { - checkServer(); - List fList = new ArrayList<>(); - fList.add(this); - - return ((IOptionsServer) server).getFileContents(fList, opts); - } - - @Override - public FilePath getDepotPath() { - return getPath(PathType.DEPOT); - } - - @Override - public int getEndRevision() { - return endRevision; - } - - @Override - public String getFileType() { - return fileType; - } - - @Override - public String getLabel() { - return label; - } - - @Override - public FilePath getLocalPath() { - return getPath(PathType.LOCAL); - } - - @Override - public FileSpecOpStatus getOpStatus() { - return opStatus; - } - - @Override - public FilePath getPreferredPath() { - if (nonNull(originalPath)) { - return originalPath; - } else if (nonNull(depotPath)) { - return depotPath; - } else if (nonNull(clientPath)) { - return clientPath; - } else if (nonNull(localPath)) { - return localPath; - } - - return null; - } - - @Override - public Map> getRevisionHistory(final int maxRevs, - final boolean contentHistory, final boolean includeInherited, final boolean longOutput, - final boolean truncatedLongOutput) - throws ConnectionException, RequestException, AccessException { - - checkServer(); - return server.getRevisionHistory( - FileSpecBuilder.makeFileSpecList(getAnnotatedPreferredPathString()), maxRevs, - contentHistory, includeInherited, longOutput, truncatedLongOutput); - } - - @Override - public Map> getRevisionHistory( - GetRevisionHistoryOptions opts) throws P4JavaException { - checkServer(); - return ((IOptionsServer) server).getRevisionHistory( - FileSpecBuilder.makeFileSpecList(getAnnotatedPreferredPathString()), opts); - } - - @Override - public List getAnnotations(final DiffType wsOptions, final boolean allResults, - final boolean useChangeNumbers, final boolean followBranches) - throws ConnectionException, RequestException, AccessException { - - checkServer(); - List specList = new ArrayList<>(); - specList.add(this); - return server.getFileAnnotations(specList, wsOptions, allResults, useChangeNumbers, - followBranches); - } - - @Override - public List getAnnotations(GetFileAnnotationsOptions opts) - throws P4JavaException { - checkServer(); - List specList = new ArrayList<>(); - specList.add(this); - return ((IOptionsServer) server).getFileAnnotations(specList, opts); - } - - @Override - public List move(final int changelistId, final boolean listOnly, - final boolean noClientMove, final String fileType, final IFileSpec toFile) - throws ConnectionException, RequestException, AccessException { - - checkServer(); - return server.moveFile(changelistId, listOnly, noClientMove, fileType, this, toFile); - } - - @Override - public List move(final IFileSpec toFile, final MoveFileOptions opts) - throws P4JavaException { - checkServer(); - return ((IOptionsServer) server).moveFile(this, toFile, opts); - } - - private void checkServer() throws P4JavaError { - Validate.notNull(server); - if (!(server instanceof IOptionsServer)) { - // This should be impossible, but you never know... -- HR. - throw new P4JavaError("File specification is not associated with an options server"); - } - } - - @Override - public int getStartRevision() { - return startRevision; - } - - @Override - public String getStatusMessage() { - return statusMessage; - } - - @Override - public int getSeverityCode() { - return severityCode; - } - - @Override - public int getGenericCode() { - return genericCode; - } - - @Override - public String getUserName() { - return userName; - } - - @Override - public boolean isLocked() { - return locked; - } - - @Override - public String getDiffStatus() { - return diffStatus; - } - - @Override - public String getResolveType() { - return resolveType; - } - - @Override - public String getContentResolveType() { - return contentResolveType; - } - - @Override - public int getShelvedChange() { - return shelvedChange; - } - - public void setOpStatus(FileSpecOpStatus opStatus) { - this.opStatus = opStatus; - } - - public void setStatusMessage(String statusMessage) { - this.statusMessage = statusMessage; - } - - public void setOriginalPath(FilePath path) { - this.originalPath = path; - } - - public void setDepotPath(FilePath depotPath) { - this.depotPath = depotPath; - } - - public void setClientPath(FilePath clientPath) { - this.clientPath = clientPath; - } - - public void setLocalPath(FilePath localPath) { - this.localPath = localPath; - } - - @Override - public void setFileType(String fileType) { - this.fileType = fileType; - } - - @Override - public void setStartRevision(int startRevision) { - this.startRevision = startRevision; - } - - @Override - public void setEndRevision(int endRevision) { - this.endRevision = endRevision; - } - - @Override - public void setChangelistId(int changeListId) { - this.changeListId = changeListId; - } - - @Override - public void setLabel(String label) { - this.label = label; - } - - @Override - public void setAction(FileAction action) { - this.action = action; - } - - @Override - public void setUserName(String userName) { - this.userName = userName; - } - - @Override - public void setClientName(String clientName) { - this.clientName = clientName; - } - - public void setClient(IClient client) { - this.client = client; - } - - @Override - public int getEndFromRev() { - return endFromRev; - } - - @Override - public int getEndToRev() { - return endToRev; - } - - @Override - public String getFromFile() { - return fromFile; - } - - @Override - public String getHowResolved() { - return howResolved; - } - - @Override - public FileAction getOtherAction() { - return otherAction; - } - - @Override - public int getStartFromRev() { - return startFromRev; - } - - @Override - public int getStartToRev() { - return startToRev; - } - - @Override - public String getToFile() { - return toFile; - } - - @Override - public int getWorkRev() { - return workRev; - } - - @Override - public boolean isUnmap() { - return unmap; - } - - @Override - public void setDate(Date date) { - this.date = date; - } - - @Override - public void setFromFile(String fromFile) { - this.fromFile = fromFile; - } - - @Override - public void setEndFromRev(int endFromRev) { - this.endFromRev = endFromRev; - } - - @Override - public void setStartFromRev(int startFromRev) { - this.startFromRev = startFromRev; - } - - @Override - public void setToFile(String toFile) { - this.toFile = toFile; - } - - @Override - public void setEndToRev(int endToRev) { - this.endToRev = endToRev; - } - - @Override - public void setStartToRev(int startToRev) { - this.startToRev = startToRev; - } - - @Override - public void setWorkRev(int workRev) { - this.workRev = workRev; - } - - @Override - public void setHowResolved(String howResolved) { - this.howResolved = howResolved; - } - - @Override - public void setOtherAction(FileAction otherAction) { - this.otherAction = otherAction; - } - - @Override - public void setLocked(boolean locked) { - this.locked = locked; - } - - @Override - public void setDiffStatus(String diffStatus) { - this.diffStatus = diffStatus; - } - - @Override - public void setResolveType(String resolveType) { - this.resolveType = resolveType; - } - - @Override - public void setContentResolveType(String contentResolveType) { - this.contentResolveType = contentResolveType; - } - - @Override - public void setShelvedChange(int shelvedChange) { - this.shelvedChange = shelvedChange; - } - - @Override - public void setUnmap(boolean unmap) { - this.unmap = unmap; - } - - @Override - public void setRepoName(String repoName) { - this.repoName = repoName; - } - - @Override - public void setSha(String sha) { - this.sha = sha; - } - - @Override - public void setBranch(String branch) { - this.branch = branch; - } - - @Override - public String getBlobSha() { - return blobSha; - } - - @Override - public void setBlobSha(String sha) { - blobSha = sha; - } - - @Override - public String getCommitSha() { - return commitSha; - } - - @Override - public void setCommitSha(String sha) { - commitSha = sha; - } + setRepoName(parseString(map, REPO)); + } + } + + /** + * Set the various error codes for this FileSpec to a value returned from + * the server or the RPC layer. Use this if you're hand-constructing a new + * FileSpec for an error condition and you have the raw code. + * + * @param rawCode rawCode + * @return file spec + */ + public FileSpec setCodes(final int rawCode) { + this.rawCode = rawCode; + subCode = (rawCode & 0x3FF); + subSystem = ((rawCode >> 10) & 0x3F); + uniqueCode = (rawCode & 0xFFFF); + genericCode = ((rawCode >> 16) & 0xFF); + severityCode = ((rawCode >> 28) & 0x00F); + return this; + } + + @Override + public FilePath getPath(@Nullable final PathType pathType) { + if (nonNull(pathType)) { + switch (pathType) { + case DEPOT: + return depotPath; + case CLIENT: + return clientPath; + case LOCAL: + return localPath; + default: + break; + } + } + + return originalPath; + } + + @Override + public void setPath(@Nullable final FilePath filePath) { + if (nonNull(filePath)) { + if (nonNull(filePath.getPathType())) { + switch (filePath.getPathType()) { + case DEPOT: + depotPath = filePath; + return; + case CLIENT: + clientPath = filePath; + return; + case LOCAL: + localPath = filePath; + return; + default: + break; + } + } + } + + originalPath = filePath; + } + + @Override + public FileAction getAction() { + return action; + } + + @Override + public int getChangelistId() { + return changeListId; + } + + @Override + public String getClientName() { + return clientName; + } + + @Override + public FilePath getClientPath() { + return getPath(PathType.CLIENT); + } + + @Override + public InputStream getContents(boolean noHeaderLine) throws ConnectionException, RequestException, AccessException { + checkServer(); + List fList = new ArrayList<>(); + fList.add(this); + + return server.getFileContents(fList, false, noHeaderLine); + } + + @Override + public InputStream getContents(GetFileContentsOptions opts) throws P4JavaException { + checkServer(); + List fList = new ArrayList<>(); + fList.add(this); + + return ((IOptionsServer) server).getFileContents(fList, opts); + } + + @Override + public FilePath getDepotPath() { + return getPath(PathType.DEPOT); + } + + @Override + public int getEndRevision() { + return endRevision; + } + + @Override + public String getFileType() { + return fileType; + } + + @Override + public String getLabel() { + return label; + } + + @Override + public FilePath getLocalPath() { + return getPath(PathType.LOCAL); + } + + @Override + public FileSpecOpStatus getOpStatus() { + return opStatus; + } + + @Override + public FilePath getPreferredPath() { + if (nonNull(originalPath)) { + return originalPath; + } else if (nonNull(depotPath)) { + return depotPath; + } else if (nonNull(clientPath)) { + return clientPath; + } else if (nonNull(localPath)) { + return localPath; + } + + return null; + } + + @Override + public Map> getRevisionHistory(final int maxRevs, final boolean contentHistory, final boolean includeInherited, final boolean longOutput, final boolean truncatedLongOutput) throws ConnectionException, RequestException, AccessException { + + checkServer(); + return server.getRevisionHistory(FileSpecBuilder.makeFileSpecList(getAnnotatedPreferredPathString()), maxRevs, contentHistory, includeInherited, longOutput, truncatedLongOutput); + } + + @Override + public Map> getRevisionHistory(GetRevisionHistoryOptions opts) throws P4JavaException { + checkServer(); + return ((IOptionsServer) server).getRevisionHistory(FileSpecBuilder.makeFileSpecList(getAnnotatedPreferredPathString()), opts); + } + + @Override + public List getAnnotations(final DiffType wsOptions, final boolean allResults, final boolean useChangeNumbers, final boolean followBranches) throws ConnectionException, RequestException, AccessException { + + checkServer(); + List specList = new ArrayList<>(); + specList.add(this); + return server.getFileAnnotations(specList, wsOptions, allResults, useChangeNumbers, followBranches); + } + + @Override + public List getAnnotations(GetFileAnnotationsOptions opts) throws P4JavaException { + checkServer(); + List specList = new ArrayList<>(); + specList.add(this); + return ((IOptionsServer) server).getFileAnnotations(specList, opts); + } + + @Override + public List move(final int changelistId, final boolean listOnly, final boolean noClientMove, final String fileType, final IFileSpec toFile) throws ConnectionException, RequestException, AccessException { + + checkServer(); + return server.moveFile(changelistId, listOnly, noClientMove, fileType, this, toFile); + } + + @Override + public List move(final IFileSpec toFile, final MoveFileOptions opts) throws P4JavaException { + checkServer(); + return ((IOptionsServer) server).moveFile(this, toFile, opts); + } + + private void checkServer() throws P4JavaError { + Validate.notNull(server); + if (!(server instanceof IOptionsServer)) { + // This should be impossible, but you never know... -- HR. + throw new P4JavaError("File specification is not associated with an options server"); + } + } + + @Override + public int getStartRevision() { + return startRevision; + } + + @Override + public String getStatusMessage() { + return statusMessage; + } + + @Override + public int getSeverityCode() { + return severityCode; + } + + @Override + public int getGenericCode() { + return genericCode; + } + + @Override + public String getUserName() { + return userName; + } + + @Override + public boolean isLocked() { + return locked; + } + + @Override + public String getDiffStatus() { + return diffStatus; + } + + @Override + public String getResolveType() { + return resolveType; + } + + @Override + public String getContentResolveType() { + return contentResolveType; + } + + @Override + public int getShelvedChange() { + return shelvedChange; + } + + public void setOpStatus(FileSpecOpStatus opStatus) { + this.opStatus = opStatus; + } + + public void setStatusMessage(String statusMessage) { + this.statusMessage = statusMessage; + } + + public void setOriginalPath(FilePath path) { + this.originalPath = path; + } + + public void setDepotPath(FilePath depotPath) { + this.depotPath = depotPath; + } + + public void setClientPath(FilePath clientPath) { + this.clientPath = clientPath; + } + + public void setLocalPath(FilePath localPath) { + this.localPath = localPath; + } + + @Override + public void setFileType(String fileType) { + this.fileType = fileType; + } + + @Override + public void setStartRevision(int startRevision) { + this.startRevision = startRevision; + } + + @Override + public void setEndRevision(int endRevision) { + this.endRevision = endRevision; + } + + @Override + public void setChangelistId(int changeListId) { + this.changeListId = changeListId; + } + + @Override + public void setLabel(String label) { + this.label = label; + } + + @Override + public void setAction(FileAction action) { + this.action = action; + } + + @Override + public void setUserName(String userName) { + this.userName = userName; + } + + @Override + public void setClientName(String clientName) { + this.clientName = clientName; + } + + public void setClient(IClient client) { + this.client = client; + } + + @Override + public int getEndFromRev() { + return endFromRev; + } + + @Override + public int getEndToRev() { + return endToRev; + } + + @Override + public String getFromFile() { + return fromFile; + } + + @Override + public String getHowResolved() { + return howResolved; + } + + @Override + public FileAction getOtherAction() { + return otherAction; + } + + @Override + public int getStartFromRev() { + return startFromRev; + } + + @Override + public int getStartToRev() { + return startToRev; + } + + @Override + public String getToFile() { + return toFile; + } + + @Override + public int getWorkRev() { + return workRev; + } + + @Override + public boolean isUnmap() { + return unmap; + } + + @Override + public void setDate(Date date) { + this.date = date; + } + + @Override + public void setFromFile(String fromFile) { + this.fromFile = fromFile; + } + + @Override + public void setEndFromRev(int endFromRev) { + this.endFromRev = endFromRev; + } + + @Override + public void setStartFromRev(int startFromRev) { + this.startFromRev = startFromRev; + } + + @Override + public void setToFile(String toFile) { + this.toFile = toFile; + } + + @Override + public void setEndToRev(int endToRev) { + this.endToRev = endToRev; + } + + @Override + public void setStartToRev(int startToRev) { + this.startToRev = startToRev; + } + + @Override + public void setWorkRev(int workRev) { + this.workRev = workRev; + } + + @Override + public void setHowResolved(String howResolved) { + this.howResolved = howResolved; + } + + @Override + public void setOtherAction(FileAction otherAction) { + this.otherAction = otherAction; + } + + @Override + public void setLocked(boolean locked) { + this.locked = locked; + } + + @Override + public void setDiffStatus(String diffStatus) { + this.diffStatus = diffStatus; + } + + @Override + public void setResolveType(String resolveType) { + this.resolveType = resolveType; + } + + @Override + public void setContentResolveType(String contentResolveType) { + this.contentResolveType = contentResolveType; + } + + @Override + public void setShelvedChange(int shelvedChange) { + this.shelvedChange = shelvedChange; + } + + @Override + public void setUnmap(boolean unmap) { + this.unmap = unmap; + } + + @Override + public void setRepoName(String repoName) { + this.repoName = repoName; + } + + @Override + public void setSha(String sha) { + this.sha = sha; + } + + @Override + public void setBranch(String branch) { + this.branch = branch; + } + + @Override + public String getBlobSha() { + return blobSha; + } + + @Override + public void setBlobSha(String sha) { + blobSha = sha; + } + + @Override + public String getCommitSha() { + return commitSha; + } + + @Override + public void setCommitSha(String sha) { + commitSha = sha; + } @Override public String getTreeSha() { @@ -945,217 +943,216 @@ public void setTreeSha(String sha) { treeSha = sha; } - public static int getRevFromString(String str) { - int rev = NO_FILE_REVISION; - - if (isNotBlank(str)) { - // can be in #rev or rev form, unfortunately... - if (contains(str, "head")) { - return HEAD_REVISION; - } - - if (contains(str, "none")) { - return NO_FILE_REVISION; - } - - try { - int length = length(str); - if (startsWith(str, "#") && length > 1) { - rev = Integer.valueOf(substring(str, 1)); - } else if (length > 0) { - rev = Integer.valueOf(str); - } - } catch (Exception exc) { - Log.error("Conversion error in FileSpec.getRevFromString: %s", - exc.getLocalizedMessage()); - Log.exception(exc); - } - } - return rev; - } - - @Override - public String getClientPathString() { - return getPathString(PathType.CLIENT); - } - - @Override - public String getDepotPathString() { - return getPathString(PathType.DEPOT); - } - - @Override - public String getLocalPathString() { - return getPathString(PathType.LOCAL); - } - - @Override - public FilePath getOriginalPath() { - if (nonNull(getPath(PathType.ORIGINAL))) { // See job061945 - return getPath(PathType.ORIGINAL); - } else { // API backward compatibility - See job070533 - return getPath(PathType.CLIENT); - } - } - - @Override - public String getOriginalPathString() { - if (nonNull(getPathString(PathType.ORIGINAL))) { // See job061945 - return getPathString(PathType.ORIGINAL); - } else { // API backward compatibility - See job070533 - return getPathString(PathType.CLIENT); - } - } - - @Override - public String getPathString(PathType pathType) { - FilePath fPath = getPath(pathType); - - if (nonNull(fPath)) { - return fPath.toString(); - } - return null; - } - - @Override - public String getAnnotatedPathString(PathType pathType) { - FilePath path = getPath(pathType); - if (nonNull(path)) { - return path.annotate(this); - } - - return null; - } - - @Override - public String getPreferredPathString() { - FilePath prefPath = getPreferredPath(); - - if (nonNull(prefPath) && nonNull(prefPath.getPathString())) { - return prefPath.toString(); - } - - return null; - } - - @Override - public String getAnnotatedPreferredPathString() { - FilePath prefPath = getPreferredPath(); - - if (nonNull(prefPath) && nonNull(prefPath.getPathString())) { - return prefPath.annotate(this); - } - - return null; - } - - @Override - public String toString() { - String usefulDescription = getAnnotatedPreferredPathString(); - if ( usefulDescription == null && statusMessage != null ) { - usefulDescription = opStatus + ": "+ statusMessage; - } + public static int getRevFromString(String str) { + int rev = NO_FILE_REVISION; + + if (isNotBlank(str)) { + // can be in #rev or rev form, unfortunately... + if (contains(str, "head")) { + return HEAD_REVISION; + } + + if (contains(str, "none")) { + return NO_FILE_REVISION; + } + + try { + int length = length(str); + if (startsWith(str, "#") && length > 1) { + rev = Integer.valueOf(substring(str, 1)); + } else if (length > 0) { + rev = Integer.valueOf(str); + } + } catch (Exception exc) { + Log.error("Conversion error in FileSpec.getRevFromString: %s", exc.getLocalizedMessage()); + Log.exception(exc); + } + } + return rev; + } + + @Override + public String getClientPathString() { + return getPathString(PathType.CLIENT); + } + + @Override + public String getDepotPathString() { + return getPathString(PathType.DEPOT); + } + + @Override + public String getLocalPathString() { + return getPathString(PathType.LOCAL); + } + + @Override + public FilePath getOriginalPath() { + if (nonNull(getPath(PathType.ORIGINAL))) { // See job061945 + return getPath(PathType.ORIGINAL); + } else { // API backward compatibility - See job070533 + return getPath(PathType.CLIENT); + } + } + + @Override + public String getOriginalPathString() { + if (nonNull(getPathString(PathType.ORIGINAL))) { // See job061945 + return getPathString(PathType.ORIGINAL); + } else { // API backward compatibility - See job070533 + return getPathString(PathType.CLIENT); + } + } + + @Override + public String getPathString(PathType pathType) { + FilePath fPath = getPath(pathType); + + if (nonNull(fPath)) { + return fPath.toString(); + } + return null; + } + + @Override + public String getAnnotatedPathString(PathType pathType) { + FilePath path = getPath(pathType); + if (nonNull(path)) { + return path.annotate(this); + } + + return null; + } + + @Override + public String getPreferredPathString() { + FilePath prefPath = getPreferredPath(); + + if (nonNull(prefPath) && nonNull(prefPath.getPathString())) { + return prefPath.toString(); + } + + return null; + } + + @Override + public String getAnnotatedPreferredPathString() { + FilePath prefPath = getPreferredPath(); + + if (nonNull(prefPath) && nonNull(prefPath.getPathString())) { + return prefPath.annotate(this); + } + + return null; + } + + @Override + public String toString() { + String usefulDescription = getAnnotatedPreferredPathString(); + if (usefulDescription == null && statusMessage != null) { + usefulDescription = opStatus + ": " + statusMessage; + } if (usefulDescription == null && repoName != null) { usefulDescription = repoName + ": " + sha; } - return usefulDescription; - } - - @Override - public void setPathFromString(PathType pathType, String pathStr) { - FilePath path = new FilePath(pathType, pathStr); - setPath(path); - } - - @Override - public Date getDate() { - return this.date; - } - - @Override - public void setClientPath(String pathStr) { - setPath(new FilePath(PathType.CLIENT, pathStr)); - } - - @Override - public void setDepotPath(String pathStr) { - setPath(new FilePath(PathType.DEPOT, pathStr)); - } - - @Override - public void setLocalPath(String pathStr) { - setPath(new FilePath(PathType.LOCAL, pathStr)); - } - - @Override - public void setOriginalPath(String pathStr) { - setPath(new FilePath(PathType.ORIGINAL, pathStr)); - } - - @Override - public int getBaseRev() { - return baseRev; - } - - @Override - public void setBaseRev(int baseRev) { - this.baseRev = baseRev; - } - - @Override - public String getBaseName() { - return baseName; - } - - @Override - public void setBaseName(String baseName) { - this.baseName = baseName; - } - - @Override - public String getBaseFile() { - return baseFile; - } - - @Override - public void setBaseFile(String baseFile) { - this.baseFile = baseFile; - } - - @Override - public int getRawCode() { - return rawCode; - } - - @Override - public int getUniqueCode() { - return uniqueCode; - } - - @Override - public int getSubCode() { - return subCode; - } - - @Override - public int getSubSystem() { - return subSystem; - } - - @Override - public String getRepoName() { - return repoName; - } - - @Override - public String getSha() { - return sha; - } - - @Override - public String getBranch() { - return branch; - } + return usefulDescription; + } + + @Override + public void setPathFromString(PathType pathType, String pathStr) { + FilePath path = new FilePath(pathType, pathStr); + setPath(path); + } + + @Override + public Date getDate() { + return this.date; + } + + @Override + public void setClientPath(String pathStr) { + setPath(new FilePath(PathType.CLIENT, pathStr)); + } + + @Override + public void setDepotPath(String pathStr) { + setPath(new FilePath(PathType.DEPOT, pathStr)); + } + + @Override + public void setLocalPath(String pathStr) { + setPath(new FilePath(PathType.LOCAL, pathStr)); + } + + @Override + public void setOriginalPath(String pathStr) { + setPath(new FilePath(PathType.ORIGINAL, pathStr)); + } + + @Override + public int getBaseRev() { + return baseRev; + } + + @Override + public void setBaseRev(int baseRev) { + this.baseRev = baseRev; + } + + @Override + public String getBaseName() { + return baseName; + } + + @Override + public void setBaseName(String baseName) { + this.baseName = baseName; + } + + @Override + public String getBaseFile() { + return baseFile; + } + + @Override + public void setBaseFile(String baseFile) { + this.baseFile = baseFile; + } + + @Override + public int getRawCode() { + return rawCode; + } + + @Override + public int getUniqueCode() { + return uniqueCode; + } + + @Override + public int getSubCode() { + return subCode; + } + + @Override + public int getSubSystem() { + return subSystem; + } + + @Override + public String getRepoName() { + return repoName; + } + + @Override + public String getSha() { + return sha; + } + + @Override + public String getBranch() { + return branch; + } @Override public List getResolveTypes() { diff --git a/src/main/java/com/perforce/p4java/impl/generic/core/file/IExtensionSummary.java b/src/main/java/com/perforce/p4java/impl/generic/core/file/IExtensionSummary.java index 79a584c..1fcbfac 100644 --- a/src/main/java/com/perforce/p4java/impl/generic/core/file/IExtensionSummary.java +++ b/src/main/java/com/perforce/p4java/impl/generic/core/file/IExtensionSummary.java @@ -100,63 +100,86 @@ public interface IExtensionSummary { /** * Set the name of the Extension being configured. + * + * @param extName name */ void setExtName(String extName); - /** Set the version of the Extension being configured. + /** + * Set the version of the Extension being configured. * + * @param extVersion version */ void setExtVersion(String extVersion); /** * Set the UUID/key of the Extension being configured. + * + * @param extUUID UUID */ void setExtUUID(String extUUID); /** * Set the revision of the Extension being configured. + * + * @param extRev revision */ void setExtRev(String extRev); /** * Enable or disable the extension + * * @param extEnabled true/false */ void setExtEnabled(String extEnabled); /** * Set the namespace of this Extension config. + * + * @param name name */ void setNameSpace(String name); /** * Set the extension developer field. + * + * @param extDeveloper developer */ void setExtDeveloper(String extDeveloper); /** - * Set the Extension description snippet. + * Set the Extension description snippet. + * + * @param extDescriptionSnippet description */ void setExtDescriptionSnippet(String extDescriptionSnippet); /** * Set the path to the file in the server extension’s unpacked archive directory. * This path is relative to the server.extensions.dir configurable. + * + * @param extArchDir archive directory */ void setExtArchDir(String extArchDir); /** * Set path in which the server extension will store the files it creates. + * + * @param extDataDir data directory */ void setExtDataDir(String extDataDir); /** * Set extension as a global. + * + * @param extGlobalConf is global */ void setExtGlobalConf(boolean extGlobalConf); /** * Set extension as an instance. + * + * @param extInstanceConf is instance */ void setExtInstanceConf(boolean extInstanceConf); } diff --git a/src/main/java/com/perforce/p4java/impl/generic/core/file/ObliterateResult.java b/src/main/java/com/perforce/p4java/impl/generic/core/file/ObliterateResult.java index 955f913..948099a 100644 --- a/src/main/java/com/perforce/p4java/impl/generic/core/file/ObliterateResult.java +++ b/src/main/java/com/perforce/p4java/impl/generic/core/file/ObliterateResult.java @@ -3,13 +3,13 @@ */ package com.perforce.p4java.impl.generic.core.file; -import java.util.ArrayList; -import java.util.List; - import com.perforce.p4java.core.file.IFileSpec; import com.perforce.p4java.core.file.IObliterateResult; import com.perforce.p4java.exception.NullPointerError; +import java.util.ArrayList; +import java.util.List; + /** * The various record stats returned by the obliterateFiles method. Obliterate * removes files and their history from the depot. The Perforce server returns @@ -29,11 +29,17 @@ public class ObliterateResult implements IObliterateResult { /** * Explicit parameterized constructor + * + * @param fileSpecs fileSpecs + * @param integrationRecAdded integrationRecAdded + * @param labelRecDeleted labelRecDeleted + * @param clientRecDeleted clientRecDeleted + * @param integrationRecDeleted integrationRecDeleted + * @param workingRecDeleted workingRecDeleted + * @param revisionRecDeleted revisionRecDeleted + * @param reportOnly reportOnly */ - public ObliterateResult(List fileSpecs, int integrationRecAdded, - int labelRecDeleted, int clientRecDeleted, - int integrationRecDeleted, int workingRecDeleted, - int revisionRecDeleted, boolean reportOnly) { + public ObliterateResult(List fileSpecs, int integrationRecAdded, int labelRecDeleted, int clientRecDeleted, int integrationRecDeleted, int workingRecDeleted, int revisionRecDeleted, boolean reportOnly) { if (fileSpecs == null) { throw new NullPointerError("null fileSpecs passed to ObliterateResult constructor"); diff --git a/src/main/java/com/perforce/p4java/impl/generic/core/file/PathAnnotations.java b/src/main/java/com/perforce/p4java/impl/generic/core/file/PathAnnotations.java index 49fe337..36356bf 100644 --- a/src/main/java/com/perforce/p4java/impl/generic/core/file/PathAnnotations.java +++ b/src/main/java/com/perforce/p4java/impl/generic/core/file/PathAnnotations.java @@ -1,18 +1,18 @@ /** - * + * */ package com.perforce.p4java.impl.generic.core.file; +import com.perforce.p4java.Log; +import com.perforce.p4java.core.IChangelist; +import com.perforce.p4java.core.file.IFileSpec; + import java.text.FieldPosition; import java.text.SimpleDateFormat; import java.util.Date; import java.util.regex.Matcher; import java.util.regex.Pattern; -import com.perforce.p4java.Log; -import com.perforce.p4java.core.IChangelist; -import com.perforce.p4java.core.file.IFileSpec; - /** * Conveniently bundles up possible Perforce path-based metadata * annotations and associated operations. This includes revision, @@ -22,72 +22,57 @@ */ public class PathAnnotations { - + /** * The string used to start Perforce file revision metadata annotations. */ public static final String REV_PFX = "#"; - + /** * The string used to separate Perforce file revision metadata annotations. */ public static final String REV_SEP = ",#"; - + /** * The string used to start Perforce file label / changelist / date metadata * annotations. */ public static final String NONREV_PFX = "@"; // non-revision prefix, i.e. - // label, date and changelist prefix... + // label, date and changelist prefix... protected int startRevision = IFileSpec.NO_FILE_REVISION; protected int endRevision = IFileSpec.NO_FILE_REVISION; protected Date date = null; protected int changelistId = IChangelist.UNKNOWN; protected String label = null; - + /** * Describes what to search for to see if any Perforce revision annotation metadata * is in the path string. */ - private static Pattern revMetadata = Pattern.compile( - "((#)(\\d+)$)" - + "|(#none$)" - + "|(#head$)" - + "|(#have$)" - + "|(#have,#head$)" - + "|((#)(\\d+),#(\\d+)$)" - + "|((#)(\\d+),#head$)" - + "|((#)(\\d+),#have$)" - + "|(#)have,(\\d+)$" - ); - + private static Pattern revMetadata = Pattern.compile("((#)(\\d+)$)" + "|(#none$)" + "|(#head$)" + "|(#have$)" + "|(#have,#head$)" + "|((#)(\\d+),#(\\d+)$)" + "|((#)(\\d+),#head$)" + "|((#)(\\d+),#have$)" + "|(#)have,(\\d+)$"); + /** * Describes what to search for to see if any Perforce non-revision annotation metadata * is in the path string. */ - private static Pattern nonRevMetadata = Pattern.compile( - "((@)(\\d+)$)" - + "|((@)(\\d+\\/\\d+\\/\\d+)$)" - + "|((@)(\\d+\\/\\d+\\/\\d+:\\d+:\\d+:\\d+)$)" - + "|((@)([^@,%#]+)$)" - ); - - private static Pattern revNumNum = Pattern.compile("(#)(\\d+),#(\\d+)$"); // #2,#3 - private static Pattern revNumHead = Pattern.compile("(#)(\\d+),#head$"); // #3,#head - private static Pattern revNumHave = Pattern.compile("(#)(\\d+),#have$"); // #3,#have - private static Pattern revHaveNum = Pattern.compile("#have,#(\\d+)$"); // #have,#3 - private static Pattern revNum = Pattern.compile("(#)(\\d+)$"); // #3 - private static Pattern revNone = Pattern.compile("#none$"); // #none - private static Pattern revHead = Pattern.compile("#head$"); // #head - private static Pattern revHave = Pattern.compile("#have$"); // #have - private static Pattern revHaveHead = Pattern.compile("#have,#head$"); // #have,#head - - private static Pattern nonrevChange = Pattern.compile("(@)(\\d+)$"); // @12345 - private static Pattern nonrevDateShort = Pattern.compile("(@)(\\d+\\/\\d+\\/\\d+)$"); // @yyyy/MM/dd + private static Pattern nonRevMetadata = Pattern.compile("((@)(\\d+)$)" + "|((@)(\\d+\\/\\d+\\/\\d+)$)" + "|((@)(\\d+\\/\\d+\\/\\d+:\\d+:\\d+:\\d+)$)" + "|((@)([^@,%#]+)$)"); + + private static Pattern revNumNum = Pattern.compile("(#)(\\d+),#(\\d+)$"); // #2,#3 + private static Pattern revNumHead = Pattern.compile("(#)(\\d+),#head$"); // #3,#head + private static Pattern revNumHave = Pattern.compile("(#)(\\d+),#have$"); // #3,#have + private static Pattern revHaveNum = Pattern.compile("#have,#(\\d+)$"); // #have,#3 + private static Pattern revNum = Pattern.compile("(#)(\\d+)$"); // #3 + private static Pattern revNone = Pattern.compile("#none$"); // #none + private static Pattern revHead = Pattern.compile("#head$"); // #head + private static Pattern revHave = Pattern.compile("#have$"); // #have + private static Pattern revHaveHead = Pattern.compile("#have,#head$"); // #have,#head + + private static Pattern nonrevChange = Pattern.compile("(@)(\\d+)$"); // @12345 + private static Pattern nonrevDateShort = Pattern.compile("(@)(\\d+\\/\\d+\\/\\d+)$"); // @yyyy/MM/dd private static Pattern nonrevDateFull = Pattern.compile("(@)(\\d+\\/\\d+\\/\\d+:\\d+:\\d+:\\d+)$"); // @yyyy/MM/dd:HH:mm:ss - private static Pattern nonrevLabel = Pattern.compile("(@)([^@,%#]+)$"); // @labelname - + private static Pattern nonrevLabel = Pattern.compile("(@)([^@,%#]+)$"); // @labelname + /** * Construct a PathAnnotations object with default field values:
* startRev, endRev = IFileSpec.NO_FILE_REVISION;
@@ -99,22 +84,27 @@ public PathAnnotations() { /** * Construct a PathAnnotations object from explicit candidate field values. + * + * @param startRevision startRevision + * @param endRevision endRevision + * @param date date + * @param changelistId changelistId + * @param label label */ - - public PathAnnotations(int startRevision, int endRevision, Date date, - int changelistId, String label) { + public PathAnnotations(int startRevision, int endRevision, Date date, int changelistId, String label) { this.startRevision = startRevision; this.endRevision = endRevision; this.date = date; this.changelistId = changelistId; this.label = label; } - + /** * Construct a PathAnnotations object for a specific file spec. If fileSpec * is null, this is equivalent to calling the default constructor. + * + * @param fileSpec fileSpec */ - public PathAnnotations(IFileSpec fileSpec) { if (fileSpec != null) { this.startRevision = fileSpec.getStartRevision(); @@ -124,13 +114,15 @@ public PathAnnotations(IFileSpec fileSpec) { this.label = fileSpec.getLabel(); } } - + /** * Construct a PathAnnotations object from the passed-in string, * which is assumed to contain a path string with optional * Perforce annotations. If pathStr is null, or contains no * parseable annotations, this is equivalent to calling the * default constructor. + * + * @param pathStr pathStr */ public PathAnnotations(String pathStr) { if (pathStr != null) { @@ -141,12 +133,15 @@ public PathAnnotations(String pathStr) { } } } - + /** * Strip any Perforce file metadata annotations from the passed-in string. * Returns the string as-is if there were no annotations or if the string * was null. Will return the empty (not null) string if there was no actual * path part of the string and pathStr wasn't null. + * + * @param pathStr pathStr + * @return stripped path */ public static String stripAnnotations(String pathStr) { if (pathStr != null) { @@ -157,27 +152,33 @@ public static String stripAnnotations(String pathStr) { return pathStr.substring(0, i); } } - + return pathStr; } - + /** * Get all Perforce metadata annotations from the passed-in string. If * there are no annotations, or the passed-in pathStr argument is null, * returns null. + * + * @param pathStr pathStr + * @return path annotations */ public static PathAnnotations getAnnotations(String pathStr) { if ((pathStr != null) && (PathAnnotations.hasPerforceAnnotations(pathStr))) { return new PathAnnotations(pathStr); } - + return null; } - + /** * Return non-negative index of first non-revision Perforce annotations match in the * string if the passed-in string is not null has Perforce * revision annotations appended to it. Otherwise returns -1. + * + * @param pathStr pathStr + * @return index */ public static int hasRevisionAnnotations(String pathStr) { if (pathStr != null) { @@ -188,14 +189,17 @@ public static int hasRevisionAnnotations(String pathStr) { } } } - + return -1; } - + /** * Return non-negative index of first non-revision Perforce annotations match in the * string if the passed-in string is not null and has label, changelist, date, * etc., specs appended. Otherwise returns -1. + * + * @param pathStr pathStr + * @return index */ public static int hasNonRevisionAnnotations(String pathStr) { if (pathStr != null) { @@ -206,25 +210,31 @@ public static int hasNonRevisionAnnotations(String pathStr) { } } } - + return -1; } - + /** * Return true if the passed-in path is not null and has Perforce file * metadata appended to it. + * + * @param pathStr pathStr + * @return has matadata */ public static boolean hasPerforceAnnotations(String pathStr) { - return (hasRevisionAnnotations(pathStr) >= 0) - || (hasNonRevisionAnnotations(pathStr) >= 0); + return (hasRevisionAnnotations(pathStr) >= 0) || (hasNonRevisionAnnotations(pathStr) >= 0); } - + /** * Extract any start / end revision info from the passed-in pathStr and put it into * the passed-in pathAnnotations object. Returns true if it found any parseable - * revision information, false otherwise.

- * + * revision information, false otherwise. + *

* If either or both pathStr and pathAnnotations is null, returns false. + * + * @param pathStr pathStr + * @param pathAnnotations pathAnnotations + * @return true if parseable revision data */ public static boolean extractRevisionData(String pathStr, PathAnnotations pathAnnotations) { /* @@ -236,79 +246,79 @@ public static boolean extractRevisionData(String pathStr, PathAnnotations pathAn * #have * #have,#head (is this legal?) */ - + try { // Note: match order is significant below; don't change it unless // you're sure you know what you're doing... - + if ((pathStr != null) && (pathAnnotations != null)) { - + Matcher mat = revNumNum.matcher(pathStr); - + if (mat.find()) { pathAnnotations.startRevision = new Integer(mat.group(2)); pathAnnotations.endRevision = new Integer(mat.group(3)); return true; } - + mat = revNumHead.matcher(pathStr); - + if (mat.find()) { pathAnnotations.startRevision = new Integer(mat.group(2)); pathAnnotations.endRevision = IFileSpec.HEAD_REVISION; return true; } - + mat = revNumHave.matcher(pathStr); - + if (mat.find()) { pathAnnotations.startRevision = new Integer(mat.group(2)); pathAnnotations.endRevision = IFileSpec.HAVE_REVISION; return true; } - + mat = revHaveNum.matcher(pathStr); - + if (mat.find()) { pathAnnotations.startRevision = IFileSpec.HAVE_REVISION; pathAnnotations.endRevision = new Integer(mat.group(1)); return true; } - + mat = revHaveHead.matcher(pathStr); - + if (mat.find()) { pathAnnotations.startRevision = IFileSpec.HAVE_REVISION; pathAnnotations.endRevision = IFileSpec.HEAD_REVISION; return true; } - + mat = revNum.matcher(pathStr); - + if (mat.find()) { pathAnnotations.startRevision = IFileSpec.NO_FILE_REVISION; pathAnnotations.endRevision = new Integer(mat.group(2)); return true; } - + mat = revHead.matcher(pathStr); - + if (mat.find()) { pathAnnotations.startRevision = IFileSpec.NO_FILE_REVISION; pathAnnotations.endRevision = IFileSpec.HEAD_REVISION; return true; } - + mat = revHave.matcher(pathStr); - + if (mat.find()) { pathAnnotations.startRevision = IFileSpec.NO_FILE_REVISION; pathAnnotations.endRevision = IFileSpec.HAVE_REVISION; return true; } - + mat = revNone.matcher(pathStr); - + if (mat.find()) { pathAnnotations.startRevision = IFileSpec.NO_FILE_REVISION; pathAnnotations.endRevision = IFileSpec.NONE_REVISION; @@ -316,84 +326,83 @@ public static boolean extractRevisionData(String pathStr, PathAnnotations pathAn } } } catch (Throwable thr) { - Log.error("Unexpected exception in PathAnnotations.extractRevisionData; " - + "pathStr: " + pathStr + "; message: " - + thr.getLocalizedMessage()); + Log.error("Unexpected exception in PathAnnotations.extractRevisionData; " + "pathStr: " + pathStr + "; message: " + thr.getLocalizedMessage()); Log.exception(thr); } - + return false; } - + /** * Extract any non-revision info from the passed-in pathStr and put it into * the passed-in pathAnnotations object. Returns true if it found any parseable - * label / changelist / date (etc.) information, false otherwise.

- * + * label / changelist / date (etc.) information, false otherwise. + *

* Note that the candidate string "@2009/09/12" is ambiguous -- it could be * either a date or a label by a generous reading of the Perforce specs -- but * we take the "if it looks like a duck..." approach here and parse it as a date * if at all possible. Similarly for the string "@12345" which could be a changelist - * ID or a label ID -- we parse it as a changelist ID if at all possible.

- * + * ID or a label ID -- we parse it as a changelist ID if at all possible. + *

* If either or both pathStr and pathAnnotations is null, returns false. + * + * @param pathStr pathStr + * @param pathAnnotations pathAnnotations + * @return false if null */ public static boolean extractNonRevisionData(String pathStr, PathAnnotations pathAnnotations) { // @date: @2009/08/15 // @changelistid: @34567 // @label: @Label10A - + // NOTE: the order of matching below is critical; don't change it unless // you know what you're doing and why you're doing it... - + if ((pathStr != null) && (pathAnnotations != null)) { try { Matcher mat = nonrevChange.matcher(pathStr); - + if (mat.find()) { pathAnnotations.changelistId = new Integer(mat.group(2)); return true; } - + mat = nonrevDateShort.matcher(pathStr); - + if (mat.find()) { pathAnnotations.date = new SimpleDateFormat("yyyy/MM/dd").parse(mat.group(2));// HH:mm:ss return true; } - + mat = nonrevDateFull.matcher(pathStr); - + if (mat.find()) { pathAnnotations.date = new SimpleDateFormat("yyyy/MM/dd:HH:mm:ss").parse(mat.group(2));// HH:mm:ss return true; } - + mat = nonrevLabel.matcher(pathStr); - + if (mat.find()) { pathAnnotations.label = mat.group(2); return true; } } catch (Exception exc) { - Log.error("Unexpected parse exception in PathAnnotations.extractNonRevData: " - + exc.getLocalizedMessage()); + Log.error("Unexpected parse exception in PathAnnotations.extractNonRevData: " + exc.getLocalizedMessage()); Log.exception(exc); } } - + return false; } - + /** * Return a Perforce-standard string representation of this * annotation. Will return an empty (not null) string if there's * nothing to represent. */ - public String toString() { - if ((startRevision != IFileSpec.NO_FILE_REVISION) - && (endRevision != IFileSpec.NO_FILE_REVISION)) { + if ((startRevision != IFileSpec.NO_FILE_REVISION) && (endRevision != IFileSpec.NO_FILE_REVISION)) { return REV_PFX + revString(startRevision) + REV_SEP + revString(endRevision); } else if (endRevision != IFileSpec.NO_FILE_REVISION) { return REV_PFX + revString(endRevision); @@ -404,12 +413,12 @@ public String toString() { } else if (getDate() != null) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd:HH:mm:ss"); StringBuffer sBuf = new StringBuffer(); - + sdf.format(getDate(), sBuf, new FieldPosition(0)); - + return NONREV_PFX + sBuf.toString(); } - + return ""; } @@ -452,22 +461,23 @@ public String getLabel() { public void setLabel(String label) { this.label = label; } - + private static String revString(int revision) { switch (revision) { case IFileSpec.NO_FILE_REVISION: return IFileSpec.NO_REVISION_STRING; - + case IFileSpec.NONE_REVISION: return IFileSpec.NONE_REVISION_STRING; - + case IFileSpec.HAVE_REVISION: return IFileSpec.HAVE_REVISION_STRING; - + case IFileSpec.HEAD_REVISION: return IFileSpec.HEAD_REVISION_STRING; - - default: return "" + revision; + + default: + return "" + revision; } } } diff --git a/src/main/java/com/perforce/p4java/impl/generic/core/file/ResolveRecord.java b/src/main/java/com/perforce/p4java/impl/generic/core/file/ResolveRecord.java index 7a767b2..453ff5b 100644 --- a/src/main/java/com/perforce/p4java/impl/generic/core/file/ResolveRecord.java +++ b/src/main/java/com/perforce/p4java/impl/generic/core/file/ResolveRecord.java @@ -1,15 +1,20 @@ /** - * + * */ package com.perforce.p4java.impl.generic.core.file; -import java.util.Map; - import com.perforce.p4java.Log; import com.perforce.p4java.core.file.FileAction; import com.perforce.p4java.core.file.IResolveRecord; -import static com.perforce.p4java.impl.mapbased.rpc.func.RpcFunctionMapKey.*; +import java.util.Map; + +import static com.perforce.p4java.impl.mapbased.rpc.func.RpcFunctionMapKey.RESOLVE_ACTION; +import static com.perforce.p4java.impl.mapbased.rpc.func.RpcFunctionMapKey.RESOLVE_BASE_FILE; +import static com.perforce.p4java.impl.mapbased.rpc.func.RpcFunctionMapKey.RESOLVE_BASE_REV; +import static com.perforce.p4java.impl.mapbased.rpc.func.RpcFunctionMapKey.RESOLVE_END_FROM_REV; +import static com.perforce.p4java.impl.mapbased.rpc.func.RpcFunctionMapKey.RESOLVE_FROM_FILE; +import static com.perforce.p4java.impl.mapbased.rpc.func.RpcFunctionMapKey.RESOLVE_START_FROM_REV; /** * Default implementation class for the IResolveRecord interface. @@ -23,19 +28,24 @@ public class ResolveRecord implements IResolveRecord { private String resolveFromFile = null; private int resolveStartFromRevision = 0; private String resolveType = null; - + /** * Default constructor; sets all fields to zero or null. */ public ResolveRecord() { } - + /** * Explicit-value constructor. - */ - public ResolveRecord(FileAction resolveAction, String resolveBaseFile, - int resolveBaseRevision, int resolveEndFromRevision, - String resolveFromFile, int resolveStartFromRevision) { + * + * @param resolveAction resolveAction + * @param resolveBaseFile resolveBaseFile + * @param resolveBaseRevision resolveBaseRevision + * @param resolveEndFromRevision resolveEndFromRevision + * @param resolveFromFile resolveFromFile + * @param resolveStartFromRevision resolveStartFromRevision + */ + public ResolveRecord(FileAction resolveAction, String resolveBaseFile, int resolveBaseRevision, int resolveEndFromRevision, String resolveFromFile, int resolveStartFromRevision) { this.resolveAction = resolveAction; this.resolveBaseFile = resolveBaseFile; this.resolveBaseRevision = resolveBaseRevision; @@ -43,13 +53,16 @@ public ResolveRecord(FileAction resolveAction, String resolveBaseFile, this.resolveFromFile = resolveFromFile; this.resolveStartFromRevision = resolveStartFromRevision; } - + /** * Construct a new ResolveRecord from the passed-in map. This map is assumed * to have been returned from the getExtendedFiles method; other maps will * probably not work. The recNum parameter is used to tell the constructor * which resolve rec to extract. If map is null and / or recNum is negative, * this is equivalent to calling the default constructor. + * + * @param map map + * @param recNum recNum */ public ResolveRecord(Map map, int recNum) { if ((map != null) && (recNum >= 0)) { @@ -69,90 +82,89 @@ public ResolveRecord(Map map, int recNum) { this.resolveEndFromRevision = new Integer((String) map.get(RESOLVE_END_FROM_REV + recNum)); } } catch (Throwable thr) { - Log.error( - "Unexpected exception in ResolveRecord constructor: " + thr.getLocalizedMessage()); + Log.error("Unexpected exception in ResolveRecord constructor: " + thr.getLocalizedMessage()); Log.exception(thr); } } } - + /** * @see com.perforce.p4java.core.file.IResolveRecord#getResolveAction() */ public FileAction getResolveAction() { return resolveAction; } - + /** * @see com.perforce.p4java.core.file.IResolveRecord#setResolveAction(com.perforce.p4java.core.file.FileAction) */ public void setResolveAction(FileAction resolveAction) { this.resolveAction = resolveAction; } - + /** * @see com.perforce.p4java.core.file.IResolveRecord#getResolveBaseFile() */ public String getResolveBaseFile() { return resolveBaseFile; } - + /** * @see com.perforce.p4java.core.file.IResolveRecord#setResolveBaseFile(java.lang.String) */ public void setResolveBaseFile(String resolveBaseFile) { this.resolveBaseFile = resolveBaseFile; } - + /** * @see com.perforce.p4java.core.file.IResolveRecord#getResolveBaseRevision() */ public int getResolveBaseRevision() { return resolveBaseRevision; } - + /** * @see com.perforce.p4java.core.file.IResolveRecord#setResolveBaseRevision(int) */ public void setResolveBaseRevision(int resolveBaseRevision) { this.resolveBaseRevision = resolveBaseRevision; } - + /** * @see com.perforce.p4java.core.file.IResolveRecord#getResolveEndFromRevision() */ public int getResolveEndFromRevision() { return resolveEndFromRevision; } - + /** * @see com.perforce.p4java.core.file.IResolveRecord#setResolveEndFromRevision(int) */ public void setResolveEndFromRevision(int resolveEndFromRevision) { this.resolveEndFromRevision = resolveEndFromRevision; } - + /** * @see com.perforce.p4java.core.file.IResolveRecord#getResolveFromFile() */ public String getResolveFromFile() { return resolveFromFile; } - + /** * @see com.perforce.p4java.core.file.IResolveRecord#setResolveFromFile(java.lang.String) */ public void setResolveFromFile(String resolveFromFile) { this.resolveFromFile = resolveFromFile; } - + /** * @see com.perforce.p4java.core.file.IResolveRecord#getResolveStartFromRevision() */ public int getResolveStartFromRevision() { return resolveStartFromRevision; } - + /** * @see com.perforce.p4java.core.file.IResolveRecord#setResolveStartFromRevision(int) */ @@ -166,7 +178,7 @@ public void setResolveStartFromRevision(int resolveStartFromRevision) { public String getResolveType() { return resolveType; } - + /** * @see com.perforce.p4java.core.file.IResolveRecord#setResolveType(java.lang.String) */ diff --git a/src/main/java/com/perforce/p4java/impl/generic/graph/GraphRef.java b/src/main/java/com/perforce/p4java/impl/generic/graph/GraphRef.java index ee72c1b..0070db2 100644 --- a/src/main/java/com/perforce/p4java/impl/generic/graph/GraphRef.java +++ b/src/main/java/com/perforce/p4java/impl/generic/graph/GraphRef.java @@ -11,6 +11,11 @@ public class GraphRef implements IGraphRef { /** * Default constructor + * + * @param repo repo + * @param type type + * @param sha sha + * @param name name */ public GraphRef(final String repo, final String type, final String sha, final String name) { this.repo = repo; diff --git a/src/main/java/com/perforce/p4java/impl/generic/graph/RevListCommit.java b/src/main/java/com/perforce/p4java/impl/generic/graph/RevListCommit.java index dbb4306..490d51d 100644 --- a/src/main/java/com/perforce/p4java/impl/generic/graph/RevListCommit.java +++ b/src/main/java/com/perforce/p4java/impl/generic/graph/RevListCommit.java @@ -3,25 +3,25 @@ import com.perforce.p4java.graph.IRevListCommit; /** - * * Represents a list of revision items made through Graph Depot functionality */ public class RevListCommit implements IRevListCommit { - private final String commit; + private final String commit; - /** - * Default constructor - */ - public RevListCommit(final String commit) - { - this.commit = commit; - } + /** + * Default constructor + * + * @param commit commit + */ + public RevListCommit(final String commit) { + this.commit = commit; + } - @Override - public String getCommit() { - return commit; - } + @Override + public String getCommit() { + return commit; + } } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/MapKeys.java b/src/main/java/com/perforce/p4java/impl/mapbased/MapKeys.java index e8a7419..add3ad0 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/MapKeys.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/MapKeys.java @@ -8,7 +8,7 @@ * implementation as static String fields. Note that the task here is * made harder by case and tense variants, etc.; normal names with suffix * are the commonest, typically upper-case first character and the - * rest lower-case.

+ * rest lower-case. *

* NOTE: not yet in general usage; will be used more with * refactoring over time -- HR. diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/client/Client.java b/src/main/java/com/perforce/p4java/impl/mapbased/client/Client.java index 5e434d0..b6d67c1 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/client/Client.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/client/Client.java @@ -50,11 +50,11 @@ import com.perforce.p4java.option.client.RevertFilesOptions; import com.perforce.p4java.option.client.ShelveFilesOptions; import com.perforce.p4java.option.client.SyncOptions; +import com.perforce.p4java.option.client.UndoFilesOptions; import com.perforce.p4java.option.client.UnlockFilesOptions; import com.perforce.p4java.option.client.UnshelveFilesOptions; import com.perforce.p4java.option.server.ListOptions; import com.perforce.p4java.option.server.OpenedFilesOptions; -import com.perforce.p4java.option.client.UndoFilesOptions; import com.perforce.p4java.server.CmdSpec; import com.perforce.p4java.server.IOptionsServer; import com.perforce.p4java.server.IServer; @@ -81,1853 +81,1614 @@ import static com.perforce.p4java.impl.mapbased.server.cmd.ResultMapParser.parseCommandResultMapAsString; /** - * Default implementation of the generic parts of an IClient interface.

+ * Default implementation of the generic parts of an IClient interface. *

* Note that this version is very much tied to the map-based server implementation, * and can (generally) only be used with that server type. This is not an onerous * requirement, however, as all IServer objects returned from the ServerFactory - * are map-based implementations.

+ * are map-based implementations. */ - public class Client extends ClientSummary implements IClient { - public static final String MERGE_TMP_FILENAME_KEY = "P4JMergeTmpFile"; - public static final String MERGE_START_FROM_REV_KEY = "P4JMergeStartFromRev"; - public static final String MERGE_END_FROM_REV_KEY = "P4JMergeEndFromRev"; - - /** - * What a new client created by the newClient method uses as a description - * if nothing is passed in explicitly. - */ - public static final String DEFAULT_DESCRIPTION = "New Client created by P4Java"; - - private Server serverImpl = null; - private ClientView clientView = null; - private ArrayList changeView = null; - private ViewDepotType viewDepotType; - - // The delegators for running perforce commands - private IWhereDelegator whereDelegator = null; - - /** - * Convenience method to return a new Client object with certain default values - * filled in.

- *

- * Only the fields corresponding to the parameters here can be explicitly set - * on creation; all others are given defaults that can be changed - * or added later. These defaults are as given for the default Client - * and ClientSummary constructors; exceptions include the client's user - * name, which is set to server.getUserName (which may cause issues later - * down the line if that wasn't set).

- *

- * Note that this object is a local object only -- you must subsequently call - * the server's createClient method to also create it on the server (or use - * the Factory.createClient convenience method).

- *

- * Note that this method is pretty simple-minded about client names, paths, etc. - * -- anything that contains unexpected spaces or weird characters (etc.) may - * cause it to get confused, in which case you're better off constructing things - * by hand or pre-massaging parameters yourself. - * - * @param server non-null IOptionsServer to be associated with the client. - * @param name non-null client name. - * @param description if not null, the client description field to be used; if null, - * DEFAULT_DESCRIPTION will be used as a default. - * @param root if not null, use this as the new client's root; if null, use the server's - * working directory if its getWorkingDirectory method returns non-null, - * otherwise use the JVM's current working directory as determine by the - * user.dir system property. - * @param paths if not null, use this as the list of view map depot / client - * paths, in the order given, and according to the format in - * MapEntry.parseViewMappingString; defaults to a single entry, - * "//depot/... //clientname/depot/..." if not given. - * @return new non-null local Client object. - */ - - public static Client newClient(IOptionsServer server, String name, String description, - String root, String[] paths) { - String rootDir = root; - Server serverImpl = null; - String userName = null; - - if (server == null) { - throw new NullPointerError("null server passed to Client.newClient"); - } - if (name == null) { - throw new NullPointerError("null client name passed to Client.newClient"); - } - if (!(server instanceof Server)) { - throw new P4JavaError( - "IOptionsServer passed to Client.newClient does not implement 'Server' class"); - } - - serverImpl = ((Server) server); - - if (rootDir == null) { - rootDir = serverImpl.getWorkingDirectory() == null ? - System.getProperty("user.dir") : - serverImpl.getWorkingDirectory(); - if (rootDir == null) { - throw new P4JavaError( - "unable to determine root directory for new client"); - } - } - - userName = server.getUserName(); - - if (paths == null) { - paths = new String[]{ - "//depot/... //" + name + "/depot/..." - }; - } - - Client client = new Client(server); - client.setName(name); - client.setDescription(description == null ? DEFAULT_DESCRIPTION : description); - client.setOwnerName(userName); - client.setRoot(rootDir); - ClientView clientView = new ClientView(); - - clientView.setClient(client); - List viewMappings = new ArrayList(); - int i = 0; - for (String mapping : paths) { - if (mapping == null) { - throw new NullPointerError("null mapping string passed to Client.newClient"); - } - viewMappings.add(new ClientView.ClientViewMapping(i, mapping)); - i++; - } - clientView.setEntryList(viewMappings); - - client.setClientView(clientView); - return client; - } - - /** - * Default constructor. Clients constructed with this constructor will need - * a suitable setServer call to set the underlying server link before being able - * to do much beyond setting local fields. Note that we also need to set - * the various IServerResource fields appropriately, as IClientSummary objects - * are not completable, refreshable, or updateable, but full IClient objects - * are (at least) refreshable and updateable.

- *

- * ClientSummary fields are set as noted in the ClientSummary default constructor - * comments. - */ - @Deprecated - public Client() { - super(); - super.refreshable = true; - super.updateable = true; - } - - /** - * Note that any IServer object returned by the ServerFactory will work for the serverImpl - * parameter; if not, a suitable cast exception will be thrown.

- *

- * ClientSummary fields are set as noted in the ClientSummary default constructor - * comments. - * - * @param server an IServer server returned from the server factory. - */ - - public Client(IServer server) { - super(); - super.refreshable = true; - super.updateable = true; - setServer(server); - } - - /** - * Construct a new Client object from explicit fields.

- *

- * Note that any IServer object returned by the ServerFactory will work for the serverImpl - * parameter; if not, a suitable cast exception will be thrown.

- */ - - public Client(String name, Date accessed, Date updated, String description, - String hostName, String ownerName, String root, - ClientLineEnd lineEnd, IClientOptions options, - IClientSubmitOptions submitOptions, List alternateRoots, - IServer serverImpl, ClientView clientView) { - super(name, accessed, updated, description, hostName, ownerName, root, - lineEnd, options, submitOptions, alternateRoots); - setServer(serverImpl); - this.clientView = clientView; - } - - /** - * Construct a new Client object from explicit fields.

- *

- * Note that any IServer object returned by the ServerFactory will work for the serverImpl - * parameter; if not, a suitable cast exception will be thrown.

- */ - - public Client(String name, Date accessed, Date updated, String description, - String hostName, String ownerName, String root, - ClientLineEnd lineEnd, IClientOptions options, - IClientSubmitOptions submitOptions, List alternateRoots, - IServer serverImpl, ClientView clientView, String stream, String type) { - super(name, accessed, updated, description, hostName, ownerName, root, - lineEnd, options, submitOptions, alternateRoots, stream, type); - setServer(serverImpl); - this.clientView = clientView; - } - - /** - * Construct a suitable Client object from an IServer and a map - * returned from the Perforce server. If map is null, this is equivalent - * to calling the Client(IServer serverImpl) constructor.

- *

- * Note that any IServer object returned by the ServerFactory will work for the serverImpl - * parameter; if not, a suitable cast exception will be thrown.

- */ - - public Client(IServer serverImpl, Map map) { - super(map, false); - super.refreshable = true; - super.updateable = true; - setServer(serverImpl); - this.viewDepotType = ViewDepotType.LOCAL; - - // Extract fields from the map that aren't in the client spec set; - // but note that maps that come back from getClientList() can use different - // field names and field formats from the maps that come back from the - // getClient() method(s). This complicates things a bit and helps explain - // the brute-force duplication of the original ClientSummary map parsing below. - - if (map != null) { - this.name = (String) map.get("Client"); - - // Try to retrieve the view map; it comes to us as a series of - // map entries starting with "View" and followed by a number, e.g. "View9". - // These view numbers *must* be used to set the order of each individual - // map entry on the view map, as order is (very) significant and must be - // preserved. - - ClientView viewImpl = new ClientView(); - ArrayList mappingList = new ArrayList(); - viewImpl.setEntryList(mappingList); - this.clientView = viewImpl; - String pfx = "View"; - - for (int i = 0; map.containsKey(pfx + i); i++) { - String key = pfx + i; - - String[] parts = MapEntry.parseViewMappingString((String) map.get(key)); - - if (parts.length < 2) { - throw new P4JavaError( - "bad client view mapping string in Client constructor: " - + (String) map.get(key)); - } - - mappingList.add(new ClientView.ClientViewMapping(i, parts[0], parts[1])); - } - - // Add change view entries to list if found. - - ArrayList changeViewImpl = new ArrayList<>(); - pfx = "ChangeView"; - - for (int i = 0; map.containsKey(pfx + i); i++) { - String key = pfx + i; - - String changeEntry = (String) map.get(key); - - if (changeEntry == null || changeEntry.isEmpty()) { - throw new P4JavaError("null or empty change view mapping string in Client constructor."); - } - - changeViewImpl.add(changeEntry); - } - this.changeView = changeViewImpl; - - // Description strings *sometimes* come back with a trailing newline (that wasn't - // there when we created the client description), which - // is annoying because we can't just simply use trim() -- there's no rule that - // says that descriptions can't start or end with whitespace -- so we kludge up - // the following to get rid of just the trailing newline if it's there -- HR. - - this.description = (String) map.get("Description"); - if ((this.description != null) && (this.description.length() > 1) && this.description.endsWith("\n")) { - this.description = this.description.substring(0, this.description.length() - 1); - } - try { - // Different format here to what's in ClientSummary. - if (map.get("Access") != null) { - this.accessed = - new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse((String) map.get("Access")); - } - } catch (Exception exc) { - Log.error("Access date parse error in Client constructor " - + exc.getLocalizedMessage()); - Log.exception(exc); - } - try { - if (map.get("Update") != null) { - this.updated = - new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse((String) map.get("Update")); - } - } catch (Exception exc) { - Log.error("Update date parse error in Client constructor " - + exc.getLocalizedMessage()); - Log.exception(exc); - } - - viewImpl.setClient(this); - if (map.get(VIEW_DEPOT_TYPE) != null) { - this.viewDepotType = ViewDepotType.fromString(map.get(VIEW_DEPOT_TYPE).toString()); - } - } - } - - /** - * Construct a new Client object using the passed-in client summary object as a partial - * template. Note that this client object will need to have its serverImpl before any - * refreshes, updates, etc., are done against it.

- *

- * If summary is null, this is equivalent to calling the default constructor. If clientSummary - * is not null, and refresh is false, the relevant ClientSummary superclass is initialized - * by copying the passed-in summary fields. If clientSummary is not null and refresh is true, - * the Client is constructed by calling refresh() using the clientSummary's name; if refresh - * is false, the client view will be as for the default constructor. - * - * @throws ConnectionException if the Perforce server is unreachable or is not - * connected. - * @throws RequestException if the Perforce server encounters an error during - * its processing of the request - * @throws AccessException if the Perforce server denies access to the caller - */ - - public Client(IClientSummary clientSummary, boolean refresh) - throws ConnectionException, RequestException, AccessException { - this(clientSummary, null, refresh); - } - - /** - * Construct a new Client object using the passed-in client summary object as a partial - * template along with the passed-in IServer object.

- *

- * Note that any IServer object returned by the ServerFactory will work for the serverImpl - * parameter; if not, a suitable cast exception will be thrown.

- *

- * If summary is null, this is equivalent to calling the default constructor. If clientSummary - * is not null, and refresh is false, the relevant ClientSummary superclass is initialized - * by copying the passed-in summary fields. If clientSummary is not null and refresh is true, - * the Client is constructed by calling refresh() using the clientSummary's name; if refresh - * is false, the client view will be as for the default constructor. - * - * @throws ConnectionException if the Perforce server is unreachable or is not - * connected. - * @throws RequestException if the Perforce server encounters an error during - * its processing of the request - * @throws AccessException if the Perforce server denies access to the caller - */ - public Client(IClientSummary clientSummary, IServer serverImpl, boolean refresh) - throws ConnectionException, RequestException, AccessException { - super(false); - setServer(serverImpl); - if (clientSummary != null) { - if (refresh) { - if (clientSummary.getName() == null) { - throw new NullPointerError( - "Null label name in client summary object passed to Client constructor"); - } - - this.name = clientSummary.getName(); - this.refresh(); - } else { - this.name = clientSummary.getName(); - this.accessed = clientSummary.getAccessed(); - this.updated = clientSummary.getUpdated(); - this.description = clientSummary.getDescription(); - this.hostName = clientSummary.getHostName(); - this.ownerName = clientSummary.getOwnerName(); - this.root = clientSummary.getRoot(); - this.lineEnd = clientSummary.getLineEnd(); - this.options = clientSummary.getOptions(); - this.submitOptions = clientSummary.getSubmitOptions(); - this.alternateRoots = clientSummary.getAlternateRoots(); - this.stream = clientSummary.getStream(); - this.serverId = clientSummary.getServerId(); - } - } - } - - private void init(IServer serverImpl) { - whereDelegator = new WhereDelegator(serverImpl, this); - } - - /** - * @see com.perforce.p4java.client.IClient#getServer() - */ - @Override - public IServer getServer() { - return this.serverImpl; - } - - /** - * Completing a client calls {@link #refresh()}. A no op for the new IClient object. - * - * @see #refresh() - * @see com.perforce.p4java.impl.generic.core.ServerResource#complete() - */ - @Override - public void complete() throws ConnectionException, RequestException, - AccessException { - } - - /** - * This method will refresh by getting the complete client model. If this - * refresh is successful then this client will be marked as complete. - * - * @see com.perforce.p4java.impl.generic.core.ServerResource#refresh() - */ - @Override - public void refresh() throws ConnectionException, RequestException, - AccessException { - IServer refreshServer = this.serverImpl; - String refreshName = null; - refreshName = this.getName(); - if (refreshServer != null && refreshName != null) { - IClient refreshedClient = refreshServer.getClient(refreshName); - if (refreshedClient != null) { - setName(refreshName); - setAccessed(refreshedClient.getAccessed()); - setUpdated(refreshedClient.getUpdated()); - setAlternateRoots(refreshedClient.getAlternateRoots()); - setClientView(refreshedClient.getClientView()); - setChangeView(refreshedClient.getChangeView()); - setDescription(refreshedClient.getDescription()); - setHostName(refreshedClient.getHostName()); - setLineEnd(refreshedClient.getLineEnd()); - setOptions(refreshedClient.getOptions()); - setOwnerName(refreshedClient.getOwnerName()); - setRoot(refreshedClient.getRoot()); - setSubmitOptions(refreshedClient.getSubmitOptions()); - setUpdated(refreshedClient.getUpdated()); - setStream(refreshedClient.getStream()); - setServerId(refreshedClient.getServerId()); - setType(refreshedClient.getType()); - } - } - } - - /** - * @see com.perforce.p4java.impl.generic.core.ServerResource#update() - */ - @Override - public void update() throws ConnectionException, RequestException, AccessException { - if (serverImpl != null) { - this.serverImpl.updateClient(this); - } else { - throw new NullPointerError( - "Attempted to update client with no associated server set on client"); - } - } - - /** - * @see com.perforce.p4java.impl.generic.core.ServerResource#update(boolean) - */ - @Override - public void update(boolean force) throws ConnectionException, RequestException, AccessException { - if (serverImpl != null) { - this.serverImpl.updateClient(this, force); - } else { - throw new NullPointerError( - "Attempted to update client with no associated server set on client"); - } - } - - /** - * @see com.perforce.p4java.client.IClient#getClientView() - */ - @Override - public ClientView getClientView() { - return this.clientView; - } - - /** - * @see com.perforce.p4java.client.IClient#setClientView(com.perforce.p4java.impl.generic.client.ClientView) - */ - @Override - public void setClientView(ClientView clientView) { - this.clientView = clientView; - } - - @Override - public ArrayList getChangeView() { - return this.changeView; - } - - @Override - public void setChangeView(ArrayList changeView) { - this.changeView = changeView; - } - - /** - * Note that this will fail with a class cast exception if the passed-in - * server is not a mapbased ServerImpl object. - * - * @param server ServerImpl server object. - */ - @Override - public void setServer(IServer server) { - this.serverImpl = (Server) server; - init(server); - } - - /** - * @see com.perforce.p4java.client.IClient#sync(java.util.List, boolean, boolean, boolean, boolean) - */ - @Override - public List sync(List fileSpecs, boolean forceUpdate, boolean noUpdate, - boolean clientBypass, boolean serverBypass) - throws ConnectionException, RequestException, AccessException { - - try { - return sync(fileSpecs, new SyncOptions(forceUpdate, noUpdate, clientBypass, serverBypass)); - } catch (ConnectionException exc) { - throw exc; - } catch (AccessException exc) { - throw exc; - } catch (RequestException exc) { - throw exc; - } catch (P4JavaException exc) { - throw new RequestException(exc.getMessage(), exc); - } - } - - /** - * @see com.perforce.p4java.client.IClient#sync(java.util.List, com.perforce.p4java.option.client.SyncOptions) - */ - @Override - public List sync(List fileSpecs, SyncOptions syncOpts) - throws P4JavaException { - List specList = new ArrayList(); - - if ((this.serverImpl.getCurrentClient() == null) - || !this.serverImpl.getCurrentClient().getName().equalsIgnoreCase(this.getName())) { - throw new RequestException( - "Attempted to sync a client that is not the server's current client"); - } - - List> resultMaps = this.serverImpl.execMapCmdList(CmdSpec.SYNC, - Parameters.processParameters( - syncOpts, fileSpecs, this.server), - null); - - if (resultMaps != null) { - for (Map map : resultMaps) { - specList.add(handleFileReturn(map, serverImpl)); - } - } - - return specList; - } - - /** - * @see com.perforce.p4java.client.IClient#syncParallel(List, SyncOptions, ParallelSyncOptions) - */ - @Override - public List syncParallel(List fileSpecs, SyncOptions syncOpts, - ParallelSyncOptions pSyncOpts) throws P4JavaException { - List specList = new ArrayList(); - - if ((this.serverImpl.getCurrentClient() == null) - || !this.serverImpl.getCurrentClient().getName().equalsIgnoreCase(this.getName())) { - throw new RequestException( - "Attempted to sync a client that is not the server's current client"); - } - - String[] syncOptions = ClientHelper.buildParallelOptions(serverImpl, fileSpecs, syncOpts, pSyncOpts); - - List> resultMaps = this.serverImpl.execMapCmdList(CmdSpec.SYNC.toString(), - syncOptions, null, pSyncOpts.getCallback()); - - if (resultMaps != null) { - for (Map map : resultMaps) { - specList.add(handleFileReturn(map, serverImpl)); - } - } - - return specList; - } - - /** - * @see com.perforce.p4java.client.IClient#sync(java.util.List, com.perforce.p4java.option.client.SyncOptions, com.perforce.p4java.server.callback.IStreamingCallback, int) - */ - @Override - public void sync(List fileSpecs, SyncOptions syncOpts, IStreamingCallback callback, int key) - throws P4JavaException { - - if ((this.serverImpl.getCurrentClient() == null) - || !this.serverImpl.getCurrentClient().getName().equalsIgnoreCase(this.getName())) { - throw new RequestException( - "Attempted to sync a client that is not the server's current client"); - } - - this.serverImpl.execStreamingMapCommand(CmdSpec.SYNC.toString(), - Parameters.processParameters( - syncOpts, fileSpecs, this.server), - null, - callback, - key); - } - - /** - * @see com.perforce.p4java.client.IClient#sync(java.util.List, com.perforce.p4java.option.client.SyncOptions, com.perforce.p4java.server.callback.IStreamingCallback, int) - */ - @Override - public void syncParallel(List fileSpecs, SyncOptions syncOpts, IStreamingCallback callback, - int key, ParallelSyncOptions pSyncOpts) - throws P4JavaException { - - if ((this.serverImpl.getCurrentClient() == null) - || !this.serverImpl.getCurrentClient().getName().equalsIgnoreCase(this.getName())) { - throw new RequestException( - "Attempted to sync a client that is not the server's current client"); - } - - String[] syncOptions = ClientHelper.buildParallelOptions(serverImpl, fileSpecs, syncOpts, pSyncOpts); - - this.serverImpl.execStreamingMapCommand(CmdSpec.SYNC.toString(), - syncOptions, null, callback, key, pSyncOpts.getCallback()); - } - - /** - * @see com.perforce.p4java.client.IClient#labelSync(java.util.List, java.lang.String, boolean, boolean, boolean) - */ - @Override - public List labelSync(List fileSpecs, String labelName, - boolean noUpdate, boolean addFiles, boolean deleteFiles) - throws ConnectionException, RequestException, AccessException { - try { - return labelSync(fileSpecs, labelName, new LabelSyncOptions(noUpdate, addFiles, deleteFiles)); - } catch (ConnectionException exc) { - throw exc; - } catch (AccessException exc) { - throw exc; - } catch (RequestException exc) { - throw exc; - } catch (P4JavaException exc) { - throw new RequestException(exc.getMessage(), exc); - } - } - - /** - * @see com.perforce.p4java.client.IClient#labelSync(java.util.List, java.lang.String, com.perforce.p4java.option.client.LabelSyncOptions) - */ - @Override - public List labelSync(List fileSpecs, String labelName, LabelSyncOptions opts) - throws P4JavaException { - List specList = new ArrayList(); - - if (labelName == null) { - throw new NullPointerError( - "null label name passed to Client.labelSync()"); - } - - List> resultMaps = this.serverImpl.execMapCmdList(CmdSpec.LABELSYNC, - Parameters.processParameters( - opts, fileSpecs, "-l" + labelName, this.server), - null); - - if (resultMaps != null) { - for (Map map : resultMaps) { - specList.add(handleFileReturn(map, serverImpl)); - } - } - - return specList; - } - - /** - * @see com.perforce.p4java.client.IClient#createChangelist(com.perforce.p4java.core.IChangelist) - */ - @Override - public IChangelist createChangelist(IChangelist newChangelist) - throws ConnectionException, RequestException, AccessException { - - if (this.getName() == null) { - throw new NullPointerError("Null client name in newChangelist method call"); - } else if (newChangelist == null) { - throw new NullPointerError("Null new change list specification in newChangelist method call"); - } else if (newChangelist.getId() != IChangelist.UNKNOWN) { - throw new RequestException("New changelist ID must be set to IChangelist.UNKNOWN"); - } - - List> resultMaps = this.serverImpl.execMapCmdList(CmdSpec.CHANGE, - new String[]{"-i"}, - InputMapper.map(newChangelist)); - - if (resultMaps != null) { - int id = IChangelist.UNKNOWN; - for (Map map : resultMaps) { - if (!this.serverImpl.handleErrorStr(map)) { - if (map.containsKey("change")) { - // Do this the easy way -- it's in the RPC map output - String changeStr = (String) map.get("change"); - if (changeStr != null) { - // skip the initial "Change " bit - int i = changeStr.indexOf(" "); - if ((i > 0) && (i < changeStr.length())) { - try { - id = new Integer(changeStr.substring(i + 1)); - } catch (Exception exc) { - Log.error("Unexpected exception in Client.newChangelist: " - + exc.getLocalizedMessage()); - Log.exception(exc); - } - } - } - } else { - String infoStr = this.serverImpl.getInfoStr(map); - - if ((infoStr != null) && infoStr.contains("Change ") && infoStr.contains(" created")) { - String[] strs = infoStr.split(" "); - - if ((strs.length >= 3) && (strs[1] != null)) { - id = IChangelist.UNKNOWN; - try { - id = new Integer(strs[1]); - } catch (Exception exc) { - Log.error("Unexpected exception in Client.newChangelist: " - + exc.getLocalizedMessage()); - Log.exception(exc); - } - } - } - } - } - if (id != IChangelist.UNKNOWN) { - return this.serverImpl.getChangelist(id); - } - } - } - return null; - } - - /** - * @see com.perforce.p4java.client.IClient#addFiles(java.util.List, boolean, int, java.lang.String, boolean) - */ - @Override - public List addFiles(List fileSpecs, - boolean noUpdate, int changeListId, String fileType, boolean useWildcards) - throws ConnectionException, AccessException { - try { - return addFiles(fileSpecs, new AddFilesOptions( - noUpdate, changeListId, fileType, useWildcards)); - } catch (ConnectionException exc) { - throw exc; - } catch (AccessException exc) { - throw exc; - } catch (P4JavaException exc) { - Log.warn("Unexpected exception in IClient.addFiles: " + exc); - return new ArrayList(); - } - } - - /** - * @see com.perforce.p4java.client.IClient#addFiles(java.util.List, com.perforce.p4java.option.client.AddFilesOptions) - */ - @Override - public List addFiles(List fileSpecs, AddFilesOptions opts) - throws P4JavaException { - List resultList = new ArrayList(); - - List> resultMaps = this.serverImpl.execMapCmdList( - CmdSpec.ADD, - Parameters.processParameters( - opts, fileSpecs, this.serverImpl), - null); - - if (resultMaps != null) { - for (Map map : resultMaps) { - resultList.add(handleFileReturn(map, serverImpl)); - } - } - return resultList; - } - - /** - * @see com.perforce.p4java.client.IClient#deleteFiles(java.util.List, int, boolean) - */ - @Override - public List deleteFiles(List fileSpecs, - int changeListId, boolean noUpdate) - throws ConnectionException, AccessException { - try { - return deleteFiles(fileSpecs, - new DeleteFilesOptions(changeListId, noUpdate, false)); - } catch (ConnectionException exc) { - throw exc; - } catch (AccessException exc) { - throw exc; - } catch (P4JavaException exc) { - Log.warn("Unexpected exception in IClient.deleteFiles: " + exc); - return new ArrayList(); - } - } - - /** - * @see com.perforce.p4java.client.IClient#deleteFiles(java.util.List, com.perforce.p4java.option.client.DeleteFilesOptions) - */ - @Override - public List deleteFiles(List fileSpecs, DeleteFilesOptions opts) - throws P4JavaException { - List resultList = new ArrayList(); - - List> resultMaps = this.serverImpl.execMapCmdList( - CmdSpec.DELETE, - Parameters.processParameters( - opts, fileSpecs, this.serverImpl), - null); - - if (resultMaps != null) { - for (Map map : resultMaps) { - resultList.add(handleFileReturn(map, serverImpl)); - } - } - return resultList; - } - - /** - * @see com.perforce.p4java.client.IClient#editFiles(java.util.List, boolean, boolean, int, java.lang.String) - */ - @Override - public List editFiles(List fileSpecs, - boolean noUpdate, boolean bypassClientUpdate, int changeListId, String fileType) - throws RequestException, ConnectionException, AccessException { - final int MINIMUM_OPTION_K_SERVER_VERSION = 20092; // minimum version number supporting bypassClientUpdate - - if (bypassClientUpdate) { - if (this.serverImpl.getServerVersionNumber() < MINIMUM_OPTION_K_SERVER_VERSION) { - throw new RequestException( - "edit option 'bypassClientUpdate' only supported on servers 2009.2 and later"); - } - } - - try { - return editFiles(fileSpecs, new EditFilesOptions( - noUpdate, bypassClientUpdate, changeListId, fileType)); - } catch (ConnectionException exc) { - throw exc; - } catch (AccessException exc) { - throw exc; - } catch (RequestException exc) { - throw exc; - } catch (P4JavaException exc) { - throw new RequestException(exc.getMessage(), exc); - } - } - - /** - * @see com.perforce.p4java.client.IClient#editFiles(java.util.List, com.perforce.p4java.option.client.EditFilesOptions) - */ - @Override - public List editFiles(List fileSpecs, EditFilesOptions opts) throws P4JavaException { - List resultList = new ArrayList(); - - List> resultMaps = this.serverImpl.execMapCmdList( - CmdSpec.EDIT, - Parameters.processParameters( - opts, fileSpecs, this.serverImpl), - null); - - if (resultMaps != null) { - for (Map map : resultMaps) { - resultList.add(handleFileReturn(map, serverImpl)); - } - } - return resultList; - } - - /** - * @see com.perforce.p4java.client.IClient#revertFiles(java.util.List, boolean, int, boolean, boolean) - */ - @Override - public List revertFiles(List fileSpecs, boolean noUpdate, - int changeListId, boolean revertOnlyUnchanged, boolean noRefresh) - throws ConnectionException, AccessException { - try { - return revertFiles(fileSpecs, new RevertFilesOptions( - noUpdate, changeListId, revertOnlyUnchanged, noRefresh)); - } catch (ConnectionException exc) { - throw exc; - } catch (AccessException exc) { - throw exc; - } catch (P4JavaException exc) { - Log.warn("Unexpected exception in IClient.revertFiles: " + exc); - return new ArrayList(); - } - } - - /** - * @see com.perforce.p4java.client.IClient#revertFiles(java.util.List, com.perforce.p4java.option.client.RevertFilesOptions) - */ - @Override - public List revertFiles(List fileSpecs, RevertFilesOptions opts) - throws P4JavaException { - List resultList = new ArrayList(); - - List> resultMaps = this.serverImpl.execMapCmdList( - CmdSpec.REVERT, - Parameters.processParameters( - opts, fileSpecs, null, false, this.serverImpl), - null); - - if (resultMaps != null) { - for (Map map : resultMaps) { - resultList.add(handleFileReturn(map, serverImpl)); - } - } - return resultList; - } - - - @Override - public List undoFiles(List fileSpecs, int changelistId, boolean listOnly) - throws ConnectionException, AccessException { - try { - UndoFilesOptions undoFilesOptions = new UndoFilesOptions( - listOnly, - changelistId); - - return undoFiles(fileSpecs, undoFilesOptions); - } catch (ConnectionException | AccessException e) { - throw e; - } catch (P4JavaException e) { - Log.warn("Unexpected exception in IServer.undoFiles: %s", e); - return Collections.emptyList(); - } - } - - @Override - public List undoFiles(final List fileSpecs, final UndoFilesOptions opts) - throws P4JavaException { - - throwRequestExceptionIfPerforceServerVersionOldThanExpected( - this.serverImpl.getServerVersion() >= 20162, - "command requires a Perforce server version 2016.2 or later"); - - List resultList = new ArrayList<>(); - - List> resultMaps = this.serverImpl.execMapCmdList( - CmdSpec.UNDO, - Parameters.processParameters( - opts, fileSpecs, null, false, this.serverImpl), - null); - - if (resultMaps != null) { - for (Map map : resultMaps) { - resultList.add(handleFileReturn(map, serverImpl)); - } - } - return resultList; - } - - - /** - * @see com.perforce.p4java.client.IClient#haveList(java.util.List) - */ - @Override - public List haveList(List fileSpecs) - throws ConnectionException, AccessException { - - return haveList(fileSpecs, null); - } - - /** - * @see com.perforce.p4java.client.IClient#graphHaveList(java.util.List) - */ - @Override - public List graphHaveList(List fileSpecs) - throws ConnectionException, AccessException { - - return haveList(fileSpecs, new String[]{"--graph-only"}); - } - - private List haveList(List fileSpecs, String[] filter) - throws ConnectionException, AccessException { - - List haveList = new ArrayList(); - - if ((this.serverImpl.getCurrentClient() == null) - || !this.serverImpl.getCurrentClient().getName().equalsIgnoreCase(this.getName())) { - return haveList; - } - - List> resultMaps = this.serverImpl.execMapCmdList( - CmdSpec.HAVE, Server.getPreferredPathArray(filter, fileSpecs), null); - - if (resultMaps != null) { - for (Map result : resultMaps) { - haveList.add(handleFileReturn(result, serverImpl)); - } - } - - return haveList; - } - - /** - * @see com.perforce.p4java.client.IClient#reopenFiles(java.util.List, int, java.lang.String) - */ - @Override - public List reopenFiles(List fileSpecs, int changeListId, - String fileType) throws ConnectionException, AccessException { - - try { - return reopenFiles(fileSpecs, - new ReopenFilesOptions().setChangelistId(changeListId).setFileType(fileType)); - } catch (ConnectionException exc) { - throw exc; - } catch (AccessException exc) { - throw exc; - } catch (P4JavaException exc) { - Log.warn("Unexpected exception in IClient.reopenFiles: " + exc); - return new ArrayList(); - } - } - - /** - * @see com.perforce.p4java.client.IClient#reopenFiles(java.util.List, com.perforce.p4java.option.client.ReopenFilesOptions) - */ - @Override - public List reopenFiles(List fileSpecs, ReopenFilesOptions opts) - throws P4JavaException { - List reopenList = new ArrayList(); - - List> resultMaps = this.serverImpl.execMapCmdList( - CmdSpec.REOPEN, - Parameters.processParameters( - opts, fileSpecs, null, false, this.serverImpl), - null); - - if (resultMaps != null) { - for (Map map : resultMaps) { - reopenList.add(handleFileReturn(map, serverImpl)); - } - } - return reopenList; - } - - /** - * @see com.perforce.p4java.client.IClient#where(java.util.List) - */ - @Override - public List where(List fileSpecs) throws ConnectionException, AccessException { - return whereDelegator.where(fileSpecs); - } - - /** - * @see com.perforce.p4java.client.IClient#localWhere(java.util.List) - */ - @Override - public List localWhere(List fileSpecs) { - return whereDelegator.localWhere(fileSpecs); - } - - /** - * @see com.perforce.p4java.client.IClient#openedFiles(java.util.List, int, int) - */ - @Override - public List openedFiles(List fileSpecs, int maxFiles, int changeListId) - throws ConnectionException, AccessException { - - try { - return this.openedFiles(fileSpecs, - new OpenedFilesOptions(false, this.getName(), maxFiles, null, changeListId)); - } catch (ConnectionException exc) { - throw exc; - } catch (AccessException exc) { - throw exc; - } catch (P4JavaException exc) { - Log.warn("Unexpected exception in IClient.openedFiless: " + exc); - return new ArrayList(); - } - } - - /** - * @see com.perforce.p4java.client.IClient#openedFiles(java.util.List, com.perforce.p4java.option.server.OpenedFilesOptions) - */ - @Override - public List openedFiles(List fileSpecs, OpenedFilesOptions opts) - throws P4JavaException { - if (opts == null) { - return this.serverImpl.getOpenedFiles(fileSpecs, - new OpenedFilesOptions().setClientName(this.name)); - } else { - // Need to clone (not quite literally) the opts so we don't change the original: - if (opts.getOptions() != null) { - List optsStrings = opts.getOptions(); - return this.serverImpl.getOpenedFiles(fileSpecs, new OpenedFilesOptions( - optsStrings.toArray(new String[optsStrings.size()]) - )); - } else { - return this.serverImpl.getOpenedFiles(fileSpecs, - opts.setAllClients(false).setClientName(this.getName())); - } - } - } - - /** - * @see com.perforce.p4java.client.IClient#integrateFiles(int, boolean, com.perforce.p4java.core.file.IntegrationOptions, java.lang.String, com.perforce.p4java.core.file.IFileSpec, com.perforce.p4java.core.file.IFileSpec) - */ - @Override - public List integrateFiles(int changeListId, boolean showActionsOnly, - IntegrationOptions integOpts, String branchSpec, - IFileSpec fromFile, IFileSpec toFile) - throws ConnectionException, AccessException { - try { - if (integOpts == null) { - integOpts = new IntegrationOptions(); // Just being generous - } - boolean integrateAroundDeletedRevs = false; - boolean rebranchSourceAfterDelete = false; - boolean deleteTargetAfterDelete = false; - boolean integrateAllAfterReAdd = false; - - String[] deleteOpts = integOpts.getDeletedOptions(); - if (deleteOpts != null) { - for (String opt : deleteOpts) { - if (opt != null) { - if (opt.equals("d")) integrateAroundDeletedRevs = true; - if (opt.equals("Di")) integrateAllAfterReAdd = true; - if (opt.equals("Dt")) rebranchSourceAfterDelete = true; - if (opt.equals("Ds")) deleteTargetAfterDelete = true; - } - } - } - - return integrateFiles(fromFile, toFile, branchSpec, - new IntegrateFilesOptions( - changeListId, // changelistId - integOpts.isBidirectionalInteg(), // bidirectionalInteg - integrateAroundDeletedRevs, // integrateAroundDeletedRevs - rebranchSourceAfterDelete, // rebranchSourceAfterDelete - deleteTargetAfterDelete, // deleteTargetAfterDelete - integrateAllAfterReAdd, // integrateAllAfterReAdd - integOpts.isForce(), // forceIntegration - integOpts.isUseHaveRev(), // useHaveRev - integOpts.isBaselessMerge(), // doBaselessMerge - integOpts.isDisplayBaseDetails(), // displayBaseDetails - showActionsOnly, // showActionsOnly - integOpts.isReverseMapping(), // reverseMapping - integOpts.isPropagateType(), // propagateType - integOpts.isDontCopyToClient(), // dontCopyToClient - integOpts.getMaxFiles() // maxFiles - )); - } catch (ConnectionException exc) { - throw exc; - } catch (AccessException exc) { - throw exc; - } catch (P4JavaException exc) { - Log.warn("Unexpected exception in IClient.integrateFiles: " + exc); - return new ArrayList(); - } - } - - /** - * @see com.perforce.p4java.client.IClient#integrateFiles(com.perforce.p4java.core.file.IFileSpec, com.perforce.p4java.core.file.IFileSpec, java.lang.String, com.perforce.p4java.option.client.IntegrateFilesOptions) - */ - @Override - public List integrateFiles(IFileSpec fromFile, IFileSpec toFile, String branchSpec, - IntegrateFilesOptions opts) throws P4JavaException { - - // Set the server's current client to this client - IClient currentClient = this.serverImpl.getCurrentClient(); - this.serverImpl.setCurrentClient(this); - List> resultMaps = this.serverImpl.execMapCmdList( - CmdSpec.INTEG, - Parameters.processParameters( - opts, fromFile, toFile, branchSpec, this.serverImpl), - null); - // Set the server's current client back to the previous one - this.serverImpl.setCurrentClient(currentClient); - - return getIntegrationFilesFromReturn(resultMaps); - } - - /** - * @see com.perforce.p4java.client.IClient#integrateFiles(com.perforce.p4java.core.file.IFileSpec, java.util.List, com.perforce.p4java.option.client.IntegrateFilesOptions) - */ - @Override - public List integrateFiles(IFileSpec fromFile, List toFiles, - IntegrateFilesOptions opts) throws P4JavaException { - - // Set the server's current client to this client - IClient currentClient = this.serverImpl.getCurrentClient(); - this.serverImpl.setCurrentClient(this); - List> resultMaps = this.serverImpl.execMapCmdList( - CmdSpec.INTEG, - Parameters.processParameters( - opts, fromFile, toFiles, null, this.serverImpl), - null); - - // Set the server's current client back to the previous one - this.serverImpl.setCurrentClient(currentClient); - - return getIntegrationFilesFromReturn(resultMaps); - } - - /** - * @see com.perforce.p4java.client.IClient#resolveFilesAuto(java.util.List, boolean, boolean, boolean, boolean, boolean) - */ - @Override - public List resolveFilesAuto(List fileSpecs, boolean safeMerge, - boolean acceptTheirs, boolean acceptYours, boolean showActionsOnly, - boolean forceResolve) - throws ConnectionException, AccessException { - try { - return resolveFilesAuto(fileSpecs, new ResolveFilesAutoOptions() - .setAcceptTheirs(acceptTheirs) - .setAcceptYours(acceptYours) - .setForceResolve(forceResolve) - .setSafeMerge(safeMerge) - .setShowActionsOnly(showActionsOnly) - ); - } catch (ConnectionException exc) { - throw exc; - } catch (AccessException exc) { - throw exc; - } catch (P4JavaException exc) { - Log.warn("Unexpected exception in IClient.resolveFilesAuto: " + exc); - return new ArrayList(); - } - } - - /** - * @see com.perforce.p4java.client.IClient#resolveFilesAuto(java.util.List, com.perforce.p4java.option.client.ResolveFilesAutoOptions) - */ - @Override - public List resolveFilesAuto(List fileSpecs, ResolveFilesAutoOptions opts) - throws P4JavaException { + public static final String MERGE_TMP_FILENAME_KEY = "P4JMergeTmpFile"; + public static final String MERGE_START_FROM_REV_KEY = "P4JMergeStartFromRev"; + public static final String MERGE_END_FROM_REV_KEY = "P4JMergeEndFromRev"; + + /** + * What a new client created by the newClient method uses as a description + * if nothing is passed in explicitly. + */ + public static final String DEFAULT_DESCRIPTION = "New Client created by P4Java"; + + private Server serverImpl = null; + private ClientView clientView = null; + private ArrayList changeView = null; + private ViewDepotType viewDepotType; + + // The delegators for running perforce commands + private IWhereDelegator whereDelegator = null; + + /** + * Convenience method to return a new Client object with certain default values + * filled in. + *

+ * Only the fields corresponding to the parameters here can be explicitly set + * on creation; all others are given defaults that can be changed + * or added later. These defaults are as given for the default Client + * and ClientSummary constructors; exceptions include the client's user + * name, which is set to server.getUserName (which may cause issues later + * down the line if that wasn't set). + *

+ * Note that this object is a local object only -- you must subsequently call + * the server's createClient method to also create it on the server (or use + * the Factory.createClient convenience method). + *

+ * Note that this method is pretty simple-minded about client names, paths, etc. + * -- anything that contains unexpected spaces or weird characters (etc.) may + * cause it to get confused, in which case you're better off constructing things + * by hand or pre-massaging parameters yourself. + * + * @param server non-null IOptionsServer to be associated with the client. + * @param name non-null client name. + * @param description if not null, the client description field to be used; if null, + * DEFAULT_DESCRIPTION will be used as a default. + * @param root if not null, use this as the new client's root; if null, use the server's + * working directory if its getWorkingDirectory method returns non-null, + * otherwise use the JVM's current working directory as determine by the + * user.dir system property. + * @param paths if not null, use this as the list of view map depot / client + * paths, in the order given, and according to the format in + * MapEntry.parseViewMappingString; defaults to a single entry, + * "//depot/... //clientname/depot/..." if not given. + * @return new non-null local Client object. + */ + public static Client newClient(IOptionsServer server, String name, String description, String root, String[] paths) { + String rootDir = root; + Server serverImpl = null; + String userName = null; + + if (server == null) { + throw new NullPointerError("null server passed to Client.newClient"); + } + if (name == null) { + throw new NullPointerError("null client name passed to Client.newClient"); + } + if (!(server instanceof Server)) { + throw new P4JavaError("IOptionsServer passed to Client.newClient does not implement 'Server' class"); + } + + serverImpl = ((Server) server); + + if (rootDir == null) { + rootDir = serverImpl.getWorkingDirectory() == null ? System.getProperty("user.dir") : serverImpl.getWorkingDirectory(); + if (rootDir == null) { + throw new P4JavaError("unable to determine root directory for new client"); + } + } + + userName = server.getUserName(); + + if (paths == null) { + paths = new String[]{"//depot/... //" + name + "/depot/..."}; + } + + Client client = new Client(server); + client.setName(name); + client.setDescription(description == null ? DEFAULT_DESCRIPTION : description); + client.setOwnerName(userName); + client.setRoot(rootDir); + ClientView clientView = new ClientView(); + + clientView.setClient(client); + List viewMappings = new ArrayList(); + int i = 0; + for (String mapping : paths) { + if (mapping == null) { + throw new NullPointerError("null mapping string passed to Client.newClient"); + } + viewMappings.add(new ClientView.ClientViewMapping(i, mapping)); + i++; + } + clientView.setEntryList(viewMappings); + + client.setClientView(clientView); + return client; + } + + /** + * Default constructor. Clients constructed with this constructor will need + * a suitable setServer call to set the underlying server link before being able + * to do much beyond setting local fields. Note that we also need to set + * the various IServerResource fields appropriately, as IClientSummary objects + * are not completable, refreshable, or updateable, but full IClient objects + * are (at least) refreshable and updateable. + *

+ * ClientSummary fields are set as noted in the ClientSummary default constructor + * comments. + */ + @Deprecated + public Client() { + super(); + super.refreshable = true; + super.updateable = true; + } + + /** + * Note that any IServer object returned by the ServerFactory will work for the serverImpl + * parameter; if not, a suitable cast exception will be thrown. + *

+ * ClientSummary fields are set as noted in the ClientSummary default constructor + * comments. + * + * @param server an IServer server returned from the server factory. + */ + + public Client(IServer server) { + super(); + super.refreshable = true; + super.updateable = true; + setServer(server); + } + + /** + * Construct a new Client object from explicit fields. + *

+ * Note that any IServer object returned by the ServerFactory will work for the serverImpl + * parameter; if not, a suitable cast exception will be thrown. + * + * @param name name + * @param accessed accessed + * @param updated updated + * @param description description + * @param hostName hostName + * @param ownerName ownerName + * @param root root + * @param lineEnd lineEnd + * @param options options + * @param submitOptions submitOptions + * @param alternateRoots alternateRoots + * @param serverImpl serverImpl + * @param clientView clientView + */ + public Client(String name, Date accessed, Date updated, String description, String hostName, String ownerName, String root, ClientLineEnd lineEnd, IClientOptions options, IClientSubmitOptions submitOptions, List alternateRoots, IServer serverImpl, ClientView clientView) { + super(name, accessed, updated, description, hostName, ownerName, root, lineEnd, options, submitOptions, alternateRoots); + setServer(serverImpl); + this.clientView = clientView; + } + + /** + * Construct a new Client object from explicit fields. + *

+ * Note that any IServer object returned by the ServerFactory will work for the serverImpl + * parameter; if not, a suitable cast exception will be thrown. + * + * @param name name + * @param accessed accessed + * @param updated updated + * @param description description + * @param hostName hostName + * @param ownerName ownerName + * @param root root + * @param lineEnd lineEnd + * @param options options + * @param submitOptions submitOptions + * @param alternateRoots alternateRoots + * @param serverImpl serverImpl + * @param clientView clientView + * @param stream stream + * @param type type + */ + public Client(String name, Date accessed, Date updated, String description, String hostName, String ownerName, String root, ClientLineEnd lineEnd, IClientOptions options, IClientSubmitOptions submitOptions, List alternateRoots, IServer serverImpl, ClientView clientView, String stream, String type) { + super(name, accessed, updated, description, hostName, ownerName, root, lineEnd, options, submitOptions, alternateRoots, stream, type); + setServer(serverImpl); + this.clientView = clientView; + } + + /** + * Construct a suitable Client object from an IServer and a map + * returned from the Perforce server. If map is null, this is equivalent + * to calling the Client(IServer serverImpl) constructor. + *

+ * Note that any IServer object returned by the ServerFactory will work for the serverImpl + * parameter; if not, a suitable cast exception will be thrown. + * + * @param serverImpl serverImpl + * @param map map + */ + public Client(IServer serverImpl, Map map) { + super(map, false); + super.refreshable = true; + super.updateable = true; + setServer(serverImpl); + this.viewDepotType = ViewDepotType.LOCAL; + + // Extract fields from the map that aren't in the client spec set; + // but note that maps that come back from getClientList() can use different + // field names and field formats from the maps that come back from the + // getClient() method(s). This complicates things a bit and helps explain + // the brute-force duplication of the original ClientSummary map parsing below. + + if (map != null) { + this.name = (String) map.get("Client"); + + // Try to retrieve the view map; it comes to us as a series of + // map entries starting with "View" and followed by a number, e.g. "View9". + // These view numbers *must* be used to set the order of each individual + // map entry on the view map, as order is (very) significant and must be + // preserved. + + ClientView viewImpl = new ClientView(); + ArrayList mappingList = new ArrayList(); + viewImpl.setEntryList(mappingList); + this.clientView = viewImpl; + String pfx = "View"; + + for (int i = 0; map.containsKey(pfx + i); i++) { + String key = pfx + i; + + String[] parts = MapEntry.parseViewMappingString((String) map.get(key)); + + if (parts.length < 2) { + throw new P4JavaError("bad client view mapping string in Client constructor: " + (String) map.get(key)); + } + + mappingList.add(new ClientView.ClientViewMapping(i, parts[0], parts[1])); + } + + // Add change view entries to list if found. + + ArrayList changeViewImpl = new ArrayList<>(); + pfx = "ChangeView"; + + for (int i = 0; map.containsKey(pfx + i); i++) { + String key = pfx + i; + + String changeEntry = (String) map.get(key); + + if (changeEntry == null || changeEntry.isEmpty()) { + throw new P4JavaError("null or empty change view mapping string in Client constructor."); + } + + changeViewImpl.add(changeEntry); + } + this.changeView = changeViewImpl; + + // Description strings *sometimes* come back with a trailing newline (that wasn't + // there when we created the client description), which + // is annoying because we can't just simply use trim() -- there's no rule that + // says that descriptions can't start or end with whitespace -- so we kludge up + // the following to get rid of just the trailing newline if it's there -- HR. + + this.description = (String) map.get("Description"); + if ((this.description != null) && (this.description.length() > 1) && this.description.endsWith("\n")) { + this.description = this.description.substring(0, this.description.length() - 1); + } + try { + // Different format here to what's in ClientSummary. + if (map.get("Access") != null) { + this.accessed = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse((String) map.get("Access")); + } + } catch (Exception exc) { + Log.error("Access date parse error in Client constructor " + exc.getLocalizedMessage()); + Log.exception(exc); + } + try { + if (map.get("Update") != null) { + this.updated = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse((String) map.get("Update")); + } + } catch (Exception exc) { + Log.error("Update date parse error in Client constructor " + exc.getLocalizedMessage()); + Log.exception(exc); + } + + viewImpl.setClient(this); + if (map.get(VIEW_DEPOT_TYPE) != null) { + this.viewDepotType = ViewDepotType.fromString(map.get(VIEW_DEPOT_TYPE).toString()); + } + } + } + + /** + * Construct a new Client object using the passed-in client summary object as a partial + * template. Note that this client object will need to have its serverImpl before any + * refreshes, updates, etc., are done against it. + *

+ * If summary is null, this is equivalent to calling the default constructor. If clientSummary + * is not null, and refresh is false, the relevant ClientSummary superclass is initialized + * by copying the passed-in summary fields. If clientSummary is not null and refresh is true, + * the Client is constructed by calling refresh() using the clientSummary's name; if refresh + * is false, the client view will be as for the default constructor. + * + * @param clientSummary clientSummary + * @param refresh refresh + * @throws ConnectionException if the Perforce server is unreachable or is not + * connected. + * @throws RequestException if the Perforce server encounters an error during + * its processing of the request + * @throws AccessException if the Perforce server denies access to the caller + */ + public Client(IClientSummary clientSummary, boolean refresh) throws ConnectionException, RequestException, AccessException { + this(clientSummary, null, refresh); + } + + /** + * Construct a new Client object using the passed-in client summary object as a partial + * template along with the passed-in IServer object. + *

+ * Note that any IServer object returned by the ServerFactory will work for the serverImpl + * parameter; if not, a suitable cast exception will be thrown. + *

+ * If summary is null, this is equivalent to calling the default constructor. If clientSummary + * is not null, and refresh is false, the relevant ClientSummary superclass is initialized + * by copying the passed-in summary fields. If clientSummary is not null and refresh is true, + * the Client is constructed by calling refresh() using the clientSummary's name; if refresh + * is false, the client view will be as for the default constructor. + * + * @param clientSummary clientSummary + * @param serverImpl serverImpl + * @param refresh refresh + * @throws ConnectionException if the Perforce server is unreachable or is not + * connected. + * @throws RequestException if the Perforce server encounters an error during + * its processing of the request + * @throws AccessException if the Perforce server denies access to the caller + */ + public Client(IClientSummary clientSummary, IServer serverImpl, boolean refresh) throws ConnectionException, RequestException, AccessException { + super(false); + setServer(serverImpl); + if (clientSummary != null) { + if (refresh) { + if (clientSummary.getName() == null) { + throw new NullPointerError("Null label name in client summary object passed to Client constructor"); + } + + this.name = clientSummary.getName(); + this.refresh(); + } else { + this.name = clientSummary.getName(); + this.accessed = clientSummary.getAccessed(); + this.updated = clientSummary.getUpdated(); + this.description = clientSummary.getDescription(); + this.hostName = clientSummary.getHostName(); + this.ownerName = clientSummary.getOwnerName(); + this.root = clientSummary.getRoot(); + this.lineEnd = clientSummary.getLineEnd(); + this.options = clientSummary.getOptions(); + this.submitOptions = clientSummary.getSubmitOptions(); + this.alternateRoots = clientSummary.getAlternateRoots(); + this.stream = clientSummary.getStream(); + this.serverId = clientSummary.getServerId(); + } + } + } + + private void init(IServer serverImpl) { + whereDelegator = new WhereDelegator(serverImpl, this); + } + + /** + * @see com.perforce.p4java.client.IClient#getServer() + */ + @Override + public IServer getServer() { + return this.serverImpl; + } + + /** + * Completing a client calls {@link #refresh()}. A no op for the new IClient object. + * + * @see #refresh() + * @see com.perforce.p4java.impl.generic.core.ServerResource#complete() + */ + @Override + public void complete() throws ConnectionException, RequestException, AccessException { + } + + /** + * This method will refresh by getting the complete client model. If this + * refresh is successful then this client will be marked as complete. + * + * @see com.perforce.p4java.impl.generic.core.ServerResource#refresh() + */ + @Override + public void refresh() throws ConnectionException, RequestException, AccessException { + IServer refreshServer = this.serverImpl; + String refreshName = null; + refreshName = this.getName(); + if (refreshServer != null && refreshName != null) { + IClient refreshedClient = refreshServer.getClient(refreshName); + if (refreshedClient != null) { + setName(refreshName); + setAccessed(refreshedClient.getAccessed()); + setUpdated(refreshedClient.getUpdated()); + setAlternateRoots(refreshedClient.getAlternateRoots()); + setClientView(refreshedClient.getClientView()); + setChangeView(refreshedClient.getChangeView()); + setDescription(refreshedClient.getDescription()); + setHostName(refreshedClient.getHostName()); + setLineEnd(refreshedClient.getLineEnd()); + setOptions(refreshedClient.getOptions()); + setOwnerName(refreshedClient.getOwnerName()); + setRoot(refreshedClient.getRoot()); + setSubmitOptions(refreshedClient.getSubmitOptions()); + setUpdated(refreshedClient.getUpdated()); + setStream(refreshedClient.getStream()); + setServerId(refreshedClient.getServerId()); + setType(refreshedClient.getType()); + } + } + } + + /** + * @see com.perforce.p4java.impl.generic.core.ServerResource#update() + */ + @Override + public void update() throws ConnectionException, RequestException, AccessException { + if (serverImpl != null) { + this.serverImpl.updateClient(this); + } else { + throw new NullPointerError("Attempted to update client with no associated server set on client"); + } + } + + /** + * @see com.perforce.p4java.impl.generic.core.ServerResource#update(boolean) + */ + @Override + public void update(boolean force) throws ConnectionException, RequestException, AccessException { + if (serverImpl != null) { + this.serverImpl.updateClient(this, force); + } else { + throw new NullPointerError("Attempted to update client with no associated server set on client"); + } + } + + /** + * @see com.perforce.p4java.client.IClient#getClientView() + */ + @Override + public ClientView getClientView() { + return this.clientView; + } + + /** + * @see com.perforce.p4java.client.IClient#setClientView(com.perforce.p4java.impl.generic.client.ClientView) + */ + @Override + public void setClientView(ClientView clientView) { + this.clientView = clientView; + } + + @Override + public ArrayList getChangeView() { + return this.changeView; + } + + @Override + public void setChangeView(ArrayList changeView) { + this.changeView = changeView; + } + + /** + * Note that this will fail with a class cast exception if the passed-in + * server is not a mapbased ServerImpl object. + * + * @param server ServerImpl server object. + */ + @Override + public void setServer(IServer server) { + this.serverImpl = (Server) server; + init(server); + } + + /** + * @see com.perforce.p4java.client.IClient#sync(java.util.List, boolean, boolean, boolean, boolean) + */ + @Override + public List sync(List fileSpecs, boolean forceUpdate, boolean noUpdate, boolean clientBypass, boolean serverBypass) throws ConnectionException, RequestException, AccessException { + + try { + return sync(fileSpecs, new SyncOptions(forceUpdate, noUpdate, clientBypass, serverBypass)); + } catch (ConnectionException exc) { + throw exc; + } catch (AccessException exc) { + throw exc; + } catch (RequestException exc) { + throw exc; + } catch (P4JavaException exc) { + throw new RequestException(exc.getMessage(), exc); + } + } + + /** + * @see com.perforce.p4java.client.IClient#sync(java.util.List, com.perforce.p4java.option.client.SyncOptions) + */ + @Override + public List sync(List fileSpecs, SyncOptions syncOpts) throws P4JavaException { + List specList = new ArrayList(); + + if ((this.serverImpl.getCurrentClient() == null) || !this.serverImpl.getCurrentClient().getName().equalsIgnoreCase(this.getName())) { + throw new RequestException("Attempted to sync a client that is not the server's current client"); + } + + List> resultMaps = this.serverImpl.execMapCmdList(CmdSpec.SYNC, Parameters.processParameters(syncOpts, fileSpecs, this.server), null); + + if (resultMaps != null) { + for (Map map : resultMaps) { + specList.add(handleFileReturn(map, serverImpl)); + } + } + + return specList; + } + + /** + * @see com.perforce.p4java.client.IClient#syncParallel(List, SyncOptions, ParallelSyncOptions) + */ + @Override + public List syncParallel(List fileSpecs, SyncOptions syncOpts, ParallelSyncOptions pSyncOpts) throws P4JavaException { + List specList = new ArrayList(); + + if ((this.serverImpl.getCurrentClient() == null) || !this.serverImpl.getCurrentClient().getName().equalsIgnoreCase(this.getName())) { + throw new RequestException("Attempted to sync a client that is not the server's current client"); + } + + String[] syncOptions = ClientHelper.buildParallelOptions(serverImpl, fileSpecs, syncOpts, pSyncOpts); + + List> resultMaps = this.serverImpl.execMapCmdList(CmdSpec.SYNC.toString(), syncOptions, null, pSyncOpts.getCallback()); + + if (resultMaps != null) { + for (Map map : resultMaps) { + specList.add(handleFileReturn(map, serverImpl)); + } + } + + return specList; + } + + /** + * @see com.perforce.p4java.client.IClient#sync(java.util.List, com.perforce.p4java.option.client.SyncOptions, com.perforce.p4java.server.callback.IStreamingCallback, int) + */ + @Override + public void sync(List fileSpecs, SyncOptions syncOpts, IStreamingCallback callback, int key) throws P4JavaException { + + if ((this.serverImpl.getCurrentClient() == null) || !this.serverImpl.getCurrentClient().getName().equalsIgnoreCase(this.getName())) { + throw new RequestException("Attempted to sync a client that is not the server's current client"); + } + + this.serverImpl.execStreamingMapCommand(CmdSpec.SYNC.toString(), Parameters.processParameters(syncOpts, fileSpecs, this.server), null, callback, key); + } + + /** + * @see com.perforce.p4java.client.IClient#sync(java.util.List, com.perforce.p4java.option.client.SyncOptions, com.perforce.p4java.server.callback.IStreamingCallback, int) + */ + @Override + public void syncParallel(List fileSpecs, SyncOptions syncOpts, IStreamingCallback callback, int key, ParallelSyncOptions pSyncOpts) throws P4JavaException { + + if ((this.serverImpl.getCurrentClient() == null) || !this.serverImpl.getCurrentClient().getName().equalsIgnoreCase(this.getName())) { + throw new RequestException("Attempted to sync a client that is not the server's current client"); + } + + String[] syncOptions = ClientHelper.buildParallelOptions(serverImpl, fileSpecs, syncOpts, pSyncOpts); + + this.serverImpl.execStreamingMapCommand(CmdSpec.SYNC.toString(), syncOptions, null, callback, key, pSyncOpts.getCallback()); + } + + /** + * @see com.perforce.p4java.client.IClient#labelSync(java.util.List, java.lang.String, boolean, boolean, boolean) + */ + @Override + public List labelSync(List fileSpecs, String labelName, boolean noUpdate, boolean addFiles, boolean deleteFiles) throws ConnectionException, RequestException, AccessException { + try { + return labelSync(fileSpecs, labelName, new LabelSyncOptions(noUpdate, addFiles, deleteFiles)); + } catch (ConnectionException exc) { + throw exc; + } catch (AccessException exc) { + throw exc; + } catch (RequestException exc) { + throw exc; + } catch (P4JavaException exc) { + throw new RequestException(exc.getMessage(), exc); + } + } + + /** + * @see com.perforce.p4java.client.IClient#labelSync(java.util.List, java.lang.String, com.perforce.p4java.option.client.LabelSyncOptions) + */ + @Override + public List labelSync(List fileSpecs, String labelName, LabelSyncOptions opts) throws P4JavaException { + List specList = new ArrayList(); + + if (labelName == null) { + throw new NullPointerError("null label name passed to Client.labelSync()"); + } + + List> resultMaps = this.serverImpl.execMapCmdList(CmdSpec.LABELSYNC, Parameters.processParameters(opts, fileSpecs, "-l" + labelName, this.server), null); + + if (resultMaps != null) { + for (Map map : resultMaps) { + specList.add(handleFileReturn(map, serverImpl)); + } + } + + return specList; + } + + /** + * @see com.perforce.p4java.client.IClient#createChangelist(com.perforce.p4java.core.IChangelist) + */ + @Override + public IChangelist createChangelist(IChangelist newChangelist) throws ConnectionException, RequestException, AccessException { + + if (this.getName() == null) { + throw new NullPointerError("Null client name in newChangelist method call"); + } else if (newChangelist == null) { + throw new NullPointerError("Null new change list specification in newChangelist method call"); + } else if (newChangelist.getId() != IChangelist.UNKNOWN) { + throw new RequestException("New changelist ID must be set to IChangelist.UNKNOWN"); + } + + List> resultMaps = this.serverImpl.execMapCmdList(CmdSpec.CHANGE, new String[]{"-i"}, InputMapper.map(newChangelist)); + + if (resultMaps != null) { + int id = IChangelist.UNKNOWN; + for (Map map : resultMaps) { + if (!ResultMapParser.handleErrorStr(map)) { + if (map.containsKey("change")) { + // Do this the easy way -- it's in the RPC map output + String changeStr = (String) map.get("change"); + if (changeStr != null) { + // skip the initial "Change " bit + int i = changeStr.indexOf(" "); + if ((i > 0) && (i < changeStr.length())) { + try { + id = new Integer(changeStr.substring(i + 1)); + } catch (Exception exc) { + Log.error("Unexpected exception in Client.newChangelist: " + exc.getLocalizedMessage()); + Log.exception(exc); + } + } + } + } else { + String infoStr = ResultMapParser.getInfoStr(map); + + if ((infoStr != null) && infoStr.contains("Change ") && infoStr.contains(" created")) { + String[] strs = infoStr.split(" "); + + if ((strs.length >= 3) && (strs[1] != null)) { + id = IChangelist.UNKNOWN; + try { + id = new Integer(strs[1]); + } catch (Exception exc) { + Log.error("Unexpected exception in Client.newChangelist: " + exc.getLocalizedMessage()); + Log.exception(exc); + } + } + } + } + } + if (id != IChangelist.UNKNOWN) { + return this.serverImpl.getChangelist(id); + } + } + } + return null; + } + + /** + * @see com.perforce.p4java.client.IClient#addFiles(java.util.List, boolean, int, java.lang.String, boolean) + */ + @Override + public List addFiles(List fileSpecs, boolean noUpdate, int changeListId, String fileType, boolean useWildcards) throws ConnectionException, AccessException { + try { + return addFiles(fileSpecs, new AddFilesOptions(noUpdate, changeListId, fileType, useWildcards)); + } catch (ConnectionException exc) { + throw exc; + } catch (AccessException exc) { + throw exc; + } catch (P4JavaException exc) { + Log.warn("Unexpected exception in IClient.addFiles: " + exc); + return new ArrayList(); + } + } + + /** + * @see com.perforce.p4java.client.IClient#addFiles(java.util.List, com.perforce.p4java.option.client.AddFilesOptions) + */ + @Override + public List addFiles(List fileSpecs, AddFilesOptions opts) throws P4JavaException { + List resultList = new ArrayList(); + + List> resultMaps = this.serverImpl.execMapCmdList(CmdSpec.ADD, Parameters.processParameters(opts, fileSpecs, this.serverImpl), null); + + if (resultMaps != null) { + for (Map map : resultMaps) { + resultList.add(handleFileReturn(map, serverImpl)); + } + } + return resultList; + } + + /** + * @see com.perforce.p4java.client.IClient#deleteFiles(java.util.List, int, boolean) + */ + @Override + public List deleteFiles(List fileSpecs, int changeListId, boolean noUpdate) throws ConnectionException, AccessException { + try { + return deleteFiles(fileSpecs, new DeleteFilesOptions(changeListId, noUpdate, false)); + } catch (ConnectionException exc) { + throw exc; + } catch (AccessException exc) { + throw exc; + } catch (P4JavaException exc) { + Log.warn("Unexpected exception in IClient.deleteFiles: " + exc); + return new ArrayList(); + } + } + + /** + * @see com.perforce.p4java.client.IClient#deleteFiles(java.util.List, com.perforce.p4java.option.client.DeleteFilesOptions) + */ + @Override + public List deleteFiles(List fileSpecs, DeleteFilesOptions opts) throws P4JavaException { + List resultList = new ArrayList(); + + List> resultMaps = this.serverImpl.execMapCmdList(CmdSpec.DELETE, Parameters.processParameters(opts, fileSpecs, this.serverImpl), null); + + if (resultMaps != null) { + for (Map map : resultMaps) { + resultList.add(handleFileReturn(map, serverImpl)); + } + } + return resultList; + } + + /** + * @see com.perforce.p4java.client.IClient#editFiles(java.util.List, boolean, boolean, int, java.lang.String) + */ + @Override + public List editFiles(List fileSpecs, boolean noUpdate, boolean bypassClientUpdate, int changeListId, String fileType) throws RequestException, ConnectionException, AccessException { + final int MINIMUM_OPTION_K_SERVER_VERSION = 20092; // minimum version number supporting bypassClientUpdate + + if (bypassClientUpdate) { + if (this.serverImpl.getServerVersionNumber() < MINIMUM_OPTION_K_SERVER_VERSION) { + throw new RequestException("edit option 'bypassClientUpdate' only supported on servers 2009.2 and later"); + } + } + + try { + return editFiles(fileSpecs, new EditFilesOptions(noUpdate, bypassClientUpdate, changeListId, fileType)); + } catch (ConnectionException exc) { + throw exc; + } catch (AccessException exc) { + throw exc; + } catch (RequestException exc) { + throw exc; + } catch (P4JavaException exc) { + throw new RequestException(exc.getMessage(), exc); + } + } + + /** + * @see com.perforce.p4java.client.IClient#editFiles(java.util.List, com.perforce.p4java.option.client.EditFilesOptions) + */ + @Override + public List editFiles(List fileSpecs, EditFilesOptions opts) throws P4JavaException { + List resultList = new ArrayList(); + + List> resultMaps = this.serverImpl.execMapCmdList(CmdSpec.EDIT, Parameters.processParameters(opts, fileSpecs, this.serverImpl), null); + + if (resultMaps != null) { + for (Map map : resultMaps) { + resultList.add(handleFileReturn(map, serverImpl)); + } + } + return resultList; + } + + /** + * @see com.perforce.p4java.client.IClient#revertFiles(java.util.List, boolean, int, boolean, boolean) + */ + @Override + public List revertFiles(List fileSpecs, boolean noUpdate, int changeListId, boolean revertOnlyUnchanged, boolean noRefresh) throws ConnectionException, AccessException { + try { + return revertFiles(fileSpecs, new RevertFilesOptions(noUpdate, changeListId, revertOnlyUnchanged, noRefresh)); + } catch (ConnectionException exc) { + throw exc; + } catch (AccessException exc) { + throw exc; + } catch (P4JavaException exc) { + Log.warn("Unexpected exception in IClient.revertFiles: " + exc); + return new ArrayList(); + } + } + + /** + * @see com.perforce.p4java.client.IClient#revertFiles(java.util.List, com.perforce.p4java.option.client.RevertFilesOptions) + */ + @Override + public List revertFiles(List fileSpecs, RevertFilesOptions opts) throws P4JavaException { + List resultList = new ArrayList(); + + List> resultMaps = this.serverImpl.execMapCmdList(CmdSpec.REVERT, Parameters.processParameters(opts, fileSpecs, null, false, this.serverImpl), null); + + if (resultMaps != null) { + for (Map map : resultMaps) { + resultList.add(handleFileReturn(map, serverImpl)); + } + } + return resultList; + } + + + @Override + public List undoFiles(List fileSpecs, int changelistId, boolean listOnly) throws ConnectionException, AccessException { + try { + UndoFilesOptions undoFilesOptions = new UndoFilesOptions(listOnly, changelistId); + + return undoFiles(fileSpecs, undoFilesOptions); + } catch (ConnectionException | AccessException e) { + throw e; + } catch (P4JavaException e) { + Log.warn("Unexpected exception in IServer.undoFiles: %s", e); + return Collections.emptyList(); + } + } + + @Override + public List undoFiles(final List fileSpecs, final UndoFilesOptions opts) throws P4JavaException { + + throwRequestExceptionIfPerforceServerVersionOldThanExpected(this.serverImpl.getServerVersion() >= 20162, "command requires a Perforce server version 2016.2 or later"); + + List resultList = new ArrayList<>(); + + List> resultMaps = this.serverImpl.execMapCmdList(CmdSpec.UNDO, Parameters.processParameters(opts, fileSpecs, null, false, this.serverImpl), null); + + if (resultMaps != null) { + for (Map map : resultMaps) { + resultList.add(handleFileReturn(map, serverImpl)); + } + } + return resultList; + } + + + /** + * @see com.perforce.p4java.client.IClient#haveList(java.util.List) + */ + @Override + public List haveList(List fileSpecs) throws ConnectionException, AccessException { + + return haveList(fileSpecs, null); + } + + /** + * @see com.perforce.p4java.client.IClient#graphHaveList(java.util.List) + */ + @Override + public List graphHaveList(List fileSpecs) throws ConnectionException, AccessException { + + return haveList(fileSpecs, new String[]{"--graph-only"}); + } + + private List haveList(List fileSpecs, String[] filter) throws ConnectionException, AccessException { + + List haveList = new ArrayList(); + + if ((this.serverImpl.getCurrentClient() == null) || !this.serverImpl.getCurrentClient().getName().equalsIgnoreCase(this.getName())) { + return haveList; + } + + List> resultMaps = this.serverImpl.execMapCmdList(CmdSpec.HAVE, Server.getPreferredPathArray(filter, fileSpecs), null); + + if (resultMaps != null) { + for (Map result : resultMaps) { + haveList.add(handleFileReturn(result, serverImpl)); + } + } + + return haveList; + } + + /** + * @see com.perforce.p4java.client.IClient#reopenFiles(java.util.List, int, java.lang.String) + */ + @Override + public List reopenFiles(List fileSpecs, int changeListId, String fileType) throws ConnectionException, AccessException { + + try { + return reopenFiles(fileSpecs, new ReopenFilesOptions().setChangelistId(changeListId).setFileType(fileType)); + } catch (ConnectionException exc) { + throw exc; + } catch (AccessException exc) { + throw exc; + } catch (P4JavaException exc) { + Log.warn("Unexpected exception in IClient.reopenFiles: " + exc); + return new ArrayList(); + } + } + + /** + * @see com.perforce.p4java.client.IClient#reopenFiles(java.util.List, com.perforce.p4java.option.client.ReopenFilesOptions) + */ + @Override + public List reopenFiles(List fileSpecs, ReopenFilesOptions opts) throws P4JavaException { + List reopenList = new ArrayList(); + + List> resultMaps = this.serverImpl.execMapCmdList(CmdSpec.REOPEN, Parameters.processParameters(opts, fileSpecs, null, false, this.serverImpl), null); + + if (resultMaps != null) { + for (Map map : resultMaps) { + reopenList.add(handleFileReturn(map, serverImpl)); + } + } + return reopenList; + } + + /** + * @see com.perforce.p4java.client.IClient#where(java.util.List) + */ + @Override + public List where(List fileSpecs) throws ConnectionException, AccessException { + return whereDelegator.where(fileSpecs); + } + + /** + * @see com.perforce.p4java.client.IClient#localWhere(java.util.List) + */ + @Override + public List localWhere(List fileSpecs) { + return whereDelegator.localWhere(fileSpecs); + } + + /** + * @see com.perforce.p4java.client.IClient#openedFiles(java.util.List, int, int) + */ + @Override + public List openedFiles(List fileSpecs, int maxFiles, int changeListId) throws ConnectionException, AccessException { + + try { + return this.openedFiles(fileSpecs, new OpenedFilesOptions(false, this.getName(), maxFiles, null, changeListId)); + } catch (ConnectionException exc) { + throw exc; + } catch (AccessException exc) { + throw exc; + } catch (P4JavaException exc) { + Log.warn("Unexpected exception in IClient.openedFiless: " + exc); + return new ArrayList(); + } + } + + /** + * @see com.perforce.p4java.client.IClient#openedFiles(java.util.List, com.perforce.p4java.option.server.OpenedFilesOptions) + */ + @Override + public List openedFiles(List fileSpecs, OpenedFilesOptions opts) throws P4JavaException { + if (opts == null) { + return this.serverImpl.getOpenedFiles(fileSpecs, new OpenedFilesOptions().setClientName(this.name)); + } else { + // Need to clone (not quite literally) the opts so we don't change the original: + if (opts.getOptions() != null) { + List optsStrings = opts.getOptions(); + return this.serverImpl.getOpenedFiles(fileSpecs, new OpenedFilesOptions(optsStrings.toArray(new String[optsStrings.size()]))); + } else { + return this.serverImpl.getOpenedFiles(fileSpecs, opts.setAllClients(false).setClientName(this.getName())); + } + } + } + + /** + * @see com.perforce.p4java.client.IClient#integrateFiles(int, boolean, com.perforce.p4java.core.file.IntegrationOptions, java.lang.String, com.perforce.p4java.core.file.IFileSpec, com.perforce.p4java.core.file.IFileSpec) + */ + @Override + public List integrateFiles(int changeListId, boolean showActionsOnly, IntegrationOptions integOpts, String branchSpec, IFileSpec fromFile, IFileSpec toFile) throws ConnectionException, AccessException { + try { + if (integOpts == null) { + integOpts = new IntegrationOptions(); // Just being generous + } + boolean integrateAroundDeletedRevs = false; + boolean rebranchSourceAfterDelete = false; + boolean deleteTargetAfterDelete = false; + boolean integrateAllAfterReAdd = false; + + String[] deleteOpts = integOpts.getDeletedOptions(); + if (deleteOpts != null) { + for (String opt : deleteOpts) { + if (opt != null) { + if (opt.equals("d")) integrateAroundDeletedRevs = true; + if (opt.equals("Di")) integrateAllAfterReAdd = true; + if (opt.equals("Dt")) rebranchSourceAfterDelete = true; + if (opt.equals("Ds")) deleteTargetAfterDelete = true; + } + } + } + + return integrateFiles(fromFile, toFile, branchSpec, new IntegrateFilesOptions(changeListId, // changelistId + integOpts.isBidirectionalInteg(), // bidirectionalInteg + integrateAroundDeletedRevs, // integrateAroundDeletedRevs + rebranchSourceAfterDelete, // rebranchSourceAfterDelete + deleteTargetAfterDelete, // deleteTargetAfterDelete + integrateAllAfterReAdd, // integrateAllAfterReAdd + integOpts.isForce(), // forceIntegration + integOpts.isUseHaveRev(), // useHaveRev + integOpts.isBaselessMerge(), // doBaselessMerge + integOpts.isDisplayBaseDetails(), // displayBaseDetails + showActionsOnly, // showActionsOnly + integOpts.isReverseMapping(), // reverseMapping + integOpts.isPropagateType(), // propagateType + integOpts.isDontCopyToClient(), // dontCopyToClient + integOpts.getMaxFiles() // maxFiles + )); + } catch (ConnectionException exc) { + throw exc; + } catch (AccessException exc) { + throw exc; + } catch (P4JavaException exc) { + Log.warn("Unexpected exception in IClient.integrateFiles: " + exc); + return new ArrayList(); + } + } + + /** + * @see com.perforce.p4java.client.IClient#integrateFiles(com.perforce.p4java.core.file.IFileSpec, com.perforce.p4java.core.file.IFileSpec, java.lang.String, com.perforce.p4java.option.client.IntegrateFilesOptions) + */ + @Override + public List integrateFiles(IFileSpec fromFile, IFileSpec toFile, String branchSpec, IntegrateFilesOptions opts) throws P4JavaException { + + // Set the server's current client to this client + IClient currentClient = this.serverImpl.getCurrentClient(); + this.serverImpl.setCurrentClient(this); + List> resultMaps = this.serverImpl.execMapCmdList(CmdSpec.INTEG, Parameters.processParameters(opts, fromFile, toFile, branchSpec, this.serverImpl), null); + // Set the server's current client back to the previous one + this.serverImpl.setCurrentClient(currentClient); + + return getIntegrationFilesFromReturn(resultMaps); + } + + /** + * @see com.perforce.p4java.client.IClient#integrateFiles(com.perforce.p4java.core.file.IFileSpec, java.util.List, com.perforce.p4java.option.client.IntegrateFilesOptions) + */ + @Override + public List integrateFiles(IFileSpec fromFile, List toFiles, IntegrateFilesOptions opts) throws P4JavaException { + + // Set the server's current client to this client + IClient currentClient = this.serverImpl.getCurrentClient(); + this.serverImpl.setCurrentClient(this); + List> resultMaps = this.serverImpl.execMapCmdList(CmdSpec.INTEG, Parameters.processParameters(opts, fromFile, toFiles, null, this.serverImpl), null); + + // Set the server's current client back to the previous one + this.serverImpl.setCurrentClient(currentClient); + + return getIntegrationFilesFromReturn(resultMaps); + } + + /** + * @see com.perforce.p4java.client.IClient#resolveFilesAuto(java.util.List, boolean, boolean, boolean, boolean, boolean) + */ + @Override + public List resolveFilesAuto(List fileSpecs, boolean safeMerge, boolean acceptTheirs, boolean acceptYours, boolean showActionsOnly, boolean forceResolve) throws ConnectionException, AccessException { + try { + return resolveFilesAuto(fileSpecs, new ResolveFilesAutoOptions().setAcceptTheirs(acceptTheirs).setAcceptYours(acceptYours).setForceResolve(forceResolve).setSafeMerge(safeMerge).setShowActionsOnly(showActionsOnly)); + } catch (ConnectionException exc) { + throw exc; + } catch (AccessException exc) { + throw exc; + } catch (P4JavaException exc) { + Log.warn("Unexpected exception in IClient.resolveFilesAuto: " + exc); + return new ArrayList(); + } + } + + /** + * @see com.perforce.p4java.client.IClient#resolveFilesAuto(java.util.List, com.perforce.p4java.option.client.ResolveFilesAutoOptions) + */ + @Override + public List resolveFilesAuto(List fileSpecs, ResolveFilesAutoOptions opts) throws P4JavaException { List> resultMaps = resolveFilesAutoMap(fileSpecs, opts); - return getIntegrationFilesFromReturn(resultMaps); - } + return getIntegrationFilesFromReturn(resultMaps); + } @Override - public String resolveStreamAuto(ResolveFilesAutoOptions opts) - throws P4JavaException { + public String resolveStreamAuto(ResolveFilesAutoOptions opts) throws P4JavaException { List> resultMaps = resolveFilesAutoMap(null, opts); return parseCommandResultMapAsString(resultMaps); } - private List> resolveFilesAutoMap(List fileSpecs, ResolveFilesAutoOptions opts) - throws P4JavaException { + private List> resolveFilesAutoMap(List fileSpecs, ResolveFilesAutoOptions opts) throws P4JavaException { String amFlag = null; - if ((opts == null) - || (!opts.isAcceptTheirs() - && !opts.isAcceptYours() - && !opts.isForceResolve() - && !opts.isSafeMerge())) { + if ((opts == null) || (!opts.isAcceptTheirs() && !opts.isAcceptYours() && !opts.isForceResolve() && !opts.isSafeMerge())) { amFlag = "-am"; } - List> resultMaps = this.serverImpl.execMapCmdList( - CmdSpec.RESOLVE, - Parameters.processParameters( - opts, fileSpecs, amFlag, serverImpl), null); + List> resultMaps = this.serverImpl.execMapCmdList(CmdSpec.RESOLVE, Parameters.processParameters(opts, fileSpecs, amFlag, serverImpl), null); return resultMaps; } - /** - * @see com.perforce.p4java.client.IClient#resolveFile(com.perforce.p4java.core.file.IFileSpec, java.io.InputStream) - */ - @Override - public IFileSpec resolveFile(IFileSpec targetFile, InputStream sourceStream) - throws ConnectionException, RequestException, AccessException { - return resolveFile(targetFile, sourceStream, true, -1, -1); - } - - /** - * @see com.perforce.p4java.client.IClient#resolveFile(com.perforce.p4java.core.file.IFileSpec, java.io.InputStream) - */ - @Override - public IFileSpec resolveFile(IFileSpec targetFileSpec, InputStream sourceStream, boolean useTextualMerge, - int startFromRev, int endFromRev) - throws ConnectionException, RequestException, AccessException { - - if (targetFileSpec == null) { - throw new NullPointerError("Null target file spec passed to IClient.resolveFile"); - } - - if (sourceStream == null) { - throw new NullPointerError("Null source stream passed to IClient.resolveFile"); - } - - if (!(this.serverImpl instanceof com.perforce.p4java.impl.mapbased.rpc.RpcServer)) { - throw new RequestException( - "Request not supported by the current P4Java implementation;" - + " use an RPC-based pure Java implementation if possible"); - } - - Map resolveMap = new HashMap(); - IFileSpec fileSpec = null; - File tmpFile = null; - - if (serverImpl != null) { - try { - String defaultTmpDir = System.getProperty("java.io.tmpdir"); - String tmpDirProp = serverImpl.getProperties().getProperty(PropertyDefs.P4JAVA_TMP_DIR_KEY, defaultTmpDir); - tmpFile = File.createTempFile("p4java", ".tmp", new File(tmpDirProp)); - - if (tmpFile != null) { - FileOutputStream outStream = new FileOutputStream(tmpFile); - byte[] bytes = new byte[1024]; - int bytesRead; - while ((bytesRead = sourceStream.read(bytes)) > 0) { - outStream.write(bytes, 0, bytesRead); - } - outStream.close(); - resolveMap.put(MERGE_TMP_FILENAME_KEY, tmpFile.getPath()); - resolveMap.put(MERGE_START_FROM_REV_KEY, new Integer(startFromRev)); - resolveMap.put(MERGE_END_FROM_REV_KEY, new Integer(endFromRev)); - } - - List args = new ArrayList(); - if (useTextualMerge) { - args.add("-t"); - } - - // make sure we don't get a client-ActionResolve call - final int MINIMUM_ACTION_RESOLVE_SERVER_VERSION = 20111; // minimum version number supporting bypassClientUpdate - if (this.serverImpl.getServerVersionNumber() >= MINIMUM_ACTION_RESOLVE_SERVER_VERSION) { - if (startFromRev != -1 || endFromRev != -1) { - args.add("-Ac"); - } - } - args.add(targetFileSpec.getAnnotatedPreferredPathString()); - - List> resultMaps = this.serverImpl.execMapCmdList(CmdSpec.RESOLVE, args.toArray(new String[0]), resolveMap); - - if (resultMaps != null) { - // This returns *two* entries in normal cases... - if (resultMaps.size() > 1) { - return handleIntegrationFileReturn(resultMaps.get(1), true, serverImpl); - } else { - return handleIntegrationFileReturn(resultMaps.get(0), false, serverImpl); - } - } - } catch (IOException exc) { - Log.error("local file I/O error on resolve: " + exc.getMessage()); - Log.exception(exc); - throw new P4JavaError("local file I/O error on resolve: " + exc.getMessage()); - } finally { - if (tmpFile != null) { - tmpFile.delete(); - } - } - } - - return fileSpec; - } - - /** - * @see com.perforce.p4java.client.IClient#resolvedFiles(java.util.List, boolean) - */ - @Override - public List resolvedFiles(List fileSpecs, - boolean showBaseRevision) throws ConnectionException, AccessException { - try { - return resolvedFiles(fileSpecs, - new ResolvedFilesOptions().setShowBaseRevision(showBaseRevision)); - } catch (ConnectionException exc) { - throw exc; - } catch (AccessException exc) { - throw exc; - } catch (P4JavaException exc) { - Log.warn("Unexpected exception in IClient.resolvedFiles: " + exc); - return new ArrayList(); - } - } - - /** - * @see com.perforce.p4java.client.IClient#resolvedFiles(java.util.List, com.perforce.p4java.option.client.ResolvedFilesOptions) - */ - @Override - public List resolvedFiles(List fileSpecs, ResolvedFilesOptions opts) - throws P4JavaException { - - List> resultMaps = this.serverImpl.execMapCmdList( - CmdSpec.RESOLVED, - Parameters.processParameters(opts, fileSpecs, serverImpl), - null); - - return getIntegrationFilesFromReturn(resultMaps); - } - - /** - * @see com.perforce.p4java.client.IClient#lockFiles(java.util.List, int) - */ - @Override - public List lockFiles(List fileSpecs, int changeListId) - throws ConnectionException, AccessException { - try { - return lockFiles(fileSpecs, new LockFilesOptions().setChangelistId(changeListId)); - } catch (ConnectionException exc) { - throw exc; - } catch (AccessException exc) { - throw exc; - } catch (P4JavaException exc) { - Log.warn("Unexpected exception in IClient.lockFiles: " + exc); - return new ArrayList(); - } - } - - /** - * @see com.perforce.p4java.client.IClient#lockFiles(java.util.List, com.perforce.p4java.option.client.LockFilesOptions) - */ - @Override - public List lockFiles(List fileSpecs, LockFilesOptions opts) - throws P4JavaException { - List lockedList = new ArrayList(); - - List> resultMaps = this.serverImpl.execMapCmdList( - CmdSpec.LOCK, - Parameters.processParameters(opts, fileSpecs, serverImpl), - null); - if (resultMaps != null) { - for (Map result : resultMaps) { - lockedList.add(handleFileReturn(result, serverImpl)); - } - } - - return lockedList; - } - - /** - * @see com.perforce.p4java.client.IClient#unlockFiles(java.util.List, int, boolean) - */ - @Override - public List unlockFiles(List fileSpecs, int changeListId, boolean force) - throws ConnectionException, AccessException { - try { - return unlockFiles(fileSpecs, - new UnlockFilesOptions().setChangelistId(changeListId).setForceUnlock(force)); - } catch (ConnectionException exc) { - throw exc; - } catch (AccessException exc) { - throw exc; - } catch (P4JavaException exc) { - Log.warn("Unexpected exception in IClient.lockFiles: " + exc); - return new ArrayList(); - } - } - - /** - * @see com.perforce.p4java.client.IClient#unlockFiles(java.util.List, com.perforce.p4java.option.client.UnlockFilesOptions) - */ - @Override - public List unlockFiles(List fileSpecs, UnlockFilesOptions opts) - throws P4JavaException { - List unlockedList = new ArrayList(); - - List> resultMaps = this.serverImpl.execMapCmdList( - CmdSpec.UNLOCK, - Parameters.processParameters(opts, fileSpecs, serverImpl), - null); - if (resultMaps != null) { - for (Map result : resultMaps) { - unlockedList.add(handleFileReturn(result, serverImpl)); - } - } - - return unlockedList; - } - - /** - * @see com.perforce.p4java.client.IClient#getDiffFiles(java.util.List, int, boolean, boolean, boolean, boolean, boolean, boolean, boolean) - */ - @Override - public List getDiffFiles(List fileSpecs, - int maxFiles, boolean diffNonTextFiles, boolean openedDifferentMissing, - boolean openedForIntegrate, boolean unopenedMissing, - boolean unopenedDifferent, boolean unopenedWithStatus, boolean openedSame) - throws ConnectionException, RequestException, AccessException { - try { - return getDiffFiles(fileSpecs, new GetDiffFilesOptions() - .setMaxFiles(maxFiles) - .setDiffNonTextFiles(diffNonTextFiles) - .setOpenedDifferentMissing(openedDifferentMissing) - .setOpenedForIntegrate(openedForIntegrate) - .setUnopenedMissing(unopenedMissing) - .setUnopenedDifferent(unopenedDifferent) - .setUnopenedWithStatus(unopenedWithStatus) - .setOpenedSame(openedSame) - ); - } catch (ConnectionException exc) { - throw exc; - } catch (AccessException exc) { - throw exc; - } catch (P4JavaException exc) { - Log.warn("Unexpected exception in IClient.getDiffFiles: " + exc); - return new ArrayList(); - } - } - - /** - * @see com.perforce.p4java.client.IClient#getDiffFiles(java.util.List, com.perforce.p4java.option.client.GetDiffFilesOptions) - */ - @Override - public List getDiffFiles(List fileSpecs, GetDiffFilesOptions opts) - throws P4JavaException { - List diffList = new ArrayList(); - - List> resultMaps = this.serverImpl.execMapCmdList( - CmdSpec.DIFF, - Parameters.processParameters(opts, fileSpecs, serverImpl), - null); - if (resultMaps != null) { - for (Map result : resultMaps) { - diffList.add(handleFileReturn(result, serverImpl)); - } - } - - return diffList; - } - - /** - * @see com.perforce.p4java.client.IClient#shelveFiles(java.util.List, int, com.perforce.p4java.option.client.ShelveFilesOptions) - */ - @Override - public List shelveFiles(List fileSpecs, int changelistId, - ShelveFilesOptions opts) throws P4JavaException { - List resultList = new ArrayList(); - - String changelistString = null; - if (changelistId == IChangelist.DEFAULT) { - changelistString = "-cdefault"; - } else if (changelistId > 0) { - changelistString = "-c" + changelistId; - } - // Set the server's current client to this client - IClient currentClient = this.serverImpl.getCurrentClient(); - this.serverImpl.setCurrentClient(this); - List> resultMaps = this.serverImpl.execMapCmdList( - CmdSpec.SHELVE, - Parameters.processParameters( - opts, fileSpecs, changelistString, serverImpl), - null); - if (resultMaps != null) { - for (Map result : resultMaps) { - resultList.add(handleFileReturn(result, serverImpl)); - } - } - // Set the server's current client back to the previous one - this.serverImpl.setCurrentClient(currentClient); - - return resultList; - } - - /** - * @see com.perforce.p4java.client.IClient#unshelveFiles(java.util.List, int, int, com.perforce.p4java.option.client.UnshelveFilesOptions) - */ - @Override - public List unshelveFiles(List fileSpecs, int sourceChangelistId, - int targetChangelistId, UnshelveFilesOptions opts) throws P4JavaException { - List resultList = new ArrayList(); - - if (sourceChangelistId <= 0) { - throw new RequestException( - "Source changelist ID must be greater than zero"); - } - - String sourceChangelistString = "-s" + sourceChangelistId; - String targetChangelistString = null; - if (targetChangelistId == IChangelist.DEFAULT) { - targetChangelistString = "-cdefault"; - } else if (targetChangelistId > 0) { - targetChangelistString = "-c" + targetChangelistId; - } - - List> resultMaps = this.serverImpl.execMapCmdList( - CmdSpec.UNSHELVE, - Parameters.processParameters( - opts, - fileSpecs, - new String[]{ - sourceChangelistString, - targetChangelistString}, - serverImpl), - null); - if (resultMaps != null) { - for (Map result : resultMaps) { - resultList.add(handleFileReturn(result, serverImpl)); - } - } - - return resultList; - } - - /** - * @see com.perforce.p4java.client.IClient#shelveChangelist(int, - * java.util.List, boolean, boolean, boolean) - */ - @Override - public List shelveChangelist(int changelistId, - List fileSpecs, boolean forceUpdate, boolean replace, - boolean discard) throws ConnectionException, RequestException, - AccessException { - try { - return shelveFiles(fileSpecs, changelistId, new ShelveFilesOptions() - .setDeleteFiles(discard) - .setForceShelve(forceUpdate) - .setReplaceFiles(replace)); - } catch (ConnectionException exc) { - throw exc; - } catch (AccessException exc) { - throw exc; - } catch (P4JavaException exc) { - Log.warn("Unexpected exception in IClient.shelveChangelist: " + exc); - return new ArrayList(); - } - } - - /** - * @see com.perforce.p4java.client.IClient#shelveChangelist(com.perforce.p4java.core.IChangelist) - */ - @Override - public List shelveChangelist(IChangelist list) throws ConnectionException, - RequestException, AccessException { - if (list == null) { - throw new NullPointerError("Null changelist specification in shelveChangelist method call"); - } - - // Set the server's current client to this client - IClient currentClient = this.serverImpl.getCurrentClient(); - this.serverImpl.setCurrentClient(this); - List> resultMaps = this.serverImpl.execMapCmdList(CmdSpec.SHELVE, - new String[]{"-i"}, - InputMapper.map(list, true)); - - List resultList = new ArrayList(); - if (resultMaps != null) { - for (Map result : resultMaps) { - resultList.add(handleFileReturn(result, serverImpl)); - } - } - // Set the server's current client back to the previous one - this.serverImpl.setCurrentClient(currentClient); - - return resultList; - } - - /** - * @see com.perforce.p4java.client.IClient#unshelveChangelist(int, - * java.util.List, int, boolean, boolean) - */ - @Override - public List unshelveChangelist(int shelveChangelistId, - List fileSpecs, int clientChangelistId, - boolean forceOverwrite, boolean previewOnly) - throws ConnectionException, RequestException, AccessException { - if (shelveChangelistId <= 0) { - throw new RequestException( - "Shelve changelist ID must be greater than zero"); - } - - try { - return unshelveFiles(fileSpecs, shelveChangelistId, clientChangelistId, - new UnshelveFilesOptions() - .setForceUnshelve(forceOverwrite) - .setPreview(previewOnly)); - } catch (ConnectionException exc) { - throw exc; - } catch (AccessException exc) { - throw exc; - } catch (P4JavaException exc) { - Log.warn("Unexpected exception in IClient.unshelveChangelist: " + exc); - return new ArrayList(); - } - } - - /** - * @see com.perforce.p4java.client.IClient#submitShelvedChangelist(int) - */ - @Override - public List submitShelvedChangelist(int shelvedChangelistId) throws P4JavaException { - - if (shelvedChangelistId <= 0) { - throw new RequestException( - "Shelved changelist ID must be greater than zero"); - } - - List> resultMaps = this.serverImpl.execMapCmdList(CmdSpec.SUBMIT, - new String[]{"-e", "" + shelvedChangelistId}, - null); - - List resultList = new ArrayList(); - if (resultMaps != null) { - for (Map result : resultMaps) { - resultList.add(handleFileReturn(result, serverImpl)); - } - } - return resultList; - } - - /** - * @see com.perforce.p4java.client.IClient#copyFiles(com.perforce.p4java.core.file.IFileSpec, com.perforce.p4java.core.file.IFileSpec, java.lang.String, com.perforce.p4java.option.client.CopyFilesOptions) - */ - @Override - public List copyFiles(IFileSpec fromFile, IFileSpec toFile, String branchSpec, - CopyFilesOptions opts) throws P4JavaException { - - List> resultMaps = this.serverImpl.execMapCmdList( - CmdSpec.COPY, - Parameters.processParameters( - opts, fromFile, toFile, branchSpec, this.serverImpl), - null); - - return getIntegrationFilesFromReturn(resultMaps); - } - - /** - * @see com.perforce.p4java.client.IClient#copyFiles(com.perforce.p4java.core.file.IFileSpec, java.util.List, com.perforce.p4java.option.client.CopyFilesOptions) - */ - @Override - public List copyFiles(IFileSpec fromFile, List toFiles, - CopyFilesOptions opts) throws P4JavaException { - - List> resultMaps = this.serverImpl.execMapCmdList( - CmdSpec.COPY, - Parameters.processParameters( - opts, fromFile, toFiles, null, this.serverImpl), - null); - - return getIntegrationFilesFromReturn(resultMaps); - } - - /** - * @see com.perforce.p4java.client.IClient#mergeFiles(com.perforce.p4java.core.file.IFileSpec, java.util.List, com.perforce.p4java.option.client.MergeFilesOptions) - */ - @Override - public List mergeFiles(IFileSpec fromFile, List toFiles, - MergeFilesOptions opts) throws P4JavaException { - - List> resultMaps = this.serverImpl.execMapCmdList( - CmdSpec.MERGE, - Parameters.processParameters( - opts, fromFile, toFiles, null, this.serverImpl), - null); - - return getIntegrationFilesFromReturn(resultMaps); - } - - /** - * Get the integration files from the return results. - */ - private List getIntegrationFilesFromReturn(List> maps) throws P4JavaException { - List integList = new ArrayList(); - if (maps != null) { - for (Map result : maps) { - integList.add(handleIntegrationFileReturn(result, serverImpl)); - } - } - return integList; - } - - /** - * @see com.perforce.p4java.client.IClient#reconcileFiles(java.util.List, com.perforce.p4java.option.client.ReconcileFilesOptions) - */ - @Override - public List reconcileFiles(List fileSpecs, ReconcileFilesOptions opts) - throws P4JavaException { - List resultList = new ArrayList(); - - List> resultMaps = this.serverImpl.execMapCmdList( - CmdSpec.RECONCILE, - Parameters.processParameters( - opts, fileSpecs, this.serverImpl), - null); - - if (resultMaps != null) { - for (Map map : resultMaps) { - resultList.add(handleFileReturn(map, serverImpl)); - } - } - return resultList; - } - - /** - * @see com.perforce.p4java.client.IClient#reconcileFiles(List, ReconcileFilesOptions, IStreamingCallback, int) - */ - @Override - public void reconcileFiles(List fileSpecs, ReconcileFilesOptions opts, IStreamingCallback callback, int key) - throws P4JavaException { - - if ((this.serverImpl.getCurrentClient() == null) - || !this.serverImpl.getCurrentClient().getName().equalsIgnoreCase(this.getName())) { - throw new RequestException( - "Attempted to reconcile a client that is not the server's current client"); - } - - this.serverImpl.execStreamingMapCommand( - CmdSpec.RECONCILE.toString(), - Parameters.processParameters( - opts, fileSpecs, this.serverImpl), - null, - callback, - key); - } - - /** - * @see com.perforce.p4java.client.IClient#populateFiles(com.perforce.p4java.core.file.IFileSpec, java.util.List, com.perforce.p4java.option.client.PopulateFilesOptions) - */ - @Override - public List populateFiles(IFileSpec fromFile, List toFiles, - PopulateFilesOptions opts) throws P4JavaException { - - List> resultMaps = this.serverImpl.execMapCmdList( - CmdSpec.POPULATE, - Parameters.processParameters( - opts, fromFile, toFiles, null, this.serverImpl), - null); - - return getIntegrationFilesFromReturn(resultMaps); - } - - /* - * @see com.perforce.p4java.server.IServer#getRepos() - */ - @Override - public List getRepos() throws ConnectionException, RequestException, AccessException { - ReposDelegator reposDelegator = new ReposDelegator(this.serverImpl); - return reposDelegator.getRepos(this.getName()); - } - - /** - * @see IClient#getViewDepotType() - */ - @Override - public ViewDepotType getViewDepotType() { - return viewDepotType; - } - - /** - * @param fileSpecs List of File specs - * @param options List options - * @return data fetched from p4 list command - * @throws P4JavaException API error - */ - @Override - public ListData getListData(List fileSpecs, ListOptions options) throws P4JavaException { - IListDelegator listDelegator = new ListDelegator(this.serverImpl); - return listDelegator.getListData(fileSpecs, options, this.getName()); - } - - - @Override - public String setStreamParentView( - IStreamSummary.ParentView parentview, boolean sourceComments) throws P4JavaException { - if (this.getStream() == null) { - throwOptionsException("Missing Stream field", this); - } + /** + * @see com.perforce.p4java.client.IClient#resolveFile(com.perforce.p4java.core.file.IFileSpec, java.io.InputStream) + */ + @Override + public IFileSpec resolveFile(IFileSpec targetFile, InputStream sourceStream) throws ConnectionException, RequestException, AccessException { + return resolveFile(targetFile, sourceStream, true, -1, -1); + } + + /** + * @see com.perforce.p4java.client.IClient#resolveFile(com.perforce.p4java.core.file.IFileSpec, java.io.InputStream) + */ + @Override + public IFileSpec resolveFile(IFileSpec targetFileSpec, InputStream sourceStream, boolean useTextualMerge, int startFromRev, int endFromRev) throws ConnectionException, RequestException, AccessException { + + if (targetFileSpec == null) { + throw new NullPointerError("Null target file spec passed to IClient.resolveFile"); + } + + if (sourceStream == null) { + throw new NullPointerError("Null source stream passed to IClient.resolveFile"); + } + + if (!(this.serverImpl instanceof com.perforce.p4java.impl.mapbased.rpc.RpcServer)) { + throw new RequestException("Request not supported by the current P4Java implementation;" + " use an RPC-based pure Java implementation if possible"); + } + + Map resolveMap = new HashMap(); + IFileSpec fileSpec = null; + File tmpFile = null; + + if (serverImpl != null) { + try { + String defaultTmpDir = System.getProperty("java.io.tmpdir"); + String tmpDirProp = serverImpl.getProperties().getProperty(PropertyDefs.P4JAVA_TMP_DIR_KEY, defaultTmpDir); + tmpFile = File.createTempFile("p4java", ".tmp", new File(tmpDirProp)); + + if (tmpFile != null) { + FileOutputStream outStream = new FileOutputStream(tmpFile); + byte[] bytes = new byte[1024]; + int bytesRead; + while ((bytesRead = sourceStream.read(bytes)) > 0) { + outStream.write(bytes, 0, bytesRead); + } + outStream.close(); + resolveMap.put(MERGE_TMP_FILENAME_KEY, tmpFile.getPath()); + resolveMap.put(MERGE_START_FROM_REV_KEY, new Integer(startFromRev)); + resolveMap.put(MERGE_END_FROM_REV_KEY, new Integer(endFromRev)); + } + + List args = new ArrayList(); + if (useTextualMerge) { + args.add("-t"); + } + + // make sure we don't get a client-ActionResolve call + final int MINIMUM_ACTION_RESOLVE_SERVER_VERSION = 20111; // minimum version number supporting bypassClientUpdate + if (this.serverImpl.getServerVersionNumber() >= MINIMUM_ACTION_RESOLVE_SERVER_VERSION) { + if (startFromRev != -1 || endFromRev != -1) { + args.add("-Ac"); + } + } + args.add(targetFileSpec.getAnnotatedPreferredPathString()); + + List> resultMaps = this.serverImpl.execMapCmdList(CmdSpec.RESOLVE, args.toArray(new String[0]), resolveMap); + + if (resultMaps != null) { + // This returns *two* entries in normal cases... + if (resultMaps.size() > 1) { + return handleIntegrationFileReturn(resultMaps.get(1), true, serverImpl); + } else { + return handleIntegrationFileReturn(resultMaps.get(0), false, serverImpl); + } + } + } catch (IOException exc) { + Log.error("local file I/O error on resolve: " + exc.getMessage()); + Log.exception(exc); + throw new P4JavaError("local file I/O error on resolve: " + exc.getMessage()); + } finally { + if (tmpFile != null) { + tmpFile.delete(); + } + } + } + + return fileSpec; + } + + /** + * @see com.perforce.p4java.client.IClient#resolvedFiles(java.util.List, boolean) + */ + @Override + public List resolvedFiles(List fileSpecs, boolean showBaseRevision) throws ConnectionException, AccessException { + try { + return resolvedFiles(fileSpecs, new ResolvedFilesOptions().setShowBaseRevision(showBaseRevision)); + } catch (ConnectionException exc) { + throw exc; + } catch (AccessException exc) { + throw exc; + } catch (P4JavaException exc) { + Log.warn("Unexpected exception in IClient.resolvedFiles: " + exc); + return new ArrayList(); + } + } + + /** + * @see com.perforce.p4java.client.IClient#resolvedFiles(java.util.List, com.perforce.p4java.option.client.ResolvedFilesOptions) + */ + @Override + public List resolvedFiles(List fileSpecs, ResolvedFilesOptions opts) throws P4JavaException { + + List> resultMaps = this.serverImpl.execMapCmdList(CmdSpec.RESOLVED, Parameters.processParameters(opts, fileSpecs, serverImpl), null); + + return getIntegrationFilesFromReturn(resultMaps); + } + + /** + * @see com.perforce.p4java.client.IClient#lockFiles(java.util.List, int) + */ + @Override + public List lockFiles(List fileSpecs, int changeListId) throws ConnectionException, AccessException { + try { + return lockFiles(fileSpecs, new LockFilesOptions().setChangelistId(changeListId)); + } catch (ConnectionException exc) { + throw exc; + } catch (AccessException exc) { + throw exc; + } catch (P4JavaException exc) { + Log.warn("Unexpected exception in IClient.lockFiles: " + exc); + return new ArrayList(); + } + } + + /** + * @see com.perforce.p4java.client.IClient#lockFiles(java.util.List, com.perforce.p4java.option.client.LockFilesOptions) + */ + @Override + public List lockFiles(List fileSpecs, LockFilesOptions opts) throws P4JavaException { + List lockedList = new ArrayList(); + + List> resultMaps = this.serverImpl.execMapCmdList(CmdSpec.LOCK, Parameters.processParameters(opts, fileSpecs, serverImpl), null); + if (resultMaps != null) { + for (Map result : resultMaps) { + lockedList.add(handleFileReturn(result, serverImpl)); + } + } + + return lockedList; + } + + /** + * @see com.perforce.p4java.client.IClient#unlockFiles(java.util.List, int, boolean) + */ + @Override + public List unlockFiles(List fileSpecs, int changeListId, boolean force) throws ConnectionException, AccessException { + try { + return unlockFiles(fileSpecs, new UnlockFilesOptions().setChangelistId(changeListId).setForceUnlock(force)); + } catch (ConnectionException exc) { + throw exc; + } catch (AccessException exc) { + throw exc; + } catch (P4JavaException exc) { + Log.warn("Unexpected exception in IClient.lockFiles: " + exc); + return new ArrayList(); + } + } + + /** + * @see com.perforce.p4java.client.IClient#unlockFiles(java.util.List, com.perforce.p4java.option.client.UnlockFilesOptions) + */ + @Override + public List unlockFiles(List fileSpecs, UnlockFilesOptions opts) throws P4JavaException { + List unlockedList = new ArrayList(); + + List> resultMaps = this.serverImpl.execMapCmdList(CmdSpec.UNLOCK, Parameters.processParameters(opts, fileSpecs, serverImpl), null); + if (resultMaps != null) { + for (Map result : resultMaps) { + unlockedList.add(handleFileReturn(result, serverImpl)); + } + } + + return unlockedList; + } + + /** + * @see com.perforce.p4java.client.IClient#getDiffFiles(java.util.List, int, boolean, boolean, boolean, boolean, boolean, boolean, boolean) + */ + @Override + public List getDiffFiles(List fileSpecs, int maxFiles, boolean diffNonTextFiles, boolean openedDifferentMissing, boolean openedForIntegrate, boolean unopenedMissing, boolean unopenedDifferent, boolean unopenedWithStatus, boolean openedSame) throws ConnectionException, RequestException, AccessException { + try { + return getDiffFiles(fileSpecs, new GetDiffFilesOptions().setMaxFiles(maxFiles).setDiffNonTextFiles(diffNonTextFiles).setOpenedDifferentMissing(openedDifferentMissing).setOpenedForIntegrate(openedForIntegrate).setUnopenedMissing(unopenedMissing).setUnopenedDifferent(unopenedDifferent).setUnopenedWithStatus(unopenedWithStatus).setOpenedSame(openedSame)); + } catch (ConnectionException exc) { + throw exc; + } catch (AccessException exc) { + throw exc; + } catch (P4JavaException exc) { + Log.warn("Unexpected exception in IClient.getDiffFiles: " + exc); + return new ArrayList(); + } + } + + /** + * @see com.perforce.p4java.client.IClient#getDiffFiles(java.util.List, com.perforce.p4java.option.client.GetDiffFilesOptions) + */ + @Override + public List getDiffFiles(List fileSpecs, GetDiffFilesOptions opts) throws P4JavaException { + List diffList = new ArrayList(); + + List> resultMaps = this.serverImpl.execMapCmdList(CmdSpec.DIFF, Parameters.processParameters(opts, fileSpecs, serverImpl), null); + if (resultMaps != null) { + for (Map result : resultMaps) { + diffList.add(handleFileReturn(result, serverImpl)); + } + } + + return diffList; + } + + /** + * @see com.perforce.p4java.client.IClient#shelveFiles(java.util.List, int, com.perforce.p4java.option.client.ShelveFilesOptions) + */ + @Override + public List shelveFiles(List fileSpecs, int changelistId, ShelveFilesOptions opts) throws P4JavaException { + List resultList = new ArrayList(); + + String changelistString = null; + if (changelistId == IChangelist.DEFAULT) { + changelistString = "-cdefault"; + } else if (changelistId > 0) { + changelistString = "-c" + changelistId; + } + // Set the server's current client to this client + IClient currentClient = this.serverImpl.getCurrentClient(); + this.serverImpl.setCurrentClient(this); + List> resultMaps = this.serverImpl.execMapCmdList(CmdSpec.SHELVE, Parameters.processParameters(opts, fileSpecs, changelistString, serverImpl), null); + if (resultMaps != null) { + for (Map result : resultMaps) { + resultList.add(handleFileReturn(result, serverImpl)); + } + } + // Set the server's current client back to the previous one + this.serverImpl.setCurrentClient(currentClient); + + return resultList; + } + + /** + * @see com.perforce.p4java.client.IClient#unshelveFiles(java.util.List, int, int, com.perforce.p4java.option.client.UnshelveFilesOptions) + */ + @Override + public List unshelveFiles(List fileSpecs, int sourceChangelistId, int targetChangelistId, UnshelveFilesOptions opts) throws P4JavaException { + List resultList = new ArrayList(); + + if (sourceChangelistId <= 0) { + throw new RequestException("Source changelist ID must be greater than zero"); + } + + String sourceChangelistString = "-s" + sourceChangelistId; + String targetChangelistString = null; + if (targetChangelistId == IChangelist.DEFAULT) { + targetChangelistString = "-cdefault"; + } else if (targetChangelistId > 0) { + targetChangelistString = "-c" + targetChangelistId; + } + + List> resultMaps = this.serverImpl.execMapCmdList(CmdSpec.UNSHELVE, Parameters.processParameters(opts, fileSpecs, new String[]{sourceChangelistString, targetChangelistString}, serverImpl), null); + if (resultMaps != null) { + for (Map result : resultMaps) { + resultList.add(handleFileReturn(result, serverImpl)); + } + } + + return resultList; + } + + /** + * @see com.perforce.p4java.client.IClient#shelveChangelist(int, + * java.util.List, boolean, boolean, boolean) + */ + @Override + public List shelveChangelist(int changelistId, List fileSpecs, boolean forceUpdate, boolean replace, boolean discard) throws ConnectionException, RequestException, AccessException { + try { + return shelveFiles(fileSpecs, changelistId, new ShelveFilesOptions().setDeleteFiles(discard).setForceShelve(forceUpdate).setReplaceFiles(replace)); + } catch (ConnectionException exc) { + throw exc; + } catch (AccessException exc) { + throw exc; + } catch (P4JavaException exc) { + Log.warn("Unexpected exception in IClient.shelveChangelist: " + exc); + return new ArrayList(); + } + } + + /** + * @see com.perforce.p4java.client.IClient#shelveChangelist(com.perforce.p4java.core.IChangelist) + */ + @Override + public List shelveChangelist(IChangelist list) throws ConnectionException, RequestException, AccessException { + if (list == null) { + throw new NullPointerError("Null changelist specification in shelveChangelist method call"); + } + + // Set the server's current client to this client + IClient currentClient = this.serverImpl.getCurrentClient(); + this.serverImpl.setCurrentClient(this); + List> resultMaps = this.serverImpl.execMapCmdList(CmdSpec.SHELVE, new String[]{"-i"}, InputMapper.map(list, true)); + + List resultList = new ArrayList(); + if (resultMaps != null) { + for (Map result : resultMaps) { + resultList.add(handleFileReturn(result, serverImpl)); + } + } + // Set the server's current client back to the previous one + this.serverImpl.setCurrentClient(currentClient); + + return resultList; + } + + /** + * @see com.perforce.p4java.client.IClient#unshelveChangelist(int, + * java.util.List, int, boolean, boolean) + */ + @Override + public List unshelveChangelist(int shelveChangelistId, List fileSpecs, int clientChangelistId, boolean forceOverwrite, boolean previewOnly) throws ConnectionException, RequestException, AccessException { + if (shelveChangelistId <= 0) { + throw new RequestException("Shelve changelist ID must be greater than zero"); + } + + try { + return unshelveFiles(fileSpecs, shelveChangelistId, clientChangelistId, new UnshelveFilesOptions().setForceUnshelve(forceOverwrite).setPreview(previewOnly)); + } catch (ConnectionException exc) { + throw exc; + } catch (AccessException exc) { + throw exc; + } catch (P4JavaException exc) { + Log.warn("Unexpected exception in IClient.unshelveChangelist: " + exc); + return new ArrayList(); + } + } + + /** + * @see com.perforce.p4java.client.IClient#submitShelvedChangelist(int) + */ + @Override + public List submitShelvedChangelist(int shelvedChangelistId) throws P4JavaException { + + if (shelvedChangelistId <= 0) { + throw new RequestException("Shelved changelist ID must be greater than zero"); + } + + List> resultMaps = this.serverImpl.execMapCmdList(CmdSpec.SUBMIT, new String[]{"-e", "" + shelvedChangelistId}, null); + + List resultList = new ArrayList(); + if (resultMaps != null) { + for (Map result : resultMaps) { + resultList.add(handleFileReturn(result, serverImpl)); + } + } + return resultList; + } + + /** + * @see com.perforce.p4java.client.IClient#copyFiles(com.perforce.p4java.core.file.IFileSpec, com.perforce.p4java.core.file.IFileSpec, java.lang.String, com.perforce.p4java.option.client.CopyFilesOptions) + */ + @Override + public List copyFiles(IFileSpec fromFile, IFileSpec toFile, String branchSpec, CopyFilesOptions opts) throws P4JavaException { + + List> resultMaps = this.serverImpl.execMapCmdList(CmdSpec.COPY, Parameters.processParameters(opts, fromFile, toFile, branchSpec, this.serverImpl), null); + + return getIntegrationFilesFromReturn(resultMaps); + } + + /** + * @see com.perforce.p4java.client.IClient#copyFiles(com.perforce.p4java.core.file.IFileSpec, java.util.List, com.perforce.p4java.option.client.CopyFilesOptions) + */ + @Override + public List copyFiles(IFileSpec fromFile, List toFiles, CopyFilesOptions opts) throws P4JavaException { + + List> resultMaps = this.serverImpl.execMapCmdList(CmdSpec.COPY, Parameters.processParameters(opts, fromFile, toFiles, null, this.serverImpl), null); + + return getIntegrationFilesFromReturn(resultMaps); + } + + /** + * @see com.perforce.p4java.client.IClient#mergeFiles(com.perforce.p4java.core.file.IFileSpec, java.util.List, com.perforce.p4java.option.client.MergeFilesOptions) + */ + @Override + public List mergeFiles(IFileSpec fromFile, List toFiles, MergeFilesOptions opts) throws P4JavaException { + + List> resultMaps = this.serverImpl.execMapCmdList(CmdSpec.MERGE, Parameters.processParameters(opts, fromFile, toFiles, null, this.serverImpl), null); + + return getIntegrationFilesFromReturn(resultMaps); + } + + /** + * Get the integration files from the return results. + */ + private List getIntegrationFilesFromReturn(List> maps) throws P4JavaException { + List integList = new ArrayList(); + if (maps != null) { + for (Map result : maps) { + integList.add(handleIntegrationFileReturn(result, serverImpl)); + } + } + return integList; + } + + /** + * @see com.perforce.p4java.client.IClient#reconcileFiles(java.util.List, com.perforce.p4java.option.client.ReconcileFilesOptions) + */ + @Override + public List reconcileFiles(List fileSpecs, ReconcileFilesOptions opts) throws P4JavaException { + List resultList = new ArrayList(); + + List> resultMaps = this.serverImpl.execMapCmdList(CmdSpec.RECONCILE, Parameters.processParameters(opts, fileSpecs, this.serverImpl), null); + + if (resultMaps != null) { + for (Map map : resultMaps) { + resultList.add(handleFileReturn(map, serverImpl)); + } + } + return resultList; + } + + /** + * @see com.perforce.p4java.client.IClient#reconcileFiles(List, ReconcileFilesOptions, IStreamingCallback, int) + */ + @Override + public void reconcileFiles(List fileSpecs, ReconcileFilesOptions opts, IStreamingCallback callback, int key) throws P4JavaException { + + if ((this.serverImpl.getCurrentClient() == null) || !this.serverImpl.getCurrentClient().getName().equalsIgnoreCase(this.getName())) { + throw new RequestException("Attempted to reconcile a client that is not the server's current client"); + } + + this.serverImpl.execStreamingMapCommand(CmdSpec.RECONCILE.toString(), Parameters.processParameters(opts, fileSpecs, this.serverImpl), null, callback, key); + } + + /** + * @see com.perforce.p4java.client.IClient#populateFiles(com.perforce.p4java.core.file.IFileSpec, java.util.List, com.perforce.p4java.option.client.PopulateFilesOptions) + */ + @Override + public List populateFiles(IFileSpec fromFile, List toFiles, PopulateFilesOptions opts) throws P4JavaException { + + List> resultMaps = this.serverImpl.execMapCmdList(CmdSpec.POPULATE, Parameters.processParameters(opts, fromFile, toFiles, null, this.serverImpl), null); + + return getIntegrationFilesFromReturn(resultMaps); + } + + /* + * @see com.perforce.p4java.server.IServer#getRepos() + */ + @Override + public List getRepos() throws ConnectionException, RequestException, AccessException { + ReposDelegator reposDelegator = new ReposDelegator(this.serverImpl); + return reposDelegator.getRepos(this.getName()); + } + + /** + * @see IClient#getViewDepotType() + */ + @Override + public ViewDepotType getViewDepotType() { + return viewDepotType; + } + + /** + * @param fileSpecs List of File specs + * @param options List options + * @return data fetched from p4 list command + * @throws P4JavaException API error + */ + @Override + public ListData getListData(List fileSpecs, ListOptions options) throws P4JavaException { + IListDelegator listDelegator = new ListDelegator(this.serverImpl); + return listDelegator.getListData(fileSpecs, options, this.getName()); + } + + + @Override + public String setStreamParentView(IStreamSummary.ParentView parentview, boolean sourceComments) throws P4JavaException { + if (this.getStream() == null) { + throwOptionsException("Missing Stream field", this); + } List opts = new ArrayList<>(); opts.add("parentview"); @@ -1936,11 +1697,8 @@ public String setStreamParentView( opts.add("--source-comments"); } - List> result = this.serverImpl.execMapCmdList( - CmdSpec.STREAM, - processParameters(null, null, opts.toArray(new String[0]), this.serverImpl), - null); - return ResultMapParser.parseCommandResultMapIfIsInfoMessageAsString(result); - } + List> result = this.serverImpl.execMapCmdList(CmdSpec.STREAM, processParameters(null, null, opts.toArray(new String[0]), this.serverImpl), null); + return ResultMapParser.parseCommandResultMapIfIsInfoMessageAsString(result); + } } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/client/ClientSummary.java b/src/main/java/com/perforce/p4java/impl/mapbased/client/ClientSummary.java index b185f5b..f7b5867 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/client/ClientSummary.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/client/ClientSummary.java @@ -78,6 +78,8 @@ public ClientSummary() { * this object is complete, updateable, and refreshable; otherwise, it's * complete and neither updateable nor refresheable. Intended mostly for use * with extended ClientSummary objects such as the full Client class. + * + * @param summaryOnly summaryOnly */ public ClientSummary(final boolean summaryOnly) { super(!summaryOnly, !summaryOnly); @@ -86,6 +88,8 @@ public ClientSummary(final boolean summaryOnly) { /** * Clone a client summary by copying all fields. If clientSummary is null, * this is equivalent to calling the default constructor. + * + * @param clientSummary clientSummary */ public ClientSummary(final IClientSummary clientSummary) { super(false, false); @@ -111,7 +115,7 @@ public ClientSummary(final IClientSummary clientSummary) { * Server map constructor. Attempts to construct a new ClientSummary * object from the passed-in map, which is assumed to have come from * a Perforce server in response to a client list command. If map is null, - * this is equivalent to calling the default constructor.

+ * this is equivalent to calling the default constructor. *

* Note that fields set here may be overridden in a full Client constructor, * as the field keys and formats can be subtly (and not so subtly) different @@ -119,6 +123,9 @@ public ClientSummary(final IClientSummary clientSummary) { * is false, this map is assumed to be from a full client retrieval, meaning * some of the fields retrieved in the full Client constructor are not * set here. Otherwise, it attempts to retrieve all known ClientSummary fields. + * + * @param map map + * @param summaryOnly summaryOnly */ public ClientSummary(final Map map, final boolean summaryOnly) { super(false, false); @@ -165,8 +172,7 @@ public ClientSummary(final Map map, final boolean summaryOnly) { streamAtChange = parseInt(map, STREAMATCHANGE_KEY); } - if (nonNull(map.get(ISUNLOADED_KEY)) - && "1".equals(parseString(map, ISUNLOADED_KEY))) { + if (nonNull(map.get(ISUNLOADED_KEY)) && "1".equals(parseString(map, ISUNLOADED_KEY))) { unloaded = true; } @@ -184,19 +190,20 @@ public ClientSummary(final Map map, final boolean summaryOnly) { * Explicit-value constructor. Intended mostly for use with "pure" ClientSummary * objects. Sets ServerResource superclass fields to indicate complete and neither * refreshable nor updateable. + * + * @param name name + * @param accessed accessed + * @param updated updated + * @param description description + * @param hostName hostName + * @param ownerName ownerName + * @param root root + * @param lineEnd lineEnd + * @param options options + * @param submitOptions submitOptions + * @param alternateRoots alternateRoots */ - public ClientSummary( - final String name, - final Date accessed, - final Date updated, - final String description, - final String hostName, - final String ownerName, - final String root, - final ClientLineEnd lineEnd, - final IClientOptions options, - final IClientSubmitOptions submitOptions, - final List alternateRoots) { + public ClientSummary(final String name, final Date accessed, final Date updated, final String description, final String hostName, final String ownerName, final String root, final ClientLineEnd lineEnd, final IClientOptions options, final IClientSubmitOptions submitOptions, final List alternateRoots) { this(name, accessed, updated, description, hostName, ownerName, root, lineEnd, options, submitOptions, alternateRoots, null, null); } @@ -205,21 +212,22 @@ public ClientSummary( * Explicit-value constructor. Intended mostly for use with "pure" ClientSummary * objects. Sets ServerResource superclass fields to indicate complete and neither * refreshable nor updateable. + * + * @param name name + * @param accessed accessed + * @param updated updated + * @param description description + * @param hostName hostName + * @param ownerName ownerName + * @param root root + * @param lineEnd lineEnd + * @param options options + * @param submitOptions submitOptions + * @param alternateRoots alternateRoots + * @param stream stream + * @param type type */ - public ClientSummary( - final String name, - final Date accessed, - final Date updated, - final String description, - final String hostName, - final String ownerName, - final String root, - final ClientLineEnd lineEnd, - final IClientOptions options, - final IClientSubmitOptions submitOptions, - final List alternateRoots, - final String stream, - final String type) { + public ClientSummary(final String name, final Date accessed, final Date updated, final String description, final String hostName, final String ownerName, final String root, final ClientLineEnd lineEnd, final IClientOptions options, final IClientSubmitOptions submitOptions, final List alternateRoots, final String stream, final String type) { super(false, false); this.name = name; diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/client/cmd/WhereDelegator.java b/src/main/java/com/perforce/p4java/impl/mapbased/client/cmd/WhereDelegator.java index d33d16f..608e3ff 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/client/cmd/WhereDelegator.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/client/cmd/WhereDelegator.java @@ -121,6 +121,10 @@ private IFileSpec clientPathToLocalPath(IFileSpec spec, IClient client) { private IFileSpec localPathToClientPath(IFileSpec spec, IClient client) { String localPath = spec.getLocalPathString(); String clientPath = localPath.replace(client.getRoot(), "//" + client.getName()); + + // Replace windows \ back-slashes with / forward slashes. + clientPath = clientPath.replace("\\", "/"); + spec.setClientPath(clientPath); return spec; } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/CommandEnv.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/CommandEnv.java index a7336aa..6147c9d 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/CommandEnv.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/CommandEnv.java @@ -3,11 +3,6 @@ */ package com.perforce.p4java.impl.mapbased.rpc; -import java.io.File; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - import com.perforce.p4java.Log; import com.perforce.p4java.exception.P4JavaException; import com.perforce.p4java.impl.mapbased.rpc.connection.RpcConnection; @@ -19,25 +14,28 @@ import com.perforce.p4java.server.callback.IProgressCallback; import com.perforce.p4java.server.callback.IStreamingCallback; +import java.io.File; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + /** * Used to package up the Perforce function environment for a single - * Perforce command across multiple RPC function calls.

- * + * Perforce command across multiple RPC function calls. + *

* In particular, we need to keep things like file handles, * arbitrary RPC function arguments, etc., around for use during * complex long-running commands that span many dispatch calls * in loop or duplex mode, etc., in response to single - * user commands like 'sync'.

- * + * user commands like 'sync'. + *

* Note that this is in distinction to a) the command's external * environment (in the ExternalEnv class), and b) the command's * individual function environments, - * - * */ public class CommandEnv { - + /** * Max number of live handlers per command cycle. * Value copied straight from the C++ API. @@ -48,9 +46,8 @@ public class CommandEnv { * Sequence used by operating system to separate lines in text files. * Default to "\n" if it is not available. */ - public static final String LINE_SEPARATOR = System.getProperty( - "line.separator", "\n"); - + public static final String LINE_SEPARATOR = System.getProperty("line.separator", "\n"); + /** * P4Java's version of the notorious handler class * in the C++ API. Basically used (and abused) in @@ -58,11 +55,11 @@ public class CommandEnv { * work out a better way to do things, at which * point it's likely to be factored out elsewhere. */ - + public class RpcHandler { - private String name = null; - private String type = null; + private String name = null; + private String type = null; private boolean error = false; private File file = null; private Map map = null; @@ -74,21 +71,26 @@ public RpcHandler(String name, boolean error, File file) { this.map = new HashMap(); } - public String getName() { - return this.name; - } - public void setName(String name) { - this.name = name; - } - public String getType() { - return this.type; - } - public void setType(String type) { - this.type = type; - } + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getType() { + return this.type; + } + + public void setType(String type) { + this.type = type; + } + public boolean isError() { return this.error; } + public void setError(boolean error) { this.error = error; } @@ -114,61 +116,62 @@ public void setMap(Map map) { * The parent server object */ private RpcServer server = null; - + /** * The current user function that started this all... */ private RpcCmdSpec cmdSpec = null; - /** - * The result maps that will ultimately be passed back to the user levels. - */ - private List> resultMaps = null; + /** + * The result maps that will ultimately be passed back to the user levels. + */ + private List> resultMaps = null; + + /** + * The last result map that's being populated by fstatPartial. + */ + private Map lastResultMap = null; - /** - * The last result map that's being populated by fstatPartial. - */ - private Map lastResultMap = null; - /** * State map for storing arbitrary state across RPC function * calls. */ private Map stateMap = null; - - /** C++ API-like handlers. Will probably be refactored + + /** + * C++ API-like handlers. Will probably be refactored * out later when I can work out what to do with them. * NOTE: code below relies on the handlers array elements * being initialized to null. */ private RpcHandler[] handlers = new RpcHandler[MAX_HANDLERS]; - + /** * Protocol specs (in command form). We carry this around * for possible reference only; it may disappear in future * refactorings if it's never used. */ private ProtocolCommand protocolSpecs = null; - + private Map serverProtocolSpecsMap = null; - + private IProgressCallback progressCallback = null; - + private int cmdCallBackKey = 0; - + private boolean syncInPlace = false; private boolean nonCheckedSyncs = false; private boolean dontWriteTicket = false; private boolean streamCmd = false; - + private RpcPacketFieldRule fieldRule = null; - + private IStreamingCallback streamingCallback = null; private int streamingCallbackKey = 0; - + private IFilterCallback filterCallback = null; - + private IParallelCallback parallelCallback = null; private long syncTime = 0; @@ -178,16 +181,10 @@ public void setMap(Map map) { * The Perforce RPC connection in use for this command. */ private RpcConnection rpcConnection = null; - + private boolean userCanceled = false; // true if the user tried to cancel the command - - public CommandEnv(RpcServer server, RpcCmdSpec cmdSpec, RpcConnection rpcConnection, - ProtocolCommand protocolSpecs, - Map serverProtocolSpecsMap, - IProgressCallback progressCallback, - int cmdCallBackKey, - boolean syncInPlace, - boolean nonCheckedSyncs) { + + public CommandEnv(RpcServer server, RpcCmdSpec cmdSpec, RpcConnection rpcConnection, ProtocolCommand protocolSpecs, Map serverProtocolSpecsMap, IProgressCallback progressCallback, int cmdCallBackKey, boolean syncInPlace, boolean nonCheckedSyncs) { this.server = server; this.cmdSpec = cmdSpec; this.rpcConnection = rpcConnection; @@ -199,70 +196,67 @@ public CommandEnv(RpcServer server, RpcCmdSpec cmdSpec, RpcConnection rpcConnect this.syncInPlace = syncInPlace; this.nonCheckedSyncs = nonCheckedSyncs; } - + public boolean addHandler(RpcHandler handler) { for (int i = 0; i < handlers.length; i++) { - if ((handlers[i] != null) && (handlers[i].name != null) - && handlers[i].name.equalsIgnoreCase(handler.name)) { - + if ((handlers[i] != null) && (handlers[i].name != null) && handlers[i].name.equalsIgnoreCase(handler.name)) { + } if (handlers[i] == null) { handlers[i] = handler; return true; } } - + return false; } - + /** * Handle a result by either adding it to the resultsMapVec * for later processing or passing it up to the streaming results * callback handler. - * - * @param resultMap + * + * @param resultMap resultMap */ public void handleResult(Map resultMap) { - if (lastResultMap != null) { - lastResultMap.putAll(resultMap); - } else { - lastResultMap = resultMap; - } - + if (lastResultMap != null) { + lastResultMap.putAll(resultMap); + } else { + lastResultMap = resultMap; + } + if (streamingCallback != null) { if (!userCanceled) { try { userCanceled = !streamingCallback.handleResult(lastResultMap, streamingCallbackKey); } catch (P4JavaException exc) { - Log.error("caught exception from streaming callback handler (key: " - + streamingCallbackKey - + "): " + exc.getLocalizedMessage()); + Log.error("caught exception from streaming callback handler (key: " + streamingCallbackKey + "): " + exc.getLocalizedMessage()); Log.exception(exc); } } } else { resultMaps.add(lastResultMap); } - + lastResultMap = null; } - + /** - * Handle a partial result by either adding it to the resultsMapVec - * for later processing or passing it up to the streaming results - * callback handler. - * - * @param resultMap - */ - public void handlePartialResult(Map resultMap) { - if (lastResultMap == null) { - lastResultMap = new HashMap(); - } - - if (streamingCallback != null) { - // try { - // if( !streamingCallback.handlePartialResult(lastResultMap, streamingCallbackKey) ) { - lastResultMap.putAll(resultMap); + * Handle a partial result by either adding it to the resultsMapVec + * for later processing or passing it up to the streaming results + * callback handler. + * + * @param resultMap resultMap + */ + public void handlePartialResult(Map resultMap) { + if (lastResultMap == null) { + lastResultMap = new HashMap(); + } + + if (streamingCallback != null) { + // try { + // if( !streamingCallback.handlePartialResult(lastResultMap, streamingCallbackKey) ) { + lastResultMap.putAll(resultMap); /* } } catch (P4JavaException exc) { Log.error("caught exception from streaming callback handler (key: " @@ -271,27 +265,26 @@ public void handlePartialResult(Map resultMap) { Log.exception(exc); lastResultMap.putAll(resultMap); }*/ - } else { - lastResultMap.putAll(resultMap); - } - } + } else { + lastResultMap.putAll(resultMap); + } + } - public void resetPartialResult() { + public void resetPartialResult() { lastResultMap = null; } public RpcHandler getHandler(String handlerName) { for (RpcHandler handler : handlers) { - if ((handler != null) && (handlerName != null) - && (handler.getName() != null) - && handler.getName().equalsIgnoreCase(handlerName)) { + if ((handler != null) && (handlerName != null) && (handler.getName() != null) && handler.getName().equalsIgnoreCase(handlerName)) { return handler; } } - + return null; - + } + public RpcCmdSpec getCmdSpec() { return this.cmdSpec; } @@ -300,17 +293,17 @@ public void setCmdSpec(RpcCmdSpec cmdSpec) { this.cmdSpec = cmdSpec; } - public List> getResultMaps() { - return this.resultMaps; - } + public List> getResultMaps() { + return this.resultMaps; + } public void setResultMaps(List> resultMaps) { this.resultMaps = resultMaps; } - - public void clearLastResultMap() { - lastResultMap = null; - } + + public void clearLastResultMap() { + lastResultMap = null; + } public Map getStateMap() { return this.stateMap; @@ -324,7 +317,7 @@ public ProtocolCommand getProtocolSpecs() { return this.protocolSpecs; } - public int getServerProtocolLevel() { + public int getServerProtocolLevel() { if (serverProtocolSpecsMap == null) { return -1; } @@ -335,7 +328,7 @@ public int getServerProtocolLevel() { return Integer.parseInt((String) serverProtocolSpecsMap.get(RpcFunctionMapKey.SERVER)); } return -1; - } + } public void setProtocolSpecs(ProtocolCommand protocolSpecs) { this.protocolSpecs = protocolSpecs; @@ -356,7 +349,7 @@ public RpcHandler[] getHandlers() { public void setHandlers(RpcHandler[] handlers) { this.handlers = handlers; } - + public void newHandler() { // Does nothing at the moment, as a standin for the C++ API version // FIXME -- HR. @@ -461,7 +454,7 @@ public void setFilterCallback(IFilterCallback filterCallback) { public IParallelCallback getParallelCallback() { return parallelCallback; } - + public void setParallelCallback(IParallelCallback parallelCallback) { this.parallelCallback = parallelCallback; } @@ -470,13 +463,13 @@ public RpcServer getServer() { return server; } - public long getSyncTime() { - return syncTime; - } + public long getSyncTime() { + return syncTime; + } - public void setSyncTime(long syncTime) { - this.syncTime = syncTime; - } + public void setSyncTime(long syncTime) { + this.syncTime = syncTime; + } public boolean isNullSync() { return nullSync; diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/NtsServerImpl.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/NtsServerImpl.java index d112163..5cb4f05 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/NtsServerImpl.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/NtsServerImpl.java @@ -44,8 +44,8 @@ import java.util.Properties; /** - * NTS (non-thread-safe) version of the P4Java RPC implementation.

- * + * NTS (non-thread-safe) version of the P4Java RPC implementation. + *

* By "not thread safe" we really mean that it's up to the consumer to * synchronize calls to the server object; if you want a thread-safe * implementation see the OneShotServerImpl class (which is @@ -63,20 +63,17 @@ public class NtsServerImpl extends RpcServer { * The short-form name (display name) of this implementation. */ public static final String SCREEN_NAME = "Native RPC (Experimental)"; - + /** * Implementation-specific comments (dependencies, limitations, etc.). */ - public static final String IMPL_COMMENTS - = "Experimental Java-native RPC standalone P4Java implementation." - + " Requires JDK 6 or later, full Java NIO support, and " - + "external thread synchronization. Not for the faint-hearted."; - + public static final String IMPL_COMMENTS = "Experimental Java-native RPC standalone P4Java implementation." + " Requires JDK 6 or later, full Java NIO support, and " + "external thread synchronization. Not for the faint-hearted."; + /** * The specific protocol name to be used in URIs for this implementation. */ public static final String PROTOCOL_NAME = Protocol.P4JRPCNTS.toString(); - + /** * The specific SSL protocol name to be used in URIs for this implementation. */ @@ -86,7 +83,7 @@ public class NtsServerImpl extends RpcServer { * The minimum Perforce server level required by this implementation. */ public static final int MINIMUM_SUPPORTED_SERVER_LEVEL = 20052; - + /** * True IFF this is the default implementation. There must be only one of * these... @@ -97,23 +94,22 @@ public class NtsServerImpl extends RpcServer { * What we use as a P4JTracer trace prefix for methods here. */ public static final String TRACE_PREFIX = "NtsServerImpl"; - + private boolean currentUseTags = true; private boolean haveSentProtocolSpecs = false; protected ProtocolCommand protocolSpecs = null; - + protected RpcPacketDispatcher dispatcher = null; protected RpcConnection rpcConnection = null; - + /** * Initialize the server. Basically defers to the superclass after setting * up the required server version. - * + * * @see com.perforce.p4java.impl.mapbased.rpc.RpcServer#init(java.lang.String, int, java.util.Properties, com.perforce.p4java.option.UsageOptions, boolean) */ - public ServerStatus init(String host, int port, Properties props, UsageOptions opts, - boolean secure, String rsh) throws ConfigException, ConnectionException { + public ServerStatus init(String host, int port, Properties props, UsageOptions opts, boolean secure, String rsh) throws ConfigException, ConnectionException { super.init(host, port, props, opts, secure); super.minimumSupportedServerVersion = MINIMUM_SUPPORTED_SERVER_LEVEL; this.rsh = rsh; @@ -122,32 +118,29 @@ public ServerStatus init(String host, int port, Properties props, UsageOptions o /** * Shorthand for the options-based init() above, but with a fasle secure arg. - * + * * @see com.perforce.p4java.impl.mapbased.rpc.RpcServer#init(java.lang.String, int, java.util.Properties, com.perforce.p4java.option.UsageOptions, boolean) */ - public ServerStatus init(String host, int port, Properties properties, UsageOptions opts, - boolean secure) throws ConfigException, ConnectionException { + public ServerStatus init(String host, int port, Properties properties, UsageOptions opts, boolean secure) throws ConfigException, ConnectionException { return this.init(host, port, properties, opts, secure, null); } - + /** * Shorthand for the options-based init() above, but with a fasle secure arg. - * + * * @see com.perforce.p4java.impl.mapbased.rpc.RpcServer#init(java.lang.String, int, java.util.Properties, com.perforce.p4java.option.UsageOptions) */ - public ServerStatus init(String host, int port, Properties props, UsageOptions opts) - throws ConfigException, ConnectionException { + public ServerStatus init(String host, int port, Properties props, UsageOptions opts) throws ConfigException, ConnectionException { return this.init(host, port, props, opts, false); } /** * Shorthand for the options-based init() above, but with a null opts arg. - * + * * @see com.perforce.p4java.impl.mapbased.rpc.RpcServer#init(java.lang.String, int, java.util.Properties) */ - public ServerStatus init(String host, int port, Properties props) - throws ConfigException, ConnectionException { + public ServerStatus init(String host, int port, Properties props) throws ConfigException, ConnectionException { return this.init(host, port, props, null); } @@ -156,46 +149,40 @@ public ServerStatus init(String host, int port, Properties props) * Most of the actual setup work is done in the RpcConnection and * RpcPacketDispatcher constructors, but associated gubbins such as * auto login, etc., are done in the superclass. - * + * * @see com.perforce.p4java.impl.mapbased.server.Server#connect() */ - - public void connect() throws ConnectionException, - AccessException, RequestException, ConfigException { - this.rpcConnection = new RpcStreamConnection(serverHost, serverPort, props, - this.serverStats, this.p4Charset, null, null, - this.secure, this.rsh); + + public void connect() throws ConnectionException, AccessException, RequestException, ConfigException { + this.rpcConnection = new RpcStreamConnection(serverHost, serverPort, props, this.serverStats, this.p4Charset, null, null, this.secure, this.rsh); this.dispatcher = new RpcPacketDispatcher(props, this); - - Log.info("RPC connection to Perforce server " - + serverHost + ":" + serverPort + " established"); - + + Log.info("RPC connection to Perforce server " + serverHost + ":" + serverPort + " established"); + super.connect(); } - + /** * Try to cleanly disconnect from the Perforce server at the other end * of the current connection (with the emphasis on "cleanly"). This * should theoretically include sending a release2 message, but we * don't always get the chance to do that. - * + * * @see com.perforce.p4java.impl.mapbased.server.Server#disconnect() */ - public void disconnect() throws ConnectionException, - AccessException { - Log.info("Disconnected RPC connection to Perforce server " - + this.serverHost + ":" + this.serverPort); - + public void disconnect() throws ConnectionException, AccessException { + Log.info("Disconnected RPC connection to Perforce server " + this.serverHost + ":" + this.serverPort); + this.dispatcher.shutdown(this.rpcConnection); this.rpcConnection.disconnect(this.dispatcher); this.haveSentProtocolSpecs = false; this.protocolSpecs = null; super.disconnect(); } - + /** * Need to override this method at this level as we keep the connection open here... - * + * * @see com.perforce.p4java.impl.mapbased.server.Server#setCharsetName(java.lang.String) */ public boolean setCharsetName(String charsetName) throws UnsupportedCharsetException { @@ -203,14 +190,12 @@ public boolean setCharsetName(String charsetName) throws UnsupportedCharsetExcep this.rpcConnection.setClientCharset(this.p4Charset); return retVal; } - + /** * @see com.perforce.p4java.impl.mapbased.server.Server#execMapCmd(java.lang.String, java.lang.String[], java.util.Map) */ @Override - public Map[] execMapCmd(String cmdName, String[] cmdArgs, - Map inMap) throws ConnectionException, - AccessException, RequestException { + public Map[] execMapCmd(String cmdName, String[] cmdArgs, Map inMap) throws ConnectionException, AccessException, RequestException { return this.execMapCmd(cmdName, cmdArgs, inMap, null, false, null, 0, null); } @@ -218,8 +203,7 @@ public Map[] execMapCmd(String cmdName, String[] cmdArgs, * @see com.perforce.p4java.impl.mapbased.server.Server#execMapCmdList(java.lang.String, java.lang.String[], java.util.Map) */ @Override - public List> execMapCmdList(String cmdName, String[] cmdArgs, - Map inMap) throws ConnectionException, AccessException, RequestException { + public List> execMapCmdList(String cmdName, String[] cmdArgs, Map inMap) throws ConnectionException, AccessException, RequestException { return this.execMapCmdList(cmdName, cmdArgs, inMap, null, false, null, 0, null, null); } @@ -227,8 +211,7 @@ public List> execMapCmdList(String cmdName, String[] cmdArgs * @see com.perforce.p4java.impl.mapbased.server.Server#execMapCmdList(java.lang.String, java.lang.String[], java.util.Map, com.perforce.p4java.server.callback.IFilterCallback) */ @Override - public List> execMapCmdList(String cmdName, String[] cmdArgs, - Map inMap, IFilterCallback filterCallback) throws P4JavaException { + public List> execMapCmdList(String cmdName, String[] cmdArgs, Map inMap, IFilterCallback filterCallback) throws P4JavaException { return this.execMapCmdList(cmdName, cmdArgs, inMap, null, false, null, 0, filterCallback, null); } @@ -236,94 +219,74 @@ public List> execMapCmdList(String cmdName, String[] cmdArgs * @see com.perforce.p4java.impl.mapbased.server.Server#execQuietMapCmd(java.lang.String, java.lang.String[], java.util.Map) */ @Override - public Map[] execQuietMapCmd(String cmdName, - String[] cmdArgs, Map inMap) - throws ConnectionException, RequestException, - AccessException { + public Map[] execQuietMapCmd(String cmdName, String[] cmdArgs, Map inMap) throws ConnectionException, RequestException, AccessException { return this.execMapCmd(cmdName, cmdArgs, inMap, null, true, null, 0, null); } - + /** * @see com.perforce.p4java.impl.mapbased.server.Server#execQuietMapCmdList(java.lang.String, java.lang.String[], java.util.Map) */ @Override - public List> execQuietMapCmdList(String cmdName, - String[] cmdArgs, Map inMap) throws P4JavaException { + public List> execQuietMapCmdList(String cmdName, String[] cmdArgs, Map inMap) throws P4JavaException { return this.execMapCmdList(cmdName, cmdArgs, inMap, null, true, null, 0, null, null); } - + /** * @see com.perforce.p4java.impl.mapbased.server.Server#execInputStringMapCmd(java.lang.String, java.lang.String[], java.lang.String) */ - public Map[] execInputStringMapCmd(String cmdName, - String[] cmdArgs, String inString) throws P4JavaException { + public Map[] execInputStringMapCmd(String cmdName, String[] cmdArgs, String inString) throws P4JavaException { return this.execMapCmd(cmdName, cmdArgs, null, inString, true, null, 0, null); } /** * @see com.perforce.p4java.impl.mapbased.server.Server#execInputStringMapCmdList(java.lang.String, java.lang.String[], java.lang.String) */ - public List> execInputStringMapCmdList(String cmdName, - String[] cmdArgs, String inString) throws P4JavaException { + public List> execInputStringMapCmdList(String cmdName, String[] cmdArgs, String inString) throws P4JavaException { return this.execMapCmdList(cmdName, cmdArgs, null, inString, true, null, 0, null, null); } - + /** * @see com.perforce.p4java.impl.mapbased.server.Server#execInputStringMapCmdList(java.lang.String, java.lang.String[], java.lang.String, com.perforce.p4java.server.callback.IFilterCallback) */ - public List> execInputStringMapCmdList(String cmdName, - String[] cmdArgs, String inString, IFilterCallback filterCallback) throws P4JavaException { + public List> execInputStringMapCmdList(String cmdName, String[] cmdArgs, String inString, IFilterCallback filterCallback) throws P4JavaException { return this.execMapCmdList(cmdName, cmdArgs, null, inString, true, null, 0, filterCallback, null); } @Override - public List> execMapCmdList(String cmdName, String[] cmdArgs, IFilterCallback filterCallback, - IParallelCallback parallelCallback) throws P4JavaException { + public List> execMapCmdList(String cmdName, String[] cmdArgs, IFilterCallback filterCallback, IParallelCallback parallelCallback) throws P4JavaException { return this.execMapCmdList(cmdName, cmdArgs, null, null, true, null, 0, filterCallback, parallelCallback); } - + /** * @see com.perforce.p4java.impl.mapbased.server.Server#execInputStringStreamingMapComd(java.lang.String, java.lang.String[], java.lang.String, com.perforce.p4java.server.callback.IStreamingCallback, int) - * * @deprecated As of release 2013.1, replaced by {@link #execInputStringStreamingMapCmd(java.lang.String, java.lang.String[], java.lang.String, com.perforce.p4java.server.callback.IStreamingCallback, int)} - */ + */ @Deprecated - public void execInputStringStreamingMapComd(String cmdName, - String[] cmdArgs, String inString, IStreamingCallback callback, - int key) throws P4JavaException { + public void execInputStringStreamingMapComd(String cmdName, String[] cmdArgs, String inString, IStreamingCallback callback, int key) throws P4JavaException { execMapCmd(cmdName, cmdArgs, null, inString, false, callback, key, null); } /** * @see com.perforce.p4java.impl.mapbased.server.Server#execInputStringStreamingMapCmd(java.lang.String, java.lang.String[], java.lang.String, com.perforce.p4java.server.callback.IStreamingCallback, int) - */ - public void execInputStringStreamingMapCmd(String cmdName, - String[] cmdArgs, String inString, IStreamingCallback callback, - int key) throws P4JavaException { + */ + public void execInputStringStreamingMapCmd(String cmdName, String[] cmdArgs, String inString, IStreamingCallback callback, int key) throws P4JavaException { execMapCmd(cmdName, cmdArgs, null, inString, false, callback, key, null); } @SuppressWarnings("unchecked") - protected Map[] execMapCmd(String cmdName, - String[] cmdArgs, Map inMap, String inString, boolean ignoreCallbacks, - IStreamingCallback callback, int callbackKey, IFilterCallback filterCallback) - throws ConnectionException, AccessException, RequestException { + protected Map[] execMapCmd(String cmdName, String[] cmdArgs, Map inMap, String inString, boolean ignoreCallbacks, IStreamingCallback callback, int callbackKey, IFilterCallback filterCallback) throws ConnectionException, AccessException, RequestException { List> results = execMapCmdList(cmdName, cmdArgs, inMap, inString, ignoreCallbacks, callback, callbackKey, filterCallback, null); if (results != null) { return results.toArray(new HashMap[results.size()]); } - + return null; } - protected List> execMapCmdList(String cmdName, - String[] cmdArgs, Map inMap, String inString, boolean ignoreCallbacks, - IStreamingCallback callback, int callbackKey, IFilterCallback filterCallback, - IParallelCallback parallelCallback) - throws ConnectionException, AccessException, RequestException { - + protected List> execMapCmdList(String cmdName, String[] cmdArgs, Map inMap, String inString, boolean ignoreCallbacks, IStreamingCallback callback, int callbackKey, IFilterCallback filterCallback, IParallelCallback parallelCallback) throws ConnectionException, AccessException, RequestException { + CommandEnv cmdEnv = null; - + try { int cmdCallBackKey = this.nextCmdCallBackKey.incrementAndGet(); long startTime = System.currentTimeMillis(); @@ -331,22 +294,7 @@ protected List> execMapCmdList(String cmdName, ClientLineEnding.convertMap(inMap); } ExternalEnv env = setupCmd(cmdName.toLowerCase(Locale.ENGLISH), cmdArgs, inMap, ignoreCallbacks, cmdCallBackKey, false); - cmdEnv = new CommandEnv( - this, - new RpcCmdSpec( - cmdName, - cmdArgs, - getAuthTicket(), - inMap, - inString, - env), - this.rpcConnection, - this.protocolSpecs, - this.serverProtocolMap, - this.progressCallback, - cmdCallBackKey, - writeInPlace(cmdName), - this.isNonCheckedSyncs()); + cmdEnv = new CommandEnv(this, new RpcCmdSpec(cmdName, cmdArgs, getAuthTicket(), inMap, inString, env), this.rpcConnection, this.protocolSpecs, this.serverProtocolMap, this.progressCallback, cmdCallBackKey, writeInPlace(cmdName), this.isNonCheckedSyncs()); cmdEnv.setDontWriteTicket(isDontWriteTicket(cmdName.toLowerCase(Locale.ENGLISH), cmdArgs)); cmdEnv.setFieldRule(getRpcPacketFieldRule(inMap, CmdSpec.getValidP4JCmdSpec(cmdName))); cmdEnv.setStreamingCallback(callback); @@ -371,30 +319,27 @@ protected List> execMapCmdList(String cmdName, Log.exception(exc); } } - + // Check if currently case sensitive so the map search for the no // case key is only performed when necessary. Once a server is // marked as case insensitive this check will never look at the // server protocol specs map. - if (this.caseSensitive - && cmdEnv.getServerProtocolSpecsMap().containsKey( - RpcFunctionMapKey.NOCASE)) { + if (this.caseSensitive && cmdEnv.getServerProtocolSpecsMap().containsKey(RpcFunctionMapKey.NOCASE)) { this.caseSensitive = false; } if (!ignoreCallbacks && (this.commandCallback != null)) { this.processCmdCallbacks(cmdCallBackKey, endTime - startTime, resultMaps); } - + // Close RPC output stream - RpcOutputStream outStream = (RpcOutputStream) cmdEnv.getStateMap().get( - RpcServer.RPC_TMP_OUTFILE_STREAM_KEY); + RpcOutputStream outStream = (RpcOutputStream) cmdEnv.getStateMap().get(RpcServer.RPC_TMP_OUTFILE_STREAM_KEY); if (outStream != null) { outStream.close(); } - + return resultMaps; - + } catch (BufferOverflowException exc) { Log.error("RPC Buffer overflow: " + exc.getLocalizedMessage()); Log.exception(exc); @@ -406,9 +351,7 @@ protected List> execMapCmdList(String cmdName, } catch (IOException ioexc) { Log.error("I/O error encountered in stream command: " + ioexc.getLocalizedMessage()); Log.exception(ioexc); - throw new RequestException( - "I/O error encountered in stream command: " - + ioexc.getLocalizedMessage(), ioexc); + throw new RequestException("I/O error encountered in stream command: " + ioexc.getLocalizedMessage(), ioexc); } finally { // Handle user cancelled command if (cmdEnv != null && cmdEnv.isUserCanceled()) { @@ -425,26 +368,22 @@ protected List> execMapCmdList(String cmdName, } } } - + /** * @see com.perforce.p4java.impl.mapbased.server.Server#execStreamingMapCommand(java.lang.String, java.lang.String[], java.util.Map, com.perforce.p4java.server.callback.IStreamingCallback, int) */ - public void execStreamingMapCommand(String cmdName, String[] cmdArgs, Map inMap, - IStreamingCallback callback, int key) throws P4JavaException { + public void execStreamingMapCommand(String cmdName, String[] cmdArgs, Map inMap, IStreamingCallback callback, int key) throws P4JavaException { if (callback == null) { - throw new NullPointerError( - "null streaming callback passed to execStreamingMapCommand method"); + throw new NullPointerError("null streaming callback passed to execStreamingMapCommand method"); } - + execMapCmdList(cmdName, cmdArgs, inMap, null, false, callback, key, null, null); } @Override - public void execStreamingMapCommand(String cmdName, String[] cmdArgs, Map inMap, - IStreamingCallback callback, int key, IParallelCallback parallelCallback) throws P4JavaException { + public void execStreamingMapCommand(String cmdName, String[] cmdArgs, Map inMap, IStreamingCallback callback, int key, IParallelCallback parallelCallback) throws P4JavaException { if (callback == null) { - throw new NullPointerError( - "null streaming callback passed to execStreamingMapCommand method"); + throw new NullPointerError("null streaming callback passed to execStreamingMapCommand method"); } execMapCmdList(cmdName, cmdArgs, inMap, null, false, callback, key, null, parallelCallback); @@ -454,9 +393,7 @@ public void execStreamingMapCommand(String cmdName, String[] cmdArgs, Map inMap) - throws P4JavaException { + public InputStream execStreamCmd(String cmdName, String[] cmdArgs, Map inMap) throws P4JavaException { return this.execStreamCmd(cmdName, cmdArgs, inMap, null, false); } @@ -483,8 +417,7 @@ public InputStream execStreamCmd(String cmdName, String[] cmdArgs, Map inMap, String inString, boolean ignoreCallbacks) - throws ConnectionException, RequestException, AccessException { + protected InputStream execStreamCmd(String cmdName, String[] cmdArgs, Map inMap, String inString, boolean ignoreCallbacks) throws ConnectionException, RequestException, AccessException { if (cmdName == null) { - throw new NullPointerError( - "Null command name passed to execStreamCmd"); + throw new NullPointerError("Null command name passed to execStreamCmd"); } - + if (!this.connected) { - throw new ConnectionNotConnectedException( - "Not currently connected to a Perforce server"); + throw new ConnectionNotConnectedException("Not currently connected to a Perforce server"); } - + CommandEnv cmdEnv = null; - + try { int cmdCallBackKey = this.nextCmdCallBackKey.incrementAndGet(); long startTime = System.currentTimeMillis(); if (inMap != null && ClientLineEnding.CONVERT_TEXT) { ClientLineEnding.convertMap(inMap); } - ExternalEnv env = setupCmd(cmdName,cmdArgs, inMap, ignoreCallbacks, cmdCallBackKey, true); - cmdEnv = new CommandEnv( - this, - new RpcCmdSpec( - cmdName, - cmdArgs, - getAuthTicket(), - inMap, - inString, - env), - this.rpcConnection, - this.protocolSpecs, - this.serverProtocolMap, - this.progressCallback, - cmdCallBackKey, - writeInPlace(cmdName), - this.isNonCheckedSyncs()); + ExternalEnv env = setupCmd(cmdName, cmdArgs, inMap, ignoreCallbacks, cmdCallBackKey, true); + cmdEnv = new CommandEnv(this, new RpcCmdSpec(cmdName, cmdArgs, getAuthTicket(), inMap, inString, env), this.rpcConnection, this.protocolSpecs, this.serverProtocolMap, this.progressCallback, cmdCallBackKey, writeInPlace(cmdName), this.isNonCheckedSyncs()); cmdEnv.setDontWriteTicket(isDontWriteTicket(cmdName.toLowerCase(Locale.ENGLISH), cmdArgs)); cmdEnv.setFieldRule(getRpcPacketFieldRule(inMap, CmdSpec.getValidP4JCmdSpec(cmdName))); cmdEnv.setStreamCmd(true); List> resultMaps = this.dispatcher.dispatch(cmdEnv); - + long endTime = System.currentTimeMillis(); - + if (!ignoreCallbacks && (this.commandCallback != null)) { this.processCmdCallbacks(cmdCallBackKey, endTime - startTime, resultMaps); } @@ -549,18 +474,16 @@ protected InputStream execStreamCmd(String cmdName, String[] cmdArgs, Map inMap, boolean ignoreCallbacks, int cmdCallBackKey, - boolean isStream) throws ConnectionException, AccessException, RequestException { + protected ExternalEnv setupCmd(String cmdName, String[] cmdArgs, Map inMap, boolean ignoreCallbacks, int cmdCallBackKey, boolean isStream) throws ConnectionException, AccessException, RequestException { if (this.rpcConnection == null) { throw new NullPointerError("Null RPC connection in execMapCmd call"); @@ -607,31 +536,18 @@ protected ExternalEnv setupCmd(String cmdName, String[] cmdArgs, throw new NullPointerError("Null RPC dispatcher in execMapCmd call"); } if (!this.isRelaxCmdNameValidationChecks() && !CmdSpec.isValidP4JCmdSpec(cmdName)) { - throw new RequestException("command name '" - + cmdName + "' unimplemented or unrecognized by p4java"); + throw new RequestException("command name '" + cmdName + "' unimplemented or unrecognized by p4java"); } // Should use tags? boolean useTags = useTags(cmdName, cmdArgs, inMap, isStream); - + // Check certificate chain and/or fingerprint. // An exception (ConnectionException) is thrown if ssl but not trusted. trustConnectionCheck(rpcConnection); - ExternalEnv env = new ExternalEnv( - this.getUsageOptions().getProgramName(), - this.getUsageOptions().getProgramVersion(), - this.getClientNameForEnv(), - this.getUsageOptions().getWorkingDirectory(), - this.getHostForEnv(), - this.getServerHostPort(), - this.getUsageOptions().getTextLanguage(), - this.getOsTypeForEnv(), - this.getUserForEnv(), - this.isServerUnicode(), - this.getClientCharset() - ); - + ExternalEnv env = new ExternalEnv(this.getUsageOptions().getProgramName(), this.getUsageOptions().getProgramVersion(), this.getClientNameForEnv(), this.getUsageOptions().getWorkingDirectory(), this.getHostForEnv(), this.getServerHostPort(), this.getUsageOptions().getTextLanguage(), this.getOsTypeForEnv(), this.getUserForEnv(), this.isServerUnicode(), this.getClientCharset()); + if (!ignoreCallbacks && (this.commandCallback != null)) { StringBuilder cmd = new StringBuilder(cmdName); for (String argStr : cmdArgs) { @@ -642,9 +558,9 @@ protected ExternalEnv setupCmd(String cmdName, String[] cmdArgs, } this.commandCallback.issuingServerCommand(cmdCallBackKey, cmd.toString()); } - + RpcPacket protPacket = null; - + // If the "useTags" state had changed from the previous command we must // send the protocol again. if (!this.haveSentProtocolSpecs || (this.currentUseTags != useTags)) { @@ -667,43 +583,33 @@ protected ExternalEnv setupCmd(String cmdName, String[] cmdArgs, protocolSpecs.setHost(env.getHost()); protocolSpecs.setPort(env.getPort()); - if (props.containsKey(RpcFunctionMapKey.IPADDR) - && props.containsKey(RpcFunctionMapKey.SVRNAME) - && props.containsKey(RpcFunctionMapKey.PORT)) { + if (props.containsKey(RpcFunctionMapKey.IPADDR) && props.containsKey(RpcFunctionMapKey.SVRNAME) && props.containsKey(RpcFunctionMapKey.PORT)) { protocolSpecs.setIpAddr(props.getProperty(RpcFunctionMapKey.IPADDR)); } - protPacket = RpcPacket.constructRpcPacket( - RpcFunctionSpec.PROTOCOL_PROTOCOL, - this.protocolSpecs.asMap(), - null); + protPacket = RpcPacket.constructRpcPacket(RpcFunctionSpec.PROTOCOL_PROTOCOL, this.protocolSpecs.asMap(), null); this.currentUseTags = useTags; this.haveSentProtocolSpecs = true; } - - RpcFunctionSpec name = RpcFunctionSpec.decodeFromEndUserCmd(cmdName, - this.isRelaxCmdNameValidationChecks()); - + + RpcFunctionSpec name = RpcFunctionSpec.decodeFromEndUserCmd(cmdName, this.isRelaxCmdNameValidationChecks()); + // For historical reasons, we need to special-case the login command //if (name == RpcFunctionSpec.USER_LOGIN) { // cmdArgs = new String[] {"-p"}; //} - RpcPacket cmdPacket = RpcPacket.constructRpcPacket( - name, - cmdName, - cmdArgs, - env); + RpcPacket cmdPacket = RpcPacket.constructRpcPacket(name, cmdName, cmdArgs, env); // Append the "tag" argument before the function name if (useTags) { cmdPacket.setMapArgs(this.cmdMapArgs); } // On each command message sent to the server (i.e. "user-foo") - // a variable "progress" should be set to 1 to indicate that - // the server should send progress messages to the client if they - // are available for that command. + // a variable "progress" should be set to 1 to indicate that + // the server should send progress messages to the client if they + // are available for that command. if (this.enableProgress) { Map valMap = new HashMap(); if (cmdPacket.getMapArgs() != null) { @@ -712,16 +618,16 @@ protected ExternalEnv setupCmd(String cmdName, String[] cmdArgs, valMap.put(ProtocolCommand.RPC_ARGNAME_PROTOCOL_ENABLE_PROGRESS, "1"); cmdPacket.setMapArgs(valMap); } - + if (protPacket == null) { this.rpcConnection.putRpcPacket(cmdPacket); } else { - this.rpcConnection.putRpcPackets(new RpcPacket[] {protPacket, cmdPacket}); + this.rpcConnection.putRpcPackets(new RpcPacket[]{protPacket, cmdPacket}); } - + return env; } - + public RpcConnection getRpcConnection() { return this.rpcConnection; } @@ -729,10 +635,10 @@ public RpcConnection getRpcConnection() { public void setRpcConnection(RpcConnection rpcConnection) { this.rpcConnection = rpcConnection; } - + /** * Get server address object - * + * * @return server address object */ public IServerAddress getServerAddressDetails() { @@ -747,7 +653,7 @@ public IServerAddress getServerAddressDetails() { } else { builder.setProtocol(Protocol.P4JRPCNTS); } - + return builder.build(); } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/OneShotServerImpl.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/OneShotServerImpl.java index a1b8a54..b76ea48 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/OneShotServerImpl.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/OneShotServerImpl.java @@ -51,34 +51,32 @@ * using the same IServer object simultaneously, and is therefore * thread-safe. The tradeoff here is connection latency -- each time * a command is executed a new connection to the Perforce server is - * created, used, and closed.

- * + * created, used, and closed. + *

* Note that performance monitors and command callback objects are shared * by all threads using this server object and are not synchronized by * this class -- you must sort out any conflicting output yourself (such * conflicting output is not a sign of underlying issues, and, as long * as you keep callbacks thread-safe, there are no problems with this at - * this level).

+ * this level). */ - public class OneShotServerImpl extends RpcServer { - + /** * The short-form name (display name) of this implementation. */ public static final String SCREEN_NAME = "Native RPC"; - + /** * Implementation-specific comments (dependencies, limitations, etc.). */ - public static final String IMPL_COMMENTS = "Java-native RPC standalone P4Java implementation." - + " Requires JDK 6 or later and full Java NIO support."; - + public static final String IMPL_COMMENTS = "Java-native RPC standalone P4Java implementation." + " Requires JDK 6 or later and full Java NIO support."; + /** * The specific protocol name to be used in URIs for this implementation. */ public static final String PROTOCOL_NAME = Protocol.P4JRPC.toString(); - + /** * The specific SSL protocol name to be used in URIs for this implementation. */ @@ -89,96 +87,80 @@ public class OneShotServerImpl extends RpcServer { * these... */ public static final boolean DEFAULT_STATUS = false; - + /** * The minimum Perforce server level required by this implementation. */ public static final int MINIMUM_SUPPORTED_SERVER_LEVEL = 20052; - + /** * What we use as a P4JTracer trace prefix for methods here. */ public static final String TRACE_PREFIX = "OneShotServerImpl"; - + /** * Socket pool for this server */ protected RpcSocketPool socketPool = null; - + /** * Initialize the server. Basically defers to the superclass after setting * up the required server version and any optional socket pools. - * + * * @see com.perforce.p4java.impl.mapbased.rpc.RpcServer#init(java.lang.String, int, java.util.Properties, com.perforce.p4java.option.UsageOptions, boolean) */ - public ServerStatus init(String host, int port, Properties props, UsageOptions opts, - boolean secure, String rsh) throws ConfigException, ConnectionException { + public ServerStatus init(String host, int port, Properties props, UsageOptions opts, boolean secure, String rsh) throws ConfigException, ConnectionException { super.init(host, port, props, opts, secure); super.minimumSupportedServerVersion = MINIMUM_SUPPORTED_SERVER_LEVEL; this.rsh = rsh; - int poolSize = RpcPropertyDefs.getPropertyAsInt(this.props, - RpcPropertyDefs.RPC_SOCKET_POOL_SIZE_NICK, - RpcPropertyDefs.RPC_SOCKET_POOL_DEFAULT_SIZE); + int poolSize = RpcPropertyDefs.getPropertyAsInt(this.props, RpcPropertyDefs.RPC_SOCKET_POOL_SIZE_NICK, RpcPropertyDefs.RPC_SOCKET_POOL_DEFAULT_SIZE); if (poolSize > 0) { ShutdownHandler handler = new ShutdownHandler() { public void shutdown(Socket socket) { try { - RpcPacketDispatcher dispatcher = new RpcPacketDispatcher( - OneShotServerImpl.this.props, - OneShotServerImpl.this); - RpcStreamConnection rpcConnection = new RpcStreamConnection( - serverHost, serverPort, - OneShotServerImpl.this.props, - OneShotServerImpl.this.serverStats, - OneShotServerImpl.this.p4Charset, - socket, null, - OneShotServerImpl.this.secure, - OneShotServerImpl.this.rsh); + RpcPacketDispatcher dispatcher = new RpcPacketDispatcher(OneShotServerImpl.this.props, OneShotServerImpl.this); + RpcStreamConnection rpcConnection = new RpcStreamConnection(serverHost, serverPort, OneShotServerImpl.this.props, OneShotServerImpl.this.serverStats, OneShotServerImpl.this.p4Charset, socket, null, OneShotServerImpl.this.secure, OneShotServerImpl.this.rsh); dispatcher.shutdown(rpcConnection); } catch (ConnectionException e) { Log.exception(e); } } }; - this.socketPool = new RpcSocketPool(poolSize, this.serverHost, - this.serverPort, this.props, handler, this.secure); + this.socketPool = new RpcSocketPool(poolSize, this.serverHost, this.serverPort, this.props, handler, this.secure); } - + return status; } - + /** * Shorthand for the options-based init() above, but with a false secure arg. - * + * * @see com.perforce.p4java.impl.mapbased.rpc.RpcServer#init(java.lang.String, int, java.util.Properties, com.perforce.p4java.option.UsageOptions) */ - public ServerStatus init(String host, int port, Properties props, UsageOptions opts) - throws ConfigException, ConnectionException { + public ServerStatus init(String host, int port, Properties props, UsageOptions opts) throws ConfigException, ConnectionException { return this.init(host, port, props, opts, false); } /** * Shorthand for the options-based init() above, but with a null opts arg. - * + * * @see com.perforce.p4java.impl.mapbased.rpc.RpcServer#init(java.lang.String, int, java.util.Properties) */ - public ServerStatus init(String host, int port, Properties props) - throws ConfigException, ConnectionException { + public ServerStatus init(String host, int port, Properties props) throws ConfigException, ConnectionException { return this.init(host, port, props, null); } - - public void connect() throws ConnectionException, AccessException, - RequestException, ConfigException { + + public void connect() throws ConnectionException, AccessException, RequestException, ConfigException { this.serverStats.clear(); super.connect(); } - + /** * @see com.perforce.p4java.impl.mapbased.rpc.RpcServer#disconnect() */ public void disconnect() throws ConnectionException, AccessException { - if( this.socketPool != null) { + if (this.socketPool != null) { this.socketPool.disconnect(); } super.disconnect(); @@ -188,9 +170,7 @@ public void disconnect() throws ConnectionException, AccessException { * @see com.perforce.p4java.impl.mapbased.server.Server#execMapCmd(java.lang.String, java.lang.String[], java.util.Map) */ @Override - public Map[] execMapCmd(String cmdName, String[] cmdArgs, - Map inMap) throws ConnectionException, - AccessException, RequestException { + public Map[] execMapCmd(String cmdName, String[] cmdArgs, Map inMap) throws ConnectionException, AccessException, RequestException { return this.execMapCmd(cmdName, cmdArgs, inMap, null, false, null, 0); } @@ -198,8 +178,7 @@ public Map[] execMapCmd(String cmdName, String[] cmdArgs, * @see com.perforce.p4java.impl.mapbased.server.Server#execMapCmdList(java.lang.String, java.lang.String[], java.util.Map) */ @Override - public List> execMapCmdList(String cmdName, String[] cmdArgs, - Map inMap) throws ConnectionException, AccessException, RequestException { + public List> execMapCmdList(String cmdName, String[] cmdArgs, Map inMap) throws ConnectionException, AccessException, RequestException { return this.execMapCmdList(cmdName, cmdArgs, inMap, null, false, null, 0, null, null); } @@ -207,8 +186,7 @@ public List> execMapCmdList(String cmdName, String[] cmdArgs * @see com.perforce.p4java.impl.mapbased.server.Server#execMapCmdList(java.lang.String, java.lang.String[], java.util.Map, com.perforce.p4java.server.callback.IFilterCallback) */ @Override - public List> execMapCmdList(String cmdName, String[] cmdArgs, - Map inMap, IFilterCallback filterCallback) throws P4JavaException { + public List> execMapCmdList(String cmdName, String[] cmdArgs, Map inMap, IFilterCallback filterCallback) throws P4JavaException { return this.execMapCmdList(cmdName, cmdArgs, inMap, null, false, null, 0, filterCallback, null); } @@ -216,136 +194,96 @@ public List> execMapCmdList(String cmdName, String[] cmdArgs * @see com.perforce.p4java.impl.mapbased.server.Server#execQuietMapCmd(java.lang.String, java.lang.String[], java.util.Map) */ @Override - public Map[] execQuietMapCmd(String cmdName, - String[] cmdArgs, Map inMap) - throws ConnectionException, RequestException, - AccessException { + public Map[] execQuietMapCmd(String cmdName, String[] cmdArgs, Map inMap) throws ConnectionException, RequestException, AccessException { return this.execMapCmd(cmdName, cmdArgs, inMap, null, true, null, 0); } - + /** * @see com.perforce.p4java.impl.mapbased.server.Server#execQuietMapCmdList(java.lang.String, java.lang.String[], java.util.Map) */ @Override - public List> execQuietMapCmdList(String cmdName, - String[] cmdArgs, Map inMap) throws P4JavaException { + public List> execQuietMapCmdList(String cmdName, String[] cmdArgs, Map inMap) throws P4JavaException { return this.execMapCmdList(cmdName, cmdArgs, inMap, null, true, null, 0, null, null); } - + /** * @see com.perforce.p4java.impl.mapbased.server.Server#execInputStringMapCmd(java.lang.String, java.lang.String[], java.lang.String) */ - public Map[] execInputStringMapCmd(String cmdName, - String[] cmdArgs, String inString) throws P4JavaException { + public Map[] execInputStringMapCmd(String cmdName, String[] cmdArgs, String inString) throws P4JavaException { return this.execMapCmd(cmdName, cmdArgs, null, inString, true, null, 0); } - + /** * @see com.perforce.p4java.impl.mapbased.server.Server#execInputStringMapCmdList(java.lang.String, java.lang.String[], java.lang.String) */ - public List> execInputStringMapCmdList(String cmdName, - String[] cmdArgs, String inString) throws P4JavaException { + public List> execInputStringMapCmdList(String cmdName, String[] cmdArgs, String inString) throws P4JavaException { return this.execMapCmdList(cmdName, cmdArgs, null, inString, true, null, 0, null, null); } /** * @see com.perforce.p4java.impl.mapbased.server.Server#execInputStringMapCmdList(java.lang.String, java.lang.String[], java.lang.String, com.perforce.p4java.server.callback.IFilterCallback) */ - public List> execInputStringMapCmdList(String cmdName, - String[] cmdArgs, String inString, IFilterCallback filterCallback) throws P4JavaException { + public List> execInputStringMapCmdList(String cmdName, String[] cmdArgs, String inString, IFilterCallback filterCallback) throws P4JavaException { return this.execMapCmdList(cmdName, cmdArgs, null, inString, true, null, 0, filterCallback, null); } - + @Override - public List> execMapCmdList(String cmdName, String[] cmdArgs, IFilterCallback filterCallback, - IParallelCallback parallelCallback) throws P4JavaException { + public List> execMapCmdList(String cmdName, String[] cmdArgs, IFilterCallback filterCallback, IParallelCallback parallelCallback) throws P4JavaException { return this.execMapCmdList(cmdName, cmdArgs, null, null, true, null, 0, filterCallback, parallelCallback); } - + /** * @see com.perforce.p4java.impl.mapbased.server.Server#execInputStringStreamingMapComd(java.lang.String, java.lang.String[], java.lang.String, com.perforce.p4java.server.callback.IStreamingCallback, int) - * * @deprecated As of release 2013.1, replaced by {@link #execInputStringStreamingMapCmd(java.lang.String, java.lang.String[], java.lang.String, com.perforce.p4java.server.callback.IStreamingCallback, int)} - */ + */ @Deprecated - public void execInputStringStreamingMapComd(String cmdName, - String[] cmdArgs, String inString, IStreamingCallback callback, - int key) throws P4JavaException { + public void execInputStringStreamingMapComd(String cmdName, String[] cmdArgs, String inString, IStreamingCallback callback, int key) throws P4JavaException { execMapCmd(cmdName, cmdArgs, null, inString, false, callback, key); } - + /** * @see com.perforce.p4java.impl.mapbased.server.Server#execInputStringStreamingMapCmd(java.lang.String, java.lang.String[], java.lang.String, com.perforce.p4java.server.callback.IStreamingCallback, int) - */ - public void execInputStringStreamingMapCmd(String cmdName, - String[] cmdArgs, String inString, IStreamingCallback callback, - int key) throws P4JavaException { + */ + public void execInputStringStreamingMapCmd(String cmdName, String[] cmdArgs, String inString, IStreamingCallback callback, int key) throws P4JavaException { execMapCmd(cmdName, cmdArgs, null, inString, false, callback, key); } @SuppressWarnings("unchecked") - protected Map[] execMapCmd(String cmdName, - String[] cmdArgs, Map inMap, String inString, boolean ignoreCallbacks, - IStreamingCallback callback, int callbackKey) - throws ConnectionException, AccessException, RequestException { - + protected Map[] execMapCmd(String cmdName, String[] cmdArgs, Map inMap, String inString, boolean ignoreCallbacks, IStreamingCallback callback, int callbackKey) throws ConnectionException, AccessException, RequestException { + List> results = execMapCmdList(cmdName, cmdArgs, inMap, inString, ignoreCallbacks, callback, callbackKey, null, null); if (results != null) { return results.toArray(new HashMap[results.size()]); } - + return null; } - protected List> execMapCmdList(String cmdName, - String[] cmdArgs, Map inMap, String inString, boolean ignoreCallbacks, - IStreamingCallback callback, int callbackKey, IFilterCallback filterCallback, - IParallelCallback parallelCallback) - throws ConnectionException, AccessException, RequestException { + protected List> execMapCmdList(String cmdName, String[] cmdArgs, Map inMap, String inString, boolean ignoreCallbacks, IStreamingCallback callback, int callbackKey, IFilterCallback filterCallback, IParallelCallback parallelCallback) throws ConnectionException, AccessException, RequestException { RpcPacketDispatcher dispatcher = null; RpcConnection rpcConnection = null; - + if (cmdName == null) { - throw new NullPointerError( - "Null command name passed to execMapCmd"); + throw new NullPointerError("Null command name passed to execMapCmd"); } - + if (!this.connected) { - throw new ConnectionNotConnectedException( - "Not currently connected to a Perforce server"); + throw new ConnectionNotConnectedException("Not currently connected to a Perforce server"); } - + try { int cmdCallBackKey = this.nextCmdCallBackKey.incrementAndGet(); long startTime = System.currentTimeMillis(); dispatcher = new RpcPacketDispatcher(props, this); - rpcConnection = new RpcStreamConnection(serverHost, serverPort, - props, this.serverStats, this.p4Charset, null, this.socketPool, - this.secure, this.rsh); + rpcConnection = new RpcStreamConnection(serverHost, serverPort, props, this.serverStats, this.p4Charset, null, this.socketPool, this.secure, this.rsh); ProtocolCommand protocolSpecs = new ProtocolCommand(); - + if (inMap != null && ClientLineEnding.CONVERT_TEXT) { ClientLineEnding.convertMap(inMap); } - ExternalEnv env = setupCmd(dispatcher, rpcConnection, protocolSpecs, - cmdName.toLowerCase(Locale.ENGLISH), cmdArgs, inMap, ignoreCallbacks, cmdCallBackKey, false); - CommandEnv cmdEnv = new CommandEnv( - this, - new RpcCmdSpec( - cmdName.toLowerCase(Locale.ENGLISH), - cmdArgs, - getAuthTicket(), - inMap, - inString, - env), - rpcConnection, - protocolSpecs, - this.serverProtocolMap, - this.progressCallback, - cmdCallBackKey, - writeInPlace(cmdName), - this.isNonCheckedSyncs()); + ExternalEnv env = setupCmd(dispatcher, rpcConnection, protocolSpecs, cmdName.toLowerCase(Locale.ENGLISH), cmdArgs, inMap, ignoreCallbacks, cmdCallBackKey, false); + CommandEnv cmdEnv = new CommandEnv(this, new RpcCmdSpec(cmdName.toLowerCase(Locale.ENGLISH), cmdArgs, getAuthTicket(), inMap, inString, env), rpcConnection, protocolSpecs, this.serverProtocolMap, this.progressCallback, cmdCallBackKey, writeInPlace(cmdName), this.isNonCheckedSyncs()); cmdEnv.setDontWriteTicket(isDontWriteTicket(cmdName.toLowerCase(Locale.ENGLISH), cmdArgs)); cmdEnv.setFieldRule(getRpcPacketFieldRule(inMap, CmdSpec.getValidP4JCmdSpec(cmdName))); cmdEnv.setStreamingCallback(callback); @@ -370,30 +308,27 @@ protected List> execMapCmdList(String cmdName, Log.exception(exc); } } - + // Check if currently case sensitive so the map search for the no // case key is only performed when necessary. Once a server is // marked as case insensitive this check will never look at the // server protocol specs map. - if (this.caseSensitive - && cmdEnv.getServerProtocolSpecsMap().containsKey( - RpcFunctionMapKey.NOCASE)) { + if (this.caseSensitive && cmdEnv.getServerProtocolSpecsMap().containsKey(RpcFunctionMapKey.NOCASE)) { this.caseSensitive = false; } - + if (!ignoreCallbacks && (this.commandCallback != null)) { this.processCmdCallbacks(cmdCallBackKey, endTime - startTime, retMapList); } // Close RPC output stream - RpcOutputStream outStream = (RpcOutputStream) cmdEnv.getStateMap().get( - RpcServer.RPC_TMP_OUTFILE_STREAM_KEY); + RpcOutputStream outStream = (RpcOutputStream) cmdEnv.getStateMap().get(RpcServer.RPC_TMP_OUTFILE_STREAM_KEY); if (outStream != null) { outStream.close(); } return retMapList; - + } catch (BufferOverflowException exc) { Log.error("RPC Buffer overflow: " + exc.getLocalizedMessage()); Log.exception(exc); @@ -405,37 +340,31 @@ protected List> execMapCmdList(String cmdName, } catch (IOException ioexc) { Log.error("RPC I/O error: " + ioexc.getLocalizedMessage()); Log.exception(ioexc); - throw new RequestException( - "I/O error encountered in stream command: " - + ioexc.getLocalizedMessage(), ioexc); - } finally { + throw new RequestException("I/O error encountered in stream command: " + ioexc.getLocalizedMessage(), ioexc); + } finally { if (rpcConnection != null) { rpcConnection.disconnect(dispatcher); } } } - + /** * @see com.perforce.p4java.impl.mapbased.server.Server#execStreamingMapCommand(java.lang.String, java.lang.String[], java.util.Map, com.perforce.p4java.server.callback.IStreamingCallback, int) */ - public void execStreamingMapCommand(String cmdName, String[] cmdArgs, Map inMap, - IStreamingCallback callback, int key) throws P4JavaException { + public void execStreamingMapCommand(String cmdName, String[] cmdArgs, Map inMap, IStreamingCallback callback, int key) throws P4JavaException { if (callback == null) { - throw new NullPointerError( - "null streaming callback passed to execStreamingMapCommand method"); + throw new NullPointerError("null streaming callback passed to execStreamingMapCommand method"); } - + execMapCmdList(cmdName, cmdArgs, inMap, null, false, callback, key, null, null); } /** * @see com.perforce.p4java.impl.mapbased.server.Server#execMapCmdList(String, String[], IFilterCallback, IParallelCallback) */ - public void execStreamingMapCommand(String cmdName, String[] cmdArgs, Map inMap, - IStreamingCallback callback, int key, IParallelCallback parallelCallback) throws P4JavaException { + public void execStreamingMapCommand(String cmdName, String[] cmdArgs, Map inMap, IStreamingCallback callback, int key, IParallelCallback parallelCallback) throws P4JavaException { if (callback == null) { - throw new NullPointerError( - "null streaming callback passed to execStreamingMapCommand method"); + throw new NullPointerError("null streaming callback passed to execStreamingMapCommand method"); } execMapCmdList(cmdName, cmdArgs, inMap, null, false, callback, key, null, parallelCallback); @@ -445,9 +374,7 @@ public void execStreamingMapCommand(String cmdName, String[] cmdArgs, Map inMap) - throws P4JavaException { + public InputStream execStreamCmd(String cmdName, String[] cmdArgs, Map inMap) throws P4JavaException { return this.execStreamCmd(cmdName, cmdArgs, inMap, null, false); } @@ -474,67 +398,55 @@ public InputStream execStreamCmd(String cmdName, String[] cmdArgs, Map inMap, String inString, boolean ignoreCallbacks) - throws ConnectionException, RequestException, AccessException { + protected InputStream execStreamCmd(String cmdName, String[] cmdArgs, Map inMap, String inString, boolean ignoreCallbacks) throws ConnectionException, RequestException, AccessException { RpcPacketDispatcher dispatcher = null; RpcConnection rpcConnection = null; if (cmdName == null) { - throw new NullPointerError( - "Null command name passed to execStreamCmd"); + throw new NullPointerError("Null command name passed to execStreamCmd"); } - + if (!this.connected) { - throw new ConnectionNotConnectedException( - "Not currently connected to a Perforce server"); + throw new ConnectionNotConnectedException("Not currently connected to a Perforce server"); } - - try { + + try { int cmdCallBackKey = this.nextCmdCallBackKey.incrementAndGet(); long startTime = System.currentTimeMillis(); dispatcher = new RpcPacketDispatcher(props, this); - rpcConnection = new RpcStreamConnection(serverHost, serverPort, - props, this.serverStats, this.p4Charset, null, this.socketPool, - this.secure, this.rsh); + rpcConnection = new RpcStreamConnection(serverHost, serverPort, props, this.serverStats, this.p4Charset, null, this.socketPool, this.secure, this.rsh); ProtocolCommand protocolSpecs = new ProtocolCommand(); if (inMap != null && ClientLineEnding.CONVERT_TEXT) { ClientLineEnding.convertMap(inMap); } - ExternalEnv env = setupCmd(dispatcher, rpcConnection, protocolSpecs, - cmdName.toLowerCase(Locale.ENGLISH),cmdArgs, inMap, ignoreCallbacks, cmdCallBackKey, true); - CommandEnv cmdEnv = new CommandEnv( - this, - new RpcCmdSpec( - cmdName.toLowerCase(Locale.ENGLISH), - cmdArgs, - getAuthTicket(), - inMap, - inString, - env), - rpcConnection, - protocolSpecs, - this.serverProtocolMap, - this.progressCallback, - cmdCallBackKey, - writeInPlace(cmdName), - this.isNonCheckedSyncs()); + ExternalEnv env = setupCmd(dispatcher, rpcConnection, protocolSpecs, cmdName.toLowerCase(Locale.ENGLISH), cmdArgs, inMap, ignoreCallbacks, cmdCallBackKey, true); + CommandEnv cmdEnv = new CommandEnv(this, new RpcCmdSpec(cmdName.toLowerCase(Locale.ENGLISH), cmdArgs, getAuthTicket(), inMap, inString, env), rpcConnection, protocolSpecs, this.serverProtocolMap, this.progressCallback, cmdCallBackKey, writeInPlace(cmdName), this.isNonCheckedSyncs()); cmdEnv.setDontWriteTicket(isDontWriteTicket(cmdName.toLowerCase(Locale.ENGLISH), cmdArgs)); cmdEnv.setFieldRule(getRpcPacketFieldRule(inMap, CmdSpec.getValidP4JCmdSpec(cmdName))); cmdEnv.setStreamCmd(true); List> retMapList = dispatcher.dispatch(cmdEnv); - + long endTime = System.currentTimeMillis(); - + if (!ignoreCallbacks && (this.commandCallback != null)) { this.processCmdCallbacks(cmdCallBackKey, endTime - startTime, retMapList); } @@ -546,18 +458,16 @@ protected InputStream execStreamCmd(String cmdName, String[] cmdArgs, Map inMap, - boolean ignoreCallbacks, int cmdCallBackKey, boolean isStream) - throws ConnectionException, AccessException, RequestException { + protected ExternalEnv setupCmd(RpcPacketDispatcher dispatcher, RpcConnection rpcConnection, ProtocolCommand protocolSpecs, String cmdName, String[] cmdArgs, Map inMap, boolean ignoreCallbacks, int cmdCallBackKey, boolean isStream) throws ConnectionException, AccessException, RequestException { if (rpcConnection == null) { throw new NullPointerError("Null RPC connection in execMapCmd call"); } @@ -598,31 +515,18 @@ protected ExternalEnv setupCmd(RpcPacketDispatcher dispatcher, throw new NullPointerError("Null RPC protocol specs in execMapCmd call"); } if (!this.isRelaxCmdNameValidationChecks() && !CmdSpec.isValidP4JCmdSpec(cmdName)) { - throw new RequestException("command name '" - + cmdName + "' unimplemented or unrecognized by p4java"); + throw new RequestException("command name '" + cmdName + "' unimplemented or unrecognized by p4java"); } - + // Should use tags? boolean useTags = useTags(cmdName, cmdArgs, inMap, isStream); // Check certificate chain and/or fingerprint. // An exception (ConnectionException) is thrown if ssl but not trusted. trustConnectionCheck(rpcConnection); - - ExternalEnv env = new ExternalEnv( - this.getUsageOptions().getProgramName(), - this.getUsageOptions().getProgramVersion(), - this.getClientNameForEnv(), - this.getUsageOptions().getWorkingDirectory(), - this.getHostForEnv(), - this.getServerHostPort(), - this.getUsageOptions().getTextLanguage(), - this.getOsTypeForEnv(), - this.getUserForEnv(), - this.isServerUnicode(), - this.getClientCharset() - ); - + + ExternalEnv env = new ExternalEnv(this.getUsageOptions().getProgramName(), this.getUsageOptions().getProgramVersion(), this.getClientNameForEnv(), this.getUsageOptions().getWorkingDirectory(), this.getHostForEnv(), this.getServerHostPort(), this.getUsageOptions().getTextLanguage(), this.getOsTypeForEnv(), this.getUserForEnv(), this.isServerUnicode(), this.getClientCharset()); + if (!ignoreCallbacks && (this.commandCallback != null)) { StringBuilder cmd = new StringBuilder(cmdName); for (String argStr : cmdArgs) { @@ -633,9 +537,9 @@ protected ExternalEnv setupCmd(RpcPacketDispatcher dispatcher, } this.commandCallback.issuingServerCommand(cmdCallBackKey, cmd.toString()); } - + RpcPacket protPacket = null; - + protocolSpecs.setClientApiLevel(this.clientApiLevel); protocolSpecs.setClientCmpFile(false); protocolSpecs.setServerApiLevel(this.serverApiLevel); @@ -651,32 +555,25 @@ protected ExternalEnv setupCmd(RpcPacketDispatcher dispatcher, // Set the 'host' (P4HOST) and 'port' (P4PORT) protocol parameters protocolSpecs.setHost(env.getHost()); protocolSpecs.setPort(env.getPort()); - - if (props.containsKey(RpcFunctionMapKey.IPADDR) - && props.containsKey(RpcFunctionMapKey.SVRNAME) - && props.containsKey(RpcFunctionMapKey.PORT)) { + + if (props.containsKey(RpcFunctionMapKey.IPADDR) && props.containsKey(RpcFunctionMapKey.SVRNAME) && props.containsKey(RpcFunctionMapKey.PORT)) { protocolSpecs.setIpAddr(props.getProperty(RpcFunctionMapKey.IPADDR)); } - protPacket = RpcPacket.constructRpcPacket( - RpcFunctionSpec.PROTOCOL_PROTOCOL, - protocolSpecs.asMap(), - null); - - RpcFunctionSpec name = RpcFunctionSpec.decodeFromEndUserCmd(cmdName, - this.isRelaxCmdNameValidationChecks()); - - RpcPacket cmdPacket = RpcPacket.constructRpcPacket(name, cmdName, cmdArgs, - env); + protPacket = RpcPacket.constructRpcPacket(RpcFunctionSpec.PROTOCOL_PROTOCOL, protocolSpecs.asMap(), null); + + RpcFunctionSpec name = RpcFunctionSpec.decodeFromEndUserCmd(cmdName, this.isRelaxCmdNameValidationChecks()); + + RpcPacket cmdPacket = RpcPacket.constructRpcPacket(name, cmdName, cmdArgs, env); // Append the "tag" argument before the function name if (useTags) { cmdPacket.setMapArgs(this.cmdMapArgs); } // On each command message sent to the server (i.e. "user-foo") - // a variable "progress" should be set to 1 to indicate that - // the server should send progress messages to the client if they - // are available for that command. + // a variable "progress" should be set to 1 to indicate that + // the server should send progress messages to the client if they + // are available for that command. if (this.enableProgress) { Map valMap = new HashMap(); if (cmdPacket.getMapArgs() != null) { @@ -685,20 +582,20 @@ protected ExternalEnv setupCmd(RpcPacketDispatcher dispatcher, valMap.put(ProtocolCommand.RPC_ARGNAME_PROTOCOL_ENABLE_PROGRESS, "1"); cmdPacket.setMapArgs(valMap); } - + if (protPacket == null) { rpcConnection.putRpcPacket(cmdPacket); } else { - rpcConnection.putRpcPackets(new RpcPacket[] {protPacket, cmdPacket}); + rpcConnection.putRpcPackets(new RpcPacket[]{protPacket, cmdPacket}); } - + return env; } /** * Get server address object - * + * * @return server address object */ public IServerAddress getServerAddressDetails() { @@ -713,7 +610,7 @@ public IServerAddress getServerAddressDetails() { } else { builder.setProtocol(Protocol.P4JRPC); } - + return builder.build(); } } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/RpcPropertyDefs.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/RpcPropertyDefs.java index 235ffed..dd077f5 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/RpcPropertyDefs.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/RpcPropertyDefs.java @@ -3,35 +3,32 @@ */ package com.perforce.p4java.impl.mapbased.rpc; -import java.util.Properties; - import com.perforce.p4java.Log; +import java.util.Properties; + /** * A convenience class used to hold all publicly-visible - * properties keys used by the RPC implementation.

- * + * properties keys used by the RPC implementation. + *

* The intention here is to simply centralize property key names * so end users have some idea what's available and what each key's * semantics are. This is NOT intended as a full property repository * -- property management is generally up to individual classes - * and packages.

- * + * and packages. + *

* Note that in general, all properties can have an optional short * form ("NICK", Anglo-English for nickname...) which is typically * just the full form without the cumbersome com.perforce.whatever * prefix; use of the short form is particularly convenient for passing * in properties through the url mechanism, but you have to be very * careful that there are no conflicting system or environmental - * properties...

- * + * properties... + *

* Note that if you add a property somewhere that's likely to be * useful to end users, you should use the mechanism here to document * it. - * - * */ - public class RpcPropertyDefs { /** @@ -43,14 +40,14 @@ public class RpcPropertyDefs { * The default property delimiter for RPC properties. */ public static final String RPC_DEFAULT_PROPERTY_DELIMITER = ","; - + /** * Default size in bytes of the "standard" send byte buffer. Usually interpreted * by P4Java as a hint for initial allocation, and may be overridden in the face * of actual conditions. It's rare that you'd want to change this. */ public static final int RPC_DEFAULT_SEND_BYTE_BUF_SIZE = 40960; - + /** * Default size in bytes of the "standard" recv byte buffer. Usually interpreted * by P4Java as a hint for initial allocation, and may be overridden in the face @@ -62,36 +59,36 @@ public class RpcPropertyDefs { * Short form for the RPC_DEFAULT_SEND_BYTE_BUF_SIZE property key. */ public static final String RPC_DEFAULT_SEND_BYTE_BUF_SIZE_NICK = "defByteSendBufSize"; - + /** * Short form for the RPC_DEFAULT_RECV_BYTE_BUF_SIZE property key. */ public static final String RPC_DEFAULT_RECV_BYTE_BUF_SIZE_NICK = "defByteRecvBufSize"; - + /** * Default size in bytes of the "standard" file I/O buffer. Usually interpreted * by P4Java as a hint for initial allocation, and may be overridden in the face * of actual conditions. */ public static final int RPC_DEFAULT_FILE_BUF_SIZE = 10240; - + /** * Short form for the RPC_DEFAULT_FILE_BUF_SIZE property key. */ public static final String RPC_DEFAULT_FILE_BUF_SIZE_NICK = "defFileBufSize"; - + /** * Default size in bytes of the "peek" we take into local files to try * to infer from the contents what type the file is. */ public static final int RPC_DEFAULT_FILETYPE_PEEK_SIZE = 1024 * 64; - + /** * Default setting for enable/disable TCP_NODELAY (disable/enable Nagle's * algorithm). */ public static final boolean RPC_SOCKET_TCP_NO_DELAY_DEFAULT = true; - + /** * If this property is set, attempt to use the associated value to * enable/disable TCP_NODELAY (disable/enable Nagle's algorithm). @@ -103,36 +100,36 @@ public class RpcPropertyDefs { * the socket keepalive option. Defaults to using keepalive. */ public static final String RPC_SOCKET_USE_KEEPALIVE_NICK = "useKeepAlive"; - + /** * Default number of milliseconds to use for RPC socket read or write timeouts. */ public static final int RPC_SOCKET_SO_TIMEOUT_DEFAULT = 30000; - + /** * The number of milliseconds to use for RPC socket read or write timeouts. * If set to zero, timeouts are disabled. */ public static final String RPC_SOCKET_SO_TIMEOUT_NICK = "sockSoTimeout"; - + /** * Default socket performance preferences are described by three integers * whose values indicate the relative importance of short connection time, * low latency, and high bandwidth. */ - public static final int[] RPC_SOCKET_PERFORMANCE_PREFERENCES_DEFAULT = new int[] {1, 2, 0}; - + public static final int[] RPC_SOCKET_PERFORMANCE_PREFERENCES_DEFAULT = new int[]{1, 2, 0}; + /** * If this property is set, attempt to set the underlying RPC socket's * performance preferences to the associated values, in integers, delimited * by commas. Note that you must specify exactly three integers, otherwise - * this property will be ignored.

- * + * this property will be ignored. + *

* The absolute values of the integers are irrelevant; in order to choose a * protocol the values are simply compared, with larger values indicating * stronger preferences. Negative values represent a lower priority than - * positive values.

- * + * positive values. + *

* If the application prefers short connection time over both low latency * and high bandwidth, for example, then it could invoke this method with * the values (1, 0, 0). If the application prefers high bandwidth above low @@ -140,46 +137,46 @@ public class RpcPropertyDefs { * invoke this method with the values (0, 1, 2). */ public static final String RPC_SOCKET_PERFORMANCE_PREFERENCES_NICK = "sockPerfPrefs"; - + /** * If this property is set, attempt to set the underlying RPC socket's * system receive buffer size to the associated value, in bytes. */ public static final String RPC_SOCKET_RECV_BUF_SIZE_NICK = "sockRecvBufSize"; - + /** * If this property is set, attempt to set the underlying RPC socket's * system send buffer size to the associated value, in bytes. */ public static final String RPC_SOCKET_SEND_BUF_SIZE_NICK = "sockSendBufSize"; - + /** * Default blocking queue size used in RPC send / recv queues; size * is in elements. */ public static final int RPC_DEFAULT_QUEUE_SIZE = 10; - + /** * If this property is set, attempt to set the underlying RPC connection's * queue lengths to the associated value, in elements. */ public static final String RPC_DEFAULT_QUEUE_SIZE_NICK = "defQueueSize"; - + /** * Number of sockets to retain in pool when released */ public static final String RPC_SOCKET_POOL_SIZE_NICK = "socketPoolSize"; - + /** * Default number of sockets retained in pool */ public static final int RPC_SOCKET_POOL_DEFAULT_SIZE = 0; - + /** * If this property is set and equals "false", do not trust all certificates. */ public static final String RPC_SECURE_SOCKET_TRUST_ALL_NICK = "secureSocketTrustAll"; - + /** * Default secure socket trust all certificates (i.e. self-signed). */ @@ -188,8 +185,8 @@ public class RpcPropertyDefs { /** * If this property is set, attempt to instantiate the SSLContext with the * associated value. The property value represents a standard name of a - * protocol (for example, TLS, SSL, etc.).

- * + * protocol (for example, TLS, SSL, etc.). + *

* Use Security.getProviders(), Provider.getServices() and Service.getAlgorithm() * to list all the providers and the algorithms supporter. */ @@ -203,10 +200,10 @@ public class RpcPropertyDefs { /** * Client Certificate validation Method, corresponds to p4api ssl.client.cert.validate *

- * 0: always use the P4TRUST mechanism. This is pre 2022.1 behavior.
- * 1: validate the certificate chain (default)
+ * 0: always use the P4TRUST mechanism. This is pre 2022.1 behavior.

+ * 1: validate the certificate chain (default)

* 2: validate the subject matches the P4PORT. The chain is not validated. but the CN of the - * certificate is compared to the host in the P4PORT.
+ * certificate is compared to the host in the P4PORT. */ public static final String RPC_SECURE_CLIENT_CERT_VALIDATE_NICK = "secureClientCertValidate"; @@ -218,11 +215,11 @@ public class RpcPropertyDefs { /** * P4TRUST file entries, corresponds to p4api ssl.client.trust.name - *
- * 0: Only IP address This is pre 2022.1 behavior.
- * 1: both IP and hostname (default)
+ *

+ * 0: Only IP address This is pre 2022.1 behavior.

+ * 1: both IP and hostname (default)

* 2: Only hostname The chain is not validated. but the CN of the - * certificate is compared to the host in the P4PORT.
+ * certificate is compared to the host in the P4PORT. */ public static final String RPC_SECURE_CLIENT_TRUST_NAME_NICK = "secureClientCertValidate"; @@ -248,16 +245,16 @@ public class RpcPropertyDefs { * If this property is set, attempt to set enabled protocol versions * (SSLSocket.setEnabledProtocols()) for the connection. The property value * represents a comma-separated list of one or more protocol versions - * (for example, TLSv1, SSLv3, etc.).

- * + * (for example, TLSv1, SSLv3, etc.). + *

* Use SSLSocket.getSupportedProtocols() and SSLSocket.getEnabledProtocols() * to list all supported and enabled protocol versions for the connection. */ public static final String RPC_SECURE_SOCKET_ENABLED_PROTOCOLS_NICK = "secureSocketEnabledProtocols"; /** - * Default secure socket enabled protocol versions.

- * + * Default secure socket enabled protocol versions. + *

* The current server (12.1) limit the protocol version support to the * IETF-standard TLSv1. */ @@ -270,7 +267,7 @@ public class RpcPropertyDefs { * "interesting" things can happen if not used properly. */ public static final String RPC_RELAX_CMD_NAME_CHECKS_NICK = "relaxCmdNameChecks"; - + /** * If this property is set, attempt to set the underlying RPC protocol 'app' * tag to the associated value. @@ -280,88 +277,102 @@ public class RpcPropertyDefs { /** * Convenience method to first try to get the short form from the passed-in * properties, then try for the long form. Returns null if it can't find - * a definition associated with either short or long form keys.

- * + * a definition associated with either short or long form keys. + *

* Note: this method is null safe, i.e. if either or both props or nick is null, * it simply returns null. + * + * @param props props + * @param nick nick + * @return property */ - public static String getProperty(Properties props, String nick) { return getProperty(props, nick, null); } - + /** * Convenience method to first try to get the short form from the passed-in * properties, then try for the long form. Returns defaultValue if it can't - * find a definition associated with either short or long form keys.

- * + * find a definition associated with either short or long form keys. + *

* Note: this method is null safe, i.e. if either or both props or nick is null, * it simply returns null. + * + * @param props props + * @param nick nick + * @param defaultValue defaultValue + * @return property */ - public static String getProperty(Properties props, String nick, String defaultValue) { - + if ((props != null) && (nick != null)) { String propStr = null; if (props.get(nick) != null) { propStr = String.valueOf(props.get(nick)); } - + if (propStr == null) { if (props.get(RPC_PROPERTY_PREFIX + nick) != null) { propStr = String.valueOf(props.get(RPC_PROPERTY_PREFIX + nick)); } } - + if (propStr != null) { return propStr; } } - + return defaultValue; } - + /** * Return a named property as an int, if possible. Defaults to defaultValue * if the property wasn't found under first its short form, then its long form, - * or if the resulting attempt to convert to an integer was unsuccessful.

- * - * Will log to P4JLog any conversion error as a warning.

- * + * or if the resulting attempt to convert to an integer was unsuccessful. + *

+ * Will log to P4JLog any conversion error as a warning. + *

* Note: this method is null safe, i.e. if either or both props or nick is null, * it simply returns defaultValue. + * + * @param props props + * @param nick nick + * @param defaultValue defaultValue + * @return value */ - public static int getPropertyAsInt(Properties props, String nick, int defaultValue) { String propStr = getProperty(props, nick, null); int retVal = defaultValue; - + if (propStr != null) { try { retVal = new Integer(propStr); } catch (Exception exc) { - Log.warn("Integer property conversion error; prop name: '" - + nick + "'; prop value: " - + propStr); + Log.warn("Integer property conversion error; prop name: '" + nick + "'; prop value: " + propStr); Log.exception(exc); } } - + return retVal; } - + /** * Return a named property as an int array, if possible. The property value * is split into values by a specified delimiter (if null, a default delimiter * will be used). Return an empty int array if the property wasn't found under first its short form, - * then its long form, or if the resulting attempt to convert to an integer was unsuccessful.

- * - * Will log to P4JLog any conversion error as a warning.

- * + * then its long form, or if the resulting attempt to convert to an integer was unsuccessful. + *

+ * Will log to P4JLog any conversion error as a warning. + *

* Note: this method is null safe, i.e. if either or both props or nick is null, * it simply returns an empty int array. + * + * @param props props + * @param nick nick + * @param delimiter delimiter + * @param defaultValues defaultValues + * @return int array */ - public static int[] getPropertyAsIntArray(Properties props, String nick, String delimiter, int[] defaultValues) { String separator = delimiter != null ? delimiter : RPC_DEFAULT_PROPERTY_DELIMITER; int[] retVals = defaultValues != null ? defaultValues : new int[]{}; @@ -373,45 +384,46 @@ public static int[] getPropertyAsIntArray(Properties props, String nick, String String[] items = propStr.split(separator); int[] results = new int[items.length]; for (int i = 0; i < items.length; i++) { - results[i] = Integer.parseInt(items[i].trim()); + results[i] = Integer.parseInt(items[i].trim()); } return results; } catch (Exception exc) { - Log.warn("Integer property conversion error; prop name: '" - + nick + "'; prop value: " - + propStr); + Log.warn("Integer property conversion error; prop name: '" + nick + "'; prop value: " + propStr); Log.exception(exc); } } - + return retVals; } /** * Return a named property a boolean, if possible. Defaults to defaultValue * if the property wasn't found under first its short form, then its long form, - * or if the resulting attempt to convert to an integer was unsuccessful.

- * - * Will log to P4JLog any conversion error as a warning.

- * + * or if the resulting attempt to convert to an integer was unsuccessful. + *

+ * Will log to P4JLog any conversion error as a warning. + *

* Note: this method is null safe, i.e. if either or both props or nick is null, * it simply returns defaultValue. + * + * @param props props + * @param nick nick + * @param defaultValue defaultValue + * @return boolean */ public static boolean getPropertyAsBoolean(Properties props, String nick, boolean defaultValue) { String propStr = getProperty(props, nick, null); boolean retVal = defaultValue; - + if (propStr != null) { try { return new Boolean(propStr); } catch (Exception exc) { - Log.warn("Integer property conversion error; prop name: '" - + nick + "'; prop value: " - + propStr); + Log.warn("Integer property conversion error; prop name: '" + nick + "'; prop value: " + propStr); Log.exception(exc); } } - + return retVal; } } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/RpcServer.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/RpcServer.java index 13862f0..2a2e77e 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/RpcServer.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/RpcServer.java @@ -43,7 +43,6 @@ import java.net.UnknownHostException; import java.nio.charset.Charset; import java.security.cert.CertificateException; -import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collections; @@ -134,7 +133,7 @@ public abstract class RpcServer extends Server { * default for most commands; some commands dynamically bump up the level * for the command's duration. */ - public static final int DEFAULT_CLIENT_API_LEVEL = 91; // 2021.2 + public static final int DEFAULT_CLIENT_API_LEVEL = 92; // 2022.1 // p4/msgs/p4tagl.cc // p4/client/client.cc @@ -232,9 +231,7 @@ public abstract class RpcServer extends Server { // failure private static final String AUTH_FAIL_STRING_2 = "Password invalid"; - private static final String[] ACCESS_ERROR_MSGS = {CORE_AUTH_FAIL_STRING_1, - CORE_AUTH_FAIL_STRING_2, CORE_AUTH_FAIL_STRING_3, CORE_AUTH_FAIL_STRING_4, - AUTH_FAIL_STRING_1, AUTH_FAIL_STRING_2}; + private static final String[] ACCESS_ERROR_MSGS = {CORE_AUTH_FAIL_STRING_1, CORE_AUTH_FAIL_STRING_2, CORE_AUTH_FAIL_STRING_3, CORE_AUTH_FAIL_STRING_4, AUTH_FAIL_STRING_1, AUTH_FAIL_STRING_2}; private static final String PASSWORD_NOT_SET_STRING = "no password set for this user"; @@ -266,6 +263,7 @@ public abstract class RpcServer extends Server { /** * was the server ssl connection validated by chain? + * * @return true if it's an ssl connection with valid chain */ public boolean isValidatedByChain() { @@ -300,6 +298,7 @@ public boolean isValidatedByHostname() { } return validatedByHostname; } + protected int authFileLockTry = 0; protected long authFileLockDelay = 0; protected long authFileLockWait = 0; @@ -407,7 +406,7 @@ public String getServerHostPort() { } public Charset getClientCharset() { - if(p4Charset == null) { + if (p4Charset == null) { return null; } return p4Charset.getCharset(); @@ -433,6 +432,8 @@ public String getServerId() { * specified here will be used when saving ticket values to a p4 tickets * file. This field should only be set to the server id returned as part of * a server message. + * + * @param serverId serverId */ public void setServerId(String serverId) { this.serverId = serverId; @@ -539,8 +540,7 @@ public void setAuthTicket(final String userName, final String serverId, final St if (isBlank(authTicket)) { authTickets.remove(composeAuthTicketEntryKey(lowerCaseableUserName, serverAddress)); } else { - authTickets.put(composeAuthTicketEntryKey(lowerCaseableUserName, serverAddress), - authTicket); + authTickets.put(composeAuthTicketEntryKey(lowerCaseableUserName, serverAddress), authTicket); } } @@ -549,8 +549,7 @@ public String getTrust() throws P4JavaException { RpcConnection rpcConnection = null; try { - rpcConnection = new RpcStreamConnection(serverHost, serverPort, props, serverStats, - p4Charset, secure); + rpcConnection = new RpcStreamConnection(serverHost, serverPort, props, serverStats, p4Charset, secure); return rpcConnection.getFingerprint(); } finally { @@ -570,13 +569,11 @@ public String addTrust(final String fingerprintValue) throws P4JavaException { } @Override - public String addTrust(final String fingerprintValue, final TrustOptions options) - throws P4JavaException { + public String addTrust(final String fingerprintValue, final TrustOptions options) throws P4JavaException { RpcConnection rpcConnection = null; try { - rpcConnection = new RpcStreamConnection(serverHost, serverPort, props, serverStats, - p4Charset, secure); + rpcConnection = new RpcStreamConnection(serverHost, serverPort, props, serverStats, p4Charset, secure); TrustOptions opts = ObjectUtils.firstNonNull(options, new TrustOptions()); // Assume '-y' and '-f' options, if specified newFingerprint value. @@ -590,27 +587,19 @@ public String addTrust(final String fingerprintValue, final TrustOptions options PerforceMessages messages = clientTrust.getMessages(); String serverHostPort = getServerHostPort(); Object[] warningParams = {serverHostPort, originalFingerprint}; - String newConnectionWarning = messages.getMessage(CLIENT_TRUST_WARNING_NEW_CONNECTION, - warningParams); + String newConnectionWarning = messages.getMessage(CLIENT_TRUST_WARNING_NEW_CONNECTION, warningParams); String newKeyWarning = messages.getMessage(CLIENT_TRUST_WARNING_NEW_KEY, warningParams); String serverIpPort = rpcConnection.getServerIpPort(); boolean fingerprintExists = fingerprintExists(serverIpPort, FINGERPRINT_USER_NAME); - boolean fingerprintMatches = fingerprintMatches(serverIpPort, FINGERPRINT_USER_NAME, - originalFingerprint); - boolean fingerprintReplaceExists = fingerprintExists(serverIpPort, - FINGERPRINT_REPLACEMENT_USER_NAME); - boolean fingerprintReplaceMatches = fingerprintMatches(serverIpPort, - FINGERPRINT_REPLACEMENT_USER_NAME, originalFingerprint); + boolean fingerprintMatches = fingerprintMatches(serverIpPort, FINGERPRINT_USER_NAME, originalFingerprint); + boolean fingerprintReplaceExists = fingerprintExists(serverIpPort, FINGERPRINT_REPLACEMENT_USER_NAME); + boolean fingerprintReplaceMatches = fingerprintMatches(serverIpPort, FINGERPRINT_REPLACEMENT_USER_NAME, originalFingerprint); boolean fingerprintExistsHost = fingerprintExists(serverHostPort, FINGERPRINT_USER_NAME); - boolean fingerprintMatchesHost = fingerprintMatches(serverHostPort, FINGERPRINT_USER_NAME, - originalFingerprint); - boolean fingerprintReplaceExistsHost = fingerprintExists(serverHostPort, - FINGERPRINT_REPLACEMENT_USER_NAME); - boolean fingerprintReplaceMatchesHost = fingerprintMatches(serverHostPort, - FINGERPRINT_REPLACEMENT_USER_NAME, originalFingerprint); - + boolean fingerprintMatchesHost = fingerprintMatches(serverHostPort, FINGERPRINT_USER_NAME, originalFingerprint); + boolean fingerprintReplaceExistsHost = fingerprintExists(serverHostPort, FINGERPRINT_REPLACEMENT_USER_NAME); + boolean fingerprintReplaceMatchesHost = fingerprintMatches(serverHostPort, FINGERPRINT_REPLACEMENT_USER_NAME, originalFingerprint); // auto refuse if (opts.isAutoRefuse()) { @@ -620,52 +609,42 @@ public String addTrust(final String fingerprintValue, final TrustOptions options } // new key // if (!fingerprintMatches) { - if (!fingerprintMatches && ! fingerprintMatchesHost) { + if (!fingerprintMatches && !fingerprintMatchesHost) { return newKeyWarning; } } // check and use replacement newFingerprint - boolean established = checkAndUseReplacementFingerprint(serverIpPort, - fingerprintExists, fingerprintMatches, - fingerprintReplaceExists, fingerprintReplaceMatches, rpcConnection) ; - boolean establishedHost = checkAndUseReplacementFingerprint(serverHostPort, - fingerprintExists, fingerprintMatches, - fingerprintReplaceExists, fingerprintReplaceMatches, rpcConnection) ; + boolean established = checkAndUseReplacementFingerprint(serverIpPort, fingerprintExists, fingerprintMatches, fingerprintReplaceExists, fingerprintReplaceMatches, rpcConnection); + boolean establishedHost = checkAndUseReplacementFingerprint(serverHostPort, fingerprintExists, fingerprintMatches, fingerprintReplaceExists, fingerprintReplaceMatches, rpcConnection); if (established || establishedHost) { return messages.getMessage(CLIENT_TRUST_ALREADY_ESTABLISHED); } - String fingerprintUser = firstConditionIsTrue(opts.isReplacement(), - FINGERPRINT_REPLACEMENT_USER_NAME, FINGERPRINT_USER_NAME); + String fingerprintUser = firstConditionIsTrue(opts.isReplacement(), FINGERPRINT_REPLACEMENT_USER_NAME, FINGERPRINT_USER_NAME); String newFingerprint = firstNonBlank(fingerprintValue, originalFingerprint); - String trustAddedInfo = messages.getMessage(CLIENT_TRUST_ADDED, - new Object[]{serverHostPort, serverIpPort}); + String trustAddedInfo = messages.getMessage(CLIENT_TRUST_ADDED, new Object[]{serverHostPort, serverIpPort}); // new connection - if (installFingerprintIfNewConnection(fingerprintExists, rpcConnection, opts, - fingerprintUser, newFingerprint)) { + if (installFingerprintIfNewConnection(fingerprintExists, rpcConnection, opts, fingerprintUser, newFingerprint)) { return newConnectionWarning + trustAddedInfo; } // new key - if (installNewFingerprintIfNewKey(fingerprintMatches, rpcConnection, opts, - fingerprintUser, newFingerprint)) { + if (installNewFingerprintIfNewKey(fingerprintMatches, rpcConnection, opts, fingerprintUser, newFingerprint)) { return newKeyWarning + trustAddedInfo; } if (fingerprintMatches && isNotBlank(fingerprintValue)) { // install newFingerprint - int sslClientTrustName = RpcPropertyDefs.getPropertyAsInt(this.props, - RpcPropertyDefs.RPC_SECURE_CLIENT_TRUST_NAME_NICK, - RpcPropertyDefs.RPC_DEFAULT_SECURE_CLIENT_TRUST_NAME ); - if (sslClientTrustName <=1 ) { + int sslClientTrustName = RpcPropertyDefs.getPropertyAsInt(this.props, RpcPropertyDefs.RPC_SECURE_CLIENT_TRUST_NAME_NICK, RpcPropertyDefs.RPC_DEFAULT_SECURE_CLIENT_TRUST_NAME); + if (sslClientTrustName <= 1) { clientTrust.installFingerprint(serverIpPort, fingerprintUser, newFingerprint); } - if ( sslClientTrustName >= 1) { + if (sslClientTrustName >= 1) { clientTrust.installFingerprint(getServerHostPort(), fingerprintUser, newFingerprint); } return trustAddedInfo; @@ -688,11 +667,9 @@ public String removeTrust(final TrustOptions opts) throws P4JavaException { RpcConnection rpcConnection = null; try { - rpcConnection = new RpcStreamConnection(serverHost, serverPort, props, serverStats, - p4Charset, secure); + rpcConnection = new RpcStreamConnection(serverHost, serverPort, props, serverStats, p4Charset, secure); - String fingerprintUser = firstConditionIsTrue(nonNull(opts) && opts.isReplacement(), - FINGERPRINT_REPLACEMENT_USER_NAME, FINGERPRINT_USER_NAME); + String fingerprintUser = firstConditionIsTrue(nonNull(opts) && opts.isReplacement(), FINGERPRINT_REPLACEMENT_USER_NAME, FINGERPRINT_USER_NAME); String message = EMPTY; PerforceMessages messages = clientTrust.getMessages(); @@ -712,14 +689,12 @@ public String removeTrust(final TrustOptions opts) throws P4JavaException { // remove the fingerprint from the trust file if (fingerprintExists(serverIpPort, fingerprintUser)) { clientTrust.removeFingerprint(serverIpPort, fingerprintUser); - message += messages.getMessage(CLIENT_TRUST_REMOVED, - new Object[]{getServerHostPort(), serverIpPort}); + message += messages.getMessage(CLIENT_TRUST_REMOVED, new Object[]{getServerHostPort(), serverIpPort}); } // remove the host entry if (fingerprintExists(getServerHostPort(), fingerprintUser)) { clientTrust.removeFingerprint(getServerHostPort(), fingerprintUser); - message += (message.length()>0 ? " ": "") + messages.getMessage(CLIENT_TRUST_REMOVED, - new Object[]{getServerHostPort(), getServerHostPort()}); + message += (message.length() > 0 ? " " : "") + messages.getMessage(CLIENT_TRUST_REMOVED, new Object[]{getServerHostPort(), getServerHostPort()}); } return message; } finally { @@ -740,8 +715,7 @@ public List getTrusts(final TrustOptions opts) throws P4JavaExcepti List replacementsList = new ArrayList<>(); for (Fingerprint fingerprint : fingerprints) { if (nonNull(fingerprint) && isNotBlank(fingerprint.getUserName())) { - if (FINGERPRINT_REPLACEMENT_USER_NAME - .equalsIgnoreCase(fingerprint.getUserName())) { + if (FINGERPRINT_REPLACEMENT_USER_NAME.equalsIgnoreCase(fingerprint.getUserName())) { replacementsList.add(fingerprint); } else { fingerprintsList.add(fingerprint); @@ -764,8 +738,7 @@ public List getTrusts(final TrustOptions opts) throws P4JavaExcepti * login, etc., are done in the superclass. */ @Override - public void connect() - throws ConnectionException, AccessException, RequestException, ConfigException { + public void connect() throws ConnectionException, AccessException, RequestException, ConfigException { connectionStart = System.currentTimeMillis(); super.connect(); } @@ -781,8 +754,7 @@ public void disconnect() throws ConnectionException, AccessException { super.disconnect(); if (connectionStart != 0) { - Log.stats("RPC connection connected for %s msec elapsed time", - (System.currentTimeMillis() - connectionStart)); + Log.stats("RPC connection connected for %s msec elapsed time", (System.currentTimeMillis() - connectionStart)); } serverStats.logStats(); @@ -827,8 +799,7 @@ public boolean isLoginNotRequired(String msgStr) { } @Override - public boolean supportsSmartMove() - throws ConnectionException, RequestException, AccessException { + public boolean supportsSmartMove() throws ConnectionException, RequestException, AccessException { // Return true iff server version >= 2009.1 // and move command is not disabled on server if (serverVersion < 20091) { @@ -839,16 +810,13 @@ public boolean supportsSmartMove() return nonNull(info) && !info.isMoveDisabled(); } - public ServerStatus init(final String host, final int port, final Properties properties, - final UsageOptions opts, final boolean secure) - throws ConfigException, ConnectionException { + public ServerStatus init(final String host, final int port, final Properties properties, final UsageOptions opts, final boolean secure) throws ConfigException, ConnectionException { super.init(host, port, properties, opts, secure); try { cmdMapArgs = new HashMap<>(); cmdMapArgs.put(ProtocolCommand.RPC_ARGNAME_PROTOCOL_ZTAGS, EMPTY); - relaxCmdNameValidationChecks = getPropertyAsBoolean(properties, - RPC_RELAX_CMD_NAME_CHECKS_NICK, false); + relaxCmdNameValidationChecks = getPropertyAsBoolean(properties, RPC_RELAX_CMD_NAME_CHECKS_NICK, false); applicationName = RpcPropertyDefs.getProperty(properties, RPC_APPLICATION_NAME_NICK); if (isNotBlank(getUsageOptions().getHostName())) { localHostName = getUsageOptions().getHostName(); @@ -856,13 +824,11 @@ public ServerStatus init(final String host, final int port, final Properties pro localHostName = InetAddress.getLocalHost().getHostName(); } - Validate.notBlank(localHostName, - "Null or empty client host name in RPC connection init"); + Validate.notBlank(localHostName, "Null or empty client host name in RPC connection init"); if (!useAuthMemoryStore) { // Search properties for ticket file path, fix for job035376 - ticketsFilePath = getPropertyByKeys(props, TICKET_PATH_KEY_SHORT_FORM, - TICKET_PATH_KEY); + ticketsFilePath = getPropertyByKeys(props, TICKET_PATH_KEY_SHORT_FORM, TICKET_PATH_KEY); // Search environment variable if (isBlank(ticketsFilePath)) { ticketsFilePath = PerforceEnvironment.getP4Tickets(); @@ -885,20 +851,13 @@ public ServerStatus init(final String host, final int port, final Properties pro } serverStats = new ServerStats(); // Auth file lock handling properties - authFileLockTry = getPropertyAsInt(properties, - new String[]{AUTH_FILE_LOCK_TRY_KEY_SHORT_FORM, AUTH_FILE_LOCK_TRY_KEY}, - AbstractAuthHelper.DEFAULT_LOCK_TRY); + authFileLockTry = getPropertyAsInt(properties, new String[]{AUTH_FILE_LOCK_TRY_KEY_SHORT_FORM, AUTH_FILE_LOCK_TRY_KEY}, AbstractAuthHelper.DEFAULT_LOCK_TRY); - authFileLockDelay = getPropertyAsLong(properties, - new String[]{AUTH_FILE_LOCK_DELAY_KEY_SHORT_FORM, AUTH_FILE_LOCK_DELAY_KEY}, - AbstractAuthHelper.DEFAULT_LOCK_DELAY); + authFileLockDelay = getPropertyAsLong(properties, new String[]{AUTH_FILE_LOCK_DELAY_KEY_SHORT_FORM, AUTH_FILE_LOCK_DELAY_KEY}, AbstractAuthHelper.DEFAULT_LOCK_DELAY); - authFileLockWait = getPropertyAsLong(properties, - new String[]{AUTH_FILE_LOCK_WAIT_KEY_SHORT_FORM, AUTH_FILE_LOCK_WAIT_KEY}, - AbstractAuthHelper.DEFAULT_LOCK_WAIT); + authFileLockWait = getPropertyAsLong(properties, new String[]{AUTH_FILE_LOCK_WAIT_KEY_SHORT_FORM, AUTH_FILE_LOCK_WAIT_KEY}, AbstractAuthHelper.DEFAULT_LOCK_WAIT); } catch (UnknownHostException uhe) { - throw new ConfigException( - "Unable to determine client host name: %s" + uhe.getLocalizedMessage()); + throw new ConfigException("Unable to determine client host name: %s" + uhe.getLocalizedMessage()); } // Initialize client trust @@ -908,8 +867,7 @@ public ServerStatus init(final String host, final int port, final Properties pro } @Override - public ServerStatus init(final String host, final int port, final Properties props, - final UsageOptions opts) throws ConfigException, ConnectionException { + public ServerStatus init(final String host, final int port, final Properties props, final UsageOptions opts) throws ConfigException, ConnectionException { return init(host, port, props, opts, false); } @@ -921,26 +879,18 @@ public ServerStatus init(final String host, final int port, final Properties pro * for the connect() call, below. */ @Override - public ServerStatus init(final String host, final int port, final Properties props) - throws ConfigException, ConnectionException { + public ServerStatus init(final String host, final int port, final Properties props) throws ConfigException, ConnectionException { return init(host, port, props, null); } - private boolean checkAndUseReplacementFingerprint(final String serverKey, - final boolean fingerprintExists, - final boolean fingerprintMatches, final boolean fingerprintReplaceExists, - final boolean fingerprintReplaceMatches, final RpcConnection rpcConnection) - throws TrustException { + private boolean checkAndUseReplacementFingerprint(final String serverKey, final boolean fingerprintExists, final boolean fingerprintMatches, final boolean fingerprintReplaceExists, final boolean fingerprintReplaceMatches, final RpcConnection rpcConnection) throws TrustException { - if ((!fingerprintExists || !fingerprintMatches) - && (fingerprintReplaceExists && fingerprintReplaceMatches)) { + if ((!fingerprintExists || !fingerprintMatches) && (fingerprintReplaceExists && fingerprintReplaceMatches)) { // Install/override newFingerprint - clientTrust.installFingerprint(serverKey, FINGERPRINT_USER_NAME, - rpcConnection.getFingerprint()); + clientTrust.installFingerprint(serverKey, FINGERPRINT_USER_NAME, rpcConnection.getFingerprint()); // Remove the replacement - clientTrust.removeFingerprint(serverKey, - FINGERPRINT_REPLACEMENT_USER_NAME); + clientTrust.removeFingerprint(serverKey, FINGERPRINT_REPLACEMENT_USER_NAME); return true; } @@ -953,17 +903,18 @@ private boolean checkAndUseReplacementFingerprint(final String serverKey, * Certificate Validation depends on RPC_SSL_CLIENT_CERT_VALIDATE_NICK. *

* Self-signed certs use only a fingerprint comparison after checking the cert's dates. + * + * @param rpcConnection rpcConnection + * @throws ConnectionException on error */ - public void trustConnectionCheck(final RpcConnection rpcConnection) throws ConnectionException { + public void trustConnectionCheck(final RpcConnection rpcConnection) throws ConnectionException { - int sslCertMethod = RpcPropertyDefs.getPropertyAsInt(this.props, - RpcPropertyDefs.RPC_SECURE_CLIENT_CERT_VALIDATE_NICK, - RpcPropertyDefs.RPC_DEFAULT_SECURE_CLIENT_CERT_VALIDATE); + int sslCertMethod = RpcPropertyDefs.getPropertyAsInt(this.props, RpcPropertyDefs.RPC_SECURE_CLIENT_CERT_VALIDATE_NICK, RpcPropertyDefs.RPC_DEFAULT_SECURE_CLIENT_CERT_VALIDATE); // 0 = fingerprint, 1=chain then fingerprint, 2=hostname check only. if (sslCertMethod < 0 || sslCertMethod > 2) { sslCertMethod = RpcPropertyDefs.RPC_DEFAULT_SECURE_CLIENT_CERT_VALIDATE; } - if ( ! rpcConnection.isSelfSigned() && sslCertMethod == 1 ) { + if (!rpcConnection.isSelfSigned() && rpcConnection.getServerCerts().length >= 2 && sslCertMethod == 1) { // validate the chain. try { ClientTrust.validateServerChain(rpcConnection.getServerCerts(), getServerHostPort().split(":")[0]); @@ -975,31 +926,34 @@ public void trustConnectionCheck(final RpcConnection rpcConnection) throws Conn // TODO: logging? - failure to validate cert chain so fallback to fingerprint. // System.out.println("Fails cert chain: " + ce.getMessage()); } - - } else if (! rpcConnection.isSelfSigned() && sslCertMethod == 2) { + } else if (!rpcConnection.isSelfSigned() && rpcConnection.getServerCerts().length >= 2 && sslCertMethod == 2) { // validate the P4PORT matches the CN. X509Certificate[] certs = rpcConnection.getServerCerts(); try { ClientTrust.verifyCertificateSubject(certs[0], this.serverHost); - validatedByHostname = true ; + validatedByHostname = true; return; } catch (Exception e) { - // TODO: logging - requested a subject match verification but didn't match. + // TODO: logging - requested a subject match verification but didn't match. } } checkFingerprint(rpcConnection); validatedByFingerprint = rpcConnection.isTrusted(); } + /** * Check the fingerprint of the Perforce server SSL connection + * + * @param rpcConnection rpcConnection + * @throws ConnectionException on error */ protected void checkFingerprint(final RpcConnection rpcConnection) throws ConnectionException { if (nonNull(rpcConnection) && rpcConnection.isSecure() && !rpcConnection.isTrusted()) { try { - if (rpcConnection.getServerCerts() .length > 0) { + if (rpcConnection.getServerCerts().length > 0) { ClientTrust.verifyCertificateDates(rpcConnection.getServerCerts()[0]); } } catch (CertificateException e) { @@ -1007,58 +961,45 @@ protected void checkFingerprint(final RpcConnection rpcConnection) throws Connec } String fingerprint = rpcConnection.getFingerprint(); - throwConnectionExceptionIfConditionFails(isNotBlank(fingerprint), - "Null fingerprint for this Perforce SSL connection"); + throwConnectionExceptionIfConditionFails(isNotBlank(fingerprint), "Null fingerprint for this Perforce SSL connection"); // look for IP in trust file String serverIpPort = rpcConnection.getServerIpPort(); boolean fingerprintExists = fingerprintExists(serverIpPort, FINGERPRINT_USER_NAME); - boolean fingerprintReplaceExist = fingerprintExists(serverIpPort, - FINGERPRINT_REPLACEMENT_USER_NAME); + boolean fingerprintReplaceExist = fingerprintExists(serverIpPort, FINGERPRINT_REPLACEMENT_USER_NAME); - boolean fingerprintMatches = clientTrust.fingerprintMatches(serverIpPort, - FINGERPRINT_USER_NAME, fingerprint); - boolean fingerprintReplaceMatches = fingerprintMatches(serverIpPort, - FINGERPRINT_REPLACEMENT_USER_NAME, fingerprint); + boolean fingerprintMatches = clientTrust.fingerprintMatches(serverIpPort, FINGERPRINT_USER_NAME, fingerprint); + boolean fingerprintReplaceMatches = fingerprintMatches(serverIpPort, FINGERPRINT_REPLACEMENT_USER_NAME, fingerprint); - boolean isNotEstablished = (!fingerprintExists && !fingerprintReplaceExist) - || (!fingerprintExists && !fingerprintReplaceMatches); + boolean isNotEstablished = (!fingerprintExists && !fingerprintReplaceExist) || (!fingerprintExists && !fingerprintReplaceMatches); // look for host:port in trust file String serverHost = getServerHostPort(); boolean fingerprintExistsHost = fingerprintExists(serverHost, FINGERPRINT_USER_NAME); - boolean fingerprintReplaceExistHost = fingerprintExists(serverHost, - FINGERPRINT_REPLACEMENT_USER_NAME); + boolean fingerprintReplaceExistHost = fingerprintExists(serverHost, FINGERPRINT_REPLACEMENT_USER_NAME); - boolean fingerprintMatchesHost = clientTrust.fingerprintMatches(serverHost, - FINGERPRINT_USER_NAME, fingerprint); - boolean fingerprintReplaceMatchesHost = fingerprintMatches(serverHost, - FINGERPRINT_REPLACEMENT_USER_NAME, fingerprint); + boolean fingerprintMatchesHost = clientTrust.fingerprintMatches(serverHost, FINGERPRINT_USER_NAME, fingerprint); + boolean fingerprintReplaceMatchesHost = fingerprintMatches(serverHost, FINGERPRINT_REPLACEMENT_USER_NAME, fingerprint); - boolean isNotEstablishedHost = (!fingerprintExistsHost && !fingerprintReplaceExistHost) - || (!fingerprintExistsHost && !fingerprintReplaceMatchesHost); + boolean isNotEstablishedHost = (!fingerprintExistsHost && !fingerprintReplaceExistHost) || (!fingerprintExistsHost && !fingerprintReplaceMatchesHost); // first check: is either IP or host found? - throwTrustExceptionIfConditionIsTrue(isNotEstablished && isNotEstablishedHost, rpcConnection, NEW_CONNECTION, - CLIENT_TRUST_WARNING_NOT_ESTABLISHED, CLIENT_TRUST_EXCEPTION_NEW_CONNECTION); + throwTrustExceptionIfConditionIsTrue(isNotEstablished && isNotEstablishedHost, rpcConnection, NEW_CONNECTION, CLIENT_TRUST_WARNING_NOT_ESTABLISHED, CLIENT_TRUST_EXCEPTION_NEW_CONNECTION); boolean isNewKey = (!fingerprintMatches && !fingerprintReplaceMatches); boolean isNewKeyHost = (!fingerprintMatchesHost && !fingerprintReplaceMatchesHost); - throwTrustExceptionIfConditionIsTrue(isNewKey && isNewKeyHost, rpcConnection, NEW_KEY, - CLIENT_TRUST_WARNING_NEW_KEY, CLIENT_TRUST_EXCEPTION_NEW_KEY); + throwTrustExceptionIfConditionIsTrue(isNewKey && isNewKeyHost, rpcConnection, NEW_KEY, CLIENT_TRUST_WARNING_NEW_KEY, CLIENT_TRUST_EXCEPTION_NEW_KEY); // Use replacement fingerprint for serverIP - if ((!fingerprintExists || !fingerprintMatches) - && (fingerprintReplaceExist && fingerprintReplaceMatches)) { + if ((!fingerprintExists || !fingerprintMatches) && (fingerprintReplaceExist && fingerprintReplaceMatches)) { // Install/override fingerprint clientTrust.installFingerprint(serverIpPort, FINGERPRINT_USER_NAME, fingerprint); // Remove the replacement clientTrust.removeFingerprint(serverIpPort, FINGERPRINT_REPLACEMENT_USER_NAME); } // Use replacement fingerprint for hostname - if ((!fingerprintExistsHost || !fingerprintMatchesHost) - && (fingerprintReplaceExistHost && fingerprintReplaceMatchesHost)) { + if ((!fingerprintExistsHost || !fingerprintMatchesHost) && (fingerprintReplaceExistHost && fingerprintReplaceMatchesHost)) { // Install/override fingerprint clientTrust.installFingerprint(serverHost, FINGERPRINT_USER_NAME, fingerprint); // Remove the replacement @@ -1074,23 +1015,18 @@ private boolean fingerprintExists(final String serverIpPort, final String finger return clientTrust.fingerprintExists(serverIpPort, fingerprintUser); } - private boolean fingerprintMatches(final String serverIpPort, final String fingerprintUser, - final String fingerprint) { + private boolean fingerprintMatches(final String serverIpPort, final String fingerprintUser, final String fingerprint) { return clientTrust.fingerprintMatches(serverIpPort, fingerprintUser, fingerprint); } - private void throwTrustExceptionIfConditionIsTrue(final boolean expression, - final RpcConnection rpcConnection, final TrustException.Type type, - final String warningMessageKey, final String exceptionMessageKey) - throws TrustException { + private void throwTrustExceptionIfConditionIsTrue(final boolean expression, final RpcConnection rpcConnection, final TrustException.Type type, final String warningMessageKey, final String exceptionMessageKey) throws TrustException { if (expression) { throwTrustException(rpcConnection, type, warningMessageKey, exceptionMessageKey); } } - private void closeQuietly(@Nullable final RpcConnection rpcConnection) - throws ConnectionException { + private void closeQuietly(@Nullable final RpcConnection rpcConnection) throws ConnectionException { if (nonNull(rpcConnection)) { rpcConnection.disconnect(null); } @@ -1098,13 +1034,15 @@ private void closeQuietly(@Nullable final RpcConnection rpcConnection) /** * Compose the key for an auth ticket entry + * + * @param userName userName + * @param serverAddress serverAddress + * @return key */ protected String composeAuthTicketEntryKey(final String userName, final String serverAddress) { - Validate.notBlank(userName, - "Null userName passed to the composeAuthTicketEntryKey method."); - Validate.notBlank(serverAddress, - "Null serverAddress passed to the composeAuthTicketEntryKey method."); + Validate.notBlank(userName, "Null userName passed to the composeAuthTicketEntryKey method."); + Validate.notBlank(serverAddress, "Null serverAddress passed to the composeAuthTicketEntryKey method."); String wellFormedServerAddress = serverAddress; @@ -1136,8 +1074,7 @@ protected String getLanguageForEnv() { protected String getOsTypeForEnv() { String osName = System.getProperty(RPC_ENV_OS_NAME_KEY); - if (isNotBlank(osName) - && osName.toLowerCase(Locale.ENGLISH).contains(RPC_ENV_WINDOWS_PREFIX)) { + if (isNotBlank(osName) && osName.toLowerCase(Locale.ENGLISH).contains(RPC_ENV_WINDOWS_PREFIX)) { return RPC_ENV_WINDOWS_SPEC; } @@ -1148,17 +1085,17 @@ protected String getOsTypeForEnv() { * Get the RPC packet field rule for skipping the charset conversion of a * range of RPC packet fields; leave the values as bytes. *

- *

* Note: currently only supporting the "export" command. + * + * @param inMap inMap + * @param cmdSpec cmdSpec + * @return RpcPacketFieldRule */ - protected RpcPacketFieldRule getRpcPacketFieldRule(final Map inMap, - final CmdSpec cmdSpec) { + protected RpcPacketFieldRule getRpcPacketFieldRule(final Map inMap, final CmdSpec cmdSpec) { if (nonNull(inMap) && nonNull(cmdSpec)) { - if (cmdSpec == CmdSpec.EXPORT && inMap.containsKey(cmdSpec.toString()) - && (inMap.get(cmdSpec.toString()) instanceof Map)) { - @SuppressWarnings("unchecked") - Map cmdMap = (Map) inMap.remove(cmdSpec.toString()); + if (cmdSpec == CmdSpec.EXPORT && inMap.containsKey(cmdSpec.toString()) && (inMap.get(cmdSpec.toString()) instanceof Map)) { + @SuppressWarnings("unchecked") Map cmdMap = (Map) inMap.remove(cmdSpec.toString()); if (nonNull(cmdMap)) { return RpcPacketFieldRule.getInstance(cmdMap); } @@ -1196,54 +1133,41 @@ protected String getUserForEnv() { return getUsageOptions().getUnsetUserName(); } - private boolean installFingerprintIfNewConnection(final boolean fingerprintExists, - final RpcConnection rpcConnection, final TrustOptions trustOptions, - final String fingerprintUser, final String newFingerprint) throws TrustException { + private boolean installFingerprintIfNewConnection(final boolean fingerprintExists, final RpcConnection rpcConnection, final TrustOptions trustOptions, final String fingerprintUser, final String newFingerprint) throws TrustException { if (!fingerprintExists) { - if (installNewFingerprintIfIsAutoAccept(rpcConnection, trustOptions, fingerprintUser, - newFingerprint)) { + if (installNewFingerprintIfIsAutoAccept(rpcConnection, trustOptions, fingerprintUser, newFingerprint)) { return true; } // didn't accept - throwTrustException(rpcConnection, NEW_CONNECTION, CLIENT_TRUST_WARNING_NEW_CONNECTION, - CLIENT_TRUST_ADD_EXCEPTION_NEW_CONNECTION); + throwTrustException(rpcConnection, NEW_CONNECTION, CLIENT_TRUST_WARNING_NEW_CONNECTION, CLIENT_TRUST_ADD_EXCEPTION_NEW_CONNECTION); } return false; } - private boolean installNewFingerprintIfNewKey(final boolean fingerprintMatches, - final RpcConnection rpcConnection, final TrustOptions trustOptions, - final String fingerprintUser, final String newFingerprint) throws TrustException { + private boolean installNewFingerprintIfNewKey(final boolean fingerprintMatches, final RpcConnection rpcConnection, final TrustOptions trustOptions, final String fingerprintUser, final String newFingerprint) throws TrustException { if (!fingerprintMatches) { // force install if (trustOptions.isForce()) { - if (installNewFingerprintIfIsAutoAccept(rpcConnection, trustOptions, - fingerprintUser, newFingerprint)) { + if (installNewFingerprintIfIsAutoAccept(rpcConnection, trustOptions, fingerprintUser, newFingerprint)) { return true; } } // didn't accept / not force install - throwTrustException(rpcConnection, NEW_KEY, CLIENT_TRUST_WARNING_NEW_KEY, - CLIENT_TRUST_ADD_EXCEPTION_NEW_KEY); + throwTrustException(rpcConnection, NEW_KEY, CLIENT_TRUST_WARNING_NEW_KEY, CLIENT_TRUST_ADD_EXCEPTION_NEW_KEY); } return false; } - private boolean installNewFingerprintIfIsAutoAccept(final RpcConnection rpcConnection, - final TrustOptions trustOptions, final String fingerprintUser, - final String newFingerprint) throws TrustException { + private boolean installNewFingerprintIfIsAutoAccept(final RpcConnection rpcConnection, final TrustOptions trustOptions, final String fingerprintUser, final String newFingerprint) throws TrustException { if (trustOptions.isAutoAccept()) { - int sslClientTrustName = RpcPropertyDefs.getPropertyAsInt(this.props, - RpcPropertyDefs.RPC_SECURE_CLIENT_TRUST_NAME_NICK, - RpcPropertyDefs.RPC_DEFAULT_SECURE_CLIENT_TRUST_NAME ); + int sslClientTrustName = RpcPropertyDefs.getPropertyAsInt(this.props, RpcPropertyDefs.RPC_SECURE_CLIENT_TRUST_NAME_NICK, RpcPropertyDefs.RPC_DEFAULT_SECURE_CLIENT_TRUST_NAME); // install newFingerprint if (sslClientTrustName == 0 || sslClientTrustName == 1) { - clientTrust.installFingerprint(rpcConnection.getServerIpPort(), fingerprintUser, - newFingerprint); + clientTrust.installFingerprint(rpcConnection.getServerIpPort(), fingerprintUser, newFingerprint); } if (sslClientTrustName == 1 || sslClientTrustName == 2) { String serverHostNamePort = rpcConnection.getServerHostNamePort(); @@ -1257,16 +1181,12 @@ private boolean installNewFingerprintIfIsAutoAccept(final RpcConnection rpcConne return false; } - private void throwTrustException(final RpcConnection rpcConnection, - final TrustException.Type type, final String warningMessageKey, - final String exceptionMessageKey) throws TrustException { + private void throwTrustException(final RpcConnection rpcConnection, final TrustException.Type type, final String warningMessageKey, final String exceptionMessageKey) throws TrustException { Object[] warningParams = {getServerHostPort(), rpcConnection.getFingerprint()}; - String warningMessage = clientTrust.getMessages().getMessage(warningMessageKey, - warningParams); + String warningMessage = clientTrust.getMessages().getMessage(warningMessageKey, warningParams); String exceptionMessage = clientTrust.getMessages().getMessage(exceptionMessageKey); - throw new TrustException(type, getServerHostPort(), rpcConnection.getServerIpPort(), - rpcConnection.getFingerprint(), warningMessage + exceptionMessage); + throw new TrustException(type, getServerHostPort(), rpcConnection.getServerIpPort(), rpcConnection.getFingerprint(), warningMessage + exceptionMessage); } /** @@ -1277,6 +1197,8 @@ private void throwTrustException(final RpcConnection rpcConnection, * the standard p4trust file location for the current OS. Will return null * if not found or if an error occurred attempt to lookup the value. * + * @param serverKey serverKey + * @param fingerprintUser fingerprintUser * @return - fingerprint or null if not found. */ public Fingerprint loadFingerprint(final String serverKey, final String fingerprintUser) { @@ -1287,8 +1209,7 @@ public Fingerprint loadFingerprint(final String serverKey, final String fingerpr Fingerprint fingerprint = null; try { - fingerprint = FingerprintsHelper.getFingerprint(fingerprintUser, serverKey, - trustFilePath); + fingerprint = FingerprintsHelper.getFingerprint(fingerprintUser, serverKey, trustFilePath); } catch (IOException e) { Log.error(e.getMessage()); } @@ -1324,6 +1245,7 @@ public Fingerprint[] loadFingerprints() { * or the standard p4tickets file location for the current OS. Will return * null if not found or if an error occurred attempt to lookup the value. * + * @param serverId serverId * @return - ticket value to get used for {@link #setAuthTicket(String)} or * null if not found. */ @@ -1340,6 +1262,8 @@ public String loadTicket(final String serverId) { * or the standard p4tickets file location for the current OS. Will return * null if not found or if an error occurred attempt to lookup the value. * + * @param serverId serverId + * @param name name * @return - ticket value to get used for {@link #setAuthTicket(String)} or * null if not found. */ @@ -1359,16 +1283,14 @@ public String loadTicket(String serverId, String name) { private String quietGetTicketValue(final String userName, final String serverOrServerId) { String ticketValue = null; try { - ticketValue = AuthTicketsHelper.getTicketValue(userName, serverOrServerId, - ticketsFilePath); + ticketValue = AuthTicketsHelper.getTicketValue(userName, serverOrServerId, ticketsFilePath); } catch (IOException ignore) { } return ticketValue; } - protected void processCmdCallbacks(final int cmdCallBackKey, final long timeTaken, - final List> resultMaps) { + protected void processCmdCallbacks(final int cmdCallBackKey, final long timeTaken, final List> resultMaps) { commandCallback.completedServerCommand(cmdCallBackKey, timeTaken); if (nonNull(resultMaps)) { @@ -1438,6 +1360,8 @@ public String getAuthId() { /** * Save current ticket returned from {@link #getAuthTicket()}. + * + * @throws P4JavaException on error * @deprecated use {@link com.perforce.p4java.impl.mapbased.rpc.RpcServer#saveTicket(String, String, String)} */ @Deprecated @@ -1451,6 +1375,9 @@ public void saveCurrentTicket() throws P4JavaException { * attempt to write an entry to the p4tickets file either specified as the * P4TICKETS environment variable or at the OS specific default location. If * the ticket value is null then the current entry in the will be cleared. + * + * @param ticketValue ticketValue + * @throws ConfigException on error * @deprecated use {@link com.perforce.p4java.impl.mapbased.rpc.RpcServer#saveTicket(String, String, String)} */ @Deprecated @@ -1464,9 +1391,13 @@ public void saveTicket(String ticketValue) throws ConfigException { * as the P4TRUST environment variable or at the OS specific default * location. If the fingerprint value is null then the current entry will be * cleared. + * + * @param serverIpPort serverIpPort + * @param fingerprintUser fingerprintUser + * @param fingerprintValue fingerprintValue + * @throws ConfigException on error */ - public void saveFingerprint(final String serverIpPort, final String fingerprintUser, - final String fingerprintValue) throws ConfigException { + public void saveFingerprint(final String serverIpPort, final String fingerprintUser, final String fingerprintValue) throws ConfigException { if (isBlank(serverIpPort) || isBlank(fingerprintUser)) { return; @@ -1474,8 +1405,7 @@ public void saveFingerprint(final String serverIpPort, final String fingerprintU // Save the fingerprint by server IP and port try { - FingerprintsHelper.saveFingerprint(fingerprintUser, serverIpPort, fingerprintValue, - trustFilePath, authFileLockTry, authFileLockDelay, authFileLockWait); + FingerprintsHelper.saveFingerprint(fingerprintUser, serverIpPort, fingerprintValue, trustFilePath, authFileLockTry, authFileLockDelay, authFileLockWait); } catch (IOException e) { throw new ConfigException(e); } @@ -1487,13 +1417,17 @@ public void saveFingerprint(final String serverIpPort, final String fingerprintU * entry to the p4tickets file either specified as the P4TICKETS environment * variable or at the OS specific default location. If the ticket value is * null then the current entry will be cleared. + * + * @param userName userName + * @param serverId serverId + * @param ticketValue ticketValue + * @throws ConfigException on error */ public void saveTicket(final String userName, final String serverId, final String ticketValue) throws ConfigException { String lowerCaseableUserName = getLowerCaseableUserName(userName); String serId = isNotBlank(serverId) ? serverId : getServerId(); // Try to save the ticket by server id first if set - ConfigException exception = quietSaveTicket(serId, lowerCaseableUserName, ticketValue, - null); + ConfigException exception = quietSaveTicket(serId, lowerCaseableUserName, ticketValue, null); // If id is null try to use configured server address // If ticket value is null try to clear out any old values by the @@ -1513,6 +1447,9 @@ public void saveTicket(final String userName, final String serverId, final Strin /** * Must downcase the username to find or save a ticket when connected to a * case insensitive server. + * + * @param userName userName + * @return username */ private String getLowerCaseableUserName(final String userName) { String lowerCaseableUserName = userName; @@ -1524,14 +1461,11 @@ private String getLowerCaseableUserName(final String userName) { } @Nullable - private ConfigException quietSaveTicket(final String serverOrServerId, - final String lowerCaseUserName, final String ticketValue, - @Nullable final ConfigException exception) { + private ConfigException quietSaveTicket(final String serverOrServerId, final String lowerCaseUserName, final String ticketValue, @Nullable final ConfigException exception) { if (isNotBlank(serverOrServerId)) { try { - AuthTicketsHelper.saveTicket(lowerCaseUserName, serverOrServerId, ticketValue, - ticketsFilePath, authFileLockTry, authFileLockDelay, authFileLockWait); + AuthTicketsHelper.saveTicket(lowerCaseUserName, serverOrServerId, ticketValue, ticketsFilePath, authFileLockTry, authFileLockDelay, authFileLockWait); } catch (IOException e) { if (nonNull(exception)) { exception.addSuppressed(e); @@ -1570,15 +1504,18 @@ public void setPbuf(final String userName, final String pBuf) { * a few commands are anomalous as far as we can tell), but may find more * uses generally with experience. *

- * . - *

* This is normally used on a per-command (OneShot RPC server) basis. In * order to use this on a per-session (NTS RPC server) implementation you * must resend the RPC protocol, if the 'useTags' state has changed, prior * to sending the command. + * + * @param cmdName cmdName + * @param cmdArgs cmdArgs + * @param inMap inMap + * @param isStreamCmd isStreamCmd + * @return RPC_TAGS_USED | false */ - protected boolean useTags(String cmdName, String[] cmdArgs, Map inMap, - boolean isStreamCmd) { + protected boolean useTags(String cmdName, String[] cmdArgs, Map inMap, boolean isStreamCmd) { CmdSpec cmdSpec = getValidP4JCmdSpec(cmdName); if (nonNull(cmdSpec)) { @@ -1607,21 +1544,17 @@ protected boolean useTags(String cmdName, String[] cmdArgs, Map } /** - * Return true if we should be performing server -> client file write I/O + * Return true if we should be performing server -> client file write I/O * operations in place for this command. *

- *

* See PropertyDefs.WRITE_IN_PLACE_KEY javadoc for the semantics of this. * * @param cmdName non-null command command name string * @return true iff we should do a sync in place */ protected boolean writeInPlace(String cmdName) { - String writeInPlaceKeyPropertyValue = System.getProperty(WRITE_IN_PLACE_KEY, - props.getProperty(WRITE_IN_PLACE_SHORT_FORM, "false")); + String writeInPlaceKeyPropertyValue = System.getProperty(WRITE_IN_PLACE_KEY, props.getProperty(WRITE_IN_PLACE_SHORT_FORM, "false")); - return cmdName.equalsIgnoreCase(CmdSpec.SYNC.toString()) - && Boolean.valueOf(writeInPlaceKeyPropertyValue); + return cmdName.equalsIgnoreCase(CmdSpec.SYNC.toString()) && Boolean.valueOf(writeInPlaceKeyPropertyValue); } - } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/connection/RpcConnection.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/connection/RpcConnection.java index 9af3ada..b022437 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/connection/RpcConnection.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/connection/RpcConnection.java @@ -43,7 +43,6 @@ * RpcStreamConnection, which implements the connection using java.io streams on * top of sockets. *

- * * Note that charset conversion should never be necessary on connections to * non-Unicode servers, as any bytes in the incoming stream that are marked as * "text" should be interpreted as ASCII (seven or eight bits). Unfortunately, @@ -56,13 +55,11 @@ * -- all conversions must be with an explicit charset in case the JVM's charset * isn't the one we actually need. *

- * * Note that, in general, we "know" that the Perforce server on the other end of * this connection is -- or should be -- a Unicode server by the fact that the * incoming clientCharset is not null. This probably isn't infallible, but it's * supposed to be true, so we use it as a proxy for IServer.supportsUnicode(). *

- * * See * http://computer.perforce.com/newwiki/index.php?title=P4Java_and_Charset_Support * for a detailed discussion of P4Java and server charset issues... @@ -70,521 +67,520 @@ public abstract class RpcConnection { - public static final String TRACE_PREFIX = "RpcConnection"; - - /** - * The charset used internally by a Perforce Unicode-enabled server. If a - * server is Unicode-enabled, then every non-binary RPC packet field - * is sent to and received from the Perforce server in this charset. - *

- * - * Do not change this unless you want all hell to break loose. - */ - public static final Charset UNICODE_SERVER_CHARSET = CharsetDefs.UTF8; - - /** - * The name of the assumed Unicode server internal charset. Do not change - * this either. - */ - public static final String UNICODE_SERVER_CHARSET_NAME = CharsetDefs.UTF8_NAME; - - /** - * Charset assumed when the server is non in Unicode mode. Do not change - * this field, either, unless you want problems... - */ - public static final Charset NON_UNICODE_SERVER_CHARSET = CharsetDefs.DEFAULT; - - /** - * The name of the assumed non-Unicode server charset. Do not change this - * either. - */ - public static final String NON_UNICODE_SERVER_CHARSET_NAME = CharsetDefs.DEFAULT_NAME; - - protected static final String UNKNOWN_SERVER_HOST = null; - protected static final int UNKNOWN_SERVER_PORT = -1; - - protected Properties props = null; - protected RpcConnectionFlowControl flowController = new RpcConnectionFlowControl(); - - protected ServerStats stats = null; - - protected P4Charset p4Charset = null; - - protected String hostIp = UNKNOWN_SERVER_HOST; - protected String ourIp = UNKNOWN_SERVER_HOST; - protected String hostName = UNKNOWN_SERVER_HOST; - protected int hostPort = UNKNOWN_SERVER_PORT; - protected int ourPort = UNKNOWN_SERVER_PORT; - protected boolean usingCompression = false; - - protected boolean unicodeServer = false; - - protected boolean secure = false; - protected String fingerprint = null; - protected boolean trusted = false; - protected Certificate[] serverCerts = null; - - public X509Certificate[] getServerCerts() { - X509Certificate[] certs; - if ( serverCerts != null) { - certs = new X509Certificate[serverCerts.length]; - for (int i = 0; i < certs.length; i++) { - certs[i] = (X509Certificate) serverCerts[i]; - } - } else { - certs = new X509Certificate[0]; - } - return certs; - } - protected boolean selfSigned = true; - public boolean isSelfSigned() { - return selfSigned; - } - - /** - * Create a Perforce RPC connection to a given host and port number pair. - *

- * - * This method will also implicitly connect to the server. Note that new - * connections are never using connection compression -- this has to come as - * an explicit command from the server after the connection has been - * established. - * - * @param serverHost - * non-null Perforce server host name or IP address. - * @param serverPort - * Perforce server host port number. - * @param props - * if not null, use the Properties for any connection- or - * implementation-specific values (such as buffer sizes, etc.). - * @param stats - * if not null, attempt to fill in these connection stats - * appropriately. - * @param p4Charset - * if non-null, sets the connection's idea of what the current - * client charset is. If null, CharsetDefs.DEFAULT is used. - * @throws ConnectionException - * if any user-reportable error occurred under the covers. - */ - public RpcConnection(String serverHost, int serverPort, Properties props, ServerStats stats, - P4Charset p4Charset) throws ConnectionException { - - this(serverHost, serverPort, props, stats, p4Charset, false); - } - - /** - * Create a Perforce RPC connection to a given host and port number pair. - *

- * - * This method will also implicitly connect to the server. Note that new - * connections are never using connection compression -- this has to come as - * an explicit command from the server after the connection has been - * established. - * - * @param serverHost - * non-null Perforce server host name or IP address. - * @param serverPort - * Perforce server host port number. - * @param props - * if not null, use the Properties for any connection- or - * implementation-specific values (such as buffer sizes, etc.). - * @param stats - * if not null, attempt to fill in these connection stats - * appropriately. - * @param p4Charset - * if non-null, sets the connection's idea of what the current - * client charset is. If null, CharsetDefs.DEFAULT is used. - * @param secure - * indicate whether the connection is secure (SSL) or not. - * @throws ConnectionException - * if any user-reportable error occurred under the covers. - */ - public RpcConnection(@Nonnull String serverHost, int serverPort, Properties props, - ServerStats stats, P4Charset p4Charset, boolean secure) throws ConnectionException { - - this.hostName = Validate.notNull(serverHost); - this.hostPort = serverPort; - this.secure = secure; - this.p4Charset = firstNonNull(p4Charset, P4Charset.getDefault()); - this.stats = firstNonNull(stats, new ServerStats()); - this.props = firstNonNull(props, new Properties()); - this.stats.serverConnections.incrementAndGet(); - this.unicodeServer = P4Charset.isUnicodeServer(p4Charset); // Note: NOT this.p4Charset.getCharset().... - } - - /** - * Get the server's IP and port used for the RPC connection. - * - * @return - possibly null server IP and port - */ - public abstract String getServerIpPort(); - - public abstract String getServerHostNamePort(); - - /** - * Get the client's IP and port used for the RPC connection. - * - * @return - possibly null client IP and port - */ - public abstract String getClientIpPort(); - - /** - * Disconnect this server. Assumes the connection is quiescent -- no further - * sends or receives will be possible after this call, and only the output - * stream is flushed (no attempt is made to look at anything still on the - * wire coming in to the socket). - */ - public abstract void disconnect(RpcPacketDispatcher dispatcher) throws ConnectionException; - - /** - * Put a Perforce RPC packet onto the output stream. The implementing method - * must make the appropriate charset translations and any other client- or - * server- (or whatever-) specific processing on the passed-in packet. - *

- * - * Returns the number of bytes actually sent to the Perforce server, which - * may not bear any relationship at all to the size of the passed-in packet. - */ - public abstract long putRpcPacket(RpcPacket rpcPacket) throws ConnectionException; - - /** - * Put an array of RPC packets. A convenience method wrapping - * putRpcPacket(packet) in the obvious way. - */ - - public abstract long putRpcPackets(RpcPacket[] rpcPackets) throws ConnectionException; - - /** - * Get the next RPC packet from the receive queue. The implementing method - * must make the appropriate charset translations and any other client- or - * server- (or whatever-) specific processing on the packet returned from - * this method by the time it's returned. - *

- * - * Will wait until either a timeout occurs (if the stream's been set up - * appropriately), the underlying stream returns EOF or error, or we get a - * complete packet. - *

- */ - - public abstract RpcPacket getRpcPacket() throws ConnectionException; - - /** - * Get the next RPC packet from the receive queue with an optional rule to - * handle the RPC packet fields. - */ - public abstract RpcPacket getRpcPacket(RpcPacketFieldRule fieldRule, - IFilterCallback filterCallback) throws ConnectionException; - - /** - * Return the system (i.e. underlying implementation) send buffer size. - */ - - public abstract int getSystemSendBufferSize(); - - /** - * Return the system (i.e. underlying implementation) receive buffer size. - */ - - public abstract int getSystemRecvBufferSize(); - - /** - * Marshal a packet field into a key value byte array pair. This must - * respect the relevant charset settings, which can be a little - * counter-intuitive or confusing. - */ - public byte[] marshalPacketField(String key, Object value) { - - // Note: either key or value can be (and often are) null, but it's rare - // for - // both to be null. But it happens... - - // Note: this could easily be improved on for performance by tuning the - // copies; the - // implementation here is to get something that works first... - - byte[] retBytes = null; - byte[] keyBytes = null; - byte[] valBytes = null; - byte[] valLengthBytes = null; - - if (key != null) { - keyBytes = getNormalizedBytes(key); - } - - valBytes = marshalPacketValue(value); - - valLengthBytes = RpcPacket.encodeInt4(valBytes == null ? 0 : valBytes.length); - - // Calculate the resulting field length, in bytes. Note that there's - // a null byte after each sub field, hence the "2 +" here. - - int fieldLength = 2 + (keyBytes == null ? 0 : keyBytes.length) + valLengthBytes.length - + (valBytes == null ? 0 : valBytes.length); - - retBytes = new byte[fieldLength]; - int retBytesPos = 0; - - if (keyBytes != null) { - System.arraycopy(keyBytes, 0, retBytes, retBytesPos, keyBytes.length); - retBytesPos += keyBytes.length; - } - retBytes[retBytesPos++] = 0; - - System.arraycopy(valLengthBytes, 0, retBytes, retBytesPos, valLengthBytes.length); - retBytesPos += valLengthBytes.length; - - if (valBytes != null) { - System.arraycopy(valBytes, 0, retBytes, retBytesPos, valBytes.length); - retBytesPos += valBytes.length; - } - retBytes[retBytesPos++] = 0; - - return retBytes; - } - - /** - * Marshal a packet field value onto a byte array and return that array. - *

- * - * For strings and similar types (e.g. StringBuilder, StringBuffer), we may - * need to do a translation to the server charset (normally UTF-8) before - * enbyteifying the underlying value. Other field types are sent as-is, and - * are assumed to have been encoded properly upstream (and are almost always - * just file contents). - *

- * - * Note: if the value object passed in is a ByteBuffer, it must have been - * flipped ready for use; this method will (of course) have predictable side - * effects on that ByteBuffer. - */ - protected byte[] marshalPacketValue(Object value) { - - byte[] valBytes = null; - - try { - if (value != null) { - if (value.getClass() == String.class) { - valBytes = getNormalizedBytes((String) value); - } else if (value instanceof byte[]) { - valBytes = (byte[]) value; - } else if (value instanceof StringBuffer) { - valBytes = getNormalizedBytes(value.toString()); - } else if (value instanceof ByteBuffer) { - int valLength = ((ByteBuffer) value).limit(); - valBytes = new byte[valLength]; - ((ByteBuffer) value).get(valBytes); - } else { - throw new P4JavaError( - "Unmarshalable value in RpcStreamConnection.marshal; type: " - + value.getClass().getCanonicalName()); - } - } - } catch (P4JavaError p4jerr) { - throw p4jerr; - } catch (Throwable thr) { - Log.error("Unexpected exception in RpcStreamConnection.marshalValue: " - + thr.getLocalizedMessage()); - Log.exception(thr); - throw new P4JavaError("Unexpected exception in RpcStreamConnection.marshalValue: " - + thr.getLocalizedMessage()); - } - - return valBytes; - } - - /** - * If called, will set this connection to use (GZIP) compression for all - * traffic on this connection from this point on. Can not be turned back off - * again. See the main P4 help documentation (and C++ API code) for "client - * compression" (etc.) for details. - */ - public void useConnectionCompression() throws ConnectionException { - if (!usingCompression) { - this.usingCompression = true; - } - } - - /** - * Encode the passed-in string properly for the server. If the server is - * Unicode-enabled, this usually means converting to UTF-8 encoding for the - * stream. This can be a very CPU-intensive process... - *

- * - * FIXME: use proper encoding / decoding with error handling -- HR. - * - * @return - normalized string - */ - protected byte[] getNormalizedBytes(String str) { - if (str == null) { - throw new NullPointerError("null string passed to RpcConnection.getNormalizedBytes"); - } - try { - if (this.unicodeServer) { - return str.getBytes(UNICODE_SERVER_CHARSET_NAME); - } else { - return str.getBytes(this.p4Charset.getCharset().name()); - } - } catch (UnsupportedEncodingException e) { - // This should never be reached since we already have the Charset - // object needed. - Log.exception(e); - } - return null; - } - - /** - * Decode the passed-in bytes from the server into a suitable string. In - * general, bytes from the server will be in ASCII (non-Unicode servers) or - * UTF-8 (Unicode servers), but there are exceptions. - *

- * - * FIXME: use proper encoding / decoding with error handling -- HR. - * - * @return - normalized string - */ - protected String getNormalizedString(byte[] bytes) { - if (bytes == null) { - throw new NullPointerError("null bytes passed to RpcConnection.getNormalizedString"); - } - try { - if (this.unicodeServer) { - return new String(bytes, UNICODE_SERVER_CHARSET_NAME); - } else { - return new String(bytes, this.p4Charset.getCharset().name()); - } - } catch (UnsupportedEncodingException e) { - // This should never be reached since we already have the Charset - // object needed. - Log.exception(e); - } - return null; - } - - public boolean isUsingCompression() { - return this.usingCompression; - } - - public RpcConnectionFlowControl getFlowController() { - return this.flowController; - } - - public void setFlowController(RpcConnectionFlowControl flowController) { - this.flowController = flowController; - } - - public Properties getProps() { - return props; - } - - public void setProps(Properties props) { - this.props = props; - } - - public Charset getClientCharset() { - return this.p4Charset.getCharset(); - } - - public P4Charset getP4Charset() { - return p4Charset; - } - - public void setClientCharset(P4Charset p4Charset) { - this.p4Charset = p4Charset; - this.unicodeServer = P4Charset.isUnicodeServer(p4Charset); - } - - public ServerStats getStats() { - return this.stats; - } - - public void setStats(ServerStats stats) { - this.stats = stats; - } - - public String getHostIp() { - return this.hostIp; - } - - public void setHostIp(String hostIp) { - this.hostIp = hostIp; - } - - public String getHostName() { - return this.hostName; - } - - public void setHostName(String hostName) { - this.hostName = hostName; - } - - public int getHostPort() { - return this.hostPort; - } - - public void setHostPort(int hostPort) { - this.hostPort = hostPort; - } - - public void setUsingCompression(boolean usingCompression) { - this.usingCompression = usingCompression; - } - - public boolean isUnicodeServer() { - return this.unicodeServer; - } - - public void setUnicodeServer(boolean unicodeServer) { - this.unicodeServer = unicodeServer; - } - - public int getFilesysUtf8bom() { - String val = PropertiesHelper.getPropertyByKeys(props, PropertyDefs.FILESYS_UTF8BOM_SHORT_FORM, PropertyDefs.FILESYS_UTF8BOM, "1"); - try { - return Integer.parseInt(val); - } catch (NumberFormatException e) { - return 1; - } - } - - public int getFilesysRestrictedSymlinks() { - String val = PropertiesHelper.getPropertyByKeys(props, PropertyDefs.FILESYS_RESTRICTSYMLINKS_SHORT_FORM, PropertyDefs.FILESYS_RESTRICTSYMLINKS, "0"); - try { - return Integer.parseInt(val); - } catch (NumberFormatException e) { - return 0; - } - } - - public boolean isSecure() { - return this.secure; - } - - public void setSecure(boolean secure) { - this.secure = secure; - } - - public String getFingerprint() { - return fingerprint; - } - - public void setFingerprint(String fingerprint) { - this.fingerprint = fingerprint; - } - - public boolean isTrusted() { - return trusted; - } - - public void setTrusted(boolean trusted) { - this.trusted = trusted; - } - - public RpcPacketDispatcher.RpcPacketDispatcherResult clientConfirm(String confirm, Map resultsMap) - throws ConnectionException { - - if(confirm == null) { - return RpcPacketDispatcher.RpcPacketDispatcherResult.CONTINUE_LOOP; + public static final String TRACE_PREFIX = "RpcConnection"; + + /** + * The charset used internally by a Perforce Unicode-enabled server. If a + * server is Unicode-enabled, then every non-binary RPC packet field + * is sent to and received from the Perforce server in this charset. + *

+ * Do not change this unless you want all hell to break loose. + */ + public static final Charset UNICODE_SERVER_CHARSET = CharsetDefs.UTF8; + + /** + * The name of the assumed Unicode server internal charset. Do not change + * this either. + */ + public static final String UNICODE_SERVER_CHARSET_NAME = CharsetDefs.UTF8_NAME; + + /** + * Charset assumed when the server is non in Unicode mode. Do not change + * this field, either, unless you want problems... + */ + public static final Charset NON_UNICODE_SERVER_CHARSET = CharsetDefs.DEFAULT; + + /** + * The name of the assumed non-Unicode server charset. Do not change this + * either. + */ + public static final String NON_UNICODE_SERVER_CHARSET_NAME = CharsetDefs.DEFAULT_NAME; + + protected static final String UNKNOWN_SERVER_HOST = null; + protected static final int UNKNOWN_SERVER_PORT = -1; + + protected Properties props = null; + protected RpcConnectionFlowControl flowController = new RpcConnectionFlowControl(); + + protected ServerStats stats = null; + + protected P4Charset p4Charset = null; + + protected String hostIp = UNKNOWN_SERVER_HOST; + protected String ourIp = UNKNOWN_SERVER_HOST; + protected String hostName = UNKNOWN_SERVER_HOST; + protected int hostPort = UNKNOWN_SERVER_PORT; + protected int ourPort = UNKNOWN_SERVER_PORT; + protected boolean usingCompression = false; + + protected boolean unicodeServer = false; + + protected boolean secure = false; + protected String fingerprint = null; + protected boolean trusted = false; + protected Certificate[] serverCerts = null; + + public X509Certificate[] getServerCerts() { + X509Certificate[] certs; + if (serverCerts != null) { + certs = new X509Certificate[serverCerts.length]; + for (int i = 0; i < certs.length; i++) { + certs[i] = (X509Certificate) serverCerts[i]; + } + } else { + certs = new X509Certificate[0]; + } + return certs; + } + + protected boolean selfSigned = true; + + public boolean isSelfSigned() { + return selfSigned; + } + + /** + * Create a Perforce RPC connection to a given host and port number pair. + *

+ * This method will also implicitly connect to the server. Note that new + * connections are never using connection compression -- this has to come as + * an explicit command from the server after the connection has been + * established. + * + * @param serverHost non-null Perforce server host name or IP address. + * @param serverPort Perforce server host port number. + * @param props if not null, use the Properties for any connection- or + * implementation-specific values (such as buffer sizes, etc.). + * @param stats if not null, attempt to fill in these connection stats + * appropriately. + * @param p4Charset if non-null, sets the connection's idea of what the current + * client charset is. If null, CharsetDefs.DEFAULT is used. + * @throws ConnectionException if any user-reportable error occurred under the covers. + */ + public RpcConnection(String serverHost, int serverPort, Properties props, ServerStats stats, P4Charset p4Charset) throws ConnectionException { + + this(serverHost, serverPort, props, stats, p4Charset, false); + } + + /** + * Create a Perforce RPC connection to a given host and port number pair. + *

+ * This method will also implicitly connect to the server. Note that new + * connections are never using connection compression -- this has to come as + * an explicit command from the server after the connection has been + * established. + * + * @param serverHost non-null Perforce server host name or IP address. + * @param serverPort Perforce server host port number. + * @param props if not null, use the Properties for any connection- or + * implementation-specific values (such as buffer sizes, etc.). + * @param stats if not null, attempt to fill in these connection stats + * appropriately. + * @param p4Charset if non-null, sets the connection's idea of what the current + * client charset is. If null, CharsetDefs.DEFAULT is used. + * @param secure indicate whether the connection is secure (SSL) or not. + * @throws ConnectionException if any user-reportable error occurred under the covers. + */ + public RpcConnection(@Nonnull String serverHost, int serverPort, Properties props, ServerStats stats, P4Charset p4Charset, boolean secure) throws ConnectionException { + + this.hostName = Validate.notNull(serverHost); + this.hostPort = serverPort; + this.secure = secure; + this.p4Charset = firstNonNull(p4Charset, P4Charset.getDefault()); + this.stats = firstNonNull(stats, new ServerStats()); + this.props = firstNonNull(props, new Properties()); + this.stats.serverConnections.incrementAndGet(); + this.unicodeServer = P4Charset.isUnicodeServer(p4Charset); // Note: NOT this.p4Charset.getCharset().... + } + + /** + * Get the server's IP and port used for the RPC connection. + * + * @return - possibly null server IP and port + */ + public abstract String getServerIpPort(); + + public abstract String getServerHostNamePort(); + + /** + * Get the client's IP and port used for the RPC connection. + * + * @return - possibly null client IP and port + */ + public abstract String getClientIpPort(); + + /** + * Disconnect this server. Assumes the connection is quiescent -- no further + * sends or receives will be possible after this call, and only the output + * stream is flushed (no attempt is made to look at anything still on the + * wire coming in to the socket). + * + * @param dispatcher dispatcher + * @throws ConnectionException on error + */ + public abstract void disconnect(RpcPacketDispatcher dispatcher) throws ConnectionException; + + /** + * Put a Perforce RPC packet onto the output stream. The implementing method + * must make the appropriate charset translations and any other client- or + * server- (or whatever-) specific processing on the passed-in packet. + *

+ * Returns the number of bytes actually sent to the Perforce server, which + * may not bear any relationship at all to the size of the passed-in packet. + * + * @param rpcPacket rpcPacket + * @return number of bytes + * @throws ConnectionException on error + */ + public abstract long putRpcPacket(RpcPacket rpcPacket) throws ConnectionException; + + /** + * Put an array of RPC packets. A convenience method wrapping + * putRpcPacket(packet) in the obvious way. + * + * @param rpcPackets rpcPackets + * @return number of bytes + * @throws ConnectionException on error + */ + public abstract long putRpcPackets(RpcPacket[] rpcPackets) throws ConnectionException; + + /** + * Get the next RPC packet from the receive queue. The implementing method + * must make the appropriate charset translations and any other client- or + * server- (or whatever-) specific processing on the packet returned from + * this method by the time it's returned. + *

+ * Will wait until either a timeout occurs (if the stream's been set up + * appropriately), the underlying stream returns EOF or error, or we get a + * complete packet. + * @return RpcPacket + * @throws ConnectionException on error + */ + public abstract RpcPacket getRpcPacket() throws ConnectionException; + + /** + * Get the next RPC packet from the receive queue with an optional rule to + * handle the RPC packet fields. + * + * @param fieldRule fieldRule + * @param filterCallback filterCallback + * @return RpcPacket + * @throws ConnectionException on error + */ + public abstract RpcPacket getRpcPacket(RpcPacketFieldRule fieldRule, IFilterCallback filterCallback) throws ConnectionException; + + /** + * Return the system (i.e. underlying implementation) send buffer size. + * + * @return size + */ + public abstract int getSystemSendBufferSize(); + + /** + * Return the system (i.e. underlying implementation) receive buffer size. + * + * @return size + */ + public abstract int getSystemRecvBufferSize(); + + /** + * Marshal a packet field into a key value byte array pair. This must + * respect the relevant charset settings, which can be a little + * counter-intuitive or confusing. + * + * @param key key + * @param value value + * @return bytes + */ + public byte[] marshalPacketField(String key, Object value) { + + // Note: either key or value can be (and often are) null, but it's rare + // for + // both to be null. But it happens... + + // Note: this could easily be improved on for performance by tuning the + // copies; the + // implementation here is to get something that works first... + + byte[] retBytes = null; + byte[] keyBytes = null; + byte[] valBytes = null; + byte[] valLengthBytes = null; + + if (key != null) { + keyBytes = getNormalizedBytes(key); + } + + valBytes = marshalPacketValue(value); + + valLengthBytes = RpcPacket.encodeInt4(valBytes == null ? 0 : valBytes.length); + + // Calculate the resulting field length, in bytes. Note that there's + // a null byte after each sub field, hence the "2 +" here. + + int fieldLength = 2 + (keyBytes == null ? 0 : keyBytes.length) + valLengthBytes.length + (valBytes == null ? 0 : valBytes.length); + + retBytes = new byte[fieldLength]; + int retBytesPos = 0; + + if (keyBytes != null) { + System.arraycopy(keyBytes, 0, retBytes, retBytesPos, keyBytes.length); + retBytesPos += keyBytes.length; + } + retBytes[retBytesPos++] = 0; + + System.arraycopy(valLengthBytes, 0, retBytes, retBytesPos, valLengthBytes.length); + retBytesPos += valLengthBytes.length; + + if (valBytes != null) { + System.arraycopy(valBytes, 0, retBytes, retBytesPos, valBytes.length); + retBytesPos += valBytes.length; + } + retBytes[retBytesPos++] = 0; + + return retBytes; + } + + /** + * Marshal a packet field value onto a byte array and return that array. + *

+ * For strings and similar types (e.g. StringBuilder, StringBuffer), we may + * need to do a translation to the server charset (normally UTF-8) before + * enbyteifying the underlying value. Other field types are sent as-is, and + * are assumed to have been encoded properly upstream (and are almost always + * just file contents). + *

+ * Note: if the value object passed in is a ByteBuffer, it must have been + * flipped ready for use; this method will (of course) have predictable side + * effects on that ByteBuffer. + * + * @param value value + * @return bytes + */ + protected byte[] marshalPacketValue(Object value) { + + byte[] valBytes = null; + + try { + if (value != null) { + if (value.getClass() == String.class) { + valBytes = getNormalizedBytes((String) value); + } else if (value instanceof byte[]) { + valBytes = (byte[]) value; + } else if (value instanceof StringBuffer) { + valBytes = getNormalizedBytes(value.toString()); + } else if (value instanceof ByteBuffer) { + int valLength = ((ByteBuffer) value).limit(); + valBytes = new byte[valLength]; + ((ByteBuffer) value).get(valBytes); + } else { + throw new P4JavaError("Unmarshalable value in RpcStreamConnection.marshal; type: " + value.getClass().getCanonicalName()); + } + } + } catch (P4JavaError p4jerr) { + throw p4jerr; + } catch (Throwable thr) { + Log.error("Unexpected exception in RpcStreamConnection.marshalValue: " + thr.getLocalizedMessage()); + Log.exception(thr); + throw new P4JavaError("Unexpected exception in RpcStreamConnection.marshalValue: " + thr.getLocalizedMessage()); + } + + return valBytes; + } + + /** + * If called, will set this connection to use (GZIP) compression for all + * traffic on this connection from this point on. Can not be turned back off + * again. See the main P4 help documentation (and C++ API code) for "client + * compression" (etc.) for details. + * + * @throws ConnectionException on error + */ + public void useConnectionCompression() throws ConnectionException { + if (!usingCompression) { + this.usingCompression = true; + } + } + + /** + * Encode the passed-in string properly for the server. If the server is + * Unicode-enabled, this usually means converting to UTF-8 encoding for the + * stream. This can be a very CPU-intensive process... + *

+ * FIXME: use proper encoding / decoding with error handling -- HR. + * + * @param str str + * @return - normalized string + */ + protected byte[] getNormalizedBytes(String str) { + if (str == null) { + throw new NullPointerError("null string passed to RpcConnection.getNormalizedBytes"); + } + try { + if (this.unicodeServer) { + return str.getBytes(UNICODE_SERVER_CHARSET_NAME); + } else { + return str.getBytes(this.p4Charset.getCharset().name()); + } + } catch (UnsupportedEncodingException e) { + // This should never be reached since we already have the Charset + // object needed. + Log.exception(e); + } + return null; + } + + /** + * Decode the passed-in bytes from the server into a suitable string. In + * general, bytes from the server will be in ASCII (non-Unicode servers) or + * UTF-8 (Unicode servers), but there are exceptions. + *

+ * FIXME: use proper encoding / decoding with error handling -- HR. + * + * @param bytes bytes + * @return - normalized string + */ + protected String getNormalizedString(byte[] bytes) { + if (bytes == null) { + throw new NullPointerError("null bytes passed to RpcConnection.getNormalizedString"); + } + try { + if (this.unicodeServer) { + return new String(bytes, UNICODE_SERVER_CHARSET_NAME); + } else { + return new String(bytes, this.p4Charset.getCharset().name()); + } + } catch (UnsupportedEncodingException e) { + // This should never be reached since we already have the Charset + // object needed. + Log.exception(e); + } + return null; + } + + public boolean isUsingCompression() { + return this.usingCompression; + } + + public RpcConnectionFlowControl getFlowController() { + return this.flowController; + } + + public void setFlowController(RpcConnectionFlowControl flowController) { + this.flowController = flowController; + } + + public Properties getProps() { + return props; + } + + public void setProps(Properties props) { + this.props = props; + } + + public Charset getClientCharset() { + return this.p4Charset.getCharset(); + } + + public P4Charset getP4Charset() { + return p4Charset; + } + + public void setClientCharset(P4Charset p4Charset) { + this.p4Charset = p4Charset; + this.unicodeServer = P4Charset.isUnicodeServer(p4Charset); + } + + public ServerStats getStats() { + return this.stats; + } + + public void setStats(ServerStats stats) { + this.stats = stats; + } + + public String getHostIp() { + return this.hostIp; + } + + public void setHostIp(String hostIp) { + this.hostIp = hostIp; + } + + public String getHostName() { + return this.hostName; + } + + public void setHostName(String hostName) { + this.hostName = hostName; + } + + public int getHostPort() { + return this.hostPort; + } + + public void setHostPort(int hostPort) { + this.hostPort = hostPort; + } + + public void setUsingCompression(boolean usingCompression) { + this.usingCompression = usingCompression; + } + + public boolean isUnicodeServer() { + return this.unicodeServer; + } + + public void setUnicodeServer(boolean unicodeServer) { + this.unicodeServer = unicodeServer; + } + + public int getFilesysUtf8bom() { + String val = PropertiesHelper.getPropertyByKeys(props, PropertyDefs.FILESYS_UTF8BOM_SHORT_FORM, PropertyDefs.FILESYS_UTF8BOM, "1"); + try { + return Integer.parseInt(val); + } catch (NumberFormatException e) { + return 1; + } + } + + public int getFilesysRestrictedSymlinks() { + String val = PropertiesHelper.getPropertyByKeys(props, PropertyDefs.FILESYS_RESTRICTSYMLINKS_SHORT_FORM, PropertyDefs.FILESYS_RESTRICTSYMLINKS, "0"); + try { + return Integer.parseInt(val); + } catch (NumberFormatException e) { + return 0; + } + } + + public boolean isSecure() { + return this.secure; + } + + public void setSecure(boolean secure) { + this.secure = secure; + } + + public String getFingerprint() { + return fingerprint; + } + + public void setFingerprint(String fingerprint) { + this.fingerprint = fingerprint; + } + + public boolean isTrusted() { + return trusted; + } + + public void setTrusted(boolean trusted) { + this.trusted = trusted; + } + + public RpcPacketDispatcher.RpcPacketDispatcherResult clientConfirm(String confirm, Map resultsMap) throws ConnectionException { + + if (confirm == null) { + return RpcPacketDispatcher.RpcPacketDispatcherResult.CONTINUE_LOOP; } // Copy all incoming vars to outgoing vars @@ -601,60 +597,59 @@ public RpcPacketDispatcher.RpcPacketDispatcherResult clientConfirm(String confir putRpcPacket(respPacket); - return RpcPacketDispatcher.RpcPacketDispatcherResult.CONTINUE_LOOP; - } - - - public String getDigest(RpcPerforceFileType fileType, File file) { - return getDigest(fileType, file, null); - } - - public String getDigest(RpcPerforceFileType fileType, File file, - RpcPerforceDigestType digest) { - - MD5Digester digester = new MD5Digester(); - - if(digest == null) { - digest = RpcPerforceDigestType.MD5; - } - - Charset digestCharset = null; - boolean convertLineEndings = false; - switch (fileType) { - case FST_SYMLINK: - return getSymlinkMD5Digest(file); - - case FST_UTF16: - digestCharset = CharsetDefs.UTF16; - break; - case FST_UTF8: - digestCharset = CharsetDefs.UTF8; - convertLineEndings = true; - break; - case FST_UNICODE: - digestCharset = getClientCharset(); - break; - case FST_XTEXT: - case FST_TEXT: - // Convert line endings - convertLineEndings = true; - break; - default: - break; - } - - // Digest the file using the configured local file content - // charset. A null digestCharset specified will cause the - // file to be read as raw byte stream directly off disk. - //TODO: Digester might be SHA* variant - String digestStr = digester.digestFileAs32ByteHex(file, digestCharset, convertLineEndings); - - return digestStr; - } - - private String getSymlinkMD5Digest(File file) { - String targetPath = SymbolicLinkHelper.readSymbolicLink(file.getAbsolutePath()); - String md5 = DigestUtils.md5Hex(targetPath + "\n").toUpperCase(); - return md5; - } + return RpcPacketDispatcher.RpcPacketDispatcherResult.CONTINUE_LOOP; + } + + + public String getDigest(RpcPerforceFileType fileType, File file) { + return getDigest(fileType, file, null); + } + + public String getDigest(RpcPerforceFileType fileType, File file, RpcPerforceDigestType digest) { + + MD5Digester digester = new MD5Digester(); + + if (digest == null) { + digest = RpcPerforceDigestType.MD5; + } + + Charset digestCharset = null; + boolean convertLineEndings = false; + switch (fileType) { + case FST_SYMLINK: + return getSymlinkMD5Digest(file); + + case FST_UTF16: + digestCharset = CharsetDefs.UTF16; + break; + case FST_UTF8: + digestCharset = CharsetDefs.UTF8; + convertLineEndings = true; + break; + case FST_UNICODE: + digestCharset = getClientCharset(); + break; + case FST_XTEXT: + case FST_TEXT: + // Convert line endings + convertLineEndings = true; + break; + default: + break; + } + + // Digest the file using the configured local file content + // charset. A null digestCharset specified will cause the + // file to be read as raw byte stream directly off disk. + //TODO: Digester might be SHA* variant + String digestStr = digester.digestFileAs32ByteHex(file, digestCharset, convertLineEndings); + + return digestStr; + } + + private String getSymlinkMD5Digest(File file) { + String targetPath = SymbolicLinkHelper.readSymbolicLink(file.getAbsolutePath()); + String md5 = DigestUtils.md5Hex(targetPath + "\n").toUpperCase(); + return md5; + } } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/connection/RpcConnectionFlowControl.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/connection/RpcConnectionFlowControl.java index 2050602..e757ed8 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/connection/RpcConnectionFlowControl.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/connection/RpcConnectionFlowControl.java @@ -3,60 +3,60 @@ */ package com.perforce.p4java.impl.mapbased.rpc.connection; -import java.util.HashMap; -import java.util.Map; - import com.perforce.p4java.impl.mapbased.rpc.func.RpcFunctionMapKey; import com.perforce.p4java.impl.mapbased.rpc.func.RpcFunctionSpec; import com.perforce.p4java.impl.mapbased.rpc.packet.RpcPacket; +import java.util.HashMap; +import java.util.Map; + /** - * Provides Perforce flow control services for the Perforce server connection.

- * - * + * Provides Perforce flow control services for the Perforce server connection. */ - public class RpcConnectionFlowControl { public static final String TRACE_PREFIX = "RpcConnectionFlowControl"; - + /** * Length in bytes of a flush command when marshaled. This is actually * a fiction -- it's more like 50 -- but the conservative sizing gives * us a little leeway when things are tight (see the C++ API for a * discussion on this -- we're just copying their behavior...). */ - public static final int FLUSH_CMD_LENGTH = 60; - + protected RpcConnectionFlowControl() { - + } /** * Construct a flush2 response to the passed-in flush1 packet. + * + * @param flush1 flush1 + * @return RpcPacket */ - public RpcPacket respondToFlush1(RpcPacket flush1) { - + if (flush1 != null) { return respondToFlush1(flush1.getResultsMap()); } - + return null; } - + /** * Construct a flush2 response to the passed-in flush1 packet. + * + * @param resultsMap resultsMap + * @return RpcPacket */ - public RpcPacket respondToFlush1(Map resultsMap) { - + if (resultsMap != null) { String hwmStr = (String) resultsMap.get(RpcFunctionMapKey.FLUSH_HWM); String seqNumStr = (String) resultsMap.get(RpcFunctionMapKey.FLUSH_SEQ); String rseqNumStr = (String) resultsMap.get(RpcFunctionMapKey.FLUSH_RSEQ); - + Map flushMap = new HashMap(); if (hwmStr != null) { flushMap.put(RpcFunctionMapKey.FLUSH_HWM, "" + new Long(hwmStr)); @@ -67,13 +67,12 @@ public RpcPacket respondToFlush1(Map resultsMap) { if (rseqNumStr != null) { flushMap.put(RpcFunctionMapKey.FLUSH_RSEQ, "" + new Long(rseqNumStr)); } - - RpcPacket flush2Packet = RpcPacket.constructRpcPacket( - RpcFunctionSpec.PROTOCOL_FLUSH2, flushMap, null); - + + RpcPacket flush2Packet = RpcPacket.constructRpcPacket(RpcFunctionSpec.PROTOCOL_FLUSH2, flushMap, null); + return flush2Packet; } - + return null; } } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/RpcFunction.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/RpcFunction.java index b39363c..6aea8f3 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/RpcFunction.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/RpcFunction.java @@ -10,11 +10,11 @@ import java.util.HashMap; /** - * General Perforce RPC function utilities and definitions.

+ * General Perforce RPC function utilities and definitions. *

* An RPC function in this context is anything that can be encoded * with the "func" field in an RPC packet, e.g. "func client-Message", - * "func user-files", or "func dm-Login".

+ * "func user-files", or "func dm-Login". *

* Note that a lot of optimizations could be done here, but we'll hold * off on this until we're clearer about usage models, actual performance, diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/RpcFunctionSpec.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/RpcFunctionSpec.java index 6d757fa..4789b77 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/RpcFunctionSpec.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/RpcFunctionSpec.java @@ -13,11 +13,11 @@ import java.nio.ByteBuffer; /** - * Defines the various Perforce RPC function names.

+ * Defines the various Perforce RPC function names. *

* If you add or change something here, make sure you also * change the corresponding definitions elsewhere in places - * like the RpcFunction class.

+ * like the RpcFunction class. */ public enum RpcFunctionSpec { @@ -85,7 +85,7 @@ public enum RpcFunctionSpec { USER_TRANSMIT, USER_LIST, USER_RETYPE, - USER_LICENSE, + USER_LICENSE, USER_STREAMLOG, USER_TOPOLOGY, @@ -121,7 +121,7 @@ public enum RpcFunctionSpec { USER_GROUP, USER_GROUPS, USER_HAVE, - USER_HEARTBEAT, + USER_HEARTBEAT, USER_HELP, USER_INFO, USER_INTEGRATE, @@ -154,7 +154,7 @@ public enum RpcFunctionSpec { USER_SET, USER_STREAM, USER_STREAMS, - USER_STREAMSPEC, + USER_STREAMSPEC, USER_STORAGE, USER_SUBMIT, USER_SWITCH, @@ -251,11 +251,15 @@ public enum RpcFunctionSpec { SERVER_DM_RESOLVEDFILE, SERVER_DM_RESOLVEDFAILED, SERVER_RECONCILEFILE, - SERVER_RECONCILEADDS,; + SERVER_RECONCILEADDS, + ; /** * Decode a RpcFunctionSpec from the passed-in string, assumed to be * in RPC wire form. + * + * @param str string + * @return RpcFunctionSpec */ public static RpcFunctionSpec decode(String str) { if (str == null) { @@ -268,6 +272,10 @@ public static RpcFunctionSpec decode(String str) { /** * A version of decode that handles the specialised case of * relaxed checking for USER commands (and user commands *only*). + * + * @param str string + * @param relaxedCheck relaxed check option + * @return RpcFunctionSpec */ public static RpcFunctionSpec decode(String str, boolean relaxedCheck) { if (str == null) { @@ -291,6 +299,10 @@ public static RpcFunctionSpec decode(String str, boolean relaxedCheck) { * levels of P4Java as an end-user command, e.g. decode "depots" to * USER_DEPOTS. This is subtly different to decoding it from the wire; * also, it's only applicable for user commands. + * + * @param str string + * @param relaxedCheck relaxed check option + * @return RpcFunctionSpec */ public static RpcFunctionSpec decodeFromEndUserCmd(String str, boolean relaxedCheck) { if (str == null) { diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/RpcFunctionType.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/RpcFunctionType.java index c395b27..bc0d57f 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/RpcFunctionType.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/RpcFunctionType.java @@ -8,75 +8,73 @@ */ public enum RpcFunctionType { - + /** * "Simple" client functions, e.g. "client-Message" to be * processed by the client and that do not (generally...) * require further interaction with the server. */ CLIENT, - + /** * More complex client functions that will probably cause * duplex back-and-forth messaging between client and server. */ CLIENT_DM, - + /** * The normal end-user-initiated perforce functions, e.g. * "info" or "depots". */ USER, - + /** * Server functions to be processed by the Perforce server. */ SERVER, - + /** * Protocol meta functions, e.g. "flush1" or "compress2". */ PROTOCOL, - + /** * Non-function; mainly serves as an error or guard. */ NONE; - + /** - * Get the string prefix used by this function type when encoded + * @return the string prefix used by this function type when encoded * for the wire. E.g. "dm-" for CLIENT_DM, or "user" for USER. * The protocol type has no prefix (at least none that I've * seen). */ - public String getEncodingPrefix() { - + switch (this) { case CLIENT_DM: return "dm-"; - + case PROTOCOL: return ""; - + default: return this.toString().toLowerCase(Locale.ENGLISH) + "-"; } } - + /** - * Return the name prefix (e.g. "USER_") for this func spec. + * @return the name prefix (e.g. "USER_") for this func spec. */ - public String getTypeNamePrefix() { switch (this) { case CLIENT_DM: return "CLIENT_DM_"; - + default: return this.toString() + "_"; } } -}; +} diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientFunctionDispatcher.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientFunctionDispatcher.java index f9d12ed..50e859a 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientFunctionDispatcher.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientFunctionDispatcher.java @@ -18,6 +18,7 @@ import com.perforce.p4java.impl.mapbased.rpc.packet.RpcPacketDispatcher.RpcPacketDispatcherMode; import com.perforce.p4java.impl.mapbased.rpc.packet.RpcPacketDispatcher.RpcPacketDispatcherResult; import com.perforce.p4java.impl.mapbased.rpc.sys.RpcOutputStream; +import com.perforce.p4java.impl.mapbased.server.cmd.ResultMapParser; import com.perforce.p4java.server.CmdSpec; import com.perforce.p4java.server.callback.IProgressCallback; @@ -31,84 +32,76 @@ * extended series of calls back to the server and / or complex * flow control management, or it may involve little more than * returning what's already been seen. - * - * */ public class ClientFunctionDispatcher { - -public static final String TRACE_PREFIX = "ClientFunctionDispatcher"; - + + public static final String TRACE_PREFIX = "ClientFunctionDispatcher"; + @SuppressWarnings("unused") private RpcPacketDispatcher mainDispatcher = null; - + private ClientUserInteraction userInteractor = null; - private ClientSystemFileMatchCommands fileMatchCommands = null; + private ClientSystemFileMatchCommands fileMatchCommands = null; private ClientSystemFileCommands fileCommands = null; private ClientSendFile fileSender = null; private ClientMerge clientMerger = null; private ClientProgressReport progressReport = null; private Properties props = null; protected RpcServer server = null; - - public ClientFunctionDispatcher(RpcPacketDispatcher mainDispatcher, - Properties props, RpcServer server) { + + public ClientFunctionDispatcher(RpcPacketDispatcher mainDispatcher, Properties props, RpcServer server) { if (mainDispatcher == null) { - throw new NullPointerError( - "Null main dispatcher passed to ClientFunctionDispatcher constructor"); + throw new NullPointerError("Null main dispatcher passed to ClientFunctionDispatcher constructor"); } - + this.props = props; this.server = server; - + this.mainDispatcher = mainDispatcher; this.userInteractor = new ClientUserInteraction(this.props, server); - this.fileMatchCommands = new ClientSystemFileMatchCommands(this.props, server); - this.fileCommands = new ClientSystemFileCommands(this.props, server, fileMatchCommands); + this.fileMatchCommands = new ClientSystemFileMatchCommands(this.props, server); + this.fileCommands = new ClientSystemFileCommands(this.props, server, fileMatchCommands); this.fileSender = new ClientSendFile(this.props); this.clientMerger = new ClientMerge(this.props); this.progressReport = new ClientProgressReport(server); } - - public RpcPacketDispatcherResult dispatch(RpcPacketDispatcherMode dispatchMode, - RpcFunctionSpec funcSpec, CommandEnv cmdEnv, - Map resultsMap) throws ConnectionException { + + public RpcPacketDispatcherResult dispatch(RpcPacketDispatcherMode dispatchMode, RpcFunctionSpec funcSpec, CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { if (funcSpec == null) { - throw new NullPointerError( - "Null function spec passed to ClientFunctionDispatcher.dispatch()"); + throw new NullPointerError("Null function spec passed to ClientFunctionDispatcher.dispatch()"); } - + if (cmdEnv == null) { - throw new NullPointerError( - "Null command environment passed to ClientFunctionDispatcher.dispatch()"); + throw new NullPointerError("Null command environment passed to ClientFunctionDispatcher.dispatch()"); } - + RpcPacketDispatcherResult result = RpcPacketDispatcherResult.NONE; RpcConnection rpcConnection = cmdEnv.getRpcConnection(); - + int cmdCallBackKey = cmdEnv.getCmdCallBackKey(); IProgressCallback progressCallback = cmdEnv.getProgressCallback(); - + boolean keepGoing = !cmdEnv.isUserCanceled(); - + if ((progressCallback != null) && keepGoing) { keepGoing = progressReport.report(progressCallback, cmdCallBackKey, funcSpec, cmdEnv, resultsMap); } - + if (!keepGoing) { // Setting userCanceled as true may or may not cause issues elsewhere; // we at least try to clean up semi-properly... - + cmdEnv.setUserCanceled(true); } - + switch (funcSpec) { - + case CLIENT_MESSAGE: - + // Quiet mode - suppress all info level messages - cmdEnv.clearLastResultMap(); - if( server.getSeverityCode(resultsMap) > 1 ) { + cmdEnv.clearLastResultMap(); + if (server.getSeverityCode(resultsMap) > 1) { server.setSecretKey(server.getUserName(), null); server.setPbuf(server.getUserName(), null); } @@ -117,10 +110,10 @@ public RpcPacketDispatcherResult dispatch(RpcPacketDispatcherMode dispatchMode, result = RpcPacketDispatcherResult.CONTINUE; break; } - + case CLIENT_FSTATINFO: - case CLIENT_FSTATPARTIAL: - // 2016/10/05 npoole + case CLIENT_FSTATPARTIAL: + // 2016/10/05 npoole // We have to special-case commands that return file contents in fstatInfo or message // packet data fields in order to do proper contents processing for charset @@ -132,27 +125,21 @@ public RpcPacketDispatcherResult dispatch(RpcPacketDispatcherMode dispatchMode, // as it probably sounds... // We need to insert the print command headers (name, rev, etc.) to the output stream // before writing the file content. - - if (cmdEnv.getCmdSpec().getCmdName().equalsIgnoreCase(CmdSpec.ANNOTATE.toString()) - || cmdEnv.getCmdSpec().getCmdName().equalsIgnoreCase(CmdSpec.LOGTAIL.toString())) { + + if (cmdEnv.getCmdSpec().getCmdName().equalsIgnoreCase(CmdSpec.ANNOTATE.toString()) || cmdEnv.getCmdSpec().getCmdName().equalsIgnoreCase(CmdSpec.LOGTAIL.toString())) { resultsMap.remove("func"); - Map fileDataMap = this.fileCommands.convertFileDataMap(resultsMap, - cmdEnv.getRpcConnection().getClientCharset(), - cmdEnv.getRpcConnection().isUnicodeServer()); + Map fileDataMap = this.fileCommands.convertFileDataMap(resultsMap, cmdEnv.getRpcConnection().getClientCharset(), cmdEnv.getRpcConnection().isUnicodeServer()); if (funcSpec == RpcFunctionSpec.CLIENT_FSTATPARTIAL) { - cmdEnv.handlePartialResult(fileDataMap); - } else { - cmdEnv.handleResult(fileDataMap); - } - } else if (cmdEnv.getCmdSpec().getCmdName().equalsIgnoreCase(CmdSpec.DIFF2.toString()) - || cmdEnv.getCmdSpec().getCmdName().equalsIgnoreCase(CmdSpec.DESCRIBE.toString()) - || cmdEnv.getCmdSpec().getCmdName().equalsIgnoreCase(CmdSpec.PRINT.toString())) { - String infoMsg = server.getErrorOrInfoStr(resultsMap); + cmdEnv.handlePartialResult(fileDataMap); + } else { + cmdEnv.handleResult(fileDataMap); + } + } else if (cmdEnv.getCmdSpec().getCmdName().equalsIgnoreCase(CmdSpec.DIFF2.toString()) || cmdEnv.getCmdSpec().getCmdName().equalsIgnoreCase(CmdSpec.DESCRIBE.toString()) || cmdEnv.getCmdSpec().getCmdName().equalsIgnoreCase(CmdSpec.PRINT.toString())) { + String infoMsg = ResultMapParser.getErrorOrInfoStr(resultsMap); if (infoMsg != null) { RpcOutputStream outStream = this.fileCommands.getTempOutputStream(cmdEnv); if (outStream != null) { - String charsetName = (rpcConnection.getClientCharset() == null ? - CharsetDefs.DEFAULT_NAME : rpcConnection.getClientCharset().name()); + String charsetName = (rpcConnection.getClientCharset() == null ? CharsetDefs.DEFAULT_NAME : rpcConnection.getClientCharset().name()); try { infoMsg += CommandEnv.LINE_SEPARATOR; if (cmdEnv.getCmdSpec().getCmdName().equalsIgnoreCase(CmdSpec.DESCRIBE.toString())) { @@ -160,61 +147,60 @@ public RpcPacketDispatcherResult dispatch(RpcPacketDispatcherMode dispatchMode, } outStream.write(infoMsg.getBytes(charsetName)); } catch (IOException ioexc) { - Log.warn("Unexpected exception in client function dispatch: " - + ioexc.getLocalizedMessage()); + Log.warn("Unexpected exception in client function dispatch: " + ioexc.getLocalizedMessage()); } } } resultsMap.remove("func"); if (funcSpec == RpcFunctionSpec.CLIENT_FSTATPARTIAL) { - cmdEnv.handlePartialResult(resultsMap); + cmdEnv.handlePartialResult(resultsMap); } else { - cmdEnv.handleResult(resultsMap); + cmdEnv.handleResult(resultsMap); } } else { resultsMap.remove("func"); if (funcSpec == RpcFunctionSpec.CLIENT_FSTATPARTIAL) { - cmdEnv.handlePartialResult(resultsMap); - } else { - cmdEnv.handleResult(resultsMap); - } + cmdEnv.handlePartialResult(resultsMap); + } else { + cmdEnv.handleResult(resultsMap); + } } result = RpcPacketDispatcherResult.CONTINUE; break; - + case CLIENT_PROMPT: - - cmdEnv.clearLastResultMap(); + + cmdEnv.clearLastResultMap(); result = this.userInteractor.clientPrompt(rpcConnection, cmdEnv, resultsMap); break; - + case CLIENT_SETPASSWORD: - + result = this.userInteractor.clientSetPassword(rpcConnection, cmdEnv, resultsMap); break; - + case CLIENT_CRYPTO: - - result = this.userInteractor.clientCrypto(rpcConnection, cmdEnv, resultsMap); + + result = this.userInteractor.clientCrypto(rpcConnection, cmdEnv, resultsMap); break; - + case CLIENT_CHMODFILE: - + result = this.fileCommands.chmodFile(rpcConnection, cmdEnv, resultsMap); break; - + case CLIENT_OPENFILE: - case CLIENT_OPENDIFF: - case CLIENT_OPENMATCH: - + case CLIENT_OPENDIFF: + case CLIENT_OPENMATCH: + result = this.fileCommands.openFile(rpcConnection, cmdEnv, resultsMap); break; - + case CLIENT_CHECKFILE: - + result = this.fileCommands.checkFile(rpcConnection, cmdEnv, resultsMap); break; - + case CLIENT_RECONCILEEDIT: // 2018/12/10 npoole result = this.fileMatchCommands.reconcileEdit(rpcConnection, cmdEnv, resultsMap); @@ -231,54 +217,54 @@ public RpcPacketDispatcherResult dispatch(RpcPacketDispatcherMode dispatchMode, break; case CLIENT_WRITEFILE: - case CLIENT_WRITEDIFF: - case CLIENT_WRITEMATCH: - + case CLIENT_WRITEDIFF: + case CLIENT_WRITEMATCH: + result = this.fileCommands.writeFile(rpcConnection, cmdEnv, resultsMap); break; - + case CLIENT_CLOSEFILE: - case CLIENT_CLOSEDIFF: - case CLIENT_CLOSEMATCH: + case CLIENT_CLOSEDIFF: + case CLIENT_CLOSEMATCH: result = this.fileCommands.closeFile(rpcConnection, cmdEnv, resultsMap); break; - + case CLIENT_ACK: - // 2016/10/05 npoole + // 2016/10/05 npoole result = this.userInteractor.clientAck(rpcConnection, cmdEnv, resultsMap); break; - + case CLIENT_INPUTDATA: - + result = this.userInteractor.clientInputData(rpcConnection, cmdEnv, resultsMap); break; - + case CLIENT_SENDFILE: - + result = this.fileSender.sendFile(rpcConnection, cmdEnv, resultsMap); break; - + case CLIENT_DELETEFILE: - + result = this.fileCommands.deleteFile(rpcConnection, cmdEnv, resultsMap); break; - + case CLIENT_OUTPUTBINARY: - + result = this.fileCommands.writeBinary(rpcConnection, cmdEnv, resultsMap); break; - + case CLIENT_OUTPUTERROR: - cmdEnv.clearLastResultMap(); + cmdEnv.clearLastResultMap(); resultsMap.remove("func"); - String msg = new String((byte[])resultsMap.remove("data")); + String msg = new String((byte[]) resultsMap.remove("data")); int code = 1 | // subcode = 1 - (14 << 10) | // subsystem = ES_P4QT - (0 << 16) | // generic = EV_NONE - (0 << 24) | // arg count = 0 - (4 << 28); // severity = E_FATAL + (14 << 10) | // subsystem = ES_P4QT + (0 << 16) | // generic = EV_NONE + (0 << 24) | // arg count = 0 + (4 << 28); // severity = E_FATAL resultsMap.put(RpcMessage.CODE + 0, String.valueOf(code)); resultsMap.put(RpcMessage.FMT + 0, msg); cmdEnv.handleResult(resultsMap); @@ -286,28 +272,24 @@ public RpcPacketDispatcherResult dispatch(RpcPacketDispatcherMode dispatchMode, server.setPbuf(server.getUserName(), null); result = RpcPacketDispatcherResult.STOP_NORMAL; break; - + case CLIENT_OUTPUTTEXT: - cmdEnv.clearLastResultMap(); + cmdEnv.clearLastResultMap(); result = this.fileCommands.writeText(rpcConnection, cmdEnv, resultsMap); // Special handling of tracking data output. // There is no distinction between successive client-OutputText. // Thus, we capture all "data" fields if (cmdEnv.getProtocolSpecs().isEnableTracking()) { - cmdEnv.handleResult(this.fileCommands.convertFileDataMap(resultsMap, - cmdEnv.getRpcConnection().getClientCharset(), - cmdEnv.getRpcConnection().isUnicodeServer())); + cmdEnv.handleResult(this.fileCommands.convertFileDataMap(resultsMap, cmdEnv.getRpcConnection().getClientCharset(), cmdEnv.getRpcConnection().isUnicodeServer())); } break; - + case CLIENT_OUTPUTDATA: case CLIENT_OUTPUTINFO: - cmdEnv.clearLastResultMap(); - resultsMap = this.fileCommands.convertFileDataMap(resultsMap, - cmdEnv.getRpcConnection().getClientCharset(), - cmdEnv.getRpcConnection().isUnicodeServer()); + cmdEnv.clearLastResultMap(); + resultsMap = this.fileCommands.convertFileDataMap(resultsMap, cmdEnv.getRpcConnection().getClientCharset(), cmdEnv.getRpcConnection().isUnicodeServer()); RpcOutputStream dataOutStream = this.fileCommands.getTempOutputStream(cmdEnv); if (dataOutStream != null) { @@ -326,7 +308,7 @@ public RpcPacketDispatcherResult dispatch(RpcPacketDispatcherMode dispatchMode, case CLIENT_PROGRESS: - cmdEnv.clearLastResultMap(); + cmdEnv.clearLastResultMap(); RpcOutputStream progressOutStream = this.fileCommands.getTempOutputStream(cmdEnv); if (progressOutStream != null) { // Compose the progress indicator message @@ -340,14 +322,13 @@ public RpcPacketDispatcherResult dispatch(RpcPacketDispatcherMode dispatchMode, if (resultsMap.get("done") != null) { sb.append(" ").append("finishing"); } - + if (sb.length() > 0) { try { sb.append(CommandEnv.LINE_SEPARATOR); progressOutStream.write(sb.toString().getBytes()); } catch (IOException ioexc) { - Log.warn("Unexpected exception in client function dispatch: " - + ioexc.getLocalizedMessage()); + Log.warn("Unexpected exception in client function dispatch: " + ioexc.getLocalizedMessage()); } } } @@ -356,81 +337,81 @@ public RpcPacketDispatcherResult dispatch(RpcPacketDispatcherMode dispatchMode, break; case CLIENT_MOVEFILE: - + result = this.fileCommands.moveFile(rpcConnection, cmdEnv, resultsMap); break; - + case CLIENT_OPENMERGE3: - + result = this.clientMerger.clientOpenMerge3(rpcConnection, cmdEnv, resultsMap, false); break; - + case CLIENT_OPENMERGE2: // Currently reuse clientOpenMerge3 for both two- and three-way merges. // This may change with experience... - + result = this.clientMerger.clientOpenMerge3(rpcConnection, cmdEnv, resultsMap, true); break; - + case CLIENT_WRITEMERGE: - + result = this.clientMerger.clientWriteMerge(rpcConnection, cmdEnv, resultsMap); break; - + case CLIENT_CLOSEMERGE: - + result = this.clientMerger.clientCloseMerge(rpcConnection, cmdEnv, resultsMap); break; - + case CLIENT_SSO: - + result = this.userInteractor.clientSingleSignon(rpcConnection, cmdEnv, resultsMap); break; - - case CLIENT_RECEIVEFILES: - // 2016/10/05 npoole - result = this.userInteractor.clientReceiveFiles(rpcConnection, cmdEnv, resultsMap); - break; - - case CLIENT_ACKMATCH: - // 2016/10/05 npoole - result = this.fileMatchCommands.ackMatch(rpcConnection, cmdEnv, resultsMap); - break; - - case CLIENT_CONVERTFILE: - // 2016/10/05 npoole - result = this.fileCommands.convertFile(rpcConnection, cmdEnv, resultsMap); - break; - - case CLIENT_ACTIONRESOLVE: - // 2016/10/05 npoole - result = this.userInteractor.clientActionResolve(rpcConnection, cmdEnv, resultsMap); - break; - - case CLIENT_EDITDATA: - // 2016/10/05 npoole - result = this.userInteractor.clientEditData(rpcConnection, cmdEnv, resultsMap); - break; - - case CLIENT_EXACTMATCH: - // 2018/12/10 npoole - result = this.fileMatchCommands.exactMatch(rpcConnection, cmdEnv, resultsMap); - break; - - case CLIENT_ERRORPAUSE: - // 2016/10/05 npoole - result = this.userInteractor.clientErrorPause(rpcConnection, cmdEnv, resultsMap); - break; - - case CLIENT_HANDLEERROR: - // 2016/10/05 npoole - result = this.userInteractor.clientHandleError(rpcConnection, cmdEnv, resultsMap); - break; - - case CLIENT_PING: - // 2016/10/05 npoole - result = this.userInteractor.clientPing(rpcConnection, cmdEnv, resultsMap); - break; + + case CLIENT_RECEIVEFILES: + // 2016/10/05 npoole + result = this.userInteractor.clientReceiveFiles(rpcConnection, cmdEnv, resultsMap); + break; + + case CLIENT_ACKMATCH: + // 2016/10/05 npoole + result = this.fileMatchCommands.ackMatch(rpcConnection, cmdEnv, resultsMap); + break; + + case CLIENT_CONVERTFILE: + // 2016/10/05 npoole + result = this.fileCommands.convertFile(rpcConnection, cmdEnv, resultsMap); + break; + + case CLIENT_ACTIONRESOLVE: + // 2016/10/05 npoole + result = this.userInteractor.clientActionResolve(rpcConnection, cmdEnv, resultsMap); + break; + + case CLIENT_EDITDATA: + // 2016/10/05 npoole + result = this.userInteractor.clientEditData(rpcConnection, cmdEnv, resultsMap); + break; + + case CLIENT_EXACTMATCH: + // 2018/12/10 npoole + result = this.fileMatchCommands.exactMatch(rpcConnection, cmdEnv, resultsMap); + break; + + case CLIENT_ERRORPAUSE: + // 2016/10/05 npoole + result = this.userInteractor.clientErrorPause(rpcConnection, cmdEnv, resultsMap); + break; + + case CLIENT_HANDLEERROR: + // 2016/10/05 npoole + result = this.userInteractor.clientHandleError(rpcConnection, cmdEnv, resultsMap); + break; + + case CLIENT_PING: + // 2016/10/05 npoole + result = this.userInteractor.clientPing(rpcConnection, cmdEnv, resultsMap); + break; case CLIENT_OPENURL: @@ -442,14 +423,11 @@ public RpcPacketDispatcherResult dispatch(RpcPacketDispatcherMode dispatchMode, default: - Log.error("Unimplemented function spec in ClientFunctionDispatcher.dispatch(): '" - + funcSpec.toString() + "'"); - throw new P4JavaError( - "Unimplemented function spec in ClientFunctionDispatcher.dispatch(): '" - + funcSpec.toString() + "'"); + Log.error("Unimplemented function spec in ClientFunctionDispatcher.dispatch(): '" + funcSpec.toString() + "'"); + throw new P4JavaError("Unimplemented function spec in ClientFunctionDispatcher.dispatch(): '" + funcSpec.toString() + "'"); } - + return result; } - + } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientHelper.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientHelper.java index 87b239f..80fd0e1 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientHelper.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientHelper.java @@ -23,13 +23,15 @@ private ClientHelper() { /* util */ } /** * Send back the data bytes written (accumulated) * This is for the progress indicator + * + * @param cmdEnv cmdEnv + * @param filePath filePath + * @param fileSize fileSize + * @param currentSize currentSize + * @param bytesRead bytesRead + * @return bytes written */ - public static long sendBackWrittenDataBytes( - final CommandEnv cmdEnv, - final String filePath, - final long fileSize, - final long currentSize, - final long bytesRead) { + public static long sendBackWrittenDataBytes(final CommandEnv cmdEnv, final String filePath, final long fileSize, final long currentSize, final long bytesRead) { long totalReadSize = currentSize; if (cmdEnv.getProtocolSpecs().isEnableProgress()) { if (fileSize > 0 && bytesRead > 0) { @@ -48,12 +50,14 @@ public static long sendBackWrittenDataBytes( /** * Helper method that build the parallel sync options * - * @param pSyncOpts - * @return String - * @throws P4JavaException + * @param serverImpl serverImpl + * @param fileSpecs fileSpecs + * @param syncOpts syncOpts + * @param pSyncOpts pSyncOpts + * @return options + * @throws P4JavaException on error */ - public static String[] buildParallelOptions(IServer serverImpl, List fileSpecs, SyncOptions syncOpts, - ParallelSyncOptions pSyncOpts) throws P4JavaException { + public static String[] buildParallelOptions(IServer serverImpl, List fileSpecs, SyncOptions syncOpts, ParallelSyncOptions pSyncOpts) throws P4JavaException { StringBuilder parallelOptionsBuilder = new StringBuilder(); parallelOptionsBuilder.append("--parallel="); diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientMerge.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientMerge.java index 6273a32..73c6256 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientMerge.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientMerge.java @@ -3,14 +3,6 @@ */ package com.perforce.p4java.impl.mapbased.rpc.func.client; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; - import com.perforce.p4java.Log; import com.perforce.p4java.PropertyDefs; import com.perforce.p4java.exception.ConnectionException; @@ -33,59 +25,61 @@ import com.perforce.p4java.impl.mapbased.rpc.packet.RpcPacket; import com.perforce.p4java.impl.mapbased.rpc.packet.RpcPacketDispatcher.RpcPacketDispatcherResult; import com.perforce.p4java.impl.mapbased.rpc.sys.RpcInputStream; -import com.perforce.p4java.impl.mapbased.rpc.sys.RpcOutputStream; import com.perforce.p4java.impl.mapbased.rpc.sys.RpcPerforceFile; import com.perforce.p4java.impl.mapbased.rpc.sys.RpcPerforceFileType; import com.perforce.p4java.impl.mapbased.rpc.sys.helper.SysFileHelperBridge; +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + /** * Support methods for the RPC merge protocols. Will grow as we implement more types * of merge; current version is very bare bones and oriented solely at non-interactive * three-way merges of text files. - * - * */ public class ClientMerge { - + /** * Possible choices available to a merge / resolve; should be * fairly self-explanatory. */ public enum ResolveChoice { - SKIP, - YOURS, - THEIRS, - EDIT, // Not currently used + SKIP, YOURS, THEIRS, EDIT, // Not currently used MERGED - }; + } + + ; public static final String MARKER_ORIGINAL = ">>>> ORIGINAL "; public static final String MARKER_THEIRS = "==== THEIRS "; public static final String MARKER_YOURS = "==== YOURS "; public static final String MARKER_BOTH = "==== BOTH "; public static final String MARKER_END = "<<<<"; - + public static final String DEFAULT_TMPFILE_PFX = "p4j"; public static final String DEFAULT_TMPFILE_SFX = ".p4j"; - + public static final String SYSTEM_TMPDIR_PROPS_KEY = "java.io.tmpdir"; public static final String SYSTEM_TMPDIR_DEFAULT = "/tmp"; - + public static final String TRACE_PREFIX = "ClientMerge"; - + protected static final String MERGE_STATE_KEY = "MergeState"; - + protected static final String MERGE_BASE_TMP_FILE_KEY = "tmpFileBase"; protected static final String MERGE_BASE_TMP_STREAM_KEY = "tmpFileBaseStream"; - + protected static final String MERGE_THEIRS_TMP_FILE_KEY = "tmpFileTheirs"; protected static final String MERGE_THEIRS_TMP_STREAM_KEY = "tmpFileTheirsStream"; - + protected static final String MERGE_YOURS_TMP_FILE_KEY = "tmpFileYours"; protected static final String MERGE_YOURS_TMP_STREAM_KEY = "tmpFileYoursStream"; - - private Properties props = null; + + private Properties props = null; private String tmpDirName = null; @SuppressWarnings("unused") @@ -100,43 +94,45 @@ public enum ResolveChoice { private static final String MERGED_THEIRS = "theirs"; private static final String MERGED_MERGED = "merged"; private static final String MERGE_UNFORCED = "no"; - + // Transliteration of bit value constant defines from the C++ API; see // the comments below for an explanation. - + private static final int SEL_BASE = 0x01; private static final int SEL_LEG1 = 0x02; private static final int SEL_LEG2 = 0x04; private static final int SEL_RSLT = 0x08; - private static final int SEL_ALL = (SEL_BASE|SEL_LEG1|SEL_LEG2|SEL_RSLT); + private static final int SEL_ALL = (SEL_BASE | SEL_LEG1 | SEL_LEG2 | SEL_RSLT); private static final int SEL_CONF = 0x10; public ClientMerge(Properties props) { this.props = props; - this.tmpDirName = RpcPropertyDefs.getProperty(this.props, - PropertyDefs.P4JAVA_TMP_DIR_KEY, - System.getProperty(SYSTEM_TMPDIR_PROPS_KEY)); - + this.tmpDirName = RpcPropertyDefs.getProperty(this.props, PropertyDefs.P4JAVA_TMP_DIR_KEY, System.getProperty(SYSTEM_TMPDIR_PROPS_KEY)); + if (tmpDirName == null) { // This can really only happen if someone has nuked or played with // the JVM's system props before we get here... the default will // work for most non-Windows boxes in most cases, and may not be // needed in many cases anyway. - + tmpDirName = SYSTEM_TMPDIR_DEFAULT; - - Log.warn("Unable to get tmp name from P4 props or System; using " - + tmpDirName + " instead"); - + + Log.warn("Unable to get tmp name from P4 props or System; using " + tmpDirName + " instead"); + } } - + /** - * Implement a non-interactive version of the three-way client-side merge.

+ * Implement a non-interactive version of the three-way client-side merge. + * + * @param rpcConnection rpcConnection + * @param cmdEnv cmdEnv + * @param resultsMap resultsMap + * @param twoWayMerge twoWayMerge + * @return RpcPacketDispatcherResult + * @throws ConnectionException on error */ - protected RpcPacketDispatcherResult clientOpenMerge3(RpcConnection rpcConnection, - CommandEnv cmdEnv, Map resultsMap, boolean twoWayMerge) - throws ConnectionException { + protected RpcPacketDispatcherResult clientOpenMerge3(RpcConnection rpcConnection, CommandEnv cmdEnv, Map resultsMap, boolean twoWayMerge) throws ConnectionException { String clientPath = (String) resultsMap.get(RpcFunctionMapKey.PATH); String handle = (String) resultsMap.get(RpcFunctionMapKey.HANDLE); String resultTypeStr = (String) resultsMap.get(RpcFunctionMapKey.TYPE2); @@ -146,17 +142,17 @@ protected RpcPacketDispatcherResult clientOpenMerge3(RpcConnection rpcConnection String theirName = (String) resultsMap.get(RpcFunctionMapKey.THEIRNAME); String yourName = (String) resultsMap.get(RpcFunctionMapKey.YOURNAME); String showAll = (String) resultsMap.get(RpcFunctionMapKey.SHOWALL); - + // old servers do not send result type, apparently... - + if (resultTypeStr == null) { - resultTypeStr = clientTypeStr; + resultTypeStr = clientTypeStr; } - + ClientMergeState mergeState = null; - + RpcHandler handler = cmdEnv.getHandler(handle); - + if (handler == null) { handler = cmdEnv.new RpcHandler(handle, false, null); cmdEnv.addHandler(handler); @@ -164,47 +160,40 @@ protected RpcPacketDispatcherResult clientOpenMerge3(RpcConnection rpcConnection // Clear out any current key mappings to ensure files/streams aren't re-used: handler.getMap().remove(MERGE_STATE_KEY); } - + handler.setError(false); - RpcPerforceFileType clientType = RpcPerforceFileType.decodeFromServerString( - clientTypeStr); - ClientLineEnding clientLineEnd = ClientLineEnding.decodeFromServerString( - clientTypeStr, clientType); - RpcPerforceFileType resultType = RpcPerforceFileType.decodeFromServerString( - resultTypeStr); - ClientLineEnding resultLineEnd = ClientLineEnding.decodeFromServerString( - resultTypeStr, resultType); + RpcPerforceFileType clientType = RpcPerforceFileType.decodeFromServerString(clientTypeStr); + ClientLineEnding clientLineEnd = ClientLineEnding.decodeFromServerString(clientTypeStr, clientType); + RpcPerforceFileType resultType = RpcPerforceFileType.decodeFromServerString(resultTypeStr); + ClientLineEnding resultLineEnd = ClientLineEnding.decodeFromServerString(resultTypeStr, resultType); if (cmdEnv.getCmdSpec().getInMap() != null) { - + // This is an external stream merge; not much to do here except // load up the merge state and return... - - String tmpFileName = (String) cmdEnv.getCmdSpec().getInMap().get( - Client.MERGE_TMP_FILENAME_KEY); - mergeState = new ClientMergeState(clientPath, true, clientType, clientLineEnd, resultType, - resultLineEnd, this.tmpDirName, rpcConnection.getClientCharset()); + + String tmpFileName = (String) cmdEnv.getCmdSpec().getInMap().get(Client.MERGE_TMP_FILENAME_KEY); + mergeState = new ClientMergeState(clientPath, true, clientType, clientLineEnd, resultType, resultLineEnd, this.tmpDirName, rpcConnection.getClientCharset()); mergeState.setExternalTmpFilename(tmpFileName); mergeState.setShowAll(false); mergeState.setTwoWayMerge(twoWayMerge); mergeState.setTheirName(theirName); handler.getMap().put(MERGE_STATE_KEY, mergeState); - + return RpcPacketDispatcherResult.CONTINUE_LOOP; - + } else { - + // "Normal" three-way merge (limited in our case to non-interactive decisions); // this means we have a bit of setting up to do, in contrast to the external // stream merge case... - - mergeState = new ClientMergeState(clientPath, false, clientType, clientLineEnd, resultType, resultLineEnd, - this.tmpDirName, rpcConnection.getClientCharset()); + + mergeState = new ClientMergeState(clientPath, false, clientType, clientLineEnd, resultType, resultLineEnd, this.tmpDirName, rpcConnection.getClientCharset()); mergeState.setTwoWayMerge(twoWayMerge); mergeState.setBaseDigest(digest); handler.getMap().put(MERGE_STATE_KEY, mergeState); - + try { mergeState.setBaseName(baseName); mergeState.setTheirName(theirName); @@ -214,38 +203,35 @@ protected RpcPacketDispatcherResult clientOpenMerge3(RpcConnection rpcConnection } catch (IOException ioexc) { handler.setError(true); - cmdEnv.handleResult( - new RpcMessage( - ClientMessageId.CANT_CREATE_FILE, - MessageSeverityCode.E_FAILED, - MessageGenericCode.EV_CLIENT, - new String[] {clientPath, ioexc.getLocalizedMessage()} - ).toMap() - ); - + cmdEnv.handleResult(new RpcMessage(ClientMessageId.CANT_CREATE_FILE, MessageSeverityCode.E_FAILED, MessageGenericCode.EV_CLIENT, new String[]{clientPath, ioexc.getLocalizedMessage()}).toMap()); + return RpcPacketDispatcherResult.CONTINUE_LOOP; } - } - + } + return RpcPacketDispatcherResult.CONTINUE_LOOP; } /** - * Write merge data to the client if necessary.

- * + * Write merge data to the client if necessary. + *

* For the external stream merge case, this is a no op, but for the * normal three-way merge case, we not only need to write the relevant * files, but we also need to keep track of the differences so we can determine * whether an automatic and / or safe merge is even possible. This determination * is done in clientCloseMerge using chunk difference counts as supplied by the - * server in the bits parameter.

- * + * server in the bits parameter. + *

* For the two-way merge, all we really need to do is write the "their" file * and keep digesting under the covers... + * + * @param rpcConnection rpcConnection + * @param cmdEnv cmdEnv + * @param resultsMap resultsMap + * @return RpcPacketDispatcherResult + * @throws ConnectionException on error */ - protected RpcPacketDispatcherResult clientWriteMerge(RpcConnection rpcConnection, - CommandEnv cmdEnv, Map resultsMap) - throws ConnectionException { + protected RpcPacketDispatcherResult clientWriteMerge(RpcConnection rpcConnection, CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { String handle = (String) resultsMap.get(RpcFunctionMapKey.HANDLE); RpcHandler handler = cmdEnv.getHandler(handle); String bitsStr = (String) resultsMap.get(RpcFunctionMapKey.BITS); @@ -255,66 +241,59 @@ protected RpcPacketDispatcherResult clientWriteMerge(RpcConnection rpcConnection @SuppressWarnings("unused") // used for debugging int markersInFile = 0; boolean needNewline = false; - + String marker = MARKER_ORIGINAL; if (handler == null) { throw new NullPointerError("Null client handler in clientWriteMerge"); } - + if (handler.isError()) { return RpcPacketDispatcherResult.CONTINUE_LOOP; } - + try { - mergeState = (ClientMergeState) handler.getMap().get( - ClientMerge.MERGE_STATE_KEY); + mergeState = (ClientMergeState) handler.getMap().get(ClientMerge.MERGE_STATE_KEY); } catch (ClassCastException cce) { - Log.error("Bad client handler class in clientWriteMerge: " - + cce.getLocalizedMessage()); + Log.error("Bad client handler class in clientWriteMerge: " + cce.getLocalizedMessage()); Log.exception(cce); - throw new NullPointerError("Bad client handler class in clientWriteMerge: " - + cce.getLocalizedMessage()); + throw new NullPointerError("Bad client handler class in clientWriteMerge: " + cce.getLocalizedMessage()); } - + if (mergeState == null) { throw new NullPointerError("Null merge state in clientWriteMerge"); } - + if (mergeState.isExternalStreamMerge()) { // We ignore the data here because we already know the merge // result, which is in the external stream we deal with later // in closeMerge(). - + return RpcPacketDispatcherResult.CONTINUE_LOOP; } else if (mergeState.isTwoWayMerge()) { try { mergeState.writeTheirChunk(data); } catch (IOException ioexc) { - Log.error("I/O exception in clientWriteMerge: " - + ioexc.getLocalizedMessage()); + Log.error("I/O exception in clientWriteMerge: " + ioexc.getLocalizedMessage()); Log.exception(ioexc); handler.setError(true); } catch (FileDecoderException e) { - Log.error("Charset converstion exception in clientWriteMerge: " - + e.getLocalizedMessage()); + Log.error("Charset converstion exception in clientWriteMerge: " + e.getLocalizedMessage()); Log.exception(e); handler.setError(true); } catch (FileEncoderException e) { - Log.error("Charset converstion exception in clientWriteMerge: " - + e.getLocalizedMessage()); + Log.error("Charset converstion exception in clientWriteMerge: " + e.getLocalizedMessage()); Log.exception(e); handler.setError(true); } return RpcPacketDispatcherResult.CONTINUE_LOOP; } - + if (bitsStr != null) { try { bits = new Integer(bitsStr); } catch (Throwable thr) { - Log.error("Unexpected exception in clientWriteMerge: " - + thr.getLocalizedMessage()); + Log.error("Unexpected exception in clientWriteMerge: " + thr.getLocalizedMessage()); Log.exception(thr); handler.setError(true); } @@ -327,7 +306,7 @@ protected RpcPacketDispatcherResult clientWriteMerge(RpcConnection rpcConnection * * SEL_CONF indicates a conflict, and is set for each of the legs that * are in conflict, including the base. Thus for a conflict the follow - * sequence will be seen: + * sequence will be seen: * * SEL_CONF | SEL_BASE * SEL_CONF | SEL_LEG1 | SEL_RSLT @@ -345,188 +324,176 @@ protected RpcPacketDispatcherResult clientWriteMerge(RpcConnection rpcConnection * will have the last leg (typically "yours") rather than the original * unchanged base. */ - + // Logic below lifted pretty much as-is from the C++ API equivalent; // note deliberate fall-throughs and commented-out marker logic (which // will be implemented properly later for real interactive resolves). - + int oldBits = mergeState.getOldBits(); - + try { if ((oldBits != 0) && (oldBits != bits)) { switch (bits) { case SEL_BASE | SEL_CONF: mergeState.incrConflictChunks(); - + // DELIBERATE FALL-THROUGH... - + default: - case SEL_BASE: - case SEL_BASE | SEL_LEG1: - case SEL_BASE | SEL_LEG2: - marker = MARKER_ORIGINAL + mergeState.getBaseName(); - break; - - case SEL_LEG1 | SEL_RSLT: + case SEL_BASE: + case SEL_BASE | SEL_LEG1: + case SEL_BASE | SEL_LEG2: + marker = MARKER_ORIGINAL + mergeState.getBaseName(); + break; + + case SEL_LEG1 | SEL_RSLT: mergeState.incrTheirChunks(); // DELIBERATE FALL-THROUGH... - - case SEL_LEG1 | SEL_RSLT | SEL_CONF: + + case SEL_LEG1 | SEL_RSLT | SEL_CONF: marker = MARKER_THEIRS + mergeState.getTheirName(); break; - - case SEL_LEG2 | SEL_RSLT: + + case SEL_LEG2 | SEL_RSLT: mergeState.incrYourChunks(); // DELIBERATE FALL-THROUGH... - - case SEL_LEG2 | SEL_RSLT | SEL_CONF: - marker = MARKER_YOURS + mergeState.getYourName(); - break; - - case SEL_LEG1 | SEL_LEG2 | SEL_RSLT: - marker = MARKER_BOTH + mergeState.getTheirName() + " " + mergeState.getYourName(); + + case SEL_LEG2 | SEL_RSLT | SEL_CONF: + marker = MARKER_YOURS + mergeState.getYourName(); + break; + + case SEL_LEG1 | SEL_LEG2 | SEL_RSLT: + marker = MARKER_BOTH + mergeState.getTheirName() + " " + mergeState.getYourName(); mergeState.incrBothChunks(); break; - - case SEL_ALL: - marker = MARKER_END; + + case SEL_ALL: + marker = MARKER_END; break; } - if (mergeState.isShowAll() || ((bits & SEL_CONF) != 0) - || ((bits == SEL_ALL) && (oldBits & SEL_CONF) != 0)) { + if (mergeState.isShowAll() || ((bits & SEL_CONF) != 0) || ((bits == SEL_ALL) && (oldBits & SEL_CONF) != 0)) { + + mergeState.writeMarker(needNewline ? "\n" : "" + marker + "\n"); - mergeState.writeMarker( - needNewline ? "\n" : "" - + marker - + "\n"); - markersInFile++; if (needNewline) { needNewline = false; } } - } - + } + mergeState.setOldBits(bits); - + if ((data != null) && (data.length > 0)) { // Note: apparently we sometimes get back empty buffers as marker placeholders, // so we don't always get to execute this block... - + if ((bits & SEL_BASE) != 0) { mergeState.writeBaseChunk(data); } - + if ((bits & SEL_LEG1) != 0) { mergeState.writeTheirChunk(data); } - + if ((bits & SEL_LEG2) != 0) { // NOTE: this doesn't actually write anything to the file, // just updates the digest: - + mergeState.writeYourChunk(data); } - + if (((bits & SEL_RSLT) != 0) || (bits == (SEL_BASE | SEL_CONF))) { mergeState.writeResultChunk(data); } - + // If this block didn't end in a linefeed, we may need to add // one before putting out the next marker. This can happen if // some yoyo has a conflict on the last line of a file, and that // line has no newline. (comment from the C++ API...). - + if (data[data.length - 1] == '\n') { needNewline = true; } - + } } catch (IOException ioexc) { - Log.error("I/O exception in clientWriteMerge: " - + ioexc.getLocalizedMessage()); + Log.error("I/O exception in clientWriteMerge: " + ioexc.getLocalizedMessage()); Log.exception(ioexc); handler.setError(true); } catch (FileDecoderException e) { - Log.error("Charset converstion exception in clientWriteMerge: " - + e.getLocalizedMessage()); + Log.error("Charset converstion exception in clientWriteMerge: " + e.getLocalizedMessage()); Log.exception(e); handler.setError(true); } catch (FileEncoderException e) { - Log.error("Charset converstion exception in clientWriteMerge: " - + e.getLocalizedMessage()); + Log.error("Charset converstion exception in clientWriteMerge: " + e.getLocalizedMessage()); Log.exception(e); handler.setError(true); } - + return RpcPacketDispatcherResult.CONTINUE_LOOP; } - + /** * Close the merge write (above) and act on the results. The actions needed here * depend on whether we're doing a merge from external stream or a safe auto merge. + * + * @param rpcConnection rpcConnection + * @param cmdEnv cmdEnv + * @param resultsMap resultsMap + * @return RpcPacketDispatcherResult + * @throws ConnectionException on error */ - protected RpcPacketDispatcherResult clientCloseMerge(RpcConnection rpcConnection, - CommandEnv cmdEnv, Map resultsMap) - throws ConnectionException { - + protected RpcPacketDispatcherResult clientCloseMerge(RpcConnection rpcConnection, CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { + String clientPath = (String) resultsMap.get(RpcFunctionMapKey.PATH); String handle = (String) resultsMap.get(RpcFunctionMapKey.HANDLE); String mergeConfirm = (String) resultsMap.get(RpcFunctionMapKey.MERGE_CONFIRM); String mergeDecline = (String) resultsMap.get(RpcFunctionMapKey.MERGE_DECLINE); String mergePerms = (String) resultsMap.get(RpcFunctionMapKey.MERGE_PERMS); String mergeAuto = (String) resultsMap.get(RpcFunctionMapKey.MERGE_AUTO); - + String mergeResponse = mergeConfirm; String mergeHow = null; String mergeForced = null; ClientMergeState mergeState = null; RpcHandler handler = cmdEnv.getHandler(handle); String digest = null; - + if (handler == null) { throw new NullPointerError("Null client handler in clientWriteMerge"); } try { - mergeState = (ClientMergeState) handler.getMap().get( - ClientMerge.MERGE_STATE_KEY); + mergeState = (ClientMergeState) handler.getMap().get(ClientMerge.MERGE_STATE_KEY); } catch (ClassCastException cce) { - Log.error("Bad client handler class in clientCloseMerge: " - + cce.getLocalizedMessage()); + Log.error("Bad client handler class in clientCloseMerge: " + cce.getLocalizedMessage()); Log.exception(cce); - throw new NullPointerError("Bad client handler class in clientCloseMerge: " - + cce.getLocalizedMessage()); + throw new NullPointerError("Bad client handler class in clientCloseMerge: " + cce.getLocalizedMessage()); } - + if (mergeState == null) { throw new NullPointerError("Null merge state in clientWriteMerge"); } - + if ((handler != null) && handler.isError()) { mergeResponse = mergeDecline; } else { - + boolean skip = false; if (cmdEnv.getCmdSpec().getInMap() != null) { String theirName = mergeState.getTheirName(); if (theirName != null) { - int theirRev = Integer.parseInt(theirName - .substring(theirName.lastIndexOf("#") + 1)); - if (cmdEnv.getCmdSpec().getInMap() - .containsKey(Client.MERGE_START_FROM_REV_KEY)) { - int startFromRev = (Integer) cmdEnv.getCmdSpec() - .getInMap() - .get(Client.MERGE_START_FROM_REV_KEY); + int theirRev = Integer.parseInt(theirName.substring(theirName.lastIndexOf("#") + 1)); + if (cmdEnv.getCmdSpec().getInMap().containsKey(Client.MERGE_START_FROM_REV_KEY)) { + int startFromRev = (Integer) cmdEnv.getCmdSpec().getInMap().get(Client.MERGE_START_FROM_REV_KEY); if (startFromRev != -1 && startFromRev > theirRev) { skip = true; } } - if (cmdEnv.getCmdSpec().getInMap() - .containsKey(Client.MERGE_END_FROM_REV_KEY)) { - int endFromRev = (Integer) cmdEnv.getCmdSpec() - .getInMap().get(Client.MERGE_END_FROM_REV_KEY); + if (cmdEnv.getCmdSpec().getInMap().containsKey(Client.MERGE_END_FROM_REV_KEY)) { + int endFromRev = (Integer) cmdEnv.getCmdSpec().getInMap().get(Client.MERGE_END_FROM_REV_KEY); if (endFromRev != -1 && endFromRev < theirRev) { skip = true; } @@ -538,42 +505,28 @@ protected RpcPacketDispatcherResult clientCloseMerge(RpcConnection rpcConnection } else if (mergeState.isExternalStreamMerge()) { // External stream merge; just get the tmp merge stream and declare // it to be the merge result. - - String tmpFileName = (String) cmdEnv.getCmdSpec().getInMap().get( - Client.MERGE_TMP_FILENAME_KEY); - + + String tmpFileName = (String) cmdEnv.getCmdSpec().getInMap().get(Client.MERGE_TMP_FILENAME_KEY); + if ((clientPath != null) && (tmpFileName != null)) { // Copy the tmp file to the target file: - - RpcPerforceFile tmpFile = new RpcPerforceFile(tmpFileName, - RpcPerforceFileType.FST_TEXT); + + RpcPerforceFile tmpFile = new RpcPerforceFile(tmpFileName, RpcPerforceFileType.FST_TEXT); if (!tmpFile.renameTo(new File(clientPath), true)) { // Was unable to rename or even copy the file to its target; // usually the sign of permissions problems, etc., that we can't // fix on the fly, so report it to the user and the log and don't // ack a confirm back to the server... - - Log.error("Rename failed completely in resolveFile (cause unknown); source file: " - + clientPath - + "; target file: " - + tmpFileName); - - cmdEnv.handleResult( - new RpcMessage( - ClientMessageId.FILE_MOVE_ERROR, - MessageSeverityCode.E_FAILED, - MessageGenericCode.EV_CLIENT, - new String[] {clientPath, "(cause unknown)"} - ).toMap() - ); + + Log.error("Rename failed completely in resolveFile (cause unknown); source file: " + clientPath + "; target file: " + tmpFileName); + + cmdEnv.handleResult(new RpcMessage(ClientMessageId.FILE_MOVE_ERROR, MessageSeverityCode.E_FAILED, MessageGenericCode.EV_CLIENT, new String[]{clientPath, "(cause unknown)"}).toMap()); mergeResponse = mergeDecline; } else { //Attempt to update perms if they are specified if (mergePerms != null) { - ISystemFileCommandsHelper fileCommands = SysFileHelperBridge - .getSysFileCommands(); - if (mergePerms - .equalsIgnoreCase(ClientSystemFileCommands.PERMS_RW)) { + ISystemFileCommandsHelper fileCommands = SysFileHelperBridge.getSysFileCommands(); + if (mergePerms.equalsIgnoreCase(ClientSystemFileCommands.PERMS_RW)) { fileCommands.setWritable(clientPath, true); } else { fileCommands.setWritable(clientPath, false); @@ -611,21 +564,21 @@ protected RpcPacketDispatcherResult clientCloseMerge(RpcConnection rpcConnection // Need to calculate fake chunk nunmbers based on the digests. // The logic below has been copied wholesale from the corresponding // C++ API methods... - + // Assign the chunk variables - there can be only one. - // - // base == yours, base != theirs, yours != theirs 1 theirs - // base != yours, base != theirs, yours != theirs 1 conflicting - // base != yours, base != theirs, yours == theirs 1 both - // base != yours, base == theirs, yours != theirs 1 yours - + // + // base == yours, base != theirs, yours != theirs 1 theirs + // base != yours, base != theirs, yours != theirs 1 conflicting + // base != yours, base != theirs, yours == theirs 1 both + // base != yours, base == theirs, yours != theirs 1 yours + String baseDigest = mergeState.getBaseDigest(); // from the initial open - String yourDigest = mergeState.getYourDigestString(); // ditto + String yourDigest = mergeState.getYourDigestString(); // ditto String theirDigest = mergeState.getTheirDigestString(); // as calculated during the writes - + // Theoretically, the string above should be non-null, but I'm not taking this // on faith just yet... - + if ((baseDigest != null) && (yourDigest != null) && baseDigest.equals(yourDigest)) { if ((theirDigest != null) && !baseDigest.equals(theirDigest)) { mergeState.setTheirChunks(1); @@ -643,125 +596,102 @@ protected RpcPacketDispatcherResult clientCloseMerge(RpcConnection rpcConnection // Traditional full non-interactive three-way auto / safe merge; need to // determine whether there were any conflicting chunks, and, if so, reject // the merge, otherwise accept the suitable source based on chunk counts. - + // First chmod "yours" if necessary; original commentary in C++ API follows below // (note that whatever mergePerms is set to, the C++ API just sets your file rw): - // Make user's file writeable for the duration of the resolve. - // We only do this if mergePerms is set for two reasons: 1) then - // we can be sure to revert the file to the proper perms below, - // 2) only servers which set mergePerms are smart enough to leave - // files opened for integ r/o to begin with. + // Make user's file writeable for the duration of the resolve. + // We only do this if mergePerms is set for two reasons: 1) then + // we can be sure to revert the file to the proper perms below, + // 2) only servers which set mergePerms are smart enough to leave + // files opened for integ r/o to begin with. ResolveChoice autoChoice = autoResolve(mergeState, mergeAuto); - + if (mergePerms != null) { - ISystemFileCommandsHelper fileCommands - = SysFileHelperBridge.getSysFileCommands(); - if ((clientPath != null) && !fileCommands.setWritable(clientPath, true)) { - // Note that failure here is OK on most platforms - // and situations, but we should probably do a better job - // in general -- HR. - - Log.warn("Unable to set merge target '" + clientPath - + "' permissions to writable; merge results should not be affected"); - } + ISystemFileCommandsHelper fileCommands = SysFileHelperBridge.getSysFileCommands(); + if ((clientPath != null) && !fileCommands.setWritable(clientPath, true)) { + // Note that failure here is OK on most platforms + // and situations, but we should probably do a better job + // in general -- HR. + + Log.warn("Unable to set merge target '" + clientPath + "' permissions to writable; merge results should not be affected"); + } } - + switch (autoChoice) { case SKIP: // Just politely decline the merge: mergeResponse = mergeDecline; break; - + case YOURS: mergeHow = MERGED_YOURS; digest = mergeState.getYourDigestString(); break; - + case THEIRS: mergeHow = MERGED_THEIRS; - mergeForced = MERGE_UNFORCED; // True for current limited implementation only + mergeForced = MERGE_UNFORCED; // True for current limited implementation only digest = mergeState.getTheirDigestString(); break; - + case MERGED: mergeHow = MERGED_MERGED; digest = mergeState.getMergeDigestString(); break; - + case EDIT: mergeHow = MERGED_EDITED; break; - - default: // Treat this like a skip for the moment + + default: // Treat this like a skip for the moment mergeResponse = mergeDecline; break; } - + try { - if (!mergeState.finishMerge(autoChoice)) { + if (!mergeState.finishMerge(autoChoice)) { // Was unable to rename or even copy the file to its target; // usually the sign of permissions problems, etc., that we can't // fix on the fly, so report it to the user and the log and don't // ack a confirm back to the server... - - Log.error("Rename failed completely in resolveFile (cause unknown); source file: " - + clientPath == null ? "" : clientPath); - - cmdEnv.handleResult( - new RpcMessage( - ClientMessageId.FILE_MOVE_ERROR, - MessageSeverityCode.E_FAILED, - MessageGenericCode.EV_CLIENT, - new String[] {clientPath == null ? "" : clientPath, - "(cause unknown)"} - ).toMap() - ); + + Log.error("Rename failed completely in resolveFile (cause unknown); source file: " + clientPath == null ? "" : clientPath); + + cmdEnv.handleResult(new RpcMessage(ClientMessageId.FILE_MOVE_ERROR, MessageSeverityCode.E_FAILED, MessageGenericCode.EV_CLIENT, new String[]{clientPath == null ? "" : clientPath, "(cause unknown)"}).toMap()); mergeResponse = mergeDecline; } else { - cmdEnv.handleResult( - new RpcMessage( - ClientMessageId.MERGE_MESSAGE3, - MessageSeverityCode.E_INFO, - MessageGenericCode.EV_CLIENT, - // "yours", "theirs", "both", "conflicting" - new String[] {"" + mergeState.getYourChunks(), - "" + mergeState.getTheirChunks(), - "" + mergeState.getBothChunks(), - "" + mergeState.getConflictChunks()} - ).toMap() - ); + cmdEnv.handleResult(new RpcMessage(ClientMessageId.MERGE_MESSAGE3, MessageSeverityCode.E_INFO, MessageGenericCode.EV_CLIENT, + // "yours", "theirs", "both", "conflicting" + new String[]{"" + mergeState.getYourChunks(), "" + mergeState.getTheirChunks(), "" + mergeState.getBothChunks(), "" + mergeState.getConflictChunks()}).toMap()); } } catch (IOException exc) { // Error in renaming; we'll decline the merge... mergeResponse = mergeDecline; - + Log.error("Unexpected I/O exception in closeMerge: " + exc.getLocalizedMessage()); Log.exception(exc); } - + // Set permissions back to whatever mergePerms is: - + if (mergePerms != null) { - ISystemFileCommandsHelper fileCommands - = SysFileHelperBridge.getSysFileCommands(); - - if ((clientPath != null) && !fileCommands.setWritable(clientPath, - mergePerms.equalsIgnoreCase(ClientSystemFileCommands.PERMS_RW))) { + ISystemFileCommandsHelper fileCommands = SysFileHelperBridge.getSysFileCommands(); + + if ((clientPath != null) && !fileCommands.setWritable(clientPath, mergePerms.equalsIgnoreCase(ClientSystemFileCommands.PERMS_RW))) { // Note that failure here is OK on most platforms // and situations, but we should probably do a better job // in general -- HR. - - Log.warn("Unable to set merge target '" + clientPath - + "' permissions back after merge; merge results should not be affected"); - } + + Log.warn("Unable to set merge target '" + clientPath + "' permissions back after merge; merge results should not be affected"); + } } } - + // Send a result back: - - Map respMap = new HashMap(); - + + Map respMap = new HashMap(); + if (mergeHow != null) { respMap.put(RpcFunctionMapKey.MERGE_HOW, mergeHow); } @@ -771,34 +701,32 @@ protected RpcPacketDispatcherResult clientCloseMerge(RpcConnection rpcConnection if (digest != null) { respMap.put(RpcFunctionMapKey.DIGEST, digest); } - + for (Map.Entry entry : resultsMap.entrySet()) { - if ((entry.getKey() != null) && !entry.getKey().equalsIgnoreCase(RpcFunctionMapKey.FUNCTION) - && !entry.getKey().equalsIgnoreCase(RpcFunctionMapKey.TYPE) - && !entry.getKey().equalsIgnoreCase(RpcFunctionMapKey.STATUS)) { + if ((entry.getKey() != null) && !entry.getKey().equalsIgnoreCase(RpcFunctionMapKey.FUNCTION) && !entry.getKey().equalsIgnoreCase(RpcFunctionMapKey.TYPE) && !entry.getKey().equalsIgnoreCase(RpcFunctionMapKey.STATUS)) { respMap.put(entry.getKey(), entry.getValue()); } } - RpcPacket respPacket = RpcPacket.constructRpcPacket( - mergeResponse, - respMap, - null); - + RpcPacket respPacket = RpcPacket.constructRpcPacket(mergeResponse, respMap, null); + rpcConnection.putRpcPacket(respPacket); } return RpcPacketDispatcherResult.CONTINUE_LOOP; } - + /** * Determine what we should do if we're doing an auto or safe merge. * Note that this version is only for non-interactive safe / auto merges; * later versions can overload this or extend the logic here radically. * Note also that we've added support for two-way merges (usually done * for binary files); this support may evolve with experience... + * + * @param mergeState mergeState + * @param mergeAuto mergeAuto + * @return ResolveChoice */ - private ResolveChoice autoResolve(ClientMergeState mergeState, String mergeAuto) { int conflictChunks = mergeState.getConflictChunks(); int theirChunks = mergeState.getTheirChunks(); @@ -821,7 +749,7 @@ private ResolveChoice autoResolve(ClientMergeState mergeState, String mergeAuto) /* If we have no unique changes, accept theirs */ /* If they have no unique changes, take ours */ /* If we both have changes -- merge or skip (if safe). */ - + if (mergeAuto != null) { if (mergeAuto.equalsIgnoreCase(SAFE_MERGE)) { safeMerge = true; @@ -829,18 +757,18 @@ private ResolveChoice autoResolve(ClientMergeState mergeState, String mergeAuto) forceMerge = true; } else if (mergeAuto.equalsIgnoreCase(AUTO_MERGE)) { autoMerge = true; - } + } } - + if (mergeState.isTwoWayMerge()) { if (conflictChunks > 0) { return ResolveChoice.SKIP; } - + if (yourChunks == 0) { return ResolveChoice.THEIRS; } - + return ResolveChoice.YOURS; } else { if (mergeAuto != null) { @@ -850,9 +778,9 @@ private ResolveChoice autoResolve(ClientMergeState mergeState, String mergeAuto) forceMerge = true; } else if (mergeAuto.equalsIgnoreCase(AUTO_MERGE)) { autoMerge = true; - } + } } - + if (conflictChunks > 0) { if (forceMerge) { return ResolveChoice.EDIT; @@ -863,18 +791,18 @@ private ResolveChoice autoResolve(ClientMergeState mergeState, String mergeAuto) return ResolveChoice.YOURS; } else if (yourChunks == 0) { return ResolveChoice.THEIRS; - } else { + } else { // No conflict, but both sides have chunks; action here depends // on whether we're doing a safe, forced, or auto merge: - + if (safeMerge) { return ResolveChoice.SKIP; } else if (forceMerge || autoMerge) { return ResolveChoice.MERGED; } } - - return ResolveChoice.SKIP; // Always the safe option at this point... + + return ResolveChoice.SKIP; // Always the safe option at this point... } } } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientMergeState.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientMergeState.java index e75e6bc..6305bfd 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientMergeState.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientMergeState.java @@ -25,7 +25,7 @@ * operations defined in ClientMerge. Modeled somewhat on the C++ API's * clientmerge3.cc object, but tuned more to our more limited purposes. * Also includes support for two-way merge, but this is currently less-well - * exercised and tested.

+ * exercised and tested. *

* Note: not particularly thread-safe, nor intended to be. */ @@ -98,12 +98,16 @@ public class ClientMergeState { protected String baseDigest = null; /** + * @param clientPath clientPath * @param externalStreamMerge set true if this is a merge from an external stream + * @param clientType clientType + * @param clientLineEnding clientLineEnding + * @param resultType resultType + * @param resultLineEnding resultLineEnding * @param tmpDir the name of a suitable directory for creating temporary files in + * @param charset charset */ - protected ClientMergeState(String clientPath, boolean externalStreamMerge, - RpcPerforceFileType clientType, ClientLineEnding clientLineEnding, RpcPerforceFileType resultType, ClientLineEnding resultLineEnding, - String tmpDir, Charset charset) { + protected ClientMergeState(String clientPath, boolean externalStreamMerge, RpcPerforceFileType clientType, ClientLineEnding clientLineEnding, RpcPerforceFileType resultType, ClientLineEnding resultLineEnding, String tmpDir, Charset charset) { this.externalStreamMerge = externalStreamMerge; this.clientPath = clientPath; this.clientType = clientType; @@ -112,8 +116,7 @@ protected ClientMergeState(String clientPath, boolean externalStreamMerge, this.resultLineEnding = resultLineEnding; this.charset = charset; if (tmpDir == null) { - throw new NullPointerError( - "null tmpdir passed to ClientMergeState constructor"); + throw new NullPointerError("null tmpdir passed to ClientMergeState constructor"); } this.tmpDir = tmpDir; } @@ -123,11 +126,12 @@ protected ClientMergeState(String clientPath, boolean externalStreamMerge, * file is the original client file, and doesn't need opening. The rest * are opened as tmp files in the system tmp directory; this isn't exactly * the same as the C++ API's behaviour (which opens them in the target directory) - * but it should be fairly safe.

+ * but it should be fairly safe. *

* Note that the file types for each file are copied from the C++ API usage; * I'm not entirely sure this arrangement always make sense... * + * @param rpcConnection rpcConnection * @throws IOException if there's been a problem opening any of the files. */ protected void openMergeFiles(RpcConnection rpcConnection) throws IOException { diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientMessage.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientMessage.java index 2897ffa..645f002 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientMessage.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientMessage.java @@ -7,7 +7,7 @@ import com.perforce.p4java.exception.NullPointerError; /** - * Perforce P4Java client error / info / warning messages.

+ * Perforce P4Java client error / info / warning messages. *

* These are messages that the P4Java API itself generates * rather than receives from the Perforce server. Most @@ -15,16 +15,16 @@ * C++ API class(es) and not all are currently used. The messages * defined here all use the common %arg% string interpolation * scheme that's used for messages coming in from the server - * in (e.g.) client-Message packets.

+ * in (e.g.) client-Message packets. *

* The errors here are not typically passed as-is back to the * end user, but are translated in the map-based server * implementation superclass ServerImpl to more generic - * P4Java exceptions or filespec statuses.

+ * P4Java exceptions or filespec statuses. *

* No attempt has (yet) been made to internationalise the * corresponding error strings, but that may happen in future - * releases of the API.

+ * releases of the API. *

* FIXME: what to do about P4Java-specific codes? -- HR.(Current * strategy is to simply use zero, as we don't actually extract error @@ -50,10 +50,10 @@ public enum ClientMessageType { /** * Basic message ID. Order here is not important; explanation of * each ID's meaning is generally given with the associated error - * string -- see the static ClientMessage array below...

+ * string -- see the static ClientMessage array below... *

* Not all codes are currently applicable, and some of these codes - * as P4Java-specific.

+ * as P4Java-specific. *

* Note that ID's are NOT the same as error codes; codes are given below * for each message as copied from the C++ API, and those codes are @@ -89,7 +89,8 @@ public enum ClientMessageId { FILE_DECODER_ERROR, // 17.3 UTF16 decoder FILE_ENCODER_ERROR, // 17.3 UTF16 encoder NO_MODIFIED_FILE, - NOT_UNDER_CLIENT_PATH + NOT_UNDER_CLIENT_PATH, + DIR_NOT_EMPTY } ; @@ -199,6 +200,10 @@ public enum ClientMessageId { 0, "%file% - decoding error.", new String[]{"file"}), + new ClientMessage(ClientMessageId.FILE_ENCODER_ERROR, + 0, + "%file% - encoding error.", + new String[]{"file"}), new ClientMessage(ClientMessageId.NO_MODIFIED_FILE, 0, "Can't %action% modified file %file%", @@ -207,14 +212,20 @@ public enum ClientMessageId { 38, "File %clientFile% is not inside permitted filesystem path %clientPath%", new String[]{"clientFile", "clientPath"}), + new ClientMessage(ClientMessageId.DIR_NOT_EMPTY, + 93, + "Directory %directory% is not empty.", + new String[]{"directory"}), }; /** * Return the ClientMessage associated with this ID, if any. * Never returns null, but will return the UNKNOWN message if it * can't find a match. + * + * @param id ClientMessageId + * @return ClientMessage */ - public static ClientMessage getClientMessage(ClientMessageId id) { if (id == null) { throw new NullPointerError( @@ -227,8 +238,7 @@ public static ClientMessage getClientMessage(ClientMessageId id) { } } - Log.warn( - "Unmatched error ID spec in ClientMessage.getClientMessage()"); + Log.warn("Unmatched error ID spec in ClientMessage.getClientMessage()"); return messages[0]; // i.e. UNKNOWN, unless someone moved it. } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientProgressReport.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientProgressReport.java index 5cbcd8c..5a0a7ba 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientProgressReport.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientProgressReport.java @@ -3,33 +3,35 @@ */ package com.perforce.p4java.impl.mapbased.rpc.func.client; -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; - import com.perforce.p4java.impl.mapbased.MapKeys; import com.perforce.p4java.impl.mapbased.rpc.CommandEnv; import com.perforce.p4java.impl.mapbased.rpc.RpcServer; import com.perforce.p4java.impl.mapbased.rpc.func.RpcFunctionMapKey; import com.perforce.p4java.impl.mapbased.rpc.func.RpcFunctionSpec; +import com.perforce.p4java.impl.mapbased.server.cmd.ResultMapParser; import com.perforce.p4java.server.CmdSpec; import com.perforce.p4java.server.callback.IProgressCallback; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + /** * Report the progress of the command tick by tick. */ public class ClientProgressReport { - + public static final String TRACE_PREFIX = "ClientProgressReport"; private static final String DATE_PATTERN = "yyyy/MM/dd HH:mm:ss"; private static final String DATE_PATTERN2 = "yyyy/MM/dd"; private static final Map cmdMap = new HashMap(); + static { cmdMap.put(CmdSpec.FSTAT.toString(), CmdSpec.FSTAT); cmdMap.put(CmdSpec.FILES.toString(), CmdSpec.FILES); @@ -40,27 +42,33 @@ public class ClientProgressReport { } protected RpcServer server = null; - + public ClientProgressReport(RpcServer server) { this.server = server; } - + /** * Do a quick and dirty probabilistic progress report. Does not try to be * too clever, but it does need to know something about the calling context * to be able to send something useful back. If the tick() callback is * called, this will return whatever the tick call returned, otherwise * it returns true (which is usually interpreted to mean "keep going"... + * + * @param progressCallback progressCallback + * @param cmdCallBackKey cmdCallBackKey + * @param funcSpec funcSpec + * @param cmdEnv cmdEnv + * @param resultsMap resultsMap + * @return ok */ - public boolean report(IProgressCallback progressCallback, int cmdCallBackKey, - RpcFunctionSpec funcSpec, CommandEnv cmdEnv, Map resultsMap) { - + public boolean report(IProgressCallback progressCallback, int cmdCallBackKey, RpcFunctionSpec funcSpec, CommandEnv cmdEnv, Map resultsMap) { + if (resultsMap != null) { // (We "know" cmdEnv, funcSpec, and progressCallback can't be null (famous last words...)). CmdSpec cmdSpec = cmdMap.get(cmdEnv.getCmdSpec().getCmdName()); - + String tickMarker = getTickMarker(cmdSpec, resultsMap); - + switch (funcSpec) { case CLIENT_FSTATINFO: // Only want to output stuff when it's significant; we can't always @@ -73,215 +81,209 @@ public boolean report(IProgressCallback progressCallback, int cmdCallBackKey, } } break; - + case CLIENT_OPENFILE: case CLIENT_SENDFILE: case CLIENT_OUTPUTBINARY: case CLIENT_OUTPUTTEXT: return progressCallback.tick(cmdCallBackKey, tickMarker); case CLIENT_MESSAGE: - tickMarker = server.getErrorOrInfoStr(resultsMap); + tickMarker = ResultMapParser.getErrorOrInfoStr(resultsMap); return progressCallback.tick(cmdCallBackKey, tickMarker); default: break; } } - + return true; } - + /** * Struggle mightily to get something useful to send back to the * consumer as a tick marker. This is sometimes difficult because * the Perforce server isn't particularly consistent in map key * name usage, etc.... + * + * @param cmdSpec cmdSpec + * @param resultsMap resultsMap + * @return result */ private String getTickMarker(CmdSpec cmdSpec, Map resultsMap) { String tickMarker = null; if (cmdSpec != null) { StringBuilder sb = null; switch (cmdSpec) { - case FSTAT: - final String[] fstatFields = { RpcFunctionMapKey.DEPOT_FILE, - RpcFunctionMapKey.CLIENT_FILE, RpcFunctionMapKey.ISMAPPED, - RpcFunctionMapKey.HEADACTION, RpcFunctionMapKey.HEADTYPE, - RpcFunctionMapKey.HEADTIME, RpcFunctionMapKey.HEADREV, - RpcFunctionMapKey.HEADCHANGE, RpcFunctionMapKey.HEADMODTIME, - RpcFunctionMapKey.HAVEREV }; - sb = new StringBuilder(); - for (String f : fstatFields) { - if (resultsMap.get(f) != null) { - if (sb.length() > 0) { - sb.append(CommandEnv.LINE_SEPARATOR); + case FSTAT: + final String[] fstatFields = {RpcFunctionMapKey.DEPOT_FILE, RpcFunctionMapKey.CLIENT_FILE, RpcFunctionMapKey.ISMAPPED, RpcFunctionMapKey.HEADACTION, RpcFunctionMapKey.HEADTYPE, RpcFunctionMapKey.HEADTIME, RpcFunctionMapKey.HEADREV, RpcFunctionMapKey.HEADCHANGE, RpcFunctionMapKey.HEADMODTIME, RpcFunctionMapKey.HAVEREV}; + sb = new StringBuilder(); + for (String f : fstatFields) { + if (resultsMap.get(f) != null) { + if (sb.length() > 0) { + sb.append(CommandEnv.LINE_SEPARATOR); + } + sb.append("... ").append(f).append(" ").append((String) resultsMap.get(f)); } - sb.append("... ").append(f).append(" ").append((String)resultsMap.get(f)); } - } - break; + break; - case FILES: - sb = new StringBuilder(); - if (resultsMap.get(RpcFunctionMapKey.DEPOT_FILE) != null) { - sb.append((String)resultsMap.get(RpcFunctionMapKey.DEPOT_FILE)); - } - if (resultsMap.get(RpcFunctionMapKey.REV) != null) { - sb.append("#").append((String)resultsMap.get(RpcFunctionMapKey.REV)); - } - if (resultsMap.get(RpcFunctionMapKey.ACTION) != null) { - sb.append(" - ").append((String)resultsMap.get(RpcFunctionMapKey.ACTION)); - } - if (resultsMap.get(RpcFunctionMapKey.CHANGE) != null) { - sb.append(" change ").append((String)resultsMap.get(RpcFunctionMapKey.CHANGE)); - } - if (resultsMap.get(RpcFunctionMapKey.TYPE) != null) { - sb.append(" (").append((String)resultsMap.get(RpcFunctionMapKey.TYPE)).append(")"); - } - break; + case FILES: + sb = new StringBuilder(); + if (resultsMap.get(RpcFunctionMapKey.DEPOT_FILE) != null) { + sb.append((String) resultsMap.get(RpcFunctionMapKey.DEPOT_FILE)); + } + if (resultsMap.get(RpcFunctionMapKey.REV) != null) { + sb.append("#").append((String) resultsMap.get(RpcFunctionMapKey.REV)); + } + if (resultsMap.get(RpcFunctionMapKey.ACTION) != null) { + sb.append(" - ").append((String) resultsMap.get(RpcFunctionMapKey.ACTION)); + } + if (resultsMap.get(RpcFunctionMapKey.CHANGE) != null) { + sb.append(" change ").append((String) resultsMap.get(RpcFunctionMapKey.CHANGE)); + } + if (resultsMap.get(RpcFunctionMapKey.TYPE) != null) { + sb.append(" (").append((String) resultsMap.get(RpcFunctionMapKey.TYPE)).append(")"); + } + break; - case SYNC: - sb = new StringBuilder(); - if (resultsMap.get(RpcFunctionMapKey.TOTALFILESIZE) != null) { - sb.append("... ").append("totalFileSize ").append((String)resultsMap.get(RpcFunctionMapKey.TOTALFILESIZE)); - } - if (resultsMap.get(RpcFunctionMapKey.TOTALFILECOUNT) != null) { + case SYNC: + sb = new StringBuilder(); + if (resultsMap.get(RpcFunctionMapKey.TOTALFILESIZE) != null) { + sb.append("... ").append("totalFileSize ").append((String) resultsMap.get(RpcFunctionMapKey.TOTALFILESIZE)); + } + if (resultsMap.get(RpcFunctionMapKey.TOTALFILECOUNT) != null) { + if (sb.length() > 0) { + sb.append(CommandEnv.LINE_SEPARATOR); + } + sb.append("... ").append("totalFileCount ").append((String) resultsMap.get(RpcFunctionMapKey.TOTALFILECOUNT)); + } if (sb.length() > 0) { sb.append(CommandEnv.LINE_SEPARATOR); } - sb.append("... ").append("totalFileCount ").append((String)resultsMap.get(RpcFunctionMapKey.TOTALFILECOUNT)); - } - if (sb.length() > 0) { - sb.append(CommandEnv.LINE_SEPARATOR); - } - if (resultsMap.get(RpcFunctionMapKey.DEPOT_FILE) != null) { - sb.append((String)resultsMap.get(RpcFunctionMapKey.DEPOT_FILE)); - } - if (resultsMap.get(RpcFunctionMapKey.REV) != null) { - sb.append("#").append((String)resultsMap.get(RpcFunctionMapKey.REV)); - } - if (resultsMap.get(RpcFunctionMapKey.ACTION) != null) { - sb.append(" - ").append((String)resultsMap.get(RpcFunctionMapKey.ACTION)); - } - if (resultsMap.get(RpcFunctionMapKey.CLIENT_FILE) != null) { - sb.append(" as ").append((String)resultsMap.get(RpcFunctionMapKey.CLIENT_FILE)); - } - break; + if (resultsMap.get(RpcFunctionMapKey.DEPOT_FILE) != null) { + sb.append((String) resultsMap.get(RpcFunctionMapKey.DEPOT_FILE)); + } + if (resultsMap.get(RpcFunctionMapKey.REV) != null) { + sb.append("#").append((String) resultsMap.get(RpcFunctionMapKey.REV)); + } + if (resultsMap.get(RpcFunctionMapKey.ACTION) != null) { + sb.append(" - ").append((String) resultsMap.get(RpcFunctionMapKey.ACTION)); + } + if (resultsMap.get(RpcFunctionMapKey.CLIENT_FILE) != null) { + sb.append(" as ").append((String) resultsMap.get(RpcFunctionMapKey.CLIENT_FILE)); + } + break; - case JOBS: - sb = new StringBuilder(); - if (resultsMap.get(MapKeys.JOB_KEY) != null) { - sb.append((String)resultsMap.get(MapKeys.JOB_KEY)); - } - if (resultsMap.get(MapKeys.DATE_KEY) != null) { - try { - Date date = parseDate((String)resultsMap.get(MapKeys.DATE_KEY), DATE_PATTERN); + case JOBS: + sb = new StringBuilder(); + if (resultsMap.get(MapKeys.JOB_KEY) != null) { + sb.append((String) resultsMap.get(MapKeys.JOB_KEY)); + } + if (resultsMap.get(MapKeys.DATE_KEY) != null) { + try { + Date date = parseDate((String) resultsMap.get(MapKeys.DATE_KEY), DATE_PATTERN); + String dateStr = formatDate(date, DATE_PATTERN2); + sb.append(" on ").append(dateStr); + } catch (ParseException e) { + // Do nothing + } + } + if (resultsMap.get(MapKeys.USER_KEY) != null) { + sb.append(" by ").append((String) resultsMap.get(MapKeys.USER_KEY)); + } + if (resultsMap.get(MapKeys.STATUS_KEY) != null) { + sb.append(" *").append((String) resultsMap.get(MapKeys.STATUS_KEY)).append("*"); + } + if (resultsMap.get(MapKeys.DESCRIPTION_KEY) != null) { + sb.append(" '").append((String) resultsMap.get(MapKeys.DESCRIPTION_KEY)).append("'"); + } + break; + + case CHANGES: + sb = new StringBuilder(); + if (resultsMap.get(RpcFunctionMapKey.CHANGE) != null) { + sb.append("Change ").append((String) resultsMap.get(RpcFunctionMapKey.CHANGE)); + } + if (resultsMap.get(RpcFunctionMapKey.TIME) != null) { + Date date = new Date(Long.parseLong((String) resultsMap.get(RpcFunctionMapKey.TIME)) * 1000); String dateStr = formatDate(date, DATE_PATTERN2); sb.append(" on ").append(dateStr); - } catch (ParseException e) { - // Do nothing } - } - if (resultsMap.get(MapKeys.USER_KEY) != null) { - sb.append(" by ").append((String)resultsMap.get(MapKeys.USER_KEY)); - } - if (resultsMap.get(MapKeys.STATUS_KEY) != null) { - sb.append(" *").append((String)resultsMap.get(MapKeys.STATUS_KEY)).append("*"); - } - if (resultsMap.get(MapKeys.DESCRIPTION_KEY) != null) { - sb.append(" '").append((String)resultsMap.get(MapKeys.DESCRIPTION_KEY)).append("'"); - } - break; - - case CHANGES: - sb = new StringBuilder(); - if (resultsMap.get(RpcFunctionMapKey.CHANGE) != null) { - sb.append("Change ").append((String)resultsMap.get(RpcFunctionMapKey.CHANGE)); - } - if (resultsMap.get(RpcFunctionMapKey.TIME) != null) { - Date date = new Date(Long.parseLong((String)resultsMap.get(RpcFunctionMapKey.TIME)) * 1000); - String dateStr = formatDate(date, DATE_PATTERN2); - sb.append(" on ").append(dateStr); - } - if (resultsMap.get(RpcFunctionMapKey.USER) != null) { - sb.append(" by ").append((String)resultsMap.get(RpcFunctionMapKey.USER)); - } - if (resultsMap.get(MapKeys.CLIENT_LC_KEY) != null) { - sb.append("@").append((String)resultsMap.get(MapKeys.CLIENT_LC_KEY)); - } - if (resultsMap.get(RpcFunctionMapKey.STATUS) != null) { - if (!((String)resultsMap.get(RpcFunctionMapKey.STATUS)).equalsIgnoreCase("submitted")) { - sb.append(" *").append((String)resultsMap.get(RpcFunctionMapKey.STATUS)).append("*"); + if (resultsMap.get(RpcFunctionMapKey.USER) != null) { + sb.append(" by ").append((String) resultsMap.get(RpcFunctionMapKey.USER)); + } + if (resultsMap.get(MapKeys.CLIENT_LC_KEY) != null) { + sb.append("@").append((String) resultsMap.get(MapKeys.CLIENT_LC_KEY)); + } + if (resultsMap.get(RpcFunctionMapKey.STATUS) != null) { + if (!((String) resultsMap.get(RpcFunctionMapKey.STATUS)).equalsIgnoreCase("submitted")) { + sb.append(" *").append((String) resultsMap.get(RpcFunctionMapKey.STATUS)).append("*"); + } + } + if (resultsMap.get(MapKeys.DESC_LC_KEY) != null) { + sb.append(" '").append((String) resultsMap.get(MapKeys.DESC_LC_KEY)).append("'"); } - } - if (resultsMap.get(MapKeys.DESC_LC_KEY) != null) { - sb.append(" '").append((String)resultsMap.get(MapKeys.DESC_LC_KEY)).append("'"); - } - break; + break; - case USERS: - sb = new StringBuilder(); - if (resultsMap.get(MapKeys.USER_KEY) != null) { - sb.append((String)resultsMap.get(MapKeys.USER_KEY)); - } - if (resultsMap.get(MapKeys.EMAIL_KEY) != null) { - sb.append(" <").append((String)resultsMap.get(MapKeys.EMAIL_KEY)).append(">"); - } - if (resultsMap.get(MapKeys.FULLNAME_KEY) != null) { - sb.append(" (").append((String)resultsMap.get(MapKeys.FULLNAME_KEY)).append(")"); - } - if (resultsMap.get(MapKeys.ACCESS_KEY) != null) { - Date date = new Date(Long.parseLong((String)resultsMap.get(MapKeys.ACCESS_KEY)) * 1000); - String dateStr = formatDate(date, DATE_PATTERN2); - sb.append(" accessed ").append(dateStr); - } - break; + case USERS: + sb = new StringBuilder(); + if (resultsMap.get(MapKeys.USER_KEY) != null) { + sb.append((String) resultsMap.get(MapKeys.USER_KEY)); + } + if (resultsMap.get(MapKeys.EMAIL_KEY) != null) { + sb.append(" <").append((String) resultsMap.get(MapKeys.EMAIL_KEY)).append(">"); + } + if (resultsMap.get(MapKeys.FULLNAME_KEY) != null) { + sb.append(" (").append((String) resultsMap.get(MapKeys.FULLNAME_KEY)).append(")"); + } + if (resultsMap.get(MapKeys.ACCESS_KEY) != null) { + Date date = new Date(Long.parseLong((String) resultsMap.get(MapKeys.ACCESS_KEY)) * 1000); + String dateStr = formatDate(date, DATE_PATTERN2); + sb.append(" accessed ").append(dateStr); + } + break; - default: - break; + default: + break; } if (sb != null && sb.length() > 0) { tickMarker = sb.toString(); } } - + return tickMarker; } - /** - * Parses the date. - * - * @param date - * the date - * @param pattern - * the pattern - * @return the date - * @throws ParseException - * the parse exception - */ - private Date parseDate(String date, String pattern) throws ParseException { - Date d = null; - if (date != null) { - DateFormat df = new SimpleDateFormat(pattern); - d = df.parse(date); - } - return d; - } + /** + * Parses the date. + * + * @param date the date + * @param pattern the pattern + * @return the date + * @throws ParseException the parse exception + */ + private Date parseDate(String date, String pattern) throws ParseException { + Date d = null; + if (date != null) { + DateFormat df = new SimpleDateFormat(pattern); + d = df.parse(date); + } + return d; + } - /** - * Format date. - * - * @param date - * the date - * @param pattern - * the pattern - * @return the string - */ - private String formatDate(Date date, String pattern) { - String d = null; - if (date != null) { - DateFormat df = new SimpleDateFormat(pattern); - d = df.format(date); - } - return d; - } + /** + * Format date. + * + * @param date the date + * @param pattern the pattern + * @return the string + */ + private String formatDate(Date date, String pattern) { + String d = null; + if (date != null) { + DateFormat df = new SimpleDateFormat(pattern); + d = df.format(date); + } + return d; + } } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientSendFile.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientSendFile.java index d549d3f..63ecd5d 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientSendFile.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientSendFile.java @@ -56,30 +56,30 @@ public class ClientSendFile { /** * Create a new rpc file sender + * + * @param props props */ protected ClientSendFile(Properties props) { this.props = props; } - - private long sendStream(InputStream stream, RpcConnection connection, String handle, String write, - MD5Digester digester, CommandEnv cmdEnv) throws ConnectionException, IOException { + + private long sendStream(InputStream stream, RpcConnection connection, String handle, String write, MD5Digester digester, CommandEnv cmdEnv) throws ConnectionException, IOException { long fileLength = 0; - + Map sendMap = new HashMap(); byte[] bytes = new byte[1024 * 64]; int bytesRead; while ((bytesRead = stream.read(bytes)) > 0) { byte[] readBytes = new byte[bytesRead]; - + System.arraycopy(bytes, 0, readBytes, 0, bytesRead); fileLength += bytesRead; sendMap.clear(); sendMap.put(RpcFunctionMapKey.DATA, readBytes); sendMap.put(RpcFunctionMapKey.HANDLE, handle); - RpcPacket sendPacket = RpcPacket.constructRpcPacket(write, - sendMap, null); - + RpcPacket sendPacket = RpcPacket.constructRpcPacket(write, sendMap, null); + connection.putRpcPacket(sendPacket); digester.update(readBytes); @@ -87,20 +87,23 @@ private long sendStream(InputStream stream, RpcConnection connection, String han } return fileLength; } - + /** * Send a file's contents back to the Perforce server. Notably assumes a * late model server... - * + *

* FIXME: digest stuff is not yet implemented -- HR. * FIXME: error handling is typically nearly non-existent -- HR. * FIXME: charset issues -- HR. * FIXME: rework to use proper flush protocol implementation -- HR. * + * @param rpcConnection rpcConnection + * @param cmdEnv cmdEnv + * @param resultsMap resultsMap * @return - result + * @throws ConnectionException on error */ - protected RpcPacketDispatcherResult sendFile(RpcConnection rpcConnection, CommandEnv cmdEnv, - Map resultsMap) throws ConnectionException { + protected RpcPacketDispatcherResult sendFile(RpcConnection rpcConnection, CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { cmdEnv.newHandler(); String clientPath = (String) resultsMap.get(RpcFunctionMapKey.PATH); @@ -129,13 +132,12 @@ protected RpcPacketDispatcherResult sendFile(RpcConnection rpcConnection, Comman InputStream inStream = null; MD5Digester digester = null; - String sProto = cmdEnv.getServerProtocolSpecsMap().containsKey(RpcFunctionMapKey.SERVER2) ? - (String)cmdEnv.getServerProtocolSpecsMap().get(RpcFunctionMapKey.SERVER2) : - (String)cmdEnv.getServerProtocolSpecsMap().get(RpcFunctionMapKey.SERVER); + String sProto = cmdEnv.getServerProtocolSpecsMap().containsKey(RpcFunctionMapKey.SERVER2) ? (String) cmdEnv.getServerProtocolSpecsMap().get(RpcFunctionMapKey.SERVER2) : (String) cmdEnv.getServerProtocolSpecsMap().get(RpcFunctionMapKey.SERVER); int serverProtocol = 0; try { serverProtocol = Integer.parseInt(sProto); - } catch (NumberFormatException nfe) {} + } catch (NumberFormatException nfe) { + } // 2016.2 submit + reopen chmod +RW upon success @@ -145,10 +147,9 @@ protected RpcPacketDispatcherResult sendFile(RpcConnection rpcConnection, Comman // 2014.2 submit --forcenoretransfer skips file transfer to call // dmsubmitfile directly, only fixing up file perms as needed. - if( skipDigestCheck != null ) - { - resultsMap.put( RpcFunctionMapKey.STATUS, "same" ); - resultsMap.put( RpcFunctionMapKey.SHA, skipDigestCheck ); + if (skipDigestCheck != null) { + resultsMap.put(RpcFunctionMapKey.STATUS, "same"); + resultsMap.put(RpcFunctionMapKey.SHA, skipDigestCheck); rpcConnection.clientConfirm(confirm, resultsMap); // Ignore failure to chmod file since the file may not exist @@ -195,7 +196,7 @@ protected RpcPacketDispatcherResult sendFile(RpcConnection rpcConnection, Comman modTime = System.currentTimeMillis(); } } - if( modTime != 0) { + if (modTime != 0) { modTime = modTime / 1000; } @@ -204,20 +205,17 @@ protected RpcPacketDispatcherResult sendFile(RpcConnection rpcConnection, Comman // 2014.1 server sends digest for shelve -a leaveunchanged // 2017.2 server sends sha1 for submit and digestType - if( digestType != null ) - { + if (digestType != null) { String localDigest = rpcConnection.getDigest(file.getFileType(), file, RpcPerforceDigestType.GetType(digestType)); - if( localDigest != null && localDigest.equals( serverDigest ) ) - { - resultsMap.put( RpcFunctionMapKey.STATUS, "same" ); - resultsMap.put( RpcFunctionMapKey.SHA, localDigest ); + if (localDigest != null && localDigest.equals(serverDigest)) { + resultsMap.put(RpcFunctionMapKey.STATUS, "same"); + resultsMap.put(RpcFunctionMapKey.SHA, localDigest); rpcConnection.clientConfirm(confirm, resultsMap); // We differ from classic here as // with 'submitunchanged' in the submitoptions set we // don't send a digest. - if( perms != null && revertUnchanged != null ) - { + if (perms != null && revertUnchanged != null) { //TODO npoole: Still to port /*if( depotTime && ( f->Stat() & FSF_WRITEABLE ) ) { @@ -268,7 +266,7 @@ protected RpcPacketDispatcherResult sendFile(RpcConnection rpcConnection, Comman */ // pre-2003.2 server, send modTime on open - if( modTime != 0 && !sendDigest ) { + if (modTime != 0 && !sendDigest) { resultsMap.put(RpcFunctionMapKey.TIME, "" + modTime); } @@ -303,9 +301,7 @@ protected RpcPacketDispatcherResult sendFile(RpcConnection rpcConnection, Comman // early protocol and state machine design -- HR. if (!file.exists() && file.getFileType() != RpcPerforceFileType.FST_SYMLINK) { handler.setError(true); - cmdEnv.handleResult(new RpcMessage(ClientMessageId.OS_FILE_READ_ERROR, - MessageSeverityCode.E_INFO, MessageGenericCode.EV_CLIENT, - new String[] { "open for read", clientPath + ": No such file or directory" }).toMap()); + cmdEnv.handleResult(new RpcMessage(ClientMessageId.OS_FILE_READ_ERROR, MessageSeverityCode.E_INFO, MessageGenericCode.EV_CLIENT, new String[]{"open for read", clientPath + ": No such file or directory"}).toMap()); } else { // Now to send the file contents: String symbolicLinkTarget = null; @@ -324,43 +320,31 @@ protected RpcPacketDispatcherResult sendFile(RpcConnection rpcConnection, Comman if (symbolicLinkTarget == null) { handler.setError(true); - cmdEnv.handleResult( - new RpcMessage(ClientMessageId.FILE_SEND_ERROR, MessageSeverityCode.E_FAILED, - MessageGenericCode.EV_CLIENT, new String[] { "symlink", clientPath }) - .toMap()); + cmdEnv.handleResult(new RpcMessage(ClientMessageId.FILE_SEND_ERROR, MessageSeverityCode.E_FAILED, MessageGenericCode.EV_CLIENT, new String[]{"symlink", clientPath}).toMap()); return RpcPacketDispatcherResult.CONTINUE_LOOP; } } digester = new MD5Digester(); - + Charset fileCharset = null; - if (RpcPerforceFileType.FST_UTF16 == file.getFileType() - || RpcPerforceFileType.FST_XUTF16 == file.getFileType()) { + if (RpcPerforceFileType.FST_UTF16 == file.getFileType() || RpcPerforceFileType.FST_XUTF16 == file.getFileType()) { fileCharset = CharsetDefs.UTF16; - } else if (RpcPerforceFileType.FST_UTF8 == file.getFileType() - || RpcPerforceFileType.FST_XUTF8 == file.getFileType()) { + } else if (RpcPerforceFileType.FST_UTF8 == file.getFileType() || RpcPerforceFileType.FST_XUTF8 == file.getFileType()) { fileCharset = CharsetDefs.UTF8; - } else if (RpcPerforceFileType.FST_UNICODE == file.getFileType() - || RpcPerforceFileType.FST_XUNICODE == file.getFileType()) { + } else if (RpcPerforceFileType.FST_UNICODE == file.getFileType() || RpcPerforceFileType.FST_XUNICODE == file.getFileType()) { // Server might have sent explicit charset here... fileCharset = rpcConnection.getClientCharset(); } - if ((!rpcConnection.isUnicodeServer() && fileCharset != CharsetDefs.UTF16) - || fileCharset == null - || fileCharset.equals(CharsetDefs.UTF8) ) { - /* + if ((!rpcConnection.isUnicodeServer() && fileCharset != CharsetDefs.UTF16) || fileCharset == null || fileCharset.equals(CharsetDefs.UTF8)) { + /* * Not unicode enabled p4d server and filetype is utf-16 * Or unicode enabled p4d server and filetype is not unicode or we're already in the target charset */ - inStream = symbolicLinkTarget == null - ? new RpcInputStream(file, null) - : new ByteArrayInputStream(symbolicLinkTarget.getBytes()); // need to convert symbolicLinkTarget to utf8 + inStream = symbolicLinkTarget == null ? new RpcInputStream(file, null) : new ByteArrayInputStream(symbolicLinkTarget.getBytes()); // need to convert symbolicLinkTarget to utf8 } else { - - inStream = symbolicLinkTarget == null - ? new RpcInputStream(file, fileCharset) - : new ByteArrayInputStream(symbolicLinkTarget.getBytes()); + + inStream = symbolicLinkTarget == null ? new RpcInputStream(file, fileCharset) : new ByteArrayInputStream(symbolicLinkTarget.getBytes()); } fileLength = sendStream(inStream, rpcConnection, handle, write, digester, cmdEnv); @@ -416,8 +400,7 @@ protected RpcPacketDispatcherResult sendFile(RpcConnection rpcConnection, Comman } catch (Exception exc) { Log.exception(exc); handler.setError(true); - cmdEnv.handleResult(new RpcMessage(ClientMessageId.FILE_SEND_ERROR, MessageSeverityCode.E_FAILED, - MessageGenericCode.EV_CLIENT, new String[] { clientPath, exc.getLocalizedMessage() }).toMap()); + cmdEnv.handleResult(new RpcMessage(ClientMessageId.FILE_SEND_ERROR, MessageSeverityCode.E_FAILED, MessageGenericCode.EV_CLIENT, new String[]{clientPath, exc.getLocalizedMessage()}).toMap()); } return RpcPacketDispatcherResult.CONTINUE_LOOP; diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientSystemFileCommands.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientSystemFileCommands.java index bb81645..7468e29 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientSystemFileCommands.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientSystemFileCommands.java @@ -39,6 +39,7 @@ import com.perforce.p4java.impl.mapbased.rpc.sys.helper.SymbolicLinkHelper; import com.perforce.p4java.impl.mapbased.rpc.sys.helper.SysFileHelperBridge; import com.perforce.p4java.util.FilesHelper; +import org.apache.commons.lang3.exception.ExceptionUtils; import java.io.ByteArrayOutputStream; import java.io.File; @@ -47,6 +48,7 @@ import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; import java.nio.charset.Charset; +import java.nio.charset.UnmappableCharacterException; import java.util.Arrays; import java.util.HashMap; import java.util.List; @@ -80,8 +82,7 @@ public class ClientSystemFileCommands { private String tmpDirName = null; - private ISystemFileCommandsHelper fileCommands - = SysFileHelperBridge.getSysFileCommands(); + private ISystemFileCommandsHelper fileCommands = SysFileHelperBridge.getSysFileCommands(); // Keeping track of file data progress info private String filePath = null; @@ -90,14 +91,11 @@ public class ClientSystemFileCommands { private ClientSystemFileMatchCommands fileMatchCommands; - protected ClientSystemFileCommands(Properties props, RpcServer server, - ClientSystemFileMatchCommands fileMatchCommands) { + protected ClientSystemFileCommands(Properties props, RpcServer server, ClientSystemFileMatchCommands fileMatchCommands) { this.props = props; this.server = server; this.fileMatchCommands = fileMatchCommands; - this.tmpDirName = RpcPropertyDefs.getProperty(this.props, - PropertyDefs.P4JAVA_TMP_DIR_KEY, - System.getProperty(SYSTEM_TMPDIR_PROPS_KEY)); + this.tmpDirName = RpcPropertyDefs.getProperty(this.props, PropertyDefs.P4JAVA_TMP_DIR_KEY, System.getProperty(SYSTEM_TMPDIR_PROPS_KEY)); if (tmpDirName == null) { // This can really only happen if someone has nuked or played with @@ -107,17 +105,20 @@ protected ClientSystemFileCommands(Properties props, RpcServer server, tmpDirName = SYSTEM_TMPDIR_DEFAULT; - Log.warn("Unable to get tmp name from P4 props or System; using " - + tmpDirName + " instead"); + Log.warn("Unable to get tmp name from P4 props or System; using " + tmpDirName + " instead"); } } /** * Change the r/w (etc.) mode of a file locally. + * + * @param rpcConnection rpcConnection + * @param cmdEnv cmdEnv + * @param resultsMap resultsMap + * @return RpcPacketDispatcherResult + * @throws ConnectionException on error */ - - protected RpcPacketDispatcherResult chmodFile(RpcConnection rpcConnection, - CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { + protected RpcPacketDispatcherResult chmodFile(RpcConnection rpcConnection, CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { if (rpcConnection == null) { throw new NullPointerError("Null rpcConnection in chmodFile()."); @@ -171,19 +172,10 @@ protected RpcPacketDispatcherResult chmodFile(RpcConnection rpcConnection, break; } } else { - cmdEnv.handleResult( - new RpcMessage( - ClientMessageId.CANT_CHMOD_FILE, - MessageSeverityCode.E_INFO, - MessageGenericCode.EV_CLIENT, - new String[]{path} - ).toMap() - ); + cmdEnv.handleResult(new RpcMessage(ClientMessageId.CANT_CHMOD_FILE, MessageSeverityCode.E_INFO, MessageGenericCode.EV_CLIENT, new String[]{path}).toMap()); } } catch (NumberFormatException nfe) { - throw new ProtocolError( - "Unexpected conversion error in ClientSystemFileCommands.chmodFile: " - + nfe.getLocalizedMessage()); + throw new ProtocolError("Unexpected conversion error in ClientSystemFileCommands.chmodFile: " + nfe.getLocalizedMessage()); } catch (Exception exc) { // FIXME: better error handling here -- HR. @@ -198,10 +190,10 @@ protected RpcPacketDispatcherResult chmodFile(RpcConnection rpcConnection, * Open a client file for writing. We have to process things like NOCLOBBER, * and ensure we write to a temp file if a file already exists, etc. Much of * the logic here is straight from the C++ API, currently minus the OpenDiff - * functionality (which will probably be factored out elsewhere).

+ * functionality (which will probably be factored out elsewhere). *

* We also have to leave the associated file descriptor (or channel equivalent) - * lying around for the rest of the function sequence to be able to pick up.

+ * lying around for the rest of the function sequence to be able to pick up. *

* Note that we also now implement the 10.2 sync (etc.) transfer integrity * checks; this is actually fairly easy as it can be done on the raw (un-translated) @@ -209,14 +201,17 @@ protected RpcPacketDispatcherResult chmodFile(RpcConnection rpcConnection, * has to consider the translated data). We do most of this work in the RpcOutputStream * and RpcPerforceFile classes after setting things up here; closeFile does the final * round up and delivers the verdict. This all only happens if Server.nonCheckedSyncs - * is false.

+ * is false. *

* The temp file created here will be deleted in the subsequent closeFile() method call. + * + * @param rpcConnection rpcConnection + * @param cmdEnv cmdEnv + * @param resultsMap resultsMap + * @return RpcPacketDispatcherResult + * @throws ConnectionException on error */ - - protected RpcPacketDispatcherResult openFile(RpcConnection rpcConnection, - CommandEnv cmdEnv, Map resultsMap) - throws ConnectionException { + protected RpcPacketDispatcherResult openFile(RpcConnection rpcConnection, CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { if (rpcConnection == null) { throw new NullPointerError("Null rpcConnection in openFile()."); @@ -311,31 +306,15 @@ protected RpcPacketDispatcherResult openFile(RpcConnection rpcConnection, if (doChecksum) { if (!rpcConnection.getDigest(fileType, cfile.getFile(), RpcPerforceDigestType.GetType(digestType)).equals(digest)) { handler.setError(true); - cmdEnv.handleResult( - new RpcMessage( - ClientMessageId.NO_MODIFIED_FILE, - MessageSeverityCode.E_FAILED, - MessageGenericCode.EV_CLIENT, - new String[]{"update", clientPath} - ).toMap()); + cmdEnv.handleResult(new RpcMessage(ClientMessageId.NO_MODIFIED_FILE, MessageSeverityCode.E_FAILED, MessageGenericCode.EV_CLIENT, new String[]{"update", clientPath}).toMap()); return RpcPacketDispatcherResult.CONTINUE_LOOP; } } // Handle noclobber. - if (cfile.getFile().exists() - && cfile.getFile().isFile() - && (noClobber != null) - && cfile.getFile().canWrite()) { + if (cfile.getFile().exists() && cfile.getFile().isFile() && (noClobber != null) && cfile.getFile().canWrite()) { handler.setError(true); - cmdEnv.handleResult( - new RpcMessage( - ClientMessageId.CANT_CLOBBER, - MessageSeverityCode.E_FAILED, - MessageGenericCode.EV_CLIENT, - new String[]{clientPath} - ).toMap() - ); + cmdEnv.handleResult(new RpcMessage(ClientMessageId.CANT_CLOBBER, MessageSeverityCode.E_FAILED, MessageGenericCode.EV_CLIENT, new String[]{clientPath}).toMap()); return RpcPacketDispatcherResult.CONTINUE_LOOP; } @@ -395,14 +374,7 @@ protected RpcPacketDispatcherResult openFile(RpcConnection rpcConnection, if (!FilesHelper.mkdirs(cfile.getFile())) { handler.setError(true); - cmdEnv.handleResult( - new RpcMessage( - ClientMessageId.CANT_CREATE_DIR, - MessageSeverityCode.E_FAILED, - MessageGenericCode.EV_CLIENT, - new String[]{clientPath} - ).toMap() - ); + cmdEnv.handleResult(new RpcMessage(ClientMessageId.CANT_CREATE_DIR, MessageSeverityCode.E_FAILED, MessageGenericCode.EV_CLIENT, new String[]{clientPath}).toMap()); return RpcPacketDispatcherResult.CONTINUE_LOOP; } @@ -429,14 +401,7 @@ protected RpcPacketDispatcherResult openFile(RpcConnection rpcConnection, } } catch (IOException ioexc) { handler.setError(true); - cmdEnv.handleResult( - new RpcMessage( - ClientMessageId.CANT_CREATE_FILE, - MessageSeverityCode.E_FAILED, - MessageGenericCode.EV_CLIENT, - new String[]{clientPath, ioexc.getLocalizedMessage()} - ).toMap() - ); + cmdEnv.handleResult(new RpcMessage(ClientMessageId.CANT_CREATE_FILE, MessageSeverityCode.E_FAILED, MessageGenericCode.EV_CLIENT, new String[]{clientPath, ioexc.getLocalizedMessage()}).toMap()); return RpcPacketDispatcherResult.CONTINUE_LOOP; } @@ -461,9 +426,7 @@ protected RpcPacketDispatcherResult openFile(RpcConnection rpcConnection, throw p4je; } catch (Exception exc) { Log.exception(exc); - throw new P4JavaError( - "Unexpected exception in ClientSystemFileCommands.openFile: " - + exc.getLocalizedMessage() + exc, exc); + throw new P4JavaError("Unexpected exception in ClientSystemFileCommands.openFile: " + exc.getLocalizedMessage() + exc, exc); } return RpcPacketDispatcherResult.CONTINUE_LOOP; @@ -473,11 +436,14 @@ protected RpcPacketDispatcherResult openFile(RpcConnection rpcConnection, * Write file contents to the target file. This method assumes that * fileOpen has previously been called, and that the state map contains * at least one valid file output stream to write bytes to. + * + * @param rpcConnection rpcConnection + * @param cmdEnv cmdEnv + * @param resultsMap resultsMap + * @return RpcPacketDispatcherResult + * @throws ConnectionException on error */ - - protected RpcPacketDispatcherResult writeFile(RpcConnection rpcConnection, - CommandEnv cmdEnv, Map resultsMap) - throws ConnectionException { + protected RpcPacketDispatcherResult writeFile(RpcConnection rpcConnection, CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { if (rpcConnection == null) { throw new NullPointerError("Null rpcConnection in writeFile()."); @@ -503,15 +469,13 @@ protected RpcPacketDispatcherResult writeFile(RpcConnection rpcConnection, } if (stateMap == null) { - throw new NullPointerError( - "Null state map in ClientSystemFileCommands.writeFile()."); + throw new NullPointerError("Null state map in ClientSystemFileCommands.writeFile()."); } Map origArgs = cfile.getArgs(); if (origArgs == null) { - throw new NullPointerError( - "Null original argument map ClientSystemFileCommands.writeFile() state map"); + throw new NullPointerError("Null original argument map ClientSystemFileCommands.writeFile() state map"); } String path = (String) origArgs.get(RpcFunctionMapKey.PATH); @@ -528,21 +492,12 @@ protected RpcPacketDispatcherResult writeFile(RpcConnection rpcConnection, tmpPath.delete(); } catch (IOException e) { handler.setError(true); - cmdEnv.handleResult( - new RpcMessage( - ClientMessageId.CANT_DELETE_FILE, - MessageSeverityCode.E_FAILED, - MessageGenericCode.EV_CLIENT, - new String[]{"symlink tmpFile", linkPath} - ).toMap() - ); + cmdEnv.handleResult(new RpcMessage(ClientMessageId.CANT_DELETE_FILE, MessageSeverityCode.E_FAILED, MessageGenericCode.EV_CLIENT, new String[]{"symlink tmpFile", linkPath}).toMap()); } } if (linkPath != null) { - convertFileDataMap(resultsMap, - cmdEnv.getRpcConnection().getClientCharset(), - cmdEnv.getRpcConnection().isUnicodeServer()); + convertFileDataMap(resultsMap, cmdEnv.getRpcConnection().getClientCharset(), cmdEnv.getRpcConnection().isUnicodeServer()); String data = (String) resultsMap.get(RpcFunctionMapKey.DATA); if (data != null) { // Remove any newline characters @@ -557,14 +512,7 @@ protected RpcPacketDispatcherResult writeFile(RpcConnection rpcConnection, // Return error message since the symlink creation failed. // Possibly the OS doesn't have support for symlinks. handler.setError(true); - cmdEnv.handleResult( - new RpcMessage( - ClientMessageId.CANT_CREATE_FILE_TYPE, - MessageSeverityCode.E_FAILED, - MessageGenericCode.EV_CLIENT, - new String[]{"symlink", path} - ).toMap() - ); + cmdEnv.handleResult(new RpcMessage(ClientMessageId.CANT_CREATE_FILE_TYPE, MessageSeverityCode.E_FAILED, MessageGenericCode.EV_CLIENT, new String[]{"symlink", path}).toMap()); return RpcPacketDispatcherResult.CONTINUE_LOOP; } } @@ -579,8 +527,7 @@ protected RpcPacketDispatcherResult writeFile(RpcConnection rpcConnection, } if (outStream == null) { - throw new P4JavaError( - "No open file stream in ClientSystemFileCommands.writeFile()"); + throw new P4JavaError("No open file stream in ClientSystemFileCommands.writeFile()"); } try { @@ -596,42 +543,27 @@ protected RpcPacketDispatcherResult writeFile(RpcConnection rpcConnection, } } catch (FileDecoderException e) { handler.setError(true); - cmdEnv.handleResult( - new RpcMessage( - ClientMessageId.FILE_DECODER_ERROR, - MessageSeverityCode.E_FAILED, - MessageGenericCode.EV_CLIENT, - new String[]{path == null ? "" : path} - ).toMap() - ); - + cmdEnv.handleResult(new RpcMessage(ClientMessageId.FILE_DECODER_ERROR, MessageSeverityCode.E_FAILED, MessageGenericCode.EV_CLIENT, new String[]{path == null ? "" : path}).toMap()); Log.error("failed to decode file " + (path == null ? "" : path) + "; exception follows..."); Log.exception(e); } catch (FileEncoderException e) { handler.setError(true); - cmdEnv.handleResult( - new RpcMessage( - ClientMessageId.FILE_ENCODER_ERROR, - MessageSeverityCode.E_FAILED, - MessageGenericCode.EV_CLIENT, - new String[]{path == null ? "" : path} - ).toMap() - ); - + cmdEnv.handleResult(new RpcMessage(ClientMessageId.FILE_ENCODER_ERROR, MessageSeverityCode.E_FAILED, MessageGenericCode.EV_CLIENT, new String[]{path == null ? "" : path}).toMap()); Log.error("failed to encode file " + (path == null ? "" : path) + "; exception follows..."); Log.exception(e); + if (ExceptionUtils.getRootCause(e) instanceof UnmappableCharacterException) { + Log.warn("cleaning up file " + (path == null ? "" : path)); + try { + outStream.close(); + outStream.getFile().delete(); + } catch (IOException ex) { + Log.error("Unable to close file " + (path == null ? "" : path)); + Log.exception(ex); + } + } } catch (IOException e) { handler.setError(true); - cmdEnv.handleResult( - new RpcMessage( - ClientMessageId.FILE_WRITE_ERROR, - MessageSeverityCode.E_FAILED, - MessageGenericCode.EV_CLIENT, - new String[]{path == null ? "" : path, - e.getLocalizedMessage()} - ).toMap() - ); - + cmdEnv.handleResult(new RpcMessage(ClientMessageId.FILE_WRITE_ERROR, MessageSeverityCode.E_FAILED, MessageGenericCode.EV_CLIENT, new String[]{path == null ? "" : path, e.getLocalizedMessage()}).toMap()); Log.error("failed write for file " + (path == null ? "" : path) + "; exception follows..."); Log.exception(e); } @@ -639,8 +571,7 @@ protected RpcPacketDispatcherResult writeFile(RpcConnection rpcConnection, return RpcPacketDispatcherResult.CONTINUE_LOOP; } - private void writeToStream(byte[] sourceBytes, int start, int length, - OutputStream stream) throws IOException { + private void writeToStream(byte[] sourceBytes, int start, int length, OutputStream stream) throws IOException { if (ClientLineEnding.CONVERT_TEXT) { for (int i = start; i < length; i++) { if (sourceBytes[i] == ClientLineEnding.FST_L_LF_BYTES[0]) { @@ -654,8 +585,7 @@ private void writeToStream(byte[] sourceBytes, int start, int length, } } - private void translate(byte[] sourceBytes, CharsetConverter converter, - int length, OutputStream stream) throws IOException, FileDecoderException, FileEncoderException { + private void translate(byte[] sourceBytes, CharsetConverter converter, int length, OutputStream stream) throws IOException, FileDecoderException, FileEncoderException { int start = 0; if (ClientLineEnding.CONVERT_TEXT) { @@ -683,17 +613,22 @@ private void translate(byte[] sourceBytes, CharsetConverter converter, } /** - * Handles the client-OutputText command.

+ * Handles the client-OutputText command. + *

* Basically uses writeBinary (below) with the twist that we * currently throw an exception when we see the trans option (which - * we haven't implemented yet).

+ * we haven't implemented yet). *

* Note that -- like the C++ API -- no line end munging is performed -- we * just throw what's coming at us straight back to whoever's catching it... + * + * @param rpcConnection rpcConnection + * @param cmdEnv cmdEnv + * @param resultsMap resultsMap + * @return RpcPacketDispatcherResult + * @throws ConnectionException on error */ - protected RpcPacketDispatcherResult writeText(RpcConnection rpcConnection, - CommandEnv cmdEnv, Map resultsMap) - throws ConnectionException { + protected RpcPacketDispatcherResult writeText(RpcConnection rpcConnection, CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { if (rpcConnection == null) { throw new NullPointerError("Null rpcConnection in writeText()."); @@ -708,8 +643,7 @@ protected RpcPacketDispatcherResult writeText(RpcConnection rpcConnection, String trans = (String) resultsMap.get(RpcFunctionMapKey.TRANS); if ((trans != null) && !trans.equalsIgnoreCase("no")) { - throw new P4JavaError( - "trans arg not 'no' or null in writeText: " + trans); + throw new P4JavaError("trans arg not 'no' or null in writeText: " + trans); } final String handlerName = "writeText"; @@ -730,33 +664,28 @@ protected RpcPacketDispatcherResult writeText(RpcConnection rpcConnection, RpcOutputStream outStream = getTempOutputStream(cmdEnv); if (outStream == null) { - throw new NullPointerError( - "Null output stream in writeText state map"); + throw new NullPointerError("Null output stream in writeText state map"); } try { if ((outStream.getFD() != null) && outStream.getFD().valid()) { - byte[] sourceBytes = (byte[]) resultsMap - .get(RpcFunctionMapKey.DATA); + byte[] sourceBytes = (byte[]) resultsMap.get(RpcFunctionMapKey.DATA); int len = sourceBytes.length; int start = 0; // Check for trans being null here as it was already checked to // be either null or 'no' so null here signifies it is not 'no'. if (trans == null) { - CharsetConverter converter = (CharsetConverter) stateMap - .get(RpcServer.RPC_TMP_CONVERTER_KEY); + CharsetConverter converter = (CharsetConverter) stateMap.get(RpcServer.RPC_TMP_CONVERTER_KEY); if (converter == null) { Charset charset = rpcConnection.getClientCharset(); // Look inside results map vector to see if file is // utf-16 since the previous fstat into message will // set it if necessary - for (Map map : cmdEnv - .getResultMaps()) { + for (Map map : cmdEnv.getResultMaps()) { if (map.containsKey(MapKeys.TYPE_LC_KEY)) { - String type = map.get(MapKeys.TYPE_LC_KEY) - .toString(); + String type = map.get(MapKeys.TYPE_LC_KEY).toString(); if (MapKeys.UTF16_LC_KEY.equals(type)) { charset = CharsetDefs.UTF16; break; @@ -766,11 +695,8 @@ protected RpcPacketDispatcherResult writeText(RpcConnection rpcConnection, // Convert if client charset is not UTF-8 if (charset != CharsetDefs.UTF8) { - converter = new CharsetConverter( - CharsetDefs.UTF8, charset); - stateMap.put( - RpcServer.RPC_TMP_CONVERTER_KEY, - converter); + converter = new CharsetConverter(CharsetDefs.UTF8, charset); + stateMap.put(RpcServer.RPC_TMP_CONVERTER_KEY, converter); } } if (converter != null) { @@ -787,52 +713,32 @@ protected RpcPacketDispatcherResult writeText(RpcConnection rpcConnection, } } catch (IOException ioexc) { handler.setError(true); - cmdEnv.getResultMaps().add( - new RpcMessage( - ClientMessageId.FILE_WRITE_ERROR, - MessageSeverityCode.E_FAILED, - MessageGenericCode.EV_CLIENT, - new String[]{"tmp file", - ioexc.getLocalizedMessage()} - ).toMap() - ); + cmdEnv.getResultMaps().add(new RpcMessage(ClientMessageId.FILE_WRITE_ERROR, MessageSeverityCode.E_FAILED, MessageGenericCode.EV_CLIENT, new String[]{"tmp file", ioexc.getLocalizedMessage()}).toMap()); } catch (FileDecoderException e) { handler.setError(true); - cmdEnv.getResultMaps().add( - new RpcMessage( - ClientMessageId.FILE_WRITE_ERROR, - MessageSeverityCode.E_FAILED, - MessageGenericCode.EV_CLIENT, - new String[]{"tmp file", - e.getLocalizedMessage()} - ).toMap() - ); + cmdEnv.getResultMaps().add(new RpcMessage(ClientMessageId.FILE_WRITE_ERROR, MessageSeverityCode.E_FAILED, MessageGenericCode.EV_CLIENT, new String[]{"tmp file", e.getLocalizedMessage()}).toMap()); } catch (FileEncoderException e) { handler.setError(true); - cmdEnv.getResultMaps().add( - new RpcMessage( - ClientMessageId.FILE_WRITE_ERROR, - MessageSeverityCode.E_FAILED, - MessageGenericCode.EV_CLIENT, - new String[]{"tmp file", - e.getLocalizedMessage()} - ).toMap() - ); + cmdEnv.getResultMaps().add(new RpcMessage(ClientMessageId.FILE_WRITE_ERROR, MessageSeverityCode.E_FAILED, MessageGenericCode.EV_CLIENT, new String[]{"tmp file", e.getLocalizedMessage()}).toMap()); } return RpcPacketDispatcherResult.CONTINUE_LOOP; } /** - * A specialised method to handle the client-OutputBinary command.

+ * A specialised method to handle the client-OutputBinary command. *

* Note that this method fakes a handler to keep state around, and assumes * that the target (tmp) stream has been passed-in by the higher levels in * the cmdEnv state map. + * + * @param rpcConnection rpcConnection + * @param cmdEnv cmdEnv + * @param resultsMap resultsMap + * @return RpcPacketDispatcherResult + * @throws ConnectionException on error */ - protected RpcPacketDispatcherResult writeBinary(RpcConnection rpcConnection, - CommandEnv cmdEnv, Map resultsMap) - throws ConnectionException { + protected RpcPacketDispatcherResult writeBinary(RpcConnection rpcConnection, CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { if (rpcConnection == null) { throw new NullPointerError("Null rpcConnection in writeBinary()."); @@ -858,13 +764,12 @@ protected RpcPacketDispatcherResult writeBinary(RpcConnection rpcConnection, } @SuppressWarnings("unused") // used for debugging - Map stateMap = cmdEnv.getStateMap(); + Map stateMap = cmdEnv.getStateMap(); RpcOutputStream outStream = getTempOutputStream(cmdEnv); if (outStream == null) { - throw new NullPointerError( - "Null output stream in writeText state map"); + throw new NullPointerError("Null output stream in writeText state map"); } try { @@ -876,37 +781,13 @@ protected RpcPacketDispatcherResult writeBinary(RpcConnection rpcConnection, } } catch (IOException ioexc) { handler.setError(true); - cmdEnv.handleResult( - new RpcMessage( - ClientMessageId.FILE_WRITE_ERROR, - MessageSeverityCode.E_FAILED, - MessageGenericCode.EV_CLIENT, - new String[]{"tmp file", - ioexc.getLocalizedMessage()} - ).toMap() - ); + cmdEnv.handleResult(new RpcMessage(ClientMessageId.FILE_WRITE_ERROR, MessageSeverityCode.E_FAILED, MessageGenericCode.EV_CLIENT, new String[]{"tmp file", ioexc.getLocalizedMessage()}).toMap()); } catch (FileDecoderException e) { handler.setError(true); - cmdEnv.handleResult( - new RpcMessage( - ClientMessageId.FILE_WRITE_ERROR, - MessageSeverityCode.E_FAILED, - MessageGenericCode.EV_CLIENT, - new String[]{"tmp file", - e.getLocalizedMessage()} - ).toMap() - ); + cmdEnv.handleResult(new RpcMessage(ClientMessageId.FILE_WRITE_ERROR, MessageSeverityCode.E_FAILED, MessageGenericCode.EV_CLIENT, new String[]{"tmp file", e.getLocalizedMessage()}).toMap()); } catch (FileEncoderException e) { handler.setError(true); - cmdEnv.handleResult( - new RpcMessage( - ClientMessageId.FILE_WRITE_ERROR, - MessageSeverityCode.E_FAILED, - MessageGenericCode.EV_CLIENT, - new String[]{"tmp file", - e.getLocalizedMessage()} - ).toMap() - ); + cmdEnv.handleResult(new RpcMessage(ClientMessageId.FILE_WRITE_ERROR, MessageSeverityCode.E_FAILED, MessageGenericCode.EV_CLIENT, new String[]{"tmp file", e.getLocalizedMessage()}).toMap()); } return RpcPacketDispatcherResult.CONTINUE_LOOP; @@ -918,11 +799,14 @@ protected RpcPacketDispatcherResult writeBinary(RpcConnection rpcConnection, * and / or deleting other files, etc., and stitching up permissions, * etc. (we are often not allowed to change a file's executable bits * in places like /tmp, etc., so we do it here...). + * + * @param rpcConnection rpcConnection + * @param cmdEnv cmdEnv + * @param resultsMap resultsMap + * @return RpcPacketDispatcherResult + * @throws ConnectionException on error */ - - protected RpcPacketDispatcherResult closeFile(RpcConnection rpcConnection, - CommandEnv cmdEnv, Map resultsMap) - throws ConnectionException { + protected RpcPacketDispatcherResult closeFile(RpcConnection rpcConnection, CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { //FIXME(S): permissions, cleanup -- HR. @@ -990,21 +874,13 @@ protected RpcPacketDispatcherResult closeFile(RpcConnection rpcConnection, if (!cfile.isError() && cfile.getServerDigest() != null && commit != null) { if (!cfile.getDigest().equals(cfile.getServerDigest())) { - cmdEnv.handleResult( - new RpcMessage( - ClientMessageId.DIGEST_MISMATCH, - MessageSeverityCode.E_FAILED, - MessageGenericCode.EV_CLIENT, - new String[]{cfile.getFile().getName(), cfile.getDigest(), cfile.getServerDigest()} - ).toMap() - ); + cmdEnv.handleResult(new RpcMessage(ClientMessageId.DIGEST_MISMATCH, MessageSeverityCode.E_FAILED, MessageGenericCode.EV_CLIENT, new String[]{cfile.getFile().getName(), cfile.getDigest(), cfile.getServerDigest()}).toMap()); return RpcPacketDispatcherResult.CONTINUE_LOOP; } } if (cfile.getFile() == null) { - throw new NullPointerError( - "Null target file ClientSystemFileCommands.closeFile() state map"); + throw new NullPointerError("Null target file ClientSystemFileCommands.closeFile() state map"); } if (cfile.isError()) { @@ -1032,8 +908,7 @@ protected RpcPacketDispatcherResult closeFile(RpcConnection rpcConnection, Map origArgs = cfile.getArgs(); if (origArgs == null) { - throw new NullPointerError( - "Null original argument map ClientSystemFileCommands.closeFile() state map"); + throw new NullPointerError("Null original argument map ClientSystemFileCommands.closeFile() state map"); } String perms = (String) origArgs.get(RpcFunctionMapKey.PERMS); @@ -1041,8 +916,7 @@ protected RpcPacketDispatcherResult closeFile(RpcConnection rpcConnection, try { if (cfile.getTmpStream() != null) { if (cfile.getTmpFile() == null) { - throw new NullPointerError( - "Null tmp file ClientSystemFileCommands.writeFile() state map"); + throw new NullPointerError("Null tmp file ClientSystemFileCommands.writeFile() state map"); } // Before rename (move) tmp file to target file, @@ -1055,8 +929,7 @@ protected RpcPacketDispatcherResult closeFile(RpcConnection rpcConnection, cfile.getTmpStream().flush(); cfile.getTmpStream().close(); } catch (IOException e) { - Log.error("Flushing or closing stream failed in closeFile(); tmp file: " - + cfile.getFile().getName()); + Log.error("Flushing or closing stream failed in closeFile(); tmp file: " + cfile.getFile().getName()); } try { @@ -1074,19 +947,9 @@ protected RpcPacketDispatcherResult closeFile(RpcConnection rpcConnection, } catch (IOException e) { // Total failure occurred - was unable to rename // or even copy the file to its target. - Log.error("Rename/copy failed completely in closeFile(); tmp file: " - + cfile.getFile().getName() - + "; target file: " - + cfile.getFile().getName()); + Log.error("Rename/copy failed completely in closeFile(); tmp file: " + cfile.getFile().getName() + "; target file: " + cfile.getFile().getName()); handler.setError(true); - cmdEnv.handleResult( - new RpcMessage( - ClientMessageId.FILE_WRITE_ERROR, - MessageSeverityCode.E_FAILED, - MessageGenericCode.EV_CLIENT, - new String[]{cfile.getFile().getName(), e.getLocalizedMessage()} - ).toMap() - ); + cmdEnv.handleResult(new RpcMessage(ClientMessageId.FILE_WRITE_ERROR, MessageSeverityCode.E_FAILED, MessageGenericCode.EV_CLIENT, new String[]{cfile.getFile().getName(), e.getLocalizedMessage()}).toMap()); return RpcPacketDispatcherResult.CONTINUE_LOOP; } @@ -1096,17 +959,9 @@ protected RpcPacketDispatcherResult closeFile(RpcConnection rpcConnection, try { cfile.getStream().flush(); } catch (IOException e) { - Log.error("Flushing stream failed in closeFile(); tmp file: " - + cfile.getFile().getName()); + Log.error("Flushing stream failed in closeFile(); tmp file: " + cfile.getFile().getName()); handler.setError(true); - cmdEnv.handleResult( - new RpcMessage( - ClientMessageId.FILE_WRITE_ERROR, - MessageSeverityCode.E_FAILED, - MessageGenericCode.EV_CLIENT, - new String[]{cfile.getFile().getName(), e.getLocalizedMessage()} - ).toMap() - ); + cmdEnv.handleResult(new RpcMessage(ClientMessageId.FILE_WRITE_ERROR, MessageSeverityCode.E_FAILED, MessageGenericCode.EV_CLIENT, new String[]{cfile.getFile().getName(), e.getLocalizedMessage()}).toMap()); return RpcPacketDispatcherResult.CONTINUE_LOOP; } @@ -1119,17 +974,9 @@ protected RpcPacketDispatcherResult closeFile(RpcConnection rpcConnection, try { cfile.getTmpStream().flush(); } catch (IOException e) { - Log.error("Flushing stream failed in closeFile(); tmp file: " - + cfile.getFile().getName()); + Log.error("Flushing stream failed in closeFile(); tmp file: " + cfile.getFile().getName()); handler.setError(true); - cmdEnv.handleResult( - new RpcMessage( - ClientMessageId.FILE_WRITE_ERROR, - MessageSeverityCode.E_FAILED, - MessageGenericCode.EV_CLIENT, - new String[]{cfile.getFile().getName(), e.getLocalizedMessage()} - ).toMap() - ); + cmdEnv.handleResult(new RpcMessage(ClientMessageId.FILE_WRITE_ERROR, MessageSeverityCode.E_FAILED, MessageGenericCode.EV_CLIENT, new String[]{cfile.getFile().getName(), e.getLocalizedMessage()}).toMap()); return RpcPacketDispatcherResult.CONTINUE_LOOP; } @@ -1141,17 +988,9 @@ protected RpcPacketDispatcherResult closeFile(RpcConnection rpcConnection, try { cfile.getStream().flush(); } catch (IOException e) { - Log.error("Flushing stream failed in closeFile(); target file: " - + cfile.getFile().getName()); + Log.error("Flushing stream failed in closeFile(); target file: " + cfile.getFile().getName()); handler.setError(true); - cmdEnv.handleResult( - new RpcMessage( - ClientMessageId.FILE_WRITE_ERROR, - MessageSeverityCode.E_FAILED, - MessageGenericCode.EV_CLIENT, - new String[]{cfile.getFile().getName(), e.getLocalizedMessage()} - ).toMap() - ); + cmdEnv.handleResult(new RpcMessage(ClientMessageId.FILE_WRITE_ERROR, MessageSeverityCode.E_FAILED, MessageGenericCode.EV_CLIENT, new String[]{cfile.getFile().getName(), e.getLocalizedMessage()}).toMap()); return RpcPacketDispatcherResult.CONTINUE_LOOP; } @@ -1161,17 +1000,9 @@ protected RpcPacketDispatcherResult closeFile(RpcConnection rpcConnection, try { cfile.getStream().close(); } catch (IOException e) { - Log.warn("target file close error in ClientSystemFileCommands.closeFile(): " - + e.getLocalizedMessage()); + Log.warn("target file close error in ClientSystemFileCommands.closeFile(): " + e.getLocalizedMessage()); handler.setError(true); - cmdEnv.handleResult( - new RpcMessage( - ClientMessageId.FILE_WRITE_ERROR, - MessageSeverityCode.E_FAILED, - MessageGenericCode.EV_CLIENT, - new String[]{cfile.getFile().getName(), e.getLocalizedMessage()} - ).toMap() - ); + cmdEnv.handleResult(new RpcMessage(ClientMessageId.FILE_WRITE_ERROR, MessageSeverityCode.E_FAILED, MessageGenericCode.EV_CLIENT, new String[]{cfile.getFile().getName(), e.getLocalizedMessage()}).toMap()); return RpcPacketDispatcherResult.CONTINUE_LOOP; } @@ -1181,18 +1012,7 @@ protected RpcPacketDispatcherResult closeFile(RpcConnection rpcConnection, if ((serverDigest != null) && !cmdEnv.isNonCheckedSyncs()) { if (!serverDigest.equals(localDigest)) { handler.setError(true); - cmdEnv.handleResult( - new RpcMessage( - ClientMessageId.DIGEST_MISMATCH, - MessageSeverityCode.E_FAILED, - MessageGenericCode.EV_CLIENT, - new String[]{ - cfile.getFile().getPath(), - serverDigest, - localDigest - } - ).toMap() - ); + cmdEnv.handleResult(new RpcMessage(ClientMessageId.DIGEST_MISMATCH, MessageSeverityCode.E_FAILED, MessageGenericCode.EV_CLIENT, new String[]{cfile.getFile().getPath(), serverDigest, localDigest}).toMap()); return RpcPacketDispatcherResult.CONTINUE_LOOP; } } @@ -1239,22 +1059,18 @@ protected RpcPacketDispatcherResult closeFile(RpcConnection rpcConnection, cfile.getTmpStream().close(); } } catch (IOException ioexc) { - Log.warn("tmp file close error in ClientSystemFileCommands.closeFile(): " - + ioexc.getLocalizedMessage()); + Log.warn("tmp file close error in ClientSystemFileCommands.closeFile(): " + ioexc.getLocalizedMessage()); } try { if (cfile.getStream() != null) { cfile.getStream().close(); } } catch (IOException ioexc) { - Log.warn("target file close error in ClientSystemFileCommands.closeFile(): " - + ioexc.getLocalizedMessage()); + Log.warn("target file close error in ClientSystemFileCommands.closeFile(): " + ioexc.getLocalizedMessage()); } if (cfile.getTmpFile() != null) { if (cfile.getTmpFile().exists() && !cfile.getTmpFile().delete()) { - Log.warn("Unable to delete tmp file '" - + cfile.getTmpFile().getPath() - + "' in ClientSystemFileCommands.closeFile() -- unknown cause"); + Log.warn("Unable to delete tmp file '" + cfile.getTmpFile().getPath() + "' in ClientSystemFileCommands.closeFile() -- unknown cause"); } } } @@ -1266,9 +1082,14 @@ protected RpcPacketDispatcherResult closeFile(RpcConnection rpcConnection, /** * Move a file from one location to another. Supports the new 2009.1 smart * move command. + * + * @param rpcConnection rpcConnection + * @param cmdEnv cmdEnv + * @param resultsMap resultsMap + * @return RpcPacketDispatcherResult + * @throws ConnectionException on error */ - protected RpcPacketDispatcherResult moveFile(RpcConnection rpcConnection, - CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { + protected RpcPacketDispatcherResult moveFile(RpcConnection rpcConnection, CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { if (rpcConnection == null) { throw new NullPointerError("Null rpcConnection in moveFile()."); @@ -1306,34 +1127,37 @@ protected RpcPacketDispatcherResult moveFile(RpcConnection rpcConnection, handler.setError(false); if (!RpcPerforceFile.fileExists(fromFile, fromFstSymlink)) { - cmdEnv.handleResult( - new RpcMessage( - ClientMessageId.FILE_NONEXISTENT, - MessageSeverityCode.E_INFO, - MessageGenericCode.EV_CLIENT, - new String[]{clientPath} - ).toMap() - ); + cmdEnv.handleResult(new RpcMessage(ClientMessageId.FILE_NONEXISTENT, MessageSeverityCode.E_INFO, MessageGenericCode.EV_CLIENT, new String[]{clientPath}).toMap()); return RpcPacketDispatcherResult.CONTINUE_LOOP; } - boolean caseSensitive - = !(cmdEnv.getServerProtocolSpecsMap().containsKey(RpcFunctionMapKey.NOCASE)); + boolean targetIsSubdir = false; + // Either clientPath = A and targetPath = A/A + // or clientPath = A/A and targetPath = A + if ((clientPath.contains(targetPath) || targetPath.contains(clientPath))) { + + //targetPath is a directory subpath of clientPath + String[] contents = toFile.list(); + int count = 0; + if (contents != null) { + count = contents.length; + } + if (count == 1) { + //client file is the only object in target dir + targetIsSubdir = true; + } else if (count > 1) { + cmdEnv.handleResult(new RpcMessage(ClientMessageId.DIR_NOT_EMPTY, MessageSeverityCode.E_FAILED, MessageGenericCode.EV_CLIENT, new String[]{targetPath}).toMap()); + } + } - if (RpcPerforceFile.fileExists(toFile, toFstSymlink) && (!caseSensitive || !clientPath.equalsIgnoreCase(targetPath))) { + boolean caseSensitive = !(cmdEnv.getServerProtocolSpecsMap().containsKey(RpcFunctionMapKey.NOCASE)); + if (RpcPerforceFile.fileExists(toFile, toFstSymlink) && (!caseSensitive || !clientPath.equalsIgnoreCase(targetPath)) && !targetIsSubdir) { // Target file exists, but this could be a case change, in which case allow this only if // the server is case sensitive (logic copied directly from the C++ equivalent) // Not sure about the logic here -- seems odd to allow this... (HR). - cmdEnv.handleResult( - new RpcMessage( - ClientMessageId.CANT_CLOBBER, - MessageSeverityCode.E_FAILED, - MessageGenericCode.EV_CLIENT, - new String[]{targetPath} - ).toMap() - ); + cmdEnv.handleResult(new RpcMessage(ClientMessageId.CANT_CLOBBER, MessageSeverityCode.E_FAILED, MessageGenericCode.EV_CLIENT, new String[]{targetPath}).toMap()); return RpcPacketDispatcherResult.CONTINUE_LOOP; } @@ -1341,14 +1165,7 @@ protected RpcPacketDispatcherResult moveFile(RpcConnection rpcConnection, if (!FilesHelper.mkdirs(toFile)) { handler.setError(true); - cmdEnv.handleResult( - new RpcMessage( - ClientMessageId.CANT_CREATE_DIR, - MessageSeverityCode.E_FAILED, - MessageGenericCode.EV_CLIENT, - new String[]{targetPath} - ).toMap() - ); + cmdEnv.handleResult(new RpcMessage(ClientMessageId.CANT_CREATE_DIR, MessageSeverityCode.E_FAILED, MessageGenericCode.EV_CLIENT, new String[]{targetPath}).toMap()); return RpcPacketDispatcherResult.CONTINUE_LOOP; } @@ -1358,10 +1175,7 @@ protected RpcPacketDispatcherResult moveFile(RpcConnection rpcConnection, resultsMap.remove(RpcFunctionMapKey.FUNCTION); - RpcPacket respPacket = RpcPacket.constructRpcPacket( - confirm, - resultsMap, - null); + RpcPacket respPacket = RpcPacket.constructRpcPacket(confirm, resultsMap, null); rpcConnection.putRpcPacket(respPacket); } else { @@ -1370,19 +1184,9 @@ protected RpcPacketDispatcherResult moveFile(RpcConnection rpcConnection, /// fix on the fly, so report it to the user and the log and don't // ack a confirm back to the server... - Log.error("Rename failed completely in moveFile (cause unknown); source file: " - + clientPath - + "; target file: " - + targetPath); + Log.error("Rename failed completely in moveFile (cause unknown); source file: " + clientPath + "; target file: " + targetPath); - cmdEnv.handleResult( - new RpcMessage( - ClientMessageId.FILE_MOVE_ERROR, - MessageSeverityCode.E_FAILED, - MessageGenericCode.EV_CLIENT, - new String[]{clientPath, "(cause unknown)"} - ).toMap() - ); + cmdEnv.handleResult(new RpcMessage(ClientMessageId.FILE_MOVE_ERROR, MessageSeverityCode.E_FAILED, MessageGenericCode.EV_CLIENT, new String[]{clientPath, "(cause unknown)"}).toMap()); } if (rmdir != null) { @@ -1394,26 +1198,23 @@ protected RpcPacketDispatcherResult moveFile(RpcConnection rpcConnection, File dir = fromFile.getParentFile(); if (dir != null) { - /* - * Don't delete parent directories that are symbolic links. This mimics the - * server behaviour that prevents a subsequent sync filling a disc when there - * were symbolic links. - */ + /* + * Don't delete parent directories that are symbolic links. This mimics the + * server behaviour that prevents a subsequent sync filling a disc when there + * were symbolic links. + */ if (!SymbolicLinkHelper.isSymbolicLink(dir.getAbsolutePath()) && !dir.delete()) { - Log.stats("Unable to delete parent directory for delete for file '" - + clientPath + "'; (unknown cause)"); + Log.stats("Unable to delete parent directory for delete for file '" + clientPath + "'; (unknown cause)"); } } else { - Log.warn("Unable to open parent directory for delete for file '" - + clientPath + "'; (no parent directory)"); + Log.warn("Unable to open parent directory for delete for file '" + clientPath + "'; (no parent directory)"); } } return RpcPacketDispatcherResult.CONTINUE_LOOP; } - protected RpcPacketDispatcherResult deleteFile(RpcConnection rpcConnection, - CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { + protected RpcPacketDispatcherResult deleteFile(RpcConnection rpcConnection, CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { if (rpcConnection == null) { throw new NullPointerError("Null rpcConnection in deleteFile()."); @@ -1467,13 +1268,7 @@ protected RpcPacketDispatcherResult deleteFile(RpcConnection rpcConnection, } handler.setError(true); - cmdEnv.handleResult( - new RpcMessage( - ClientMessageId.NO_MODIFIED_FILE, - MessageSeverityCode.E_FAILED, - MessageGenericCode.EV_CLIENT, - new String[]{"delete", clientPath} - ).toMap()); + cmdEnv.handleResult(new RpcMessage(ClientMessageId.NO_MODIFIED_FILE, MessageSeverityCode.E_FAILED, MessageGenericCode.EV_CLIENT, new String[]{"delete", clientPath}).toMap()); return RpcPacketDispatcherResult.CONTINUE_LOOP; } } @@ -1481,8 +1276,7 @@ protected RpcPacketDispatcherResult deleteFile(RpcConnection rpcConnection, // Don't clobber poor file // noclobber, handle new to 99.1 // be safe about clientHandle being set - if (file.exists() && file.isFile() && (noClobber != null) - && file.canWrite() && clientHandle != null && !fstSymlink) { + if (file.exists() && file.isFile() && (noClobber != null) && file.canWrite() && clientHandle != null && !fstSymlink) { RpcHandler handler = cmdEnv.getHandler(clientHandle); if (handler == null) { @@ -1494,14 +1288,7 @@ protected RpcPacketDispatcherResult deleteFile(RpcConnection rpcConnection, } handler.setError(true); - cmdEnv.handleResult( - new RpcMessage( - ClientMessageId.CANT_CLOBBER, - MessageSeverityCode.E_FAILED, - MessageGenericCode.EV_CLIENT, - new String[]{clientPath} - ).toMap() - ); + cmdEnv.handleResult(new RpcMessage(ClientMessageId.CANT_CLOBBER, MessageSeverityCode.E_FAILED, MessageGenericCode.EV_CLIENT, new String[]{clientPath}).toMap()); return RpcPacketDispatcherResult.CONTINUE_LOOP; } @@ -1525,14 +1312,7 @@ protected RpcPacketDispatcherResult deleteFile(RpcConnection rpcConnection, // Unfortunately we have no ack or anything to give to the // server on file delete, so we just let this go with a warning... - cmdEnv.handleResult( - new RpcMessage( - ClientMessageId.CANT_DELETE_FILE, - MessageSeverityCode.E_FAILED, - MessageGenericCode.EV_CLIENT, - new String[]{clientPath} - ).toMap() - ); + cmdEnv.handleResult(new RpcMessage(ClientMessageId.CANT_DELETE_FILE, MessageSeverityCode.E_FAILED, MessageGenericCode.EV_CLIENT, new String[]{clientPath}).toMap()); return RpcPacketDispatcherResult.CONTINUE_LOOP; } @@ -1548,20 +1328,18 @@ protected RpcPacketDispatcherResult deleteFile(RpcConnection rpcConnection, do { dir = dir.getParentFile(); if (dir != null) { - /* - * Don't delete parent directories that are symbolic links. This mimics the - * server behaviour that prevents a subsequent sync filling a disc when there - * were symbolic links. - */ + /* + * Don't delete parent directories that are symbolic links. This mimics the + * server behaviour that prevents a subsequent sync filling a disc when there + * were symbolic links. + */ if (!SymbolicLinkHelper.isSymbolicLink(dir.getAbsolutePath()) && !dir.delete()) { - Log.stats("Unable to delete parent directory for delete for file '" - + clientPath + "'; (unknown cause)"); + Log.stats("Unable to delete parent directory for delete for file '" + clientPath + "'; (unknown cause)"); // Stop when unable to delete the parent directory break; } } else { - Log.warn("Unable to open parent directory for delete for file '" - + clientPath + "' (unknown cause)"); + Log.warn("Unable to open parent directory for delete for file '" + clientPath + "' (unknown cause)"); // Stop when unable to open the parent directory break; } @@ -1575,44 +1353,48 @@ protected RpcPacketDispatcherResult deleteFile(RpcConnection rpcConnection, * The infamous checkFile omnibus method, used to, well, check files * on the Perforce client side. Basically copied and transliterated * into Java from the C++ original; not all of it currently makes - * sense in a Java environment, but this will be fixed (HR).

+ * sense in a Java environment, but this will be fixed (HR). *

* Much of the work happens off-stage in the support methods * elsewhere. *

- * What follows is copied from the C++ API:

+ * What follows is copied from the C++ API: *

- * This routine, for compatibility purposes, has several modes.

+ * This routine, for compatibility purposes, has several modes. *

* 1. If clientType is set, we know the type and we're checking to see * if the file exists and (if digest is set) if the file has the same * fingerprint. We return this in "status" with a value of "missing", - * "exists", or "same". This starts around version 1742.

+ * "exists", or "same". This starts around version 1742. *

* 2. If clientType is unset, we're looking for the type of the file, * and we'll return it in "type". This is sort of overloaded, 'cause * it can also get set with pseudo-types like "missing". In this * case, we use the "xfiles" protocol check to make sure we don't - * return something the server doesn't expect.

- *

+	 * return something the server doesn't expect.
+	 * 
{@code
 	 * 	- xfiles unset: return text, binary.
 	 * 	- xfiles >= 0: also return xtext, xbinary.
 	 * 	- xfiles >= 1: also return symlink.
 	 * 	- xfiles >= 2; also return resource (mac resource file).
 	 * 	- xfiles >= 3; also return ubinary
 	 * 	- xfiles >= 4; also return apple
-	 * 
+ * }
* If forceType is set, we'll use that in preference over what * we've discovered. We still check the file (to make sure they're * not adding a directory, and so they get to right warning if * they add an empty file), but we'll just override that back to - * the (typemap's) forceType.

+ * the (typemap's) forceType. *

* We map empty/missing/unreadable into forceType/"text". + * + * @param rpcConnection rpcConnection + * @param cmdEnv cmdEnv + * @param resultsMap resultsMap + * @return RpcPacketDispatcherResult + * @throws ConnectionException on error */ - - protected RpcPacketDispatcherResult checkFile(RpcConnection rpcConnection, - CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { + protected RpcPacketDispatcherResult checkFile(RpcConnection rpcConnection, CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { if (rpcConnection == null) { throw new NullPointerError("Null rpcConnection in checkFile()."); @@ -1641,6 +1423,10 @@ protected RpcPacketDispatcherResult checkFile(RpcConnection rpcConnection, } catch (NumberFormatException nfe) { } + if (null == clientPath && (null != checkLinks || null != ignore || null == clientType)) { + return RpcPacketDispatcherResult.CONTINUE_LOOP; + } + if (digest != null && digestType != null) { return checkFileGraph(rpcConnection, cmdEnv, resultsMap); } @@ -1703,17 +1489,14 @@ protected RpcPacketDispatcherResult checkFile(RpcConnection rpcConnection, RpcFunctionSpec funcSpec = RpcFunctionSpec.decode(ignore); if (funcSpec == RpcFunctionSpec.CLIENT_ACK) { - if (confirm.length() > 0) { + if (null != confirm && confirm.length() > 0) { Map respMap = new HashMap(); for (Map.Entry entry : resultsMap.entrySet()) { if ((entry.getKey() != null) && !entry.getKey().equalsIgnoreCase(RpcFunctionMapKey.FUNCTION)) { respMap.put(entry.getKey(), entry.getValue()); } } - RpcPacket respPacket = RpcPacket.constructRpcPacket( - confirm, - respMap, - null); + RpcPacket respPacket = RpcPacket.constructRpcPacket(confirm, respMap, null); rpcConnection.putRpcPacket(respPacket); } @@ -1735,9 +1518,9 @@ protected RpcPacketDispatcherResult checkFile(RpcConnection rpcConnection, /* * If we do know the type, we want to know if it's missing. - * If it isn't missing and a digest is given, we want to know if - * it is the same. - */ + * If it isn't missing and a digest is given, we want to know if + * it is the same. + */ if (!RpcPerforceFile.fileExists(file, fstSymlink)) { status = "missing"; @@ -1759,22 +1542,13 @@ protected RpcPacketDispatcherResult checkFile(RpcConnection rpcConnection, // Infer the file type, since it's not given. File file = new File(clientPath); - fileType = RpcPerforceFileType.inferFileType(file, scan, - cmdEnv.getRpcConnection().isUnicodeServer(), - cmdEnv.getRpcConnection().getClientCharset()); + fileType = RpcPerforceFileType.inferFileType(file, scan, cmdEnv.getRpcConnection().isUnicodeServer(), cmdEnv.getRpcConnection().getClientCharset()); fstSymlink = (fileType == RpcPerforceFileType.FST_SYMLINK); if (!RpcPerforceFile.fileExists(file, fstSymlink)) { status = "missing"; - cmdEnv.handleResult( - new RpcMessage( - ClientMessageId.FILE_MISSING_ASSUMING_TYPE, - MessageSeverityCode.E_INFO, - MessageGenericCode.EV_CLIENT, - new String[]{clientPath, nType} - ).toMap() - ); + cmdEnv.handleResult(new RpcMessage(ClientMessageId.FILE_MISSING_ASSUMING_TYPE, MessageSeverityCode.E_INFO, MessageGenericCode.EV_CLIENT, new String[]{clientPath, nType}).toMap()); } String serverXLevelStr = (String) cmdEnv.getServerProtocolSpecsMap().get("xfiles"); @@ -1783,21 +1557,13 @@ protected RpcPacketDispatcherResult checkFile(RpcConnection rpcConnection, try { serverXLevel = new Integer(serverXLevelStr); } catch (NumberFormatException nfe) { - throw new ProtocolError( - "Unexpected number conversion exception in " - + TRACE_PREFIX + ".checkFile: " - + nfe.getLocalizedMessage(), nfe); + throw new ProtocolError("Unexpected number conversion exception in " + TRACE_PREFIX + ".checkFile: " + nfe.getLocalizedMessage(), nfe); } } boolean overSize = false; - RpcServerTypeStringSpec spec - = RpcPerforceFileType.getServerFileTypeString( - clientPath, - overSize, - fileType, - forceType, serverXLevel); + RpcServerTypeStringSpec spec = RpcPerforceFileType.getServerFileTypeString(clientPath, overSize, fileType, forceType, serverXLevel); if (spec.getServerTypeString() == null) { @@ -1829,26 +1595,19 @@ protected RpcPacketDispatcherResult checkFile(RpcConnection rpcConnection, respMap.put(RpcFunctionMapKey.STATUS, status); for (Map.Entry entry : resultsMap.entrySet()) { - if ((entry.getKey() != null) && !entry.getKey().equalsIgnoreCase(RpcFunctionMapKey.FUNCTION) - && !entry.getKey().equalsIgnoreCase(RpcFunctionMapKey.TYPE) - && !entry.getKey().equalsIgnoreCase(RpcFunctionMapKey.STATUS)) { + if ((entry.getKey() != null) && !entry.getKey().equalsIgnoreCase(RpcFunctionMapKey.FUNCTION) && !entry.getKey().equalsIgnoreCase(RpcFunctionMapKey.TYPE) && !entry.getKey().equalsIgnoreCase(RpcFunctionMapKey.STATUS)) { respMap.put(entry.getKey(), entry.getValue()); } } - RpcPacket respPacket = RpcPacket.constructRpcPacket( - confirm, - respMap, - null); + RpcPacket respPacket = RpcPacket.constructRpcPacket(confirm, respMap, null); rpcConnection.putRpcPacket(respPacket); return RpcPacketDispatcherResult.CONTINUE_LOOP; } - protected RpcPacketDispatcherResult checkFileGraph(RpcConnection rpcConnection, - CommandEnv cmdEnv, Map resultsMap) - throws ConnectionException { + protected RpcPacketDispatcherResult checkFileGraph(RpcConnection rpcConnection, CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { if (rpcConnection == null) { throw new NullPointerError("Null rpcConnection in checkFile()."); @@ -1873,8 +1632,7 @@ protected RpcPacketDispatcherResult checkFileGraph(RpcConnection rpcConnection, if (!RpcPerforceFile.fileExists(file, true)) { status = "missing"; } else { - if (rpcConnection.getDigest(RpcPerforceFileType.decodeFromServerString(clientType), file, - RpcPerforceDigestType.GetType(digestType)).equals(digest)) { + if (rpcConnection.getDigest(RpcPerforceFileType.decodeFromServerString(clientType), file, RpcPerforceDigestType.GetType(digestType)).equals(digest)) { status = "same"; } } @@ -1884,26 +1642,19 @@ protected RpcPacketDispatcherResult checkFileGraph(RpcConnection rpcConnection, respMap.put(RpcFunctionMapKey.STATUS, status); for (Map.Entry entry : resultsMap.entrySet()) { - if ((entry.getKey() != null) && !entry.getKey().equalsIgnoreCase(RpcFunctionMapKey.FUNCTION) - && !entry.getKey().equalsIgnoreCase(RpcFunctionMapKey.TYPE) - && !entry.getKey().equalsIgnoreCase(RpcFunctionMapKey.STATUS)) { + if ((entry.getKey() != null) && !entry.getKey().equalsIgnoreCase(RpcFunctionMapKey.FUNCTION) && !entry.getKey().equalsIgnoreCase(RpcFunctionMapKey.TYPE) && !entry.getKey().equalsIgnoreCase(RpcFunctionMapKey.STATUS)) { respMap.put(entry.getKey(), entry.getValue()); } } - RpcPacket respPacket = RpcPacket.constructRpcPacket( - confirm, - respMap, - null); + RpcPacket respPacket = RpcPacket.constructRpcPacket(confirm, respMap, null); rpcConnection.putRpcPacket(respPacket); return RpcPacketDispatcherResult.CONTINUE_LOOP; } - protected RpcPacketDispatcherResult convertFile( - RpcConnection rpcConnection, CommandEnv cmdEnv, - Map resultsMap) throws ConnectionException { + protected RpcPacketDispatcherResult convertFile(RpcConnection rpcConnection, CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { if (rpcConnection == null) { throw new NullPointerError("Null rpcConnection in convertFile()."); @@ -2026,33 +1777,28 @@ protected RpcPacketDispatcherResult convertFile( * Return the temp RPC output stream. If it doesn't exist, try to create a * new one only if the command is run from a "streamCmd" method or tracking * is enabled. + * + * @param cmdEnv cmdEnv + * @return RpcOutputStream + * @throws ConnectionException on error */ - public RpcOutputStream getTempOutputStream(CommandEnv cmdEnv) - throws ConnectionException { + public RpcOutputStream getTempOutputStream(CommandEnv cmdEnv) throws ConnectionException { if (cmdEnv == null) { - throw new NullPointerError( - "Null command env in ClientSystemFileCommands.getTempOutputStream()"); + throw new NullPointerError("Null command env in ClientSystemFileCommands.getTempOutputStream()"); } if (cmdEnv.getStateMap() == null) { - throw new NullPointerError( - "Null command env state map in ClientSystemFileCommands.getTempOutputStream()"); + throw new NullPointerError("Null command env state map in ClientSystemFileCommands.getTempOutputStream()"); } if (cmdEnv.getProtocolSpecs() == null) { - throw new NullPointerError( - "Null command env protocol specs in ClientSystemFileCommands.getTempOutputStream()"); + throw new NullPointerError("Null command env protocol specs in ClientSystemFileCommands.getTempOutputStream()"); } - RpcOutputStream outStream = (RpcOutputStream) cmdEnv.getStateMap().get( - RpcServer.RPC_TMP_OUTFILE_STREAM_KEY); + RpcOutputStream outStream = (RpcOutputStream) cmdEnv.getStateMap().get(RpcServer.RPC_TMP_OUTFILE_STREAM_KEY); if (outStream == null) { if (cmdEnv.isStreamCmd() || cmdEnv.getProtocolSpecs().isEnableTracking()) { try { - String tmpFileName = RpcPerforceFile - .createTempFileName(RpcPropertyDefs.getProperty( - this.server.getProperties(), - PropertyDefs.P4JAVA_TMP_DIR_KEY, - System.getProperty("java.io.tmpdir"))); + String tmpFileName = RpcPerforceFile.createTempFileName(RpcPropertyDefs.getProperty(this.server.getProperties(), PropertyDefs.P4JAVA_TMP_DIR_KEY, System.getProperty("java.io.tmpdir"))); RpcPerforceFile tmpFile = new RpcPerforceFile(tmpFileName, RpcPerforceFileType.FST_BINARY); outStream = RpcOutputStream.getTmpOutputStream(tmpFile); // Set the new temp RPC output stream to the command env state map @@ -2060,9 +1806,7 @@ public RpcOutputStream getTempOutputStream(CommandEnv cmdEnv) } catch (IOException ioexc) { Log.error("tmp file creation error: " + ioexc.getLocalizedMessage()); Log.exception(ioexc); - throw new ConnectionException("Unable to create temporary file for Perforce file retrieval; " + - "reason: " + ioexc.getLocalizedMessage(), - ioexc); + throw new ConnectionException("Unable to create temporary file for Perforce file retrieval; " + "reason: " + ioexc.getLocalizedMessage(), ioexc); } } } @@ -2084,9 +1828,7 @@ public Map convertFileDataMap(Map map, Charset c if (dataBytes != null) { try { - dataString = new String(dataBytes, charset == null ? - RpcConnection.NON_UNICODE_SERVER_CHARSET_NAME : - (isUnicodeServer ? CharsetDefs.UTF8_NAME : charset.name())); + dataString = new String(dataBytes, charset == null ? RpcConnection.NON_UNICODE_SERVER_CHARSET_NAME : (isUnicodeServer ? CharsetDefs.UTF8_NAME : charset.name())); map.put(RpcFunctionMapKey.DATA, dataString); } catch (UnsupportedEncodingException e) { Log.exception(e); @@ -2117,14 +1859,7 @@ private boolean validatePath(RpcConnection rpcConnection, CommandEnv cmdEnv, Cli if (cfile.isSymlink() && rpcConnection.getFilesysRestrictedSymlinks() == 1) { if (!SymbolicLinkHelper.isSymbolicLinkCapable()) { cfile.setError(true); - cmdEnv.handleResult( - new RpcMessage( - ClientMessageId.CANT_CREATE_FILE_TYPE, - MessageSeverityCode.E_FAILED, - MessageGenericCode.EV_CLIENT, - new String[]{"symlink", cfile.getFile().getAbsolutePath()} - ).toMap() - ); + cmdEnv.handleResult(new RpcMessage(ClientMessageId.CANT_CREATE_FILE_TYPE, MessageSeverityCode.E_FAILED, MessageGenericCode.EV_CLIENT, new String[]{"symlink", cfile.getFile().getAbsolutePath()}).toMap()); // Symlink not supported - return false return false; } @@ -2144,14 +1879,7 @@ private boolean validatePath(RpcConnection rpcConnection, CommandEnv cmdEnv, Cli } cfile.setError(true); - cmdEnv.handleResult( - new RpcMessage( - ClientMessageId.NOT_UNDER_CLIENT_PATH, - MessageSeverityCode.E_FAILED, - MessageGenericCode.EV_CLIENT, - new String[]{file, clientPath} - ).toMap() - ); + cmdEnv.handleResult(new RpcMessage(ClientMessageId.NOT_UNDER_CLIENT_PATH, MessageSeverityCode.E_FAILED, MessageGenericCode.EV_CLIENT, new String[]{file, clientPath}).toMap()); // Symlink or File is outside P4CLIENTPATH - return false return false; } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientSystemFileMatchCommands.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientSystemFileMatchCommands.java index 51dc658..196876b 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientSystemFileMatchCommands.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientSystemFileMatchCommands.java @@ -46,107 +46,100 @@ /** * Implements the simpler lower-level file commands that typically * correspond to system commands such as chmod, delete, etc. - * - * */ public class ClientSystemFileMatchCommands { - + public static final String TRACE_PREFIX = "ClientSystemFileCommands"; - + public static final String DEFAULT_TMPFILE_PFX = "p4j"; public static final String DEFAULT_TMPFILE_SFX = ".p4j"; - + public static final String SYSTEM_TMPDIR_PROPS_KEY = "java.io.tmpdir"; public static final String SYSTEM_TMPDIR_DEFAULT = "/tmp"; - + public static final String PERMS_RW = "rw"; - + // Reconcile handler map key for 'skipAdd' protected static final String RECONCILE_HANDLE = "skipAdd"; - + private Properties props = null; private RpcServer server = null; private ClientIgnoreChecker checker = null; - + private String tmpDirName = null; - + protected ClientSystemFileMatchCommands(Properties props, RpcServer server) { this.props = props; this.server = server; - this.tmpDirName = RpcPropertyDefs.getProperty(this.props, - PropertyDefs.P4JAVA_TMP_DIR_KEY, - System.getProperty(SYSTEM_TMPDIR_PROPS_KEY)); - + this.tmpDirName = RpcPropertyDefs.getProperty(this.props, PropertyDefs.P4JAVA_TMP_DIR_KEY, System.getProperty(SYSTEM_TMPDIR_PROPS_KEY)); + if (tmpDirName == null) { // This can really only happen if someone has nuked or played with // the JVM's system props before we get here... the default will // work for most non-Windows boxes in most cases, and may not be // needed in many cases anyway. - + tmpDirName = SYSTEM_TMPDIR_DEFAULT; - - Log.warn("Unable to get tmp name from P4 props or System; using " - + tmpDirName + " instead"); - + + Log.warn("Unable to get tmp name from P4 props or System; using " + tmpDirName + " instead"); + } } - - void openMatch(RpcConnection rpcConnection, - CommandEnv cmdEnv, Map resultsMap, ClientFile cfile) throws ConnectionException { - - // Follow on from clientOpenFile, not called by server directly. - // Grab RPC vars and attach them to the file handle so that - // clientCloseMatch can use them for N-way diffing. + void openMatch(RpcConnection rpcConnection, CommandEnv cmdEnv, Map resultsMap, ClientFile cfile) throws ConnectionException { - String fromFile = (String) resultsMap.get(RpcFunctionMapKey.FROM_FILE); - String key = (String) resultsMap.get(RpcFunctionMapKey.KEY); - String flags = (String) resultsMap.get(RpcFunctionMapKey.DIFF_FLAGS); - - if( fromFile == null || key == null ) { - throw new NullPointerException("Missing fromFile or key"); - } + // Follow on from clientOpenFile, not called by server directly. - cfile.getMatchDict().put( RpcFunctionMapKey.FROM_FILE , fromFile ); - cfile.getMatchDict().put( RpcFunctionMapKey.KEY, key ); - if( flags != null ) { - cfile.getMatchDict().put( RpcFunctionMapKey.DIFF_FLAGS, flags ); - } - - for( int i = 0 ; ; i++ ) { - String index = (String) resultsMap.get(RpcFunctionMapKey.INDEX + i); - String file = (String) resultsMap.get(RpcFunctionMapKey.TO_FILE + i ); - if (index == null || file == null) { - break; - } - cfile.getMatchDict().put( RpcFunctionMapKey.INDEX + i, index ); - cfile.getMatchDict().put( RpcFunctionMapKey.TO_FILE + i, file ); - } + // Grab RPC vars and attach them to the file handle so that + // clientCloseMatch can use them for N-way diffing. + + String fromFile = (String) resultsMap.get(RpcFunctionMapKey.FROM_FILE); + String key = (String) resultsMap.get(RpcFunctionMapKey.KEY); + String flags = (String) resultsMap.get(RpcFunctionMapKey.DIFF_FLAGS); + + if (fromFile == null || key == null) { + throw new NullPointerException("Missing fromFile or key"); + } + + cfile.getMatchDict().put(RpcFunctionMapKey.FROM_FILE, fromFile); + cfile.getMatchDict().put(RpcFunctionMapKey.KEY, key); + if (flags != null) { + cfile.getMatchDict().put(RpcFunctionMapKey.DIFF_FLAGS, flags); + } + + for (int i = 0; ; i++) { + String index = (String) resultsMap.get(RpcFunctionMapKey.INDEX + i); + String file = (String) resultsMap.get(RpcFunctionMapKey.TO_FILE + i); + if (index == null || file == null) { + break; + } + cfile.getMatchDict().put(RpcFunctionMapKey.INDEX + i, index); + cfile.getMatchDict().put(RpcFunctionMapKey.TO_FILE + i, file); + } } - - void closeMatch(RpcConnection rpcConnection, - CommandEnv cmdEnv, Map resultsMap, ClientFile cfile) throws ConnectionException { - - if (rpcConnection == null) { - throw new NullPointerError("Null rpcConnection in convertFile()."); - } - if (cmdEnv == null) { - throw new NullPointerError("Null cmdEnv in convertFile()."); - } - if (resultsMap == null) { - throw new NullPointerError("Null resultsMap in convertFile()."); - } - - // Follow on from clientCloseFile, not called by server directly. - - // Compare temp file to existing client files. Figure out the - // best match, along with a quantitative measure of how good - // the match was (lines matched vs total lines). Stash it - // in the handle so clientAckMatch can report it back. - - //String matchFile = null; - //String matchIndex = null; + + void closeMatch(RpcConnection rpcConnection, CommandEnv cmdEnv, Map resultsMap, ClientFile cfile) throws ConnectionException { + + if (rpcConnection == null) { + throw new NullPointerError("Null rpcConnection in convertFile()."); + } + if (cmdEnv == null) { + throw new NullPointerError("Null cmdEnv in convertFile()."); + } + if (resultsMap == null) { + throw new NullPointerError("Null resultsMap in convertFile()."); + } + + // Follow on from clientCloseFile, not called by server directly. + + // Compare temp file to existing client files. Figure out the + // best match, along with a quantitative measure of how good + // the match was (lines matched vs total lines). Stash it + // in the handle so clientAckMatch can report it back. + + //String matchFile = null; + //String matchIndex = null; /* XXX: still to port String fname = null; @@ -218,155 +211,152 @@ void closeMatch(RpcConnection rpcConnection, cfile.getMatchDict().put( RpcFunctionMapKey.UPPER, totalLines ); } */ - // clientAckMatch will send this back + // clientAckMatch will send this back + } + + protected RpcPacketDispatcherResult ackMatch(RpcConnection rpcConnection, CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { + + if (rpcConnection == null) { + throw new NullPointerError("Null rpcConnection in convertFile()."); + } + if (cmdEnv == null) { + throw new NullPointerError("Null cmdEnv in convertFile()."); + } + if (resultsMap == null) { + throw new NullPointerError("Null resultsMap in convertFile()."); + } + + String confirm = (String) resultsMap.get(RpcFunctionMapKey.CONFIRM); + String clientHandle = (String) resultsMap.get(RpcFunctionMapKey.HANDLE); + + // Get handle. + + RpcHandler handler = cmdEnv.getHandler(clientHandle); + ClientFile cfile = new ClientFile(handler); + + // Fire everything back. + + String fromFile = cfile.getMatchDict().get(RpcFunctionMapKey.FROM_FILE); + String key = cfile.getMatchDict().get(RpcFunctionMapKey.KEY); + String toFile = cfile.getMatchDict().get(RpcFunctionMapKey.TO_FILE); + String index = cfile.getMatchDict().get(RpcFunctionMapKey.INDEX); + String lower = cfile.getMatchDict().get(RpcFunctionMapKey.LOWER); + String upper = cfile.getMatchDict().get(RpcFunctionMapKey.UPPER); + + if (fromFile != null && key != null) { + resultsMap.put(RpcFunctionMapKey.FROM_FILE, fromFile); + resultsMap.put(RpcFunctionMapKey.KEY, key); + } else { + throw new RuntimeException("Required parameter 'fromFile/key' not set!"); + } + + if (toFile != null && index != null && lower != null && upper != null) { + resultsMap.put(RpcFunctionMapKey.TO_FILE, toFile); + resultsMap.put(RpcFunctionMapKey.INDEX, index); + resultsMap.put(RpcFunctionMapKey.LOWER, lower); + resultsMap.put(RpcFunctionMapKey.UPPER, upper); + } + + rpcConnection.clientConfirm(confirm, resultsMap); + + return RpcPacketDispatcherResult.CONTINUE_LOOP; + } + + protected RpcPacketDispatcherResult exactMatch(RpcConnection rpcConnection, CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { + + if (rpcConnection == null) { + throw new NullPointerError("Null rpcConnection in exactMatch()."); + } + if (cmdEnv == null) { + throw new NullPointerError("Null cmdEnv in exactMatch()."); + } + if (resultsMap == null) { + throw new NullPointerError("Null resultsMap in exactMatch()."); + } + + // Compare existing digest to list of + // new client files, return match, or not. + + // Args: + // type = existing file type (clientpart) + // digest = existing file digest + // fileSize = existing file size + // charSet = existing file charset + // toFileN = new file local path + // indexN = new file index + // confirm = return callback + // + // Return: + // toFile = exact match + // index = exact match + + cmdEnv.newHandler(); + String clientType = (String) resultsMap.get(RpcFunctionMapKey.TYPE); + String digest = (String) resultsMap.get(RpcFunctionMapKey.DIGEST); + String confirm = (String) resultsMap.get(RpcFunctionMapKey.CONFIRM); + + if (confirm == null) { + throw new NullPointerError("No confirm value."); + } + + String matchFile = null; + String matchIndex = null; + + for (int i = 0; resultsMap.containsKey(RpcFunctionMapKey.TO_FILE + i); i++) { + + File f = new File((String) resultsMap.get(RpcFunctionMapKey.TO_FILE + i)); + RpcPerforceFileType fileType = RpcPerforceFileType.decodeFromServerString(clientType); + // If we encounter a problem with a file, we just don't return + // it as a match. No need to blat out lots of errors. + + if (f == null || digest == null) { + continue; + } + + // Skip files that are symlinks when we + // aren't looking for symlinks. + + if (!(f.exists() || RpcPerforceFileType.isProbablySymLink(f)) || (!RpcPerforceFileType.isProbablySymLink(f) && fileType == RpcPerforceFileType.FST_SYMLINK) || (RpcPerforceFileType.isProbablySymLink(f) && fileType != RpcPerforceFileType.FST_SYMLINK)) { + continue; + } + + String localDigest = digestFile(f, fileType, rpcConnection.getClientCharset()); + + if (localDigest == null) { + continue; + } + + if (!localDigest.equals(digest)) { + matchFile = (String) resultsMap.get(RpcFunctionMapKey.TO_FILE + i); + matchIndex = (String) resultsMap.get(RpcFunctionMapKey.INDEX + i); + break; // doesn't get any better + } + } + + if (matchFile != null && matchIndex != null) { + resultsMap.put(RpcFunctionMapKey.TO_FILE, matchFile); + resultsMap.put(RpcFunctionMapKey.INDEX, matchIndex); + } + + rpcConnection.clientConfirm(confirm, resultsMap); + + return RpcPacketDispatcherResult.CONTINUE_LOOP; } - protected RpcPacketDispatcherResult ackMatch(RpcConnection rpcConnection, - CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { - - if (rpcConnection == null) { - throw new NullPointerError("Null rpcConnection in convertFile()."); - } - if (cmdEnv == null) { - throw new NullPointerError("Null cmdEnv in convertFile()."); - } - if (resultsMap == null) { - throw new NullPointerError("Null resultsMap in convertFile()."); - } - - String confirm = (String) resultsMap.get(RpcFunctionMapKey.CONFIRM); - String clientHandle = (String) resultsMap.get(RpcFunctionMapKey.HANDLE); - - // Get handle. - - RpcHandler handler = cmdEnv.getHandler(clientHandle); - ClientFile cfile = new ClientFile(handler); - - // Fire everything back. - - String fromFile = cfile.getMatchDict().get( RpcFunctionMapKey.FROM_FILE ); - String key = cfile.getMatchDict().get( RpcFunctionMapKey.KEY ); - String toFile = cfile.getMatchDict().get( RpcFunctionMapKey.TO_FILE ); - String index = cfile.getMatchDict().get( RpcFunctionMapKey.INDEX ); - String lower = cfile.getMatchDict().get( RpcFunctionMapKey.LOWER ); - String upper = cfile.getMatchDict().get( RpcFunctionMapKey.UPPER ); - - if( fromFile != null && key != null ) { - resultsMap.put(RpcFunctionMapKey.FROM_FILE, fromFile); - resultsMap.put(RpcFunctionMapKey.KEY, key); - } else { - throw new RuntimeException("Required parameter 'fromFile/key' not set!"); - } - - if( toFile != null && index != null && lower != null && upper != null ) { - resultsMap.put( RpcFunctionMapKey.TO_FILE, toFile ); - resultsMap.put( RpcFunctionMapKey.INDEX, index ); - resultsMap.put( RpcFunctionMapKey.LOWER, lower ); - resultsMap.put( RpcFunctionMapKey.UPPER, upper ); - } - - rpcConnection.clientConfirm(confirm, resultsMap); - - return RpcPacketDispatcherResult.CONTINUE_LOOP; - } - - protected RpcPacketDispatcherResult exactMatch( - RpcConnection rpcConnection, CommandEnv cmdEnv, - Map resultsMap) throws ConnectionException { - - if (rpcConnection == null) { - throw new NullPointerError("Null rpcConnection in exactMatch()."); - } - if (cmdEnv == null) { - throw new NullPointerError("Null cmdEnv in exactMatch()."); - } - if (resultsMap == null) { - throw new NullPointerError("Null resultsMap in exactMatch()."); - } - - // Compare existing digest to list of - // new client files, return match, or not. - - // Args: - // type = existing file type (clientpart) - // digest = existing file digest - // fileSize = existing file size - // charSet = existing file charset - // toFileN = new file local path - // indexN = new file index - // confirm = return callback - // - // Return: - // toFile = exact match - // index = exact match - - cmdEnv.newHandler(); - String clientType = (String) resultsMap.get( RpcFunctionMapKey.TYPE ); - String digest = (String) resultsMap.get( RpcFunctionMapKey.DIGEST ); - String confirm = (String) resultsMap.get( RpcFunctionMapKey.CONFIRM ); - - if( confirm == null ) { - throw new NullPointerError("No confirm value."); - } - - String matchFile = null; - String matchIndex = null; - - for( int i = 0 ; - resultsMap.containsKey( RpcFunctionMapKey.TO_FILE + i ); - i++ ) { - - File f = new File((String) resultsMap.get( RpcFunctionMapKey.TO_FILE + i )); - RpcPerforceFileType fileType = RpcPerforceFileType.decodeFromServerString(clientType); - // If we encounter a problem with a file, we just don't return - // it as a match. No need to blat out lots of errors. - - if (f == null || digest == null) { - continue; - } - - // Skip files that are symlinks when we - // aren't looking for symlinks. - - if( !( f.exists() || RpcPerforceFileType.isProbablySymLink(f) ) - || ( !RpcPerforceFileType.isProbablySymLink(f) && fileType == RpcPerforceFileType.FST_SYMLINK ) - || ( RpcPerforceFileType.isProbablySymLink(f) && fileType != RpcPerforceFileType.FST_SYMLINK ) ) { - continue; - } - - String localDigest = digestFile(f, fileType, rpcConnection.getClientCharset()); - - if( localDigest == null ) { - continue; - } - - if( !localDigest.equals( digest ) ) { - matchFile = (String) resultsMap.get( RpcFunctionMapKey.TO_FILE + i ); - matchIndex = (String) resultsMap.get( RpcFunctionMapKey.INDEX + i ); - break; // doesn't get any better - } - } - - if( matchFile != null && matchIndex != null ) { - resultsMap.put( RpcFunctionMapKey.TO_FILE, matchFile ); - resultsMap.put( RpcFunctionMapKey.INDEX, matchIndex ); - } - - rpcConnection.clientConfirm( confirm, resultsMap ); - - return RpcPacketDispatcherResult.CONTINUE_LOOP; - } - /** - * "inquire" about file, for 'p4 reconcile'

- * + * "inquire" about file, for 'p4 reconcile' + *

* This routine performs clientCheckFile's scenario 1 checking, but also * saves the list of files that are in the depot so they can be compared to * the list of files on the client when reconciling later for add. + * + * @param rpcConnection rpcConnection + * @param cmdEnv cmdEnv + * @param resultsMap resultsMap + * @return RpcPacketDispatcherResult + * @throws ConnectionException on error */ - protected RpcPacketDispatcherResult reconcileEdit( - RpcConnection rpcConnection, CommandEnv cmdEnv, - Map resultsMap) throws ConnectionException { + protected RpcPacketDispatcherResult reconcileEdit(RpcConnection rpcConnection, CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { if (rpcConnection == null) { throw new NullPointerError("Null rpcConnection in reconcileEdit()."); @@ -379,26 +369,28 @@ protected RpcPacketDispatcherResult reconcileEdit( } String clientType = (String) resultsMap.get(RpcFunctionMapKey.TYPE); - String digest = (String) resultsMap.get(RpcFunctionMapKey.DIGEST); + String digest = (String) resultsMap.get(RpcFunctionMapKey.DIGEST); String digestType = (String) resultsMap.get(RpcFunctionMapKey.DIGESTTYPE); - String confirm = (String) resultsMap.get(RpcFunctionMapKey.CONFIRM); - String fileSize = (String) resultsMap.get(RpcFunctionMapKey.FILESIZE); - String submitTime = (String) resultsMap.get(RpcFunctionMapKey.TIME); + String confirm = (String) resultsMap.get(RpcFunctionMapKey.CONFIRM); + String fileSize = (String) resultsMap.get(RpcFunctionMapKey.FILESIZE); + String submitTime = (String) resultsMap.get(RpcFunctionMapKey.TIME); String clientPath = (String) resultsMap.get(RpcFunctionMapKey.PATH); ReconcileHandle recHandle = getReconcileHandle(cmdEnv); - long checkSize = 0; - long time = 0; - try { - checkSize = Long.parseLong(fileSize); - } catch (NumberFormatException nfe) { } - try { - time = Long.parseLong(submitTime); - } catch (NumberFormatException nfe) { } - - List skipFilesMap = recHandle.getSkipFiles(); - + long checkSize = 0; + long time = 0; + try { + checkSize = Long.parseLong(fileSize); + } catch (NumberFormatException nfe) { + } + try { + time = Long.parseLong(submitTime); + } catch (NumberFormatException nfe) { + } + + List skipFilesMap = recHandle.getSkipFiles(); + String status = "exists"; String nType = (clientType == null) ? "text" : clientType; @@ -406,25 +398,23 @@ protected RpcPacketDispatcherResult reconcileEdit( boolean fstSymlink = (fileType == RpcPerforceFileType.FST_SYMLINK); /* - * If we do know the type, we want to know if it's missing. - * If it isn't missing and a digest is given, we want to know if - * it is the same. - */ + * If we do know the type, we want to know if it's missing. + * If it isn't missing and a digest is given, we want to know if + * it is the same. + */ File file = new File(clientPath); if (!fileExists(file, true)) { status = "missing"; recHandle.incrementDelCount(); - } else if ( ( !RpcPerforceFileType.isProbablySymLink(file) && fstSymlink ) || - ( RpcPerforceFileType.isProbablySymLink(file) && !fstSymlink ) ) { + } else if ((!RpcPerforceFileType.isProbablySymLink(file) && fstSymlink) || (RpcPerforceFileType.isProbablySymLink(file) && !fstSymlink)) { skipFilesMap.add(file.getAbsolutePath()); } else if (digest != null) { // Calculate actual file digest; if same, we assume the file's // the same as on the server. - if( digestType != null ) - { + if (digestType != null) { String digestStr = rpcConnection.getDigest(fileType, file, RpcPerforceDigestType.GetType(digestType)); if ((digestStr != null) && digestStr.equals(digest)) { status = "same"; @@ -453,30 +443,34 @@ else if ((checkSize == 0) || (file.length() == checkSize)) { // means copying the incoming args, appending or changing // "type" and "status" if necessary, and changing the // function type to server-ReconcileFile. - + resultsMap.put(RpcFunctionMapKey.TYPE, nType); resultsMap.put(RpcFunctionMapKey.STATUS, status); return rpcConnection.clientConfirm(confirm, resultsMap); } - + private ReconcileHandle getReconcileHandle(CommandEnv cmdEnv) { - RpcHandler handler = cmdEnv.getHandler(RECONCILE_HANDLE); - if (handler == null) { - handler = cmdEnv.new RpcHandler(RECONCILE_HANDLE, false, null); - cmdEnv.addHandler(handler); - } - return new ReconcileHandle(handler); - } - - /** + RpcHandler handler = cmdEnv.getHandler(RECONCILE_HANDLE); + if (handler == null) { + handler = cmdEnv.new RpcHandler(RECONCILE_HANDLE, false, null); + cmdEnv.addHandler(handler); + } + return new ReconcileHandle(handler); + } + + /** * Reconcile add confirm - scans the directory (local syntax) and returns * files in the directory using the full path. This supports traversing - * sub-directories.

+ * sub-directories. + * + * @param rpcConnection rpcConnection + * @param cmdEnv cmdEnv + * @param resultsMap resultsMap + * @return RpcPacketDispatcherResult + * @throws ConnectionException on error */ - protected RpcPacketDispatcherResult reconcileAdd( - RpcConnection rpcConnection, CommandEnv cmdEnv, - Map resultsMap) throws ConnectionException { + protected RpcPacketDispatcherResult reconcileAdd(RpcConnection rpcConnection, CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { if (rpcConnection == null) { throw new NullPointerError("Null rpcConnection in reconcileAdd()."); @@ -491,10 +485,10 @@ protected RpcPacketDispatcherResult reconcileAdd( String dir = (String) resultsMap.get(RpcFunctionMapKey.DIR); String confirm = (String) resultsMap.get(RpcFunctionMapKey.CONFIRM); String traverse = (String) resultsMap.get(RpcFunctionMapKey.TRAVERSE); - String summary = (String) resultsMap.get(RpcFunctionMapKey.SUMMARY); - String skipIgnore = (String) resultsMap.get(RpcFunctionMapKey.SKIP_IGNORE); - String skipCurrent = (String) resultsMap.get(RpcFunctionMapKey.SKIP_CURRENT); - String sendDigest = (String) resultsMap.get(RpcFunctionMapKey.SEND_DIGEST); + String summary = (String) resultsMap.get(RpcFunctionMapKey.SUMMARY); + String skipIgnore = (String) resultsMap.get(RpcFunctionMapKey.SKIP_IGNORE); + String skipCurrent = (String) resultsMap.get(RpcFunctionMapKey.SKIP_CURRENT); + String sendDigest = (String) resultsMap.get(RpcFunctionMapKey.SEND_DIGEST); if (dir == null) { throw new NullPointerError("Null 'dir' in resultsMap in reconcileAdd()."); @@ -502,140 +496,135 @@ protected RpcPacketDispatcherResult reconcileAdd( if (confirm == null) { throw new NullPointerError("Null 'confirm' in resultsMap in reconcileAdd()."); } - - boolean isTraverse = (traverse != null && !traverse.equalsIgnoreCase("0")) ? true : false; - boolean isSummary = (summary != null && !summary.equalsIgnoreCase("0")) ? true : false; - boolean isSkipIgnore = (skipIgnore != null && !skipIgnore.equalsIgnoreCase("0")) ? true : false; - boolean isSkipCurrent = (skipCurrent != null && !skipCurrent.equalsIgnoreCase("0")) ? true : false; - boolean isSendDigest = (sendDigest != null && !sendDigest.equalsIgnoreCase("0")) ? true : false; + + boolean isTraverse = (traverse != null && !traverse.equalsIgnoreCase("0")) ? true : false; + boolean isSummary = (summary != null && !summary.equalsIgnoreCase("0")) ? true : false; + boolean isSkipIgnore = (skipIgnore != null && !skipIgnore.equalsIgnoreCase("0")) ? true : false; + boolean isSkipCurrent = (skipCurrent != null && !skipCurrent.equalsIgnoreCase("0")) ? true : false; + boolean isSendDigest = (sendDigest != null && !sendDigest.equalsIgnoreCase("0")) ? true : false; MapTable map = new MapTable(); List files = new LinkedList(); - Map sizes = new HashMap(); + Map sizes = new HashMap(); List dirs = new LinkedList(); List depotFiles = new LinkedList(); - Map digests = new HashMap(); + Map digests = new HashMap(); // Construct a MapTable object from the strings passed in by server for (int i = 0; resultsMap.get(RpcFunctionMapKey.MAP_TABLE + i) != null; i++) { - String entry = (String)resultsMap.get(RpcFunctionMapKey.MAP_TABLE + i); + String entry = (String) resultsMap.get(RpcFunctionMapKey.MAP_TABLE + i); entry = new File(entry).getAbsolutePath(); if (entry != null) { MapFlag flag = MapFlag.MfMap; - if( entry.startsWith( "-" ) ) { + if (entry.startsWith("-")) { flag = MapFlag.MfUnmap; - } else if( entry.startsWith( "+" ) ) { + } else if (entry.startsWith("+")) { flag = MapFlag.MfRemap; - } else if( entry.startsWith( "&" ) ) { + } else if (entry.startsWith("&")) { flag = MapFlag.MfAndmap; } - if( flag != MapFlag.MfMap ) - entry = entry.substring(1); - map.insert(entry, entry, flag ); + if (flag != MapFlag.MfMap) entry = entry.substring(1); + map.insert(entry, entry, flag); } } - + // If we have a list of files we know are in the depot already, - // filter them out of our list of files to add. For -s option, - // we need to have this list of depot files for computing files - // and directories to add (even if it is an empty list). - + // filter them out of our list of files to add. For -s option, + // we need to have this list of depot files for computing files + // and directories to add (even if it is an empty list). + ReconcileHandle recHandle = null; - RpcHandler handler = cmdEnv.getHandler(RECONCILE_HANDLE); - if (handler != null) { - //TODO: Do we need to sort the paths? + RpcHandler handler = cmdEnv.getHandler(RECONCILE_HANDLE); + if (handler != null) { + //TODO: Do we need to sort the paths? //recHandle->pathArray->Sort( !StrBuf::CaseUsage() ); - } else if (handler == null && isSummary ) { - handler = cmdEnv.new RpcHandler(RECONCILE_HANDLE, false, null); - cmdEnv.addHandler(handler); - recHandle = new ReconcileHandle(handler); - } - - // status -s also needs the list of files opened for add appended - // to the list of depot files. - - if( isSummary ) - { - for( int j=0; resultsMap.containsKey( RpcFunctionMapKey.DEPOT_FILES + j); j++) { - depotFiles.add( (String) resultsMap.get( RpcFunctionMapKey.DEPOT_FILES + j) ); - } - if( recHandle != null ) { - for( String fname : recHandle.getSkipFiles() ) { - depotFiles.add( fname ); - } - } + } else if (handler == null && isSummary) { + handler = cmdEnv.new RpcHandler(RECONCILE_HANDLE, false, null); + cmdEnv.addHandler(handler); + recHandle = new ReconcileHandle(handler); + } + + // status -s also needs the list of files opened for add appended + // to the list of depot files. + + if (isSummary) { + for (int j = 0; resultsMap.containsKey(RpcFunctionMapKey.DEPOT_FILES + j); j++) { + depotFiles.add((String) resultsMap.get(RpcFunctionMapKey.DEPOT_FILES + j)); + } + if (recHandle != null) { + for (String fname : recHandle.getSkipFiles()) { + depotFiles.add(fname); + } + } //TODO: Do we need to sort the paths? //depotFiles->Sort( !StrBuf::CaseUsage() ); - } - - // status -s will output files in the current directory and paths - // rather than all of the files individually. Compare against depot - // files early so we can abort traversal early if we can. - - int hasIndex = 0; - //TODO: still to translate - //const char *config = client->GetEnviro()->Get( "P4CONFIG" ); - - if( isSummary ) { - AtomicInteger idx = new AtomicInteger(0); + } + + // status -s will output files in the current directory and paths + // rather than all of the files individually. Compare against depot + // files early so we can abort traversal early if we can. + + int hasIndex = 0; + //TODO: still to translate + //const char *config = client->GetEnviro()->Get( "P4CONFIG" ); + + if (isSummary) { + AtomicInteger idx = new AtomicInteger(0); AtomicInteger ddx = new AtomicInteger(0); - traverseShort( resultsMap, new File(dir), new File(dir), isTraverse, isSkipIgnore, - true, false, isSkipCurrent, - map, files, dirs, idx, depotFiles, ddx, - rpcConnection.isUnicodeServer(), - rpcConnection.getClientCharset(), cmdEnv); - } else { - traverseDirs( new File(dir), isTraverse, isSkipIgnore, isSendDigest, map, files, - sizes, digests, hasIndex, recHandle != null ? recHandle.getSkipFiles() : null, - rpcConnection.isUnicodeServer(), - rpcConnection.getClientCharset(), cmdEnv); - } + traverseShort(resultsMap, new File(dir), new File(dir), isTraverse, isSkipIgnore, true, false, isSkipCurrent, map, files, dirs, idx, depotFiles, ddx, rpcConnection.isUnicodeServer(), rpcConnection.getClientCharset(), cmdEnv); + } else { + traverseDirs(new File(dir), isTraverse, isSkipIgnore, isSendDigest, map, files, sizes, digests, hasIndex, recHandle != null ? recHandle.getSkipFiles() : null, rpcConnection.isUnicodeServer(), rpcConnection.getClientCharset(), cmdEnv); + } // Compare list of files on client with list of files in the depot - // if we have this list from ReconcileEdit. Skip this comparison - // if summary because it was done already. - - int j = 0; - if( recHandle != null && !isSummary ) { - for (String file : files) { - if( recHandle.getSkipFiles().contains(file)) { - continue; - } - - resultsMap.put(RpcFunctionMapKey.FILE + j, file); - - if( !isSendDigest && recHandle.getDelCount() > 0 ) { - // Deleted files? Send filesize info so the - // server can try to pair up moves. - - resultsMap.put(RpcFunctionMapKey.FILESIZE + j, "" + sizes.get(file) ); - } - if( isSendDigest ) { - resultsMap.put(RpcFunctionMapKey.DIGEST + j, digests.get(file) ); - } - j++; - } - } else { - for (String file : files) { - resultsMap.put(RpcFunctionMapKey.FILE + j, file); - - if( isSendDigest ) { - resultsMap.put(RpcFunctionMapKey.DIGEST + j, digests.get(file) ); - } - j++; - } - } - + // if we have this list from ReconcileEdit. Skip this comparison + // if summary because it was done already. + + int j = 0; + if (recHandle != null && !isSummary) { + for (String file : files) { + if (recHandle.getSkipFiles().contains(file)) { + continue; + } + + resultsMap.put(RpcFunctionMapKey.FILE + j, file); + + if (!isSendDigest && recHandle.getDelCount() > 0) { + // Deleted files? Send filesize info so the + // server can try to pair up moves. + + resultsMap.put(RpcFunctionMapKey.FILESIZE + j, "" + sizes.get(file)); + } + if (isSendDigest) { + resultsMap.put(RpcFunctionMapKey.DIGEST + j, digests.get(file)); + } + j++; + } + } else { + for (String file : files) { + resultsMap.put(RpcFunctionMapKey.FILE + j, file); + + if (isSendDigest) { + resultsMap.put(RpcFunctionMapKey.DIGEST + j, digests.get(file)); + } + j++; + } + } + return rpcConnection.clientConfirm(confirm, resultsMap); } /** * Reconcile flush - remove the skip add files map from the reconcile handler. + * + * @param rpcConnection rpcConnection + * @param cmdEnv cmdEnv + * @param resultsMap resultsMap + * @return RpcPacketDispatcherResult + * @throws ConnectionException on error */ - protected RpcPacketDispatcherResult reconcileFlush( - RpcConnection rpcConnection, CommandEnv cmdEnv, - Map resultsMap) throws ConnectionException { + protected RpcPacketDispatcherResult reconcileFlush(RpcConnection rpcConnection, CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { if (rpcConnection == null) { throw new NullPointerError("Null rpcConnection in reconcileFlush()."); @@ -648,27 +637,39 @@ protected RpcPacketDispatcherResult reconcileFlush( } RpcHandler handler = cmdEnv.getHandler(RECONCILE_HANDLE); - + if (handler != null) { - ReconcileHandle recHandle = new ReconcileHandle(handler); - recHandle.getSkipFiles().clear(); - } - + ReconcileHandle recHandle = new ReconcileHandle(handler); + recHandle.getSkipFiles().clear(); + } + return RpcPacketDispatcherResult.CONTINUE_LOOP; - } + } /** - * Recursively (optional) traverse the directory tree for files.

- * + * Recursively (optional) traverse the directory tree for files. + *

* Check MapApi; if no mapping, continue. + * + * @param file file + * @param traverse traverse + * @param skipIgnore skipIgnore + * @param sendDigest sendDigest + * @param map map + * @param addFilesMap addFilesMap + * @param sizes sizes + * @param digests digests + * @param hasIndex hasIndex + * @param skipFiles skipFiles + * @param unicode unicode + * @param charset charset + * @param cmdEnv cmdEnv */ - private void traverseDirs(File file, boolean traverse, boolean skipIgnore, boolean sendDigest, - MapTable map, List addFilesMap, Map sizes, Map digests, - int hasIndex, List skipFiles, boolean unicode, Charset charset, CommandEnv cmdEnv) { - - if (addFilesMap == null) { - throw new IllegalArgumentException("Must pass in a non-null 'files' list as a parameter."); - } + private void traverseDirs(File file, boolean traverse, boolean skipIgnore, boolean sendDigest, MapTable map, List addFilesMap, Map sizes, Map digests, int hasIndex, List skipFiles, boolean unicode, Charset charset, CommandEnv cmdEnv) { + + if (addFilesMap == null) { + throw new IllegalArgumentException("Must pass in a non-null 'files' list as a parameter."); + } // Return all files in dir, and optionally traverse dirs in dir, // while checking each file against map before returning it @@ -684,14 +685,14 @@ private void traverseDirs(File file, boolean traverse, boolean skipIgnore, boole if (file.isFile()) { if (skipIgnore || !isIgnore(file, charset, cmdEnv)) { - addFilesMap.add(file.getAbsolutePath()); - sizes.put(file.getAbsolutePath(), file.length()); - if(sendDigest) { - String digestStr = digestFile(file, RpcPerforceFileType.FST_BINARY, charset); - if(digestStr != null) { - digests.put(file.getAbsolutePath(), digestStr); - } - } + addFilesMap.add(file.getAbsolutePath()); + sizes.put(file.getAbsolutePath(), file.length()); + if (sendDigest) { + String digestStr = digestFile(file, RpcPerforceFileType.FST_BINARY, charset); + if (digestStr != null) { + digests.put(file.getAbsolutePath(), digestStr); + } + } } return; } @@ -703,23 +704,23 @@ private void traverseDirs(File file, boolean traverse, boolean skipIgnore, boole if (skipIgnore || !isIgnore(file, charset, cmdEnv)) { addFilesMap.add(file.getAbsolutePath()); sizes.put(file.getAbsolutePath(), file.length()); - if(sendDigest) { - String digestStr = digestFile(file, RpcPerforceFileType.FST_BINARY, charset); - if(digestStr != null) { - digests.put(file.getAbsolutePath(), digestStr); - } - } + if (sendDigest) { + String digestStr = digestFile(file, RpcPerforceFileType.FST_BINARY, charset); + if (digestStr != null) { + digests.put(file.getAbsolutePath(), digestStr); + } + } } return; } if (!file.isDirectory()) { - //XXX: not sure if a Java file can be neither a file or directory - return; + //XXX: not sure if a Java file can be neither a file or directory + return; } - + // Directory might be ignored, bail - if( !skipIgnore && isIgnoreDir(file, charset, cmdEnv) ) { + if (!skipIgnore && isIgnoreDir(file, charset, cmdEnv)) { return; } @@ -738,24 +739,20 @@ private void traverseDirs(File file, boolean traverse, boolean skipIgnore, boole // Do compare with array list (skip files if possible) int cmp = -1; - while( skipFiles != null && hasIndex < skipFiles.size() ) - { + while (skipFiles != null && hasIndex < skipFiles.size()) { //XXX: uncertain that the correct portion of the file is being compared - cmp = fileName.compareTo(skipFiles.get( hasIndex ) ); + cmp = fileName.compareTo(skipFiles.get(hasIndex)); - if( cmp < 0 ) - break; + if (cmp < 0) break; hasIndex++; - if( cmp == 0 ) - break; + if (cmp == 0) break; } // Don't stat if we matched a file from the edit list - if( cmp == 0 ) - continue; + if (cmp == 0) continue; if (f.isDirectory()) { // Directory if (RpcPerforceFileType.isProbablySymLink(f)) { @@ -768,29 +765,27 @@ private void traverseDirs(File file, boolean traverse, boolean skipIgnore, boole // matched = map->Translate( from, to, MapLeftRight ); // from.SetCaseFolding( !client->protocolNocase ); //} else { - MapWrap mw = map.translate( MapTableT.LHS, from ); + MapWrap mw = map.translate(MapTableT.LHS, from); matched = mw == null ? null : mw.getTo(); //} - if( matched == null ) { + if (matched == null) { continue; } if (skipIgnore || !isIgnore(f, charset, cmdEnv)) { addFilesMap.add(fileName); sizes.put(fileName, file.length()); - if(sendDigest) { + if (sendDigest) { String digestStr = digestFile(f, RpcPerforceFileType.FST_BINARY, charset); - if(digestStr != null) { + if (digestStr != null) { digests.put(fileName, digestStr); } } } } else if (traverse) { // Recursive call - traverseDirs(f, traverse, skipIgnore, sendDigest, map, addFilesMap, - sizes, digests, hasIndex, skipFiles, - unicode, charset, cmdEnv); + traverseDirs(f, traverse, skipIgnore, sendDigest, map, addFilesMap, sizes, digests, hasIndex, skipFiles, unicode, charset, cmdEnv); } } else { // File String from = fileName; @@ -802,226 +797,204 @@ private void traverseDirs(File file, boolean traverse, boolean skipIgnore, boole // matched = map->Translate( from, to, MapLeftRight ); // from.SetCaseFolding( !client->protocolNocase ); //} else { - MapWrap mw = map.translate( MapTableT.LHS, from ); + MapWrap mw = map.translate(MapTableT.LHS, from); matched = mw == null ? null : mw.getTo(); //} - if( matched == null ) { + if (matched == null) { continue; } if (skipIgnore || !isIgnore(f, charset, cmdEnv)) { addFilesMap.add(fileName); sizes.put(fileName, file.length()); - if(sendDigest) { + if (sendDigest) { String digestStr = digestFile(f, RpcPerforceFileType.FST_BINARY, charset); - if(digestStr != null) { + if (digestStr != null) { digests.put(fileName, digestStr); } } } } } - } + } private String digestFile(File file, RpcPerforceFileType fileType, Charset charset) { - - MD5Digester digester = new MD5Digester(); - RpcPerforceFile pFile = new RpcPerforceFile(file.getName(), fileType); - - // Digest the file using the configured local file content - // charset. A null digestCharset specified will cause the - // file to be read as raw byte stream directly off disk. - return digester.digestFileAs32ByteHex(pFile, charset); - } - - private boolean traverseShort( - Map resultsMap, - File cwd, - File file, - boolean traverse, - boolean skipIgnore, - boolean initial, - boolean skipCheck, - boolean skipCurrent, - MapTable map, - List addFilesMap, - List dirs, - AtomicInteger idx, - List depotFiles, - AtomicInteger ddx, - boolean unicode, - Charset charset, - CommandEnv cmdEnv) { - - // Variant of traverseDirs that computes the files to be - // added during traversal of directories instead of at the end, - // and returns directories and files rather than all files. - // This is used by 'status -s'. - - // Scan the directory. - - boolean found = false; - - if (addFilesMap == null) { - throw new IllegalArgumentException("Must pass in a non-null 'files' list as a parameter."); - } - - if (file == null || !file.exists()) { - return false; - } - - // If this is a file, not a directory, and not to be ignored, - // save the filename and return. - if (!file.isDirectory() && (file.isFile() || RpcPerforceFileType.isProbablySymLink(file))) { - if (skipIgnore || !isIgnore(file, charset, cmdEnv)) { - addFilesMap.add(file.getAbsolutePath()); - found = true; - } - return found; - } - - // If this is a symlink to a directory, and not to be ignored, - // save the filename and return. - if (file.isDirectory() && RpcPerforceFileType.isProbablySymLink(file)) { - if (skipIgnore || !isIgnore(file, charset, cmdEnv)) { - addFilesMap.add(file.getAbsolutePath()); - found = true; - } - return found; - } - - // This is a directory to be scanned. - - if (!file.isDirectory()) { - return false; - } - - // Directory might be ignored, bail - - if( !skipIgnore && isIgnoreDir(file, charset, cmdEnv) ) { - return false; - } - - // If directory is unknown to p4, we don't need to check that files - // are in depot (they aren't), so just return after the first file - // is found and bypass checking. - - boolean doSkipCheck = skipCheck; - - int dddx = 0; - List depotDirs = new LinkedList(); - - // First time through we save depot dirs - - if( initial ) { - for( int j=0; resultsMap.containsKey( RpcFunctionMapKey.DEPOT_DIRS + j); j++) { - depotDirs.add((String) resultsMap.get( RpcFunctionMapKey.DEPOT_DIRS + j )); - } - } - // For each directory entry. - - File[] files = file.listFiles(); - if (files == null) { - return found; - } - - for (File f : files) { - - boolean isDir = false; - boolean isSymDir = false; - String fileName = f.getAbsolutePath(); - - // Attach path delimiter to dirs so Sort() works correctly, and also to - // save relevant Stat() information. - - if( f.isDirectory() && !RpcPerforceFileType.isProbablySymLink(f) ) { - isDir = true; - } else if( f.isDirectory() && RpcPerforceFileType.isProbablySymLink(f) ) { - isDir = true; - isSymDir = true; - } else if( !f.exists() && !RpcPerforceFileType.isProbablySymLink(f) ) { - continue; - } - - - // Check mapping, ignore files before sending file or symlink back - - boolean checkFile = false; - - if( isDir ) { - if( isSymDir ) { - String from = fileName + "/"; + MD5Digester digester = new MD5Digester(); + RpcPerforceFile pFile = new RpcPerforceFile(file.getName(), fileType); + + // Digest the file using the configured local file content + // charset. A null digestCharset specified will cause the + // file to be read as raw byte stream directly off disk. + return digester.digestFileAs32ByteHex(pFile, charset); + } + + private boolean traverseShort(Map resultsMap, File cwd, File file, boolean traverse, boolean skipIgnore, boolean initial, boolean skipCheck, boolean skipCurrent, MapTable map, List addFilesMap, List dirs, AtomicInteger idx, List depotFiles, AtomicInteger ddx, boolean unicode, Charset charset, CommandEnv cmdEnv) { + + // Variant of traverseDirs that computes the files to be + // added during traversal of directories instead of at the end, + // and returns directories and files rather than all files. + // This is used by 'status -s'. + + // Scan the directory. + + boolean found = false; + + if (addFilesMap == null) { + throw new IllegalArgumentException("Must pass in a non-null 'files' list as a parameter."); + } + + if (file == null || !file.exists()) { + return false; + } + + // If this is a file, not a directory, and not to be ignored, + // save the filename and return. + if (!file.isDirectory() && (file.isFile() || RpcPerforceFileType.isProbablySymLink(file))) { + if (skipIgnore || !isIgnore(file, charset, cmdEnv)) { + addFilesMap.add(file.getAbsolutePath()); + found = true; + } + return found; + } + + // If this is a symlink to a directory, and not to be ignored, + // save the filename and return. + if (file.isDirectory() && RpcPerforceFileType.isProbablySymLink(file)) { + if (skipIgnore || !isIgnore(file, charset, cmdEnv)) { + addFilesMap.add(file.getAbsolutePath()); + found = true; + } + return found; + } + + // This is a directory to be scanned. + + if (!file.isDirectory()) { + return false; + } + + // Directory might be ignored, bail + + if (!skipIgnore && isIgnoreDir(file, charset, cmdEnv)) { + return false; + } + + // If directory is unknown to p4, we don't need to check that files + // are in depot (they aren't), so just return after the first file + // is found and bypass checking. + + boolean doSkipCheck = skipCheck; + + int dddx = 0; + List depotDirs = new LinkedList(); + + // First time through we save depot dirs + + if (initial) { + for (int j = 0; resultsMap.containsKey(RpcFunctionMapKey.DEPOT_DIRS + j); j++) { + depotDirs.add((String) resultsMap.get(RpcFunctionMapKey.DEPOT_DIRS + j)); + } + } + + // For each directory entry. + + File[] files = file.listFiles(); + if (files == null) { + return found; + } + + for (File f : files) { + + boolean isDir = false; + boolean isSymDir = false; + String fileName = f.getAbsolutePath(); + + // Attach path delimiter to dirs so Sort() works correctly, and also to + // save relevant Stat() information. + + if (f.isDirectory() && !RpcPerforceFileType.isProbablySymLink(f)) { + isDir = true; + } else if (f.isDirectory() && RpcPerforceFileType.isProbablySymLink(f)) { + isDir = true; + isSymDir = true; + } else if (!f.exists() && !RpcPerforceFileType.isProbablySymLink(f)) { + continue; + } + + + // Check mapping, ignore files before sending file or symlink back + + boolean checkFile = false; + + if (isDir) { + if (isSymDir) { + String from = fileName + "/"; String matched = null; - // TODO: protocol case mode - //if( client->protocolNocase != StrBuf::CaseUsage() ) { - // from.SetCaseFolding( client->protocolNocase ); - // matched = map->Translate( from, to, MapLeftRight ); - // from.SetCaseFolding( !client->protocolNocase ); - //} else { - MapWrap mw = map.translate( MapTableT.LHS, from ); - matched = mw == null ? null : mw.getTo(); - //} - - if( matched == null ) { - continue; - } - - if( skipIgnore || !isIgnore(f, charset, cmdEnv) ) { - if( doSkipCheck ){ - String alt = sendDir( f, cwd, dirs, idx, skipCurrent ); - addFilesMap.add( alt != null ? alt : f.getAbsolutePath()); - found = true; - break; - } else { - checkFile = true; - } - } - } else if( traverse ) { - if( initial ) { - dirs.add( fileName ); - boolean foundOne = false; - int l = 0; - - // If this directory is unknown to the depot, we don't - // need to compare against depot files. - - for( ; dddx < depotDirs.size() && !foundOne; dddx++) - { - String depotDir = depotDirs.get( dddx ); - //p->SetLocal( *cwd, *ddir ); - l = sysCompare(fileName, depotDir); - if( l == 0 ) { - foundOne = true; - } else if( l < 0 ) { - break; - } - } - skipCheck = !foundOne; - } - - found = traverseShort( resultsMap, cwd, f, - traverse, skipIgnore, false, - skipCheck, skipCurrent, map, - addFilesMap, dirs, idx, depotFiles, - ddx, unicode, charset, cmdEnv); - - // Stop traversing directories when we have a file to - // to add, unless we are at the top and need to check - // for files in the current directory. - - if( found && !initial ) { - break; - } else if( found && initial && !skipCurrent ) { - found = false; - } - if( found ) { - break; - } - } - } else { + // TODO: protocol case mode + //if( client->protocolNocase != StrBuf::CaseUsage() ) { + // from.SetCaseFolding( client->protocolNocase ); + // matched = map->Translate( from, to, MapLeftRight ); + // from.SetCaseFolding( !client->protocolNocase ); + //} else { + MapWrap mw = map.translate(MapTableT.LHS, from); + matched = mw == null ? null : mw.getTo(); + //} + + if (matched == null) { + continue; + } + + if (skipIgnore || !isIgnore(f, charset, cmdEnv)) { + if (doSkipCheck) { + String alt = sendDir(f, cwd, dirs, idx, skipCurrent); + addFilesMap.add(alt != null ? alt : f.getAbsolutePath()); + found = true; + break; + } else { + checkFile = true; + } + } + } else if (traverse) { + if (initial) { + dirs.add(fileName); + boolean foundOne = false; + int l = 0; + + // If this directory is unknown to the depot, we don't + // need to compare against depot files. + + for (; dddx < depotDirs.size() && !foundOne; dddx++) { + String depotDir = depotDirs.get(dddx); + //p->SetLocal( *cwd, *ddir ); + l = sysCompare(fileName, depotDir); + if (l == 0) { + foundOne = true; + } else if (l < 0) { + break; + } + } + skipCheck = !foundOne; + } + + found = traverseShort(resultsMap, cwd, f, traverse, skipIgnore, false, skipCheck, skipCurrent, map, addFilesMap, dirs, idx, depotFiles, ddx, unicode, charset, cmdEnv); + + // Stop traversing directories when we have a file to + // to add, unless we are at the top and need to check + // for files in the current directory. + + if (found && !initial) { + break; + } else if (found && initial && !skipCurrent) { + found = false; + } + if (found) { + break; + } + } + } else { String matched = null; // TODO: protocol case mode @@ -1030,96 +1003,95 @@ private boolean traverseShort( // matched = map->Translate( from, to, MapLeftRight ); // from.SetCaseFolding( !client->protocolNocase ); //} else { - MapWrap mw = map.translate( MapTableT.LHS, fileName ); - matched = mw == null ? null : mw.getTo(); + MapWrap mw = map.translate(MapTableT.LHS, fileName); + matched = mw == null ? null : mw.getTo(); //} - if( matched == null ) { + if (matched == null) { continue; } - - if( skipIgnore || !isIgnore(f, charset, cmdEnv) ) { - if( doSkipCheck ) { - String alt = sendDir( f, cwd, dirs, idx, skipCurrent ); - addFilesMap.add( alt != null ? alt : f.getAbsolutePath()); - found = true; - break; - } else { - checkFile = true; - } - } - } - // See if file is in depot and if not, either set the file - // or directory to be reported back to the server. - - if( checkFile ) { - int l = 0; - boolean finished = false; - while ( !finished ) { - if( ddx.get() >= depotFiles.size()) { - l = -1; - } else { - l = sysCompare( fileName, depotFiles.get(ddx.get())); - } - - if( l == 0 ) { + if (skipIgnore || !isIgnore(f, charset, cmdEnv)) { + if (doSkipCheck) { + String alt = sendDir(f, cwd, dirs, idx, skipCurrent); + addFilesMap.add(alt != null ? alt : f.getAbsolutePath()); + found = true; + break; + } else { + checkFile = true; + } + } + } + + // See if file is in depot and if not, either set the file + // or directory to be reported back to the server. + + if (checkFile) { + int l = 0; + boolean finished = false; + while (!finished) { + if (ddx.get() >= depotFiles.size()) { + l = -1; + } else { + l = sysCompare(fileName, depotFiles.get(ddx.get())); + } + + if (l == 0) { ddx.incrementAndGet(); - finished = true; - } else if( l < 0 ) { - if( initial && skipCurrent ) { - addFilesMap.add(FilePathHelper.getLocal(f.getParentFile().getAbsolutePath(), "...")); - } else { - String alt = sendDir( f, cwd, dirs, idx, skipCurrent ); - addFilesMap.add(alt != null ? alt : f.getAbsolutePath()); - } - found = true; - break; - } else { - ddx.incrementAndGet(); - } - } - if( ( !initial || skipCurrent ) && found ) { - break; - } - } - } + finished = true; + } else if (l < 0) { + if (initial && skipCurrent) { + addFilesMap.add(FilePathHelper.getLocal(f.getParentFile().getAbsolutePath(), "...")); + } else { + String alt = sendDir(f, cwd, dirs, idx, skipCurrent); + addFilesMap.add(alt != null ? alt : f.getAbsolutePath()); + } + found = true; + break; + } else { + ddx.incrementAndGet(); + } + } + if ((!initial || skipCurrent) && found) { + break; + } + } + } - return found; + return found; } - /* - * SendDir - utility method used by clientTraverseShort to decide if a - * filename should be output as a file or as a directory (status -s) - */ - private String sendDir( File file, File cwd, List dirs, AtomicInteger idx, boolean skip ) - { - // Skip printing file in current directory and just report subdirectory - if( skip ) { - return FilePathHelper.getLocal( cwd.getAbsolutePath(), "..." ); - } - - // If file is in the current directory: isDirs is unset so that our - // caller will send back the original file. - - file = file.getParentFile(); - - if( sysCompare( file.getAbsolutePath(), cwd.getAbsolutePath() ) != 0 ) { - return null; - } - - // Set path to the directory under cwd containing this file. - // 'dirs' is the list of dirs in cwd on workspace. - - boolean isDir = false; - for( ; idx.get() < dirs.size() && !isDir; idx.getAndIncrement() ) { - if( file.getAbsolutePath().startsWith( new File( dirs.get( idx.get() ) ).getAbsolutePath() ) ) { - return FilePathHelper.getLocal( dirs.get(idx.get()), "..." ); - } - } - - return null; - } + /* + * SendDir - utility method used by clientTraverseShort to decide if a + * filename should be output as a file or as a directory (status -s) + */ + private String sendDir(File file, File cwd, List dirs, AtomicInteger idx, boolean skip) { + // Skip printing file in current directory and just report subdirectory + if (skip) { + return FilePathHelper.getLocal(cwd.getAbsolutePath(), "..."); + } + + // If file is in the current directory: isDirs is unset so that our + // caller will send back the original file. + + file = file.getParentFile(); + + if (sysCompare(file.getAbsolutePath(), cwd.getAbsolutePath()) != 0) { + return null; + } + + // Set path to the directory under cwd containing this file. + // 'dirs' is the list of dirs in cwd on workspace. + + boolean isDir = false; + for (; idx.get() < dirs.size() && !isDir; idx.getAndIncrement()) { + if (file.getAbsolutePath().startsWith(new File(dirs.get(idx.get())).getAbsolutePath())) { + return FilePathHelper.getLocal(dirs.get(idx.get()), "..."); + } + } + + return null; + } /** * Check if the file or symbolic link exists. @@ -1136,7 +1108,7 @@ private boolean fileExists(File file, boolean fstSymlink) { return false; } - + /** * Check if the file should be ignored. */ @@ -1145,98 +1117,90 @@ boolean isIgnore(File file, Charset charset, CommandEnv cmdEnv) { if (getChecker(charset) != null) { try { if (checker.match(file)) { - cmdEnv.handleResult(new RpcMessage( - ClientMessageId.CANT_ADD_FILE_TYPE, - MessageSeverityCode.E_INFO, - MessageGenericCode.EV_CLIENT, new String[] { - file.getAbsolutePath(), "ignored" }).toMap()); + cmdEnv.handleResult(new RpcMessage(ClientMessageId.CANT_ADD_FILE_TYPE, MessageSeverityCode.E_INFO, MessageGenericCode.EV_CLIENT, new String[]{file.getAbsolutePath(), "ignored"}).toMap()); return true; } } catch (FileNotFoundException e) { - Log.error("Exception occurred during ignore files checking: " - + e); + Log.error("Exception occurred during ignore files checking: " + e); } catch (IOException e) { - Log.error("Exception occurred during ignore files checking: " - + e); + Log.error("Exception occurred during ignore files checking: " + e); } } - + return false; } - /** - * Check if the file should be ignored. - */ - boolean isIgnoreDir(File file, Charset charset, CommandEnv cmdEnv) { - // Do ignore checking, reject file matching ignore patterns - if (getChecker(charset) != null) { - try { - if (checker.match(file)) { - cmdEnv.handleResult(new RpcMessage( - ClientMessageId.CANT_ADD_FILE_TYPE, - MessageSeverityCode.E_INFO, - MessageGenericCode.EV_CLIENT, new String[] { - file.getAbsolutePath(), "ignored" }).toMap()); - return true; - } - } catch (FileNotFoundException e) { - Log.error("Exception occurred during ignore files checking: " - + e); - } catch (IOException e) { - Log.error("Exception occurred during ignore files checking: " - + e); - } - } - - return false; - } - - int sysCompare(String a, String b){ - String os = System.getProperty("os.name").toLowerCase(); - if( os.contains("windows") || os.contains("mac os") ) { - return a.compareToIgnoreCase(b); - } - return a.compareTo(b); - } - - /** - * Recursively get all files in a directory.

- * - * Note: must pass in a non-null 'files' list as a parameter. - */ - public static void getFiles(File dir, FilenameFilter filter, List files) { - if (files == null) { - throw new IllegalArgumentException("Must pass in a non-null 'files' list as a parameter."); - } - if (dir != null) { - if (dir.isDirectory()) { - String[] children = dir.list(filter); - if (children != null) { - for (int i=0; i + * Note: must pass in a non-null 'files' list as a parameter. + * + * @param dir dir + * @param filter filter + * @param files files + */ + public static void getFiles(File dir, FilenameFilter filter, List files) { + if (files == null) { + throw new IllegalArgumentException("Must pass in a non-null 'files' list as a parameter."); + } + if (dir != null) { + if (dir.isDirectory()) { + String[] children = dir.list(filter); + if (children != null) { + for (int i = 0; i < children.length; i++) { + getFiles(new File(dir, children[i]), filter, files); + } + } + } else { + files.add(dir); + } + } + } + + /** + * Return the client ignore checker; create a new one if it doesn't exist. + * + * @param charset charset + * @return ClientIgnoreChecker + */ private ClientIgnoreChecker getChecker(Charset charset) { if (this.checker == null) { if (this.server != null) { - if (this.server.getCurrentClient() != null - && this.server.getIgnoreFileName() != null) { - this.checker = new ClientIgnoreChecker(this.server - .getCurrentClient().getRoot(), - this.server.getIgnoreFileName(), charset); + if (this.server.getCurrentClient() != null && this.server.getIgnoreFileName() != null) { + this.checker = new ClientIgnoreChecker(this.server.getCurrentClient().getRoot(), this.server.getIgnoreFileName(), charset); } } } return this.checker; } - + } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientTrust.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientTrust.java index b95e854..8299e23 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientTrust.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientTrust.java @@ -3,6 +3,18 @@ */ package com.perforce.p4java.impl.mapbased.rpc.func.client; +import com.perforce.p4java.exception.ConfigException; +import com.perforce.p4java.exception.NullPointerError; +import com.perforce.p4java.exception.TrustException; +import com.perforce.p4java.impl.mapbased.rpc.RpcServer; +import com.perforce.p4java.messages.PerforceMessages; +import com.perforce.p4java.server.Fingerprint; + +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509TrustManager; +import java.net.InetAddress; +import java.net.UnknownHostException; import java.security.GeneralSecurityException; import java.security.InvalidAlgorithmParameterException; import java.security.KeyStore; @@ -26,20 +38,9 @@ import java.util.List; import java.util.Set; -import com.perforce.p4java.exception.ConfigException; -import com.perforce.p4java.exception.NullPointerError; -import com.perforce.p4java.exception.TrustException; -import com.perforce.p4java.impl.mapbased.rpc.RpcServer; -import com.perforce.p4java.messages.PerforceMessages; -import com.perforce.p4java.server.Fingerprint; - -import javax.net.ssl.TrustManager; -import javax.net.ssl.TrustManagerFactory; -import javax.net.ssl.X509TrustManager; - /** * Handle the client trust and fingerprint for Perforce SSL connections. - * + *

* This also include methods to assist in validating a certificate path. * We trust all certificates but save the certificates for * later checking with methods in this class. @@ -48,8 +49,7 @@ public class ClientTrust { public static final String DIGEST_TYPE = "SHA"; - public static final char[] HEX_CHARS = { '0', '1', '2', '3', '4', '5', '6', - '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + public static final char[] HEX_CHARS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; public static final String FINGERPRINT_USER_NAME = "**++**"; @@ -74,109 +74,83 @@ public class ClientTrust { public static final String CLIENT_TRUST_INSTALL_EXCEPTION = "client.trust.install.exception"; public static final String CLIENT_TRUST_UNINSTALL_EXCEPTION = "client.trust.uninstall.exception"; - public static final String SSL_CLIENT_TRUST_BADDATE= "client.trust.cert.bad.date.exception"; + public static final String SSL_CLIENT_TRUST_BADDATE = "client.trust.cert.bad.date.exception"; public static final String SSL_CLIENT_TRUST_BADHOST = "client.trust.cert.bad.host.exception"; private RpcServer rpcServer = null; - private static PerforceMessages messages = new PerforceMessages( - ClientTrust.CLIENT_TRUST_MESSAGES); + private static PerforceMessages messages = new PerforceMessages(ClientTrust.CLIENT_TRUST_MESSAGES); /** * Instantiates a new client trust. - * - * @param rpcServer - * the rpc server + * + * @param rpcServer the rpc server */ public ClientTrust(RpcServer rpcServer) { if (rpcServer == null) { - throw new NullPointerError( - "null rpcServer passed to ClientTrust constructor"); + throw new NullPointerError("null rpcServer passed to ClientTrust constructor"); } this.rpcServer = rpcServer; } /** * Install the fingerprint for the specified server IP and port - * - * @param serverIpPort - * the serverIpPort - * @param fingerprintUser - * the fingerprintUser - * @param fingerprint - * the fingerprint - * @throws TrustException - * the trust exception + * + * @param serverIpPort the serverIpPort + * @param fingerprintUser the fingerprintUser + * @param fingerprint the fingerprint + * @throws TrustException the trust exception */ - public void installFingerprint(String serverIpPort, String fingerprintUser, String fingerprint) - throws TrustException { + public void installFingerprint(String serverIpPort, String fingerprintUser, String fingerprint) throws TrustException { if (serverIpPort == null) { - throw new NullPointerError( - "null serverIpPort passed to the ClientTrust installFingerprint method"); + throw new NullPointerError("null serverIpPort passed to the ClientTrust installFingerprint method"); } if (fingerprintUser == null) { - throw new NullPointerError( - "null fingerprintUser passed to the ClientTrust installFingerprint method"); + throw new NullPointerError("null fingerprintUser passed to the ClientTrust installFingerprint method"); } if (fingerprint == null) { - throw new NullPointerError( - "null fingerprint passed to the ClientTrust installFingerprint method"); + throw new NullPointerError("null fingerprint passed to the ClientTrust installFingerprint method"); } try { rpcServer.saveFingerprint(serverIpPort, fingerprintUser, fingerprint); } catch (ConfigException e) { - throw new TrustException(TrustException.Type.INSTALL, - rpcServer.getServerHostPort(), serverIpPort, fingerprint, - messages.getMessage(ClientTrust.CLIENT_TRUST_INSTALL_EXCEPTION, - new Object[] { fingerprint, rpcServer.getServerHostPort(), serverIpPort }), e); + throw new TrustException(TrustException.Type.INSTALL, rpcServer.getServerHostPort(), serverIpPort, fingerprint, messages.getMessage(ClientTrust.CLIENT_TRUST_INSTALL_EXCEPTION, new Object[]{fingerprint, rpcServer.getServerHostPort(), serverIpPort}), e); } } /** * Removes the fingerprint for the specified server IP and port - * - * @param serverIpPort - * the serverIpPort - * @param fingerprintUser - * the fingerprintUser - * @throws TrustException - * the trust exception + * + * @param serverIpPort the serverIpPort + * @param fingerprintUser the fingerprintUser + * @throws TrustException the trust exception */ public void removeFingerprint(String serverIpPort, String fingerprintUser) throws TrustException { if (serverIpPort == null) { - throw new NullPointerError( - "null serverIpPort passed to the ClientTrust removeFingerprint method"); + throw new NullPointerError("null serverIpPort passed to the ClientTrust removeFingerprint method"); } if (fingerprintUser == null) { - throw new NullPointerError( - "null fingerprintUser passed to the ClientTrust removeFingerprint method"); + throw new NullPointerError("null fingerprintUser passed to the ClientTrust removeFingerprint method"); } try { rpcServer.saveFingerprint(serverIpPort, fingerprintUser, null); } catch (ConfigException e) { - throw new TrustException(TrustException.Type.UNINSTALL, - rpcServer.getServerHostPort(), serverIpPort, null, - messages.getMessage(ClientTrust.CLIENT_TRUST_UNINSTALL_EXCEPTION, - new Object[] { rpcServer.getServerHostPort(), serverIpPort }), e); + throw new TrustException(TrustException.Type.UNINSTALL, rpcServer.getServerHostPort(), serverIpPort, null, messages.getMessage(ClientTrust.CLIENT_TRUST_UNINSTALL_EXCEPTION, new Object[]{rpcServer.getServerHostPort(), serverIpPort}), e); } } /** * Check if the fingerprint exists for the specified server IP and port - * - * @param serverKey - * the serverIpPort or serverHostName - * @param fingerprintUser - * the fingerprintUser + * + * @param serverKey the serverIpPort or serverHostName + * @param fingerprintUser the fingerprintUser * @return true, if successful */ public boolean fingerprintExists(String serverKey, String fingerprintUser) { if (serverKey == null) { - throw new NullPointerError( - "null serverIpPort passed to the ClientTrust fingerprintExists method"); + throw new NullPointerError("null serverIpPort passed to the ClientTrust fingerprintExists method"); } if (fingerprintUser == null) { - throw new NullPointerError( - "null fingerprintUser passed to the ClientTrust fingerprintExists method"); + throw new NullPointerError("null fingerprintUser passed to the ClientTrust fingerprintExists method"); } return (rpcServer.loadFingerprint(serverKey, fingerprintUser) != null); } @@ -185,34 +159,25 @@ public boolean fingerprintExists(String serverKey, String fingerprintUser) { * Check if the fingerprint for the specified server IP and port matches the * one in trust file. * - * @param serverKey - * the serverIpPort or serverHostName - * @param fingerprintUser - * the fingerprintUser - * @param fingerprint - * the fingerprint + * @param serverKey the serverIpPort or serverHostName + * @param fingerprintUser the fingerprintUser + * @param fingerprint the fingerprint * @return true, if successful */ public boolean fingerprintMatches(String serverKey, String fingerprintUser, String fingerprint) { if (serverKey == null) { - throw new NullPointerError( - "null serverIpPort passed to the ClientTrust fingerprintMatches method"); + throw new NullPointerError("null serverIpPort passed to the ClientTrust fingerprintMatches method"); } if (fingerprintUser == null) { - throw new NullPointerError( - "null fingerprintUser passed to the ClientTrust fingerprintMatches method"); + throw new NullPointerError("null fingerprintUser passed to the ClientTrust fingerprintMatches method"); } if (fingerprint == null) { - throw new NullPointerError( - "null fingerprint passed to the ClientTrust fingerprintMatches method"); + throw new NullPointerError("null fingerprint passed to the ClientTrust fingerprintMatches method"); } if (fingerprintExists(serverKey, fingerprintUser)) { - Fingerprint existingFingerprint = rpcServer - .loadFingerprint(serverKey, fingerprintUser); - if (existingFingerprint != null - && existingFingerprint.getFingerprintValue() != null) { - if (fingerprint.equalsIgnoreCase(existingFingerprint - .getFingerprintValue())) { + Fingerprint existingFingerprint = rpcServer.loadFingerprint(serverKey, fingerprintUser); + if (existingFingerprint != null && existingFingerprint.getFingerprintValue() != null) { + if (fingerprint.equalsIgnoreCase(existingFingerprint.getFingerprintValue())) { return true; } } @@ -222,15 +187,12 @@ public boolean fingerprintMatches(String serverKey, String fingerprintUser, Stri /** * Generate fingerprint from public key using MessageDigest. - * - * @param publicKey - * the public key + * + * @param publicKey the public key * @return the string - * @throws NoSuchAlgorithmException - * the no such algorithm exception + * @throws NoSuchAlgorithmException the no such algorithm exception */ - public static String generateFingerprint(PublicKey publicKey) - throws NoSuchAlgorithmException { + public static String generateFingerprint(PublicKey publicKey) throws NoSuchAlgorithmException { MessageDigest md = MessageDigest.getInstance(DIGEST_TYPE); md.update(publicKey.getEncoded()); byte[] fp = md.digest(); @@ -239,17 +201,13 @@ public static String generateFingerprint(PublicKey publicKey) /** * Generate fingerprint from a certificate using MessageDigest. - * - * @param certificate - * the certificate + * + * @param certificate the certificate * @return the string - * @throws NoSuchAlgorithmException - * the no such algorithm exception - * @throws CertificateEncodingException - * the certificate encoding exception + * @throws NoSuchAlgorithmException the no such algorithm exception + * @throws CertificateEncodingException the certificate encoding exception */ - public static String generateFingerprint(X509Certificate certificate) - throws NoSuchAlgorithmException, CertificateEncodingException { + public static String generateFingerprint(X509Certificate certificate) throws NoSuchAlgorithmException, CertificateEncodingException { MessageDigest md = MessageDigest.getInstance(DIGEST_TYPE); md.update(certificate.getEncoded()); byte[] fp = md.digest(); @@ -258,9 +216,8 @@ public static String generateFingerprint(X509Certificate certificate) /** * Convert a byte array to a hexadecimal string - * - * @param data - * the data + * + * @param data the data * @return the string */ public static String convert2Hex(byte[] data) { @@ -278,7 +235,7 @@ public static String convert2Hex(byte[] data) { /** * Gets the messages. - * + * * @return the messages */ public PerforceMessages getMessages() { @@ -296,24 +253,28 @@ public PerforceMessages getMessages() { * Gets the root CAs in the trust store, either the default truststore or as * specified by javax.net.ssl.trustStore/javax.net.ssl.trustStorePassword. * root CAs are cached. + * + * @return root CAs + * @throws NoSuchAlgorithmException on error + * @throws KeyStoreException on error + * @throws InvalidAlgorithmParameterException on error */ - public static Set getTrustedCAs() - throws NoSuchAlgorithmException, KeyStoreException, InvalidAlgorithmParameterException { + public static Set getTrustedCAs() throws NoSuchAlgorithmException, KeyStoreException, InvalidAlgorithmParameterException { return getTrustedCAs(false); } + /** * Gets the root CAs from the trust store, either the default truststore or as * specified by javax.net.ssl.trustStore/javax.net.ssl.trustStorePassword. * * @param refreshCache force retrieve from truststore - * @return - * @throws NoSuchAlgorithmException - * @throws KeyStoreException - * @throws InvalidAlgorithmParameterException + * @return root CAs + * @throws NoSuchAlgorithmException on error + * @throws KeyStoreException on error + * @throws InvalidAlgorithmParameterException on error */ - public static synchronized Set getTrustedCAs(boolean refreshCache) - throws NoSuchAlgorithmException, KeyStoreException, InvalidAlgorithmParameterException { - if (! refreshCache && trustedCAs != null) { + public static synchronized Set getTrustedCAs(boolean refreshCache) throws NoSuchAlgorithmException, KeyStoreException, InvalidAlgorithmParameterException { + if (!refreshCache && trustedCAs != null) { return trustedCAs; } X509TrustManager x509tm = getDefaultX509TrustManager(); @@ -323,8 +284,13 @@ public static synchronized Set getTrustedCAs(boolean refreshCache) } return trustedCAs; } + /** * Get the system default trust manager {@link X509TrustManager} + * + * @return trust manager + * @throws NoSuchAlgorithmException on errror + * @throws KeyStoreException on error */ public static X509TrustManager getDefaultX509TrustManager() throws NoSuchAlgorithmException, KeyStoreException { TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); @@ -341,11 +307,11 @@ public static X509TrustManager getDefaultX509TrustManager() throws NoSuchAlgorit /** * Check the certificate chain. * - * @param certs the certificates from p4d handshake. + * @param certs the certificates from p4d handshake. + * @param refName refName * @throws CertificateException if the validation fails */ - public static void validateServerChain(X509Certificate[] certs, String refName) - throws CertificateException { + public static void validateServerChain(X509Certificate[] certs, String refName) throws CertificateException { // workaround for bug P4-22041: // remove duplicates at the end of the chain. @@ -374,7 +340,7 @@ public static void validateServerChain(X509Certificate[] certs, String refName) // TODO logging for validation: ssl=3 System.out.println("result=" + valDetails.toString()); - } catch (GeneralSecurityException e) { + } catch (GeneralSecurityException | UnknownHostException e ) { // example: java.security.cert.CertPathValidatorException: path does not chain with any of the trust anchors throw new CertificateException(e); } @@ -382,21 +348,20 @@ public static void validateServerChain(X509Certificate[] certs, String refName) /** * Check the certificate Not Before and Not After dates - * @param cert - * @throws CertificateException + * + * @param cert cert + * @throws CertificateException on error */ public static void verifyCertificateDates(X509Certificate cert) throws CertificateException { - Date after= cert.getNotAfter(); - Date before = cert.getNotBefore() ; + Date after = cert.getNotAfter(); + Date before = cert.getNotBefore(); Date now = new Date(); if (now.before(before)) { - throw new CertificateException(messages.getMessage(SSL_CLIENT_TRUST_BADDATE, - new Object[] { "before", before})); + throw new CertificateException(messages.getMessage(SSL_CLIENT_TRUST_BADDATE, new Object[]{"before", before})); } if (now.after(after)) { - throw new CertificateException(messages.getMessage(SSL_CLIENT_TRUST_BADDATE, - new Object[] { "after", after})); + throw new CertificateException(messages.getMessage(SSL_CLIENT_TRUST_BADDATE, new Object[]{"after", after})); } return; } @@ -404,19 +369,21 @@ public static void verifyCertificateDates(X509Certificate cert) throws Certifica /** * Verify the request's hostname to that in the certificate. * - * @param cert certificate + * @param cert certificate * @param hostName Host name - * @throws CertificateParsingException - * @throws CertificateException + * @throws CertificateParsingException on error + * @throws CertificateException on error + * @throws UnknownHostException Could not find IP Address for Given Host name */ - public static void verifyCertificateSubject(X509Certificate cert, String hostName) throws CertificateParsingException, CertificateException { + public static void verifyCertificateSubject(X509Certificate cert, String hostName) throws CertificateParsingException, CertificateException, UnknownHostException { // check SANs first, https://www.rfc-editor.org/rfc/rfc6125#section-6.4.3 + InetAddress address = InetAddress.getByName(hostName); for (List entry : cert.getSubjectAlternativeNames()) { final int type = ((Integer) entry.get(0)).intValue(); // DNS or IP if (type == 2 || type == 7) { - if ( matchSubject((String)entry.get(1), hostName)) { + if (matchSubject((String) entry.get(1), hostName) || matchSubject((String)entry.get(1),address.getHostAddress())) { return; } } @@ -427,7 +394,7 @@ public static void verifyCertificateSubject(X509Certificate cert, String hostNam if (cn.startsWith("CN=")) { cn = cn.substring(3); } - if ( matchSubject(cn, hostName)) { + if (matchSubject(cn, hostName) || matchSubject(cn,address.getHostAddress())) { return; } @@ -437,26 +404,26 @@ public static void verifyCertificateSubject(X509Certificate cert, String hostNam for (List entry : cert.getSubjectAlternativeNames()) { final int type = ((Integer) entry.get(0)).intValue(); if (type == 2 || type == 7) { - sb.append((String)entry.get(1) + ","); + sb.append((String) entry.get(1) + ","); } } sb.append(cn); - throw new CertificateException(messages.getMessage(SSL_CLIENT_TRUST_BADHOST,new Object[]{hostName, sb})); + throw new CertificateException(messages.getMessage(SSL_CLIENT_TRUST_BADHOST, new Object[]{hostName, sb})); } /** * Check to see if a cert's subject matches with a reference name (e.g., hostname in P4PORT) - * Note that the subject may contain a leading wildcard "*.".
- * + * Note that the subject may contain a leading wildcard "*.". + *

* @param subject - certificate's subject name (a SAN value or CN) * @param refName reference name to compare. * @return true if matches. */ private static boolean matchSubject(String subject, String refName) { - if ( subject.startsWith("*.") ) { + if (subject.startsWith("*.")) { subject = subject.substring(1); // remove "*" int firstDot = refName.indexOf("."); // remove hostname? - firstDot = (firstDot >= 0 ) ? firstDot : 0; + firstDot = (firstDot >= 0) ? firstDot : 0; if (subject.equalsIgnoreCase(refName.substring(firstDot))) { return true; } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientUserInteraction.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientUserInteraction.java index 9128152..728d13d 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientUserInteraction.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/client/ClientUserInteraction.java @@ -31,11 +31,7 @@ import com.perforce.p4java.server.callback.ISSOCallback; import com.perforce.p4java.server.callback.ISSOCallback.Status; -import java.awt.*; -import java.io.IOException; import java.io.InputStream; -import java.net.URI; -import java.net.URISyntaxException; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; @@ -72,7 +68,7 @@ protected ClientUserInteraction(Properties props, RpcServer server) { * Prompt the end-user (i.e. the upper-levels of P4Java...) in response to a * server request. The various parameters in resultsMap determine things like * whether the prompt uses echoing, what digest to use (if any), what prompt - * string to use, etc., many of which aren't relevant in our context.

+ * string to use, etc., many of which aren't relevant in our context. *

* In the most common usage -- password extraction from the user -- we * follow a fairly simple scheme where we first hash the password with @@ -80,20 +76,24 @@ protected ClientUserInteraction(Properties props, RpcServer server) { * MD5 cycle and hash it against the "digest" string passed in from * the server. Everything else that's sent to us from the server is * simply echoed for the server's own purposes (i.e. I still don't know - * what some of this stuff does...).

+ * what some of this stuff does...). *

* Note that we have to do what the C++ API does in the same circumstances; * this means converting the hash hex string results into upper-case, etc., * and several other mild quirks whose use or motivation aren't always - * obvious.

+ * obvious. *

* Note also that we're not currently implementing the full panoply of * possible processing here, just the subset that's useful to us for P4WSAD * and that presumes a 2003.2 or later server in not-too-strict mode. + * + * @param rpcConnection rpcConnection + * @param cmdEnv cmdEnv + * @param resultsMap resultsMap + * @return RpcPacketDispatcherResult + * @throws ConnectionException on error */ - - protected RpcPacketDispatcherResult clientPrompt(RpcConnection rpcConnection, - CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { + protected RpcPacketDispatcherResult clientPrompt(RpcConnection rpcConnection, CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { if (rpcConnection == null) { throw new NullPointerError("Null rpcConnection in clientPrompt()."); @@ -146,8 +146,7 @@ protected RpcPacketDispatcherResult clientPrompt(RpcConnection rpcConnection, } RpcFunctionSpec funcSpec = RpcFunctionSpec.decode(confirm); if (funcSpec == RpcFunctionSpec.NONE) { - throw new ProtocolError("Unable to decode confirm server function '" - + confirm + "' in clientPrompt."); + throw new ProtocolError("Unable to decode confirm server function '" + confirm + "' in clientPrompt."); } if (noprompt) { @@ -205,8 +204,7 @@ protected RpcPacketDispatcherResult clientPrompt(RpcConnection rpcConnection, } break; default: - throw new UnimplementedError("Unimplemented confirmation to server function '" - + funcSpec.getEncoding() + "' in clientPrompt."); + throw new UnimplementedError("Unimplemented confirmation to server function '" + funcSpec.getEncoding() + "' in clientPrompt."); } } @@ -281,26 +279,27 @@ protected RpcPacketDispatcherResult clientPrompt(RpcConnection rpcConnection, return rpcConnection.clientConfirm(confirm, resultsMap); } catch (Exception exc) { Log.exception(exc); - throw new P4JavaError( - "Unexpected exception in ClientUserInteraction.clientPrompt:" - + exc.getLocalizedMessage(), - exc); + throw new P4JavaError("Unexpected exception in ClientUserInteraction.clientPrompt:" + exc.getLocalizedMessage(), exc); } } /** * Set the client-side password in response to a Perforce server command * telling us to do just that, usually as a result of an earlier - * successful login attempt in the same session.

+ * successful login attempt in the same session. *

* In this context setting the password really just means performing a few * sanity and consistency checks, then returning a suitable ticket for use * with the -P option in future commands. This can be an arbitrarily - * complex process...

+ * complex process... + * + * @param rpcConnection rpcConnection + * @param cmdEnv cmdEnv + * @param resultsMap resultsMap + * @return RpcPacketDispatcherResult + * @throws ConnectionException on error */ - - protected RpcPacketDispatcherResult clientSetPassword(RpcConnection rpcConnection, - CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { + protected RpcPacketDispatcherResult clientSetPassword(RpcConnection rpcConnection, CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { if (rpcConnection == null) { throw new NullPointerError("Null rpcConnection in clientSetPassword()."); @@ -353,7 +352,7 @@ protected RpcPacketDispatcherResult clientSetPassword(RpcConnection rpcConnectio String secretKey = sameUser ? this.server.getSecretKey(userName) : null; // from the earlier clientGetPrompt() call... if (secretKey == null) { - secretKey = this.server.getAuthTicket(userName); + secretKey = this.server.getAuthTicket(userName, serverId); } if (secretKey == null) { secretKey = this.server.getAuthTicket(); @@ -375,8 +374,7 @@ protected RpcPacketDispatcherResult clientSetPassword(RpcConnection rpcConnectio ticket = new String(data); } this.server.setAuthTicket(userName, serverId, ticket); - if (!cmdEnv.isDontWriteTicket() || - !resultsMap.containsKey(RpcFunctionMapKey.OUTPUT)) { // skip if "login -p" + if (!cmdEnv.isDontWriteTicket() || !resultsMap.containsKey(RpcFunctionMapKey.OUTPUT)) { // skip if "login -p" try { this.server.saveTicket(userName, serverId, ticket); } catch (ConfigException e) { @@ -407,10 +405,14 @@ protected RpcPacketDispatcherResult clientSetPassword(RpcConnection rpcConnectio * Implements the client-side of the Perforce single sign on (SSO) protocol. * Basically defers to the registered SSO callback (if it exists) and simply * responds back to the server appropriately. + * + * @param rpcConnection rpcConnection + * @param cmdEnv cmdEnv + * @param resultsMap resultsMap + * @return RpcPacketDispatcherResult + * @throws ConnectionException on error */ - - protected RpcPacketDispatcherResult clientSingleSignon(RpcConnection rpcConnection, - CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { + protected RpcPacketDispatcherResult clientSingleSignon(RpcConnection rpcConnection, CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { if (rpcConnection == null) { throw new NullPointerError("Null rpcConnection in clientSingleSignon()."); @@ -429,28 +431,24 @@ protected RpcPacketDispatcherResult clientSingleSignon(RpcConnection rpcConnecti if (this.server != null) { ISSOCallback ssoCallback = this.server.getSSOCallback(); if (ssoCallback != null) { - status = ssoCallback.getSSOCredentials(credBuf, - this.server.getSSOKey(), this.server.getUserName()); + status = ssoCallback.getSSOCredentials(credBuf, this.server.getSSOKey(), this.server.getUserName()); } } else { // How did this happen?! - Log.error( - "null server object in ClientUserInteraction.clientSingleSignon method"); + Log.error("null server object in ClientUserInteraction.clientSingleSignon method"); } if (status == null) { status = Status.UNSET; } - resultsMap.put(RpcFunctionMapKey.STATUS, status.toString() - .toLowerCase()); + resultsMap.put(RpcFunctionMapKey.STATUS, status.toString().toLowerCase()); String sso = null; // If not unset then set the SSO key based on the buffered passed to // the sso callback if (status != Status.UNSET) { - if ((credBuf != null) - && (credBuf.length() > ISSOCallback.MAX_CRED_LENGTH)) { + if ((credBuf != null) && (credBuf.length() > ISSOCallback.MAX_CRED_LENGTH)) { sso = credBuf.substring(0, ISSOCallback.MAX_CRED_LENGTH); } else { // Note: credBuf could be null, which is OK in this context @@ -464,8 +462,7 @@ protected RpcPacketDispatcherResult clientSingleSignon(RpcConnection rpcConnecti return RpcPacketDispatcherResult.CONTINUE_LOOP; } - protected RpcPacketDispatcherResult clientReceiveFiles(RpcConnection rpcConnection, - CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { + protected RpcPacketDispatcherResult clientReceiveFiles(RpcConnection rpcConnection, CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { if (rpcConnection == null) { throw new NullPointerError("Null rpcConnection in clientReceiveFiles()."); @@ -539,10 +536,14 @@ protected RpcPacketDispatcherResult clientReceiveFiles(RpcConnection rpcConnecti * I guess; we just decline automatically if anything went wrong, * and say yes ("dm-OpenFile") if things went fine... in effect, we * just do a pass-through. This may change as we gain experience. + * + * @param rpcConnection rpcConnection + * @param cmdEnv cmdEnv + * @param resultsMap resultsMap + * @return RpcPacketDispatcherResult + * @throws ConnectionException on error */ - - protected RpcPacketDispatcherResult clientAck(RpcConnection rpcConnection, - CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { + protected RpcPacketDispatcherResult clientAck(RpcConnection rpcConnection, CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { if (rpcConnection == null) { throw new NullPointerError("Null rpcConnection in clientAck()."); @@ -585,15 +586,19 @@ protected RpcPacketDispatcherResult clientAck(RpcConnection rpcConnection, /** * Process the client-Crypto command from the Perforce server. This is typically * called in response to an earlier login using the ticket feature (which is how - * we normally do logins in P4Java).

+ * we normally do logins in P4Java). *

* In the P4Java context, this really means first MD5-hashing the incoming token, then * hashing the previously-returned ticket, then returning the results to the server for * inspection. + * + * @param rpcConnection rpcConnection + * @param cmdEnv cmdEnv + * @param resultsMap resultsMap + * @return RpcPacketDispatcherResult + * @throws ConnectionException on error */ - - protected RpcPacketDispatcherResult clientCrypto(RpcConnection rpcConnection, - CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { + protected RpcPacketDispatcherResult clientCrypto(RpcConnection rpcConnection, CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { if (rpcConnection == null) { throw new NullPointerError("Null rpcConnection in clientCrypto()."); @@ -618,9 +623,7 @@ protected RpcPacketDispatcherResult clientCrypto(RpcConnection rpcConnection, String token = (String) resultsMap.get(RpcFunctionMapKey.TOKEN); Map respMap = new HashMap<>(); - boolean proxy = props.containsKey(RpcFunctionMapKey.IPADDR) && - props.containsKey(RpcFunctionMapKey.SVRNAME) && - props.containsKey(RpcFunctionMapKey.PORT); + boolean proxy = props.containsKey(RpcFunctionMapKey.IPADDR) && props.containsKey(RpcFunctionMapKey.SVRNAME) && props.containsKey(RpcFunctionMapKey.PORT); String svcUser = props.getProperty(RpcFunctionMapKey.SVRNAME); @@ -695,8 +698,7 @@ protected RpcPacketDispatcherResult clientCrypto(RpcConnection rpcConnection, } if (proxy) { - respMap.put(RpcFunctionMapKey.CADDR, - props.getProperty(RpcFunctionMapKey.IPADDR)); + respMap.put(RpcFunctionMapKey.CADDR, props.getProperty(RpcFunctionMapKey.IPADDR)); } if (daddr0 != null) { @@ -714,18 +716,12 @@ protected RpcPacketDispatcherResult clientCrypto(RpcConnection rpcConnection, respMap.put("dhash0", resp); } - RpcPacket respPacket = RpcPacket.constructRpcPacket( - confirm, - respMap, - null); + RpcPacket respPacket = RpcPacket.constructRpcPacket(confirm, respMap, null); rpcConnection.putRpcPacket(respPacket); } catch (Exception exc) { Log.exception(exc); - throw new P4JavaError( - "Unexpected exception in ClientUserInteraction.clientCrypto:" - + exc.getLocalizedMessage(), - exc); + throw new P4JavaError("Unexpected exception in ClientUserInteraction.clientCrypto:" + exc.getLocalizedMessage(), exc); } return RpcPacketDispatcherResult.CONTINUE_LOOP; @@ -753,8 +749,7 @@ private String getTicketStr(String user, String serverId) { return ticketStr; } - protected RpcPacketDispatcherResult clientOpenURL(RpcConnection rpcConnection, - CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { + protected RpcPacketDispatcherResult clientOpenURL(RpcConnection rpcConnection, CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { if (rpcConnection == null) { throw new NullPointerError("Null rpcConnection in clientOpenURL)."); @@ -785,10 +780,14 @@ protected RpcPacketDispatcherResult clientOpenURL(RpcConnection rpcConnection, * Get some requested data (typically something like a submit form) from * somewhere (typically a map passed in from the upper levels of the API) and * pass it back to the server, properly munged. + * + * @param rpcConnection rpcConnection + * @param cmdEnv cmdEnv + * @param resultsMap resultsMap + * @return RpcPacketDispatcherResult + * @throws ConnectionException on error */ - - protected RpcPacketDispatcherResult clientInputData(RpcConnection rpcConnection, - CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { + protected RpcPacketDispatcherResult clientInputData(RpcConnection rpcConnection, CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { if (rpcConnection == null) { throw new NullPointerError("Null rpcConnection in clientInputData()."); @@ -894,6 +893,10 @@ protected RpcPacketDispatcherResult clientInputData(RpcConnection rpcConnection, /** * Get bytes from the stream passed in. + * + * @param cmdName cmdName + * @param inStream inStream + * @return bytes */ protected byte[] getStreamBytes(String cmdName, InputStream inStream) { @@ -924,8 +927,7 @@ protected byte[] getStreamBytes(String cmdName, InputStream inStream) { return null; } - protected RpcPacketDispatcherResult clientPing(RpcConnection rpcConnection, - CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { + protected RpcPacketDispatcherResult clientPing(RpcConnection rpcConnection, CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { if (rpcConnection == null) { throw new NullPointerError("Null rpcConnection in clientPing()."); @@ -951,8 +953,7 @@ protected RpcPacketDispatcherResult clientPing(RpcConnection rpcConnection, try { int size = Integer.parseInt(payloadSize); - if (size > 1000000) - size = 1000000; + if (size > 1000000) size = 1000000; StringBuffer sbuf = new StringBuffer(); for (int i = 0; i < size; i++) { @@ -972,18 +973,14 @@ protected RpcPacketDispatcherResult clientPing(RpcConnection rpcConnection, respMap.put(RpcFunctionMapKey.TIME, timer); } - RpcPacket respPacket = RpcPacket.constructRpcPacket( - "dm-Ping", - respMap, - null); + RpcPacket respPacket = RpcPacket.constructRpcPacket("dm-Ping", respMap, null); rpcConnection.putRpcPacket(respPacket); return RpcPacketDispatcherResult.CONTINUE_LOOP; } - protected RpcPacketDispatcherResult clientErrorPause(RpcConnection rpcConnection, - CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { + protected RpcPacketDispatcherResult clientErrorPause(RpcConnection rpcConnection, CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { if (rpcConnection == null) { throw new NullPointerError("Null rpcConnection in clientPing()."); @@ -1010,8 +1007,7 @@ protected RpcPacketDispatcherResult clientErrorPause(RpcConnection rpcConnection return RpcPacketDispatcherResult.CONTINUE_LOOP; } - protected RpcPacketDispatcherResult clientHandleError(RpcConnection rpcConnection, - CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { + protected RpcPacketDispatcherResult clientHandleError(RpcConnection rpcConnection, CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { if (rpcConnection == null) { throw new NullPointerError("Null rpcConnection in clientPing()."); @@ -1054,8 +1050,7 @@ protected RpcPacketDispatcherResult clientHandleError(RpcConnection rpcConnectio } - protected RpcPacketDispatcherResult clientActionResolve(RpcConnection rpcConnection, - CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { + protected RpcPacketDispatcherResult clientActionResolve(RpcConnection rpcConnection, CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { if (rpcConnection == null) { throw new NullPointerError("Null rpcConnection in clientPing()."); @@ -1212,8 +1207,7 @@ else if ( *autoResult == P4Tag::v_rOptYours ) return RpcPacketDispatcherResult.CONTINUE_LOOP; } - protected RpcPacketDispatcherResult clientEditData(RpcConnection rpcConnection, - CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { + protected RpcPacketDispatcherResult clientEditData(RpcConnection rpcConnection, CommandEnv cmdEnv, Map resultsMap) throws ConnectionException { if (rpcConnection == null) { throw new NullPointerError("Null rpcConnection in clientPing()."); diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/helper/MD5Digester.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/helper/MD5Digester.java index b244ac1..6275946 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/helper/MD5Digester.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/helper/MD5Digester.java @@ -38,11 +38,7 @@ * Provide MD5 digest methods for the rest of the RPC implementation. Basically * just a wrapper around the normal Java stuff, with a useful added method to * finalise the digest as a hex string. - *

- * - * @author Sean Shou - clean code & unit test */ - public class MD5Digester { private static final String DIGEST_TYPE = "MD5"; private static final int LENGTH_OF_HEX_STRING = 32; @@ -55,9 +51,7 @@ public MD5Digester() throws P4JavaError { messageDigest = MessageDigest.getInstance(DIGEST_TYPE); messageDigest.reset(); } catch (NoSuchAlgorithmException exc) { - throw new P4JavaError( - "Unable to create an MD5 digester for P4Java: " + exc.getLocalizedMessage(), - exc); + throw new P4JavaError("Unable to create an MD5 digester for P4Java: " + exc.getLocalizedMessage(), exc); } } @@ -80,6 +74,7 @@ public byte[] digestAsBytes() { * Returns null if it can't read or digest the file for whatever reason; * otherwise the finalized digest is returned as a 32 byte hex string. * + * @param file file * @return - computed digest or null if computation failed */ @Nullable @@ -117,6 +112,8 @@ public void update(byte[] bytes, int off, int len) { * Return the finalised digest as a 32 byte hex string. It's important * elsewhere and in the server that the string be exactly 32 bytes long, so * we stitch it up if possible to make it that long... + * + * @return digest */ public String digestAs32ByteHex() { String retStr = new BigInteger(1, messageDigest.digest()).toString(16).toUpperCase(); @@ -124,8 +121,7 @@ public String digestAs32ByteHex() { if (retStr.length() > 0 && (retStr.length() <= LENGTH_OF_HEX_STRING)) { return StringUtils.leftPad(retStr, LENGTH_OF_HEX_STRING, '0'); } else { - throw new P4JavaError("Bad 32 byte digest string size in MD5Digester.digestAs32ByteHex;" - + " string: " + retStr + ";" + " length: " + retStr.length()); + throw new P4JavaError("Bad 32 byte digest string size in MD5Digester.digestAs32ByteHex;" + " string: " + retStr + ";" + " length: " + retStr.length()); } } @@ -135,6 +131,8 @@ public String digestAs32ByteHex() { * Returns null if it can't read or digest the file for whatever reason; * otherwise the finalized digest is returned as a 32 byte hex string. * + * @param file file + * @param charset charset * @return - computed digest or null if computation failed */ @Nullable @@ -148,11 +146,13 @@ public String digestFileAs32ByteHex(@Nonnull File file, @Nullable Charset charse * Returns null if it can't read or digest the file for whatever reason; * otherwise the finalized digest is returned as a 32 byte hex string. * + * @param file file + * @param charset charset + * @param doesNeedConvertLineEndings doesNeedConvertLineEndings * @return - computed digest or null if computation failed */ @Nullable - public String digestFileAs32ByteHex(@Nonnull File file, @Nullable Charset charset, - boolean doesNeedConvertLineEndings) { + public String digestFileAs32ByteHex(@Nonnull File file, @Nullable Charset charset, boolean doesNeedConvertLineEndings) { return digestFileAs32ByteHex(file, charset, doesNeedConvertLineEndings, null); } @@ -164,19 +164,21 @@ public String digestFileAs32ByteHex(@Nonnull File file, @Nullable Charset charse * Returns null if it can't read or digest the file for whatever reason; * otherwise the finalized digest is returned as a 32 byte hex string. * + * @param file file + * @param charset charset + * @param isRequireLineEndingConvert isRequireLineEndingConvert + * @param clientLineEnding clientLineEnding * @return - computed digest or null if computation failed */ @Nullable - public String digestFileAs32ByteHex(@Nonnull File file, @Nullable Charset charset, - boolean isRequireLineEndingConvert, @Nullable ClientLineEnding clientLineEnding) { + public String digestFileAs32ByteHex(@Nonnull File file, @Nullable Charset charset, boolean isRequireLineEndingConvert, @Nullable ClientLineEnding clientLineEnding) { requireNonNull(file, "Null file passed to MD5Digester.digestFileAs32ByteHex()"); if (Files.isReadable(file.toPath())) { try (FileInputStream inStream = new FileInputStream(file)) { reset(); if (nonNull(charset)) { - digestEncodedStreamToUtf8(inStream, charset, isRequireLineEndingConvert, - clientLineEnding); + digestEncodedStreamToUtf8(inStream, charset, isRequireLineEndingConvert, clientLineEnding); } else { digestStream(inStream, isRequireLineEndingConvert, clientLineEnding); } @@ -190,82 +192,61 @@ public String digestFileAs32ByteHex(@Nonnull File file, @Nullable Charset charse return null; } - private void digestEncodedStreamToUtf8(@Nonnull InputStream inStream, @Nonnull Charset charset, - boolean isRequireLineEndingConvert, @Nullable ClientLineEnding clientLineEnding) - throws IOException { + private void digestEncodedStreamToUtf8(@Nonnull InputStream inStream, @Nonnull Charset charset, boolean isRequireLineEndingConvert, @Nullable ClientLineEnding clientLineEnding) throws IOException { - try (BOMInputStream unicodeInputStream = new BOMInputStream(inStream, false, - ByteOrderMark.UTF_8, ByteOrderMark.UTF_16LE, ByteOrderMark.UTF_16BE, - ByteOrderMark.UTF_32LE, ByteOrderMark.UTF_32BE)) { + try (BOMInputStream unicodeInputStream = new BOMInputStream(inStream, false, ByteOrderMark.UTF_8, ByteOrderMark.UTF_16LE, ByteOrderMark.UTF_16BE, ByteOrderMark.UTF_32LE, ByteOrderMark.UTF_32BE)) { if (unicodeInputStream.hasBOM() && (charset.name() == "UTF-16")) { charset = Charset.forName(unicodeInputStream.getBOMCharsetName()); } - InputStreamReader encodedStreamReader = new InputStreamReader(unicodeInputStream, - charset); + InputStreamReader encodedStreamReader = new InputStreamReader(unicodeInputStream, charset); - CharsetEncoder utf8CharsetEncoder = CharsetDefs.UTF8.newEncoder() - .onMalformedInput(CodingErrorAction.REPORT) - .onUnmappableCharacter(CodingErrorAction.REPORT); + CharsetEncoder utf8CharsetEncoder = CharsetDefs.UTF8.newEncoder().onMalformedInput(CodingErrorAction.REPORT).onUnmappableCharacter(CodingErrorAction.REPORT); char[] buffer = new char[bufferSize]; int read; while ((read = encodedStreamReader.read(buffer)) > 0) { // Convert encoded stream to UTF8 since server digest is UTF8 - ByteBuffer utf8ByteBuffer = utf8CharsetEncoder - .encode(CharBuffer.wrap(buffer, 0, read)); + ByteBuffer utf8ByteBuffer = utf8CharsetEncoder.encode(CharBuffer.wrap(buffer, 0, read)); if (isRequireLineEndingConvert) { - ByteBuffer convert = findAndReplaceEncodedClientLineEndingIfRequireLineEndingCovert( - encodedStreamReader, utf8CharsetEncoder, utf8ByteBuffer, - clientLineEnding); + ByteBuffer convert = findAndReplaceEncodedClientLineEndingIfRequireLineEndingCovert(encodedStreamReader, utf8CharsetEncoder, utf8ByteBuffer, clientLineEnding); update(convert.array(), convert.arrayOffset(), convert.limit()); } else { - update(utf8ByteBuffer.array(), utf8ByteBuffer.arrayOffset(), - utf8ByteBuffer.limit()); + update(utf8ByteBuffer.array(), utf8ByteBuffer.arrayOffset(), utf8ByteBuffer.limit()); } } } } - private ByteBuffer findAndReplaceEncodedClientLineEndingIfRequireLineEndingCovert( - @Nonnull InputStreamReader encodedStreamReader, - @Nonnull CharsetEncoder utf8CharsetEncoder, @Nonnull ByteBuffer initialUtf8ByteBuffer, - @Nullable ClientLineEnding clientLineEnding) throws IOException { + private ByteBuffer findAndReplaceEncodedClientLineEndingIfRequireLineEndingCovert(@Nonnull InputStreamReader encodedStreamReader, @Nonnull CharsetEncoder utf8CharsetEncoder, @Nonnull ByteBuffer initialUtf8ByteBuffer, @Nullable ClientLineEnding clientLineEnding) throws IOException { int limit = initialUtf8ByteBuffer.limit(); - byte[] allUtf8Bytes = Arrays.copyOfRange(initialUtf8ByteBuffer.array(), - initialUtf8ByteBuffer.arrayOffset(), limit); + byte[] allUtf8Bytes = Arrays.copyOfRange(initialUtf8ByteBuffer.array(), initialUtf8ByteBuffer.arrayOffset(), limit); byte lastByte = initialUtf8ByteBuffer.get(limit - 1); - int offset = findOffsetOfNextClientLineEndingIfReadBytesEndWithFirstByteOfClientLineEnding( - lastByte, clientLineEnding); + int offset = findOffsetOfNextClientLineEndingIfReadBytesEndWithFirstByteOfClientLineEnding(lastByte, clientLineEnding); while (offset > 0) { char[] followingPotentialClientLineEndingChars = new char[offset]; offset = encodedStreamReader.read(followingPotentialClientLineEndingChars); if (offset > 0) { - ByteBuffer moreBuffer = utf8CharsetEncoder.encode( - CharBuffer.wrap(followingPotentialClientLineEndingChars, 0, offset)); + ByteBuffer moreBuffer = utf8CharsetEncoder.encode(CharBuffer.wrap(followingPotentialClientLineEndingChars, 0, offset)); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); outputStream.write(allUtf8Bytes); - outputStream.write(Arrays.copyOfRange(moreBuffer.array(), - moreBuffer.arrayOffset(), moreBuffer.limit())); + outputStream.write(Arrays.copyOfRange(moreBuffer.array(), moreBuffer.arrayOffset(), moreBuffer.limit())); allUtf8Bytes = outputStream.toByteArray(); lastByte = allUtf8Bytes[allUtf8Bytes.length - 1]; - offset = findOffsetOfNextClientLineEndingIfReadBytesEndWithFirstByteOfClientLineEnding( - lastByte, clientLineEnding); + offset = findOffsetOfNextClientLineEndingIfReadBytesEndWithFirstByteOfClientLineEnding(lastByte, clientLineEnding); } } - return convertToP4dServerEndingsIfRequired(allUtf8Bytes, 0, allUtf8Bytes.length, - clientLineEnding); + return convertToP4dServerEndingsIfRequired(allUtf8Bytes, 0, allUtf8Bytes.length, clientLineEnding); } - private int findOffsetOfNextClientLineEndingIfReadBytesEndWithFirstByteOfClientLineEnding( - byte lastByte, @Nullable ClientLineEnding clientLineEnding) { + private int findOffsetOfNextClientLineEndingIfReadBytesEndWithFirstByteOfClientLineEnding(byte lastByte, @Nullable ClientLineEnding clientLineEnding) { int more = -1; if (isRequireConvertClientOrLocalLineEndingToServerFormat(clientLineEnding)) { @@ -277,27 +258,23 @@ private int findOffsetOfNextClientLineEndingIfReadBytesEndWithFirstByteOfClientL return more; } - private boolean isRequireConvertClientOrLocalLineEndingToServerFormat( - @Nullable ClientLineEnding clientLineEnding) { + private boolean isRequireConvertClientOrLocalLineEndingToServerFormat(@Nullable ClientLineEnding clientLineEnding) { boolean isLocalLineEndingSameAsServerFormat = ClientLineEnding.CONVERT_TEXT; if (nonNull(clientLineEnding)) { - isLocalLineEndingSameAsServerFormat = ClientLineEnding - .needsLineEndFiltering(clientLineEnding); + isLocalLineEndingSameAsServerFormat = ClientLineEnding.needsLineEndFiltering(clientLineEnding); } return isLocalLineEndingSameAsServerFormat; } - private ByteBuffer convertToP4dServerEndingsIfRequired(@Nonnull byte[] sourceBytes, - final int start, final int length, @Nullable ClientLineEnding clientLineEnding) { + private ByteBuffer convertToP4dServerEndingsIfRequired(@Nonnull byte[] sourceBytes, final int start, final int length, @Nullable ClientLineEnding clientLineEnding) { ByteBuffer convertedByteBuffer; if (isRequireConvertClientOrLocalLineEndingToServerFormat(clientLineEnding)) { convertedByteBuffer = ByteBuffer.allocate(length); byte p4dServerLineEnding = ClientLineEnding.FST_L_LF_BYTES[0]; byte[] clientLineEndBytes = ClientLineEnding.getLineEndBytes(clientLineEnding); for (int i = start; i < length; i++) { - if (doesSourceBytesUseSameClientLineEnding(sourceBytes, i, length, - clientLineEndBytes)) { + if (doesSourceBytesUseSameClientLineEnding(sourceBytes, i, length, clientLineEndBytes)) { convertedByteBuffer.put(p4dServerLineEnding); i += clientLineEndBytes.length - 1; } else { @@ -311,30 +288,26 @@ private ByteBuffer convertToP4dServerEndingsIfRequired(@Nonnull byte[] sourceByt return convertedByteBuffer; } - private boolean doesSourceBytesUseSameClientLineEnding(@Nonnull byte[] sourceBytes, - final int indexOfSourceBytes, final int length, byte[] clientLineEndBytes) { + private boolean doesSourceBytesUseSameClientLineEnding(@Nonnull byte[] sourceBytes, final int indexOfSourceBytes, final int length, byte[] clientLineEndBytes) { boolean isSame = false; int potentialLastIndex = indexOfSourceBytes + clientLineEndBytes.length - 1; if (potentialLastIndex < length) { - byte[] subSourceBytes = Arrays.copyOfRange(sourceBytes, indexOfSourceBytes, - potentialLastIndex + 1); + byte[] subSourceBytes = Arrays.copyOfRange(sourceBytes, indexOfSourceBytes, potentialLastIndex + 1); isSame = Arrays.equals(subSourceBytes, clientLineEndBytes); } return isSame; } - private void digestStream(@Nonnull InputStream inStream, boolean isRequireLineEndingConvert, - @Nullable ClientLineEnding clientLineEnding) throws IOException { + private void digestStream(@Nonnull InputStream inStream, boolean isRequireLineEndingConvert, @Nullable ClientLineEnding clientLineEnding) throws IOException { byte[] buffer = new byte[bufferSize]; int read; while ((read = inStream.read(buffer)) > 0) { int start = 0; if (isRequireLineEndingConvert) { - ByteBuffer convert = findAndReplaceNonEncodedClientLineEndingIfRequireLineEndingConvert( - inStream, buffer, read, clientLineEnding); + ByteBuffer convert = findAndReplaceNonEncodedClientLineEndingIfRequireLineEndingConvert(inStream, buffer, read, clientLineEnding); update(convert.array(), convert.arrayOffset(), convert.limit()); } else { update(buffer, start, read); @@ -342,16 +315,12 @@ private void digestStream(@Nonnull InputStream inStream, boolean isRequireLineEn } } - private ByteBuffer findAndReplaceNonEncodedClientLineEndingIfRequireLineEndingConvert( - @Nonnull InputStream inStream, @Nonnull final byte[] readBuffer, - final int totalBytesReadIntoBuffer, @Nullable ClientLineEnding clientLineEnding) - throws IOException { + private ByteBuffer findAndReplaceNonEncodedClientLineEndingIfRequireLineEndingConvert(@Nonnull InputStream inStream, @Nonnull final byte[] readBuffer, final int totalBytesReadIntoBuffer, @Nullable ClientLineEnding clientLineEnding) throws IOException { byte lastReadByte = readBuffer[totalBytesReadIntoBuffer - 1]; byte[] allBytes = Arrays.copyOfRange(readBuffer, 0, totalBytesReadIntoBuffer); int length = totalBytesReadIntoBuffer; - int offset = findOffsetOfNextClientLineEndingIfReadBytesEndWithFirstByteOfClientLineEnding( - lastReadByte, clientLineEnding); + int offset = findOffsetOfNextClientLineEndingIfReadBytesEndWithFirstByteOfClientLineEnding(lastReadByte, clientLineEnding); while (offset > 0) { byte[] potentialClientLineEndingBytes = new byte[offset]; offset = inStream.read(potentialClientLineEndingBytes); @@ -361,8 +330,7 @@ private ByteBuffer findAndReplaceNonEncodedClientLineEndingIfRequireLineEndingCo outputStream.write(Arrays.copyOfRange(potentialClientLineEndingBytes, 0, offset)); allBytes = outputStream.toByteArray(); length = allBytes.length; - offset = findOffsetOfNextClientLineEndingIfReadBytesEndWithFirstByteOfClientLineEnding( - allBytes[allBytes.length - 1], clientLineEnding); + offset = findOffsetOfNextClientLineEndingIfReadBytesEndWithFirstByteOfClientLineEnding(allBytes[allBytes.length - 1], clientLineEnding); } } return convertToP4dServerEndingsIfRequired(allBytes, 0, length, clientLineEnding); @@ -384,16 +352,4 @@ public void update(byte[] bytes) { messageDigest.update(bytes); } } - - /** - * NOTE: side effects!! It will be removed from next release - */ - @Deprecated - public void update(ByteBuffer byteBuf) { - if (byteBuf != null) { - byte[] bytes = new byte[byteBuf.limit()]; - byteBuf.get(bytes); - update(bytes); - } - } } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/helper/MapUnmapper.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/helper/MapUnmapper.java index 8aaa7ce..b5b652e 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/helper/MapUnmapper.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/helper/MapUnmapper.java @@ -17,7 +17,7 @@ * These are not what they probably sound like -- they're basically * a way to serialise an input map for something like a changelist * or job onto a single byte buffer to be sent to the server as a - * single data argument with newlines, tabs, etc.

+ * single data argument with newlines, tabs, etc. *

* The need for this will probably go away when we refactor the upper * levels of P4Java to optimise and rationalise the use of maps overall. @@ -25,783 +25,757 @@ public class MapUnmapper { - /** - * Unmap a change list. Absolutely no sanity or other checks are done on - * the passed-in map... - * - * @param inMap - * @param strBuf - */ - - public static void unmapChangelistMap(Map inMap, - StringBuffer strBuf) { - if ((inMap != null) && (strBuf != null)) { - strBuf.append(MapKeys.CHANGE_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.CHANGE_KEY) + MapKeys.DOUBLE_LF); - - Object client = inMap.get(MapKeys.CLIENT_KEY); - if (client != null) { - strBuf.append(MapKeys.CLIENT_KEY + MapKeys.COLON_SPACE + client + MapKeys.DOUBLE_LF); - } - Object user = inMap.get(MapKeys.USER_KEY); - if (user != null) { - strBuf.append(MapKeys.USER_KEY + MapKeys.COLON_SPACE + user + MapKeys.DOUBLE_LF); - } - Object type = inMap.get(MapKeys.TYPE_KEY); - if (type != null) { - strBuf.append(MapKeys.TYPE_KEY + MapKeys.COLON_SPACE + type + MapKeys.DOUBLE_LF); - } - Object status = inMap.get(MapKeys.STATUS_KEY); - if (status != null) { - strBuf.append(MapKeys.STATUS_KEY + MapKeys.COLON_SPACE + status + MapKeys.DOUBLE_LF); - } - Object date = inMap.get(MapKeys.DATE_KEY); - if (date != null) { - strBuf.append(MapKeys.DATE_KEY + MapKeys.COLON_SPACE + date + MapKeys.DOUBLE_LF); - } - Object stream = inMap.get(MapKeys.STREAM_KEY); - if (stream != null) { - strBuf.append(MapKeys.STREAM_KEY + MapKeys.COLON_SPACE + stream + MapKeys.DOUBLE_LF); - } - - String descr = replaceNewlines((String) inMap.get(MapKeys.DESCRIPTION_KEY)); - strBuf.append(MapKeys.DESCRIPTION_KEY + MapKeys.COLON_LF + (descr == null ? MapKeys.EMPTY : descr) + MapKeys.LF); - strBuf.append(MapKeys.FILES_KEY + MapKeys.COLON_LF); - - for (int i = 0; ; i++) { - String fileStr = (String) inMap.get(MapKeys.FILES_KEY + i); - - if (fileStr != null) { - strBuf.append(MapKeys.TAB + inMap.get(MapKeys.FILES_KEY + i) + MapKeys.LF); - } else { - break; - } - } - - strBuf.append(MapKeys.LF); - - for (int i = 0; ; i++) { - String fileStr = (String) inMap.get(MapKeys.JOBS_KEY + i); - - if (fileStr != null) { - if (i == 0) { - strBuf.append(MapKeys.JOBS_KEY + MapKeys.COLON_LF); - } - strBuf.append(MapKeys.TAB + inMap.get(MapKeys.JOBS_KEY + i) + MapKeys.LF); - } else { - break; - } - } - - strBuf.append(MapKeys.LF); - } - } - - /** - * Unmap a job. Jobs basically have free format defined by the associated - * jobspec (which we don't have access to here), so we have to try to the - * best we can with what we've got -- which is to dump the map to the strbuf - * while guessing at things like string formats, etc. This may prove error-prone - * in the long run. - * - * @param inMap - * @param strBuf - */ - public static void unmapJobMap(Map inMap, - StringBuffer strBuf) { - if ((inMap != null) && (strBuf != null)) { - for (Map.Entry entry : inMap.entrySet()) { - strBuf.append(entry.getKey() + MapKeys.COLON_SPACE + replaceNewlines((String) entry.getValue()) + MapKeys.DOUBLE_LF); - } - } - } - - /** - * Unmap a spec. specs basically have free format so we have to try to the - * best we can with what we've got -- which is to dump the map to the strbuf - * while guessing at things like string formats, etc. This may prove error-prone - * in the long run. - * - * @param inMap - * @param strBuf - */ - public static void unmapSpecMap(Map inMap, - StringBuffer strBuf) { - if ((inMap != null) && (strBuf != null)) { - updateSpecSection(inMap, MapKeys.FIELDS_KEY, strBuf); - updateSpecSection(inMap, MapKeys.VALUES_KEY, strBuf); - updateSpecSection(inMap, MapKeys.PRESETS_KEY, strBuf); - updateSpecSection(inMap, MapKeys.WORDS_KEY, strBuf); - updateSpecSection(inMap, MapKeys.FORMATS_KEY, strBuf); - updateSpecSection(inMap, MapKeys.OPENABLE_KEY, strBuf); - updateSpecSection(inMap, MapKeys.COMMENTS_KEY, strBuf); - } - } - - public static void unmapLicenseMap(Map inMap, - StringBuffer strBuf) { - if ((inMap != null) && (strBuf != null)) { - strBuf.append(MapKeys.LICENSE_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.LICENSE_KEY) + MapKeys.DOUBLE_LF); - - Object licenseExpires = inMap.get(MapKeys.LICENSE_EXPIRES_KEY); - if (licenseExpires != null) { - strBuf.append(MapKeys.LICENSE_EXPIRES_KEY + MapKeys.COLON_SPACE + licenseExpires + MapKeys.DOUBLE_LF); - } - - Object supportExpires = inMap.get(MapKeys.LICENSE_SUPPORT_KEY); - if (supportExpires != null) { - strBuf.append(MapKeys.LICENSE_SUPPORT_KEY + MapKeys.COLON_SPACE + supportExpires + MapKeys.DOUBLE_LF); - } - - Object customer = inMap.get(MapKeys.LICENSE_CUSTOMER_KEY); - if (customer != null) { - strBuf.append(MapKeys.LICENSE_CUSTOMER_KEY + MapKeys.COLON_SPACE + customer + MapKeys.DOUBLE_LF); - } - - Object application = inMap.get(MapKeys.LICENSE_APPLICATION_KEY); - if (application != null) { - strBuf.append(MapKeys.LICENSE_APPLICATION_KEY + MapKeys.COLON_SPACE + application + MapKeys.DOUBLE_LF); - } - - Object ipaddress = inMap.get(MapKeys.LICENSE_IPADDRESS_KEY); - if (ipaddress != null) { - strBuf.append(MapKeys.LICENSE_IPADDRESS_KEY + MapKeys.COLON_SPACE + ipaddress + MapKeys.DOUBLE_LF); - } - - Object platform = inMap.get(MapKeys.LICENSE_PLATFORM_KEY); - if (platform != null) { - strBuf.append(MapKeys.LICENSE_PLATFORM_KEY + MapKeys.COLON_SPACE + platform + MapKeys.DOUBLE_LF); - } - - long clients = License.readValues(inMap, MapKeys.LICENSE_CLIENTS_KEY); - if (clients > 0) { - strBuf.append(MapKeys.LICENSE_CLIENTS_KEY + MapKeys.COLON_SPACE + clients + MapKeys.DOUBLE_LF); - } - - long users = License.readValues(inMap, MapKeys.LICENSE_USERS_KEY); - if (users > 0) { - strBuf.append(MapKeys.LICENSE_USERS_KEY + MapKeys.COLON_SPACE + users + MapKeys.DOUBLE_LF); - } - - if (inMap.get(MapKeys.LICENSE_CAPABILITIES_KEY + 0) != null) { - strBuf.append(MapKeys.LICENSE_CAPABILITIES_KEY + MapKeys.COLON_SPACE + MapKeys.LF); - - for (int i = 0; ; i++) { - String capability = (String) inMap.get(MapKeys.LICENSE_CAPABILITIES_KEY + i); - - if (capability != null) { - strBuf.append(MapKeys.TAB + inMap.get(MapKeys.LICENSE_CAPABILITIES_KEY + i) + MapKeys.LF); - } else { - break; - } - } - } - } - } - - public static void unmapExtensionMap(Map inMap, - StringBuffer strBuf) { - if ((inMap != null) && (strBuf != null)) { - - Object extName = inMap.get(MapKeys.EXTENSION_NAME_KEY); - if (extName != null) { - strBuf.append(MapKeys.EXTENSION_NAME_KEY + MapKeys.COLON_SPACE + extName + MapKeys.DOUBLE_LF); - } - - Object extDescription = inMap.get(MapKeys.EXTENSION_EXT_DESCRIPTION_KEY); - if (extDescription != null) { - strBuf.append(MapKeys.EXTENSION_EXT_DESCRIPTION_KEY + MapKeys.COLON_SPACE + extDescription + MapKeys.DOUBLE_LF); - } - - Object extVersion = inMap.get(MapKeys.EXTENSION_VERSION_KEY); - if (extVersion != null) { - strBuf.append(MapKeys.EXTENSION_VERSION_KEY + MapKeys.COLON_SPACE + extVersion + MapKeys.DOUBLE_LF); - } - - Object extUUID = inMap.get(MapKeys.EXTENSION_UUID_KEY); - if (extUUID != null) { - strBuf.append(MapKeys.EXTENSION_UUID_KEY + MapKeys.COLON_SPACE + extUUID + MapKeys.DOUBLE_LF); - } - - Object extRev = inMap.get(MapKeys.EXTENSION_REV_KEY); - if (extRev != null) { - strBuf.append(MapKeys.EXTENSION_REV_KEY + MapKeys.COLON_SPACE + extRev + MapKeys.DOUBLE_LF); - } - - Object extMaxScriptTime = inMap.get(MapKeys.EXTENSION_SCRIPT_TIME_KEY); - if (extMaxScriptTime != null) { - strBuf.append(MapKeys.EXTENSION_SCRIPT_TIME_KEY + MapKeys.COLON_SPACE + extMaxScriptTime + MapKeys.DOUBLE_LF); - } - - Object extMaxScriptMem = inMap.get(MapKeys.EXTENSION_SCRIPT_MEMORY_KEY); - if (extMaxScriptMem != null) { - strBuf.append(MapKeys.EXTENSION_SCRIPT_MEMORY_KEY + MapKeys.COLON_SPACE + extMaxScriptMem + MapKeys.DOUBLE_LF); - } - - Object extEnabled = inMap.get(MapKeys.EXTENSION_ENABLED_KEY); - if (extEnabled != null) { - strBuf.append(MapKeys.EXTENSION_ENABLED_KEY + MapKeys.COLON_SPACE + extEnabled + MapKeys.DOUBLE_LF); - } - - Object name = inMap.get(MapKeys.EXTENSION_NAME_SPACE_KEY); - if (name != null) { - strBuf.append(MapKeys.EXTENSION_NAME_SPACE_KEY + MapKeys.COLON_SPACE + name + MapKeys.DOUBLE_LF); - } - - Object owner = inMap.get(MapKeys.EXTENSION_OWNER_KEY); - if (owner != null) { - strBuf.append(MapKeys.EXTENSION_OWNER_KEY + MapKeys.COLON_SPACE + owner + MapKeys.DOUBLE_LF); - } - - Object update = inMap.get(MapKeys.EXTENSION_UPDATE_KEY); - if (update != null) { - strBuf.append(MapKeys.EXTENSION_UPDATE_KEY + MapKeys.COLON_SPACE + update + MapKeys.DOUBLE_LF); - } - - Object description = inMap.get(MapKeys.EXTENSION_DESCRIPTION_KEY); - if (description != null) { - strBuf.append(MapKeys.EXTENSION_DESCRIPTION_KEY + MapKeys.COLON_SPACE + description + MapKeys.DOUBLE_LF); - } - - Object extConfig = inMap.get(MapKeys.EXTENSION_CONFIG_KEY); - if (extConfig != null) { - Map extConfigMap = (Map)extConfig; - /** - * ExtConfig: - * auth_token: 00000000-0000-0000-0000-000000000000 - * p4search_url: http://p4search.mydomain.com:4567/api/v1/obliterate - */ - strBuf.append(MapKeys.EXTENSION_CONFIG_KEY + MapKeys.COLON_LF); - for (String key : extConfigMap.keySet()) { - strBuf.append(MapKeys.TAB + key + MapKeys.COLON_SPACE + extConfigMap.get(key) + MapKeys.LF); - } - - } - - Object extAllowedGroups = inMap.get(MapKeys.EXTENSION_GROUPS_KEY); - if (extAllowedGroups != null) { - strBuf.append(MapKeys.EXTENSION_GROUPS_KEY + MapKeys.COLON_SPACE + extAllowedGroups + MapKeys.DOUBLE_LF); - } - - Object extP4USER = inMap.get(MapKeys.EXTENSION_P4USER_KEY); - if (extP4USER != null) { - strBuf.append(MapKeys.EXTENSION_P4USER_KEY + MapKeys.COLON_SPACE + extP4USER + MapKeys.DOUBLE_LF); - } - - Object extDebug = inMap.get(MapKeys.EXTENSION_DEBUG); - if (extDebug != null) { - strBuf.append(MapKeys.EXTENSION_DEBUG + MapKeys.COLON_SPACE + extDebug + MapKeys.DOUBLE_LF); - } - } - - } + /** + * Unmap a change list. Absolutely no sanity or other checks are done on + * the passed-in map... + * + * @param inMap inMap + * @param strBuf strBuf + */ + + public static void unmapChangelistMap(Map inMap, StringBuffer strBuf) { + if ((inMap != null) && (strBuf != null)) { + strBuf.append(MapKeys.CHANGE_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.CHANGE_KEY) + MapKeys.DOUBLE_LF); + + Object client = inMap.get(MapKeys.CLIENT_KEY); + if (client != null) { + strBuf.append(MapKeys.CLIENT_KEY + MapKeys.COLON_SPACE + client + MapKeys.DOUBLE_LF); + } + Object user = inMap.get(MapKeys.USER_KEY); + if (user != null) { + strBuf.append(MapKeys.USER_KEY + MapKeys.COLON_SPACE + user + MapKeys.DOUBLE_LF); + } + Object type = inMap.get(MapKeys.TYPE_KEY); + if (type != null) { + strBuf.append(MapKeys.TYPE_KEY + MapKeys.COLON_SPACE + type + MapKeys.DOUBLE_LF); + } + Object status = inMap.get(MapKeys.STATUS_KEY); + if (status != null) { + strBuf.append(MapKeys.STATUS_KEY + MapKeys.COLON_SPACE + status + MapKeys.DOUBLE_LF); + } + Object date = inMap.get(MapKeys.DATE_KEY); + if (date != null) { + strBuf.append(MapKeys.DATE_KEY + MapKeys.COLON_SPACE + date + MapKeys.DOUBLE_LF); + } + Object stream = inMap.get(MapKeys.STREAM_KEY); + if (stream != null) { + strBuf.append(MapKeys.STREAM_KEY + MapKeys.COLON_SPACE + stream + MapKeys.DOUBLE_LF); + } + + String descr = replaceNewlines((String) inMap.get(MapKeys.DESCRIPTION_KEY)); + strBuf.append(MapKeys.DESCRIPTION_KEY + MapKeys.COLON_LF + (descr == null ? MapKeys.EMPTY : descr) + MapKeys.LF); + strBuf.append(MapKeys.FILES_KEY + MapKeys.COLON_LF); + + for (int i = 0; ; i++) { + String fileStr = (String) inMap.get(MapKeys.FILES_KEY + i); + + if (fileStr != null) { + strBuf.append(MapKeys.TAB + inMap.get(MapKeys.FILES_KEY + i) + MapKeys.LF); + } else { + break; + } + } + + strBuf.append(MapKeys.LF); + + for (int i = 0; ; i++) { + String fileStr = (String) inMap.get(MapKeys.JOBS_KEY + i); + + if (fileStr != null) { + if (i == 0) { + strBuf.append(MapKeys.JOBS_KEY + MapKeys.COLON_LF); + } + strBuf.append(MapKeys.TAB + inMap.get(MapKeys.JOBS_KEY + i) + MapKeys.LF); + } else { + break; + } + } + + strBuf.append(MapKeys.LF); + } + } + + /** + * Unmap a job. Jobs basically have free format defined by the associated + * jobspec (which we don't have access to here), so we have to try to the + * best we can with what we've got -- which is to dump the map to the strbuf + * while guessing at things like string formats, etc. This may prove error-prone + * in the long run. + * + * @param inMap inMap + * @param strBuf strBuf + */ + public static void unmapJobMap(Map inMap, StringBuffer strBuf) { + if ((inMap != null) && (strBuf != null)) { + for (Map.Entry entry : inMap.entrySet()) { + strBuf.append(entry.getKey() + MapKeys.COLON_SPACE + replaceNewlines((String) entry.getValue()) + MapKeys.DOUBLE_LF); + } + } + } + + /** + * Unmap a spec. specs basically have free format so we have to try to the + * best we can with what we've got -- which is to dump the map to the strbuf + * while guessing at things like string formats, etc. This may prove error-prone + * in the long run. + * + * @param inMap inMap + * @param strBuf strBuf + */ + public static void unmapSpecMap(Map inMap, StringBuffer strBuf) { + if ((inMap != null) && (strBuf != null)) { + updateSpecSection(inMap, MapKeys.FIELDS_KEY, strBuf); + updateSpecSection(inMap, MapKeys.VALUES_KEY, strBuf); + updateSpecSection(inMap, MapKeys.PRESETS_KEY, strBuf); + updateSpecSection(inMap, MapKeys.WORDS_KEY, strBuf); + updateSpecSection(inMap, MapKeys.FORMATS_KEY, strBuf); + updateSpecSection(inMap, MapKeys.OPENABLE_KEY, strBuf); + updateSpecSection(inMap, MapKeys.COMMENTS_KEY, strBuf); + } + } + + public static void unmapLicenseMap(Map inMap, StringBuffer strBuf) { + if ((inMap != null) && (strBuf != null)) { + strBuf.append(MapKeys.LICENSE_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.LICENSE_KEY) + MapKeys.DOUBLE_LF); + + Object licenseExpires = inMap.get(MapKeys.LICENSE_EXPIRES_KEY); + if (licenseExpires != null) { + strBuf.append(MapKeys.LICENSE_EXPIRES_KEY + MapKeys.COLON_SPACE + licenseExpires + MapKeys.DOUBLE_LF); + } + + Object supportExpires = inMap.get(MapKeys.LICENSE_SUPPORT_KEY); + if (supportExpires != null) { + strBuf.append(MapKeys.LICENSE_SUPPORT_KEY + MapKeys.COLON_SPACE + supportExpires + MapKeys.DOUBLE_LF); + } + + Object customer = inMap.get(MapKeys.LICENSE_CUSTOMER_KEY); + if (customer != null) { + strBuf.append(MapKeys.LICENSE_CUSTOMER_KEY + MapKeys.COLON_SPACE + customer + MapKeys.DOUBLE_LF); + } + + Object application = inMap.get(MapKeys.LICENSE_APPLICATION_KEY); + if (application != null) { + strBuf.append(MapKeys.LICENSE_APPLICATION_KEY + MapKeys.COLON_SPACE + application + MapKeys.DOUBLE_LF); + } + + Object ipaddress = inMap.get(MapKeys.LICENSE_IPADDRESS_KEY); + if (ipaddress != null) { + strBuf.append(MapKeys.LICENSE_IPADDRESS_KEY + MapKeys.COLON_SPACE + ipaddress + MapKeys.DOUBLE_LF); + } + + Object platform = inMap.get(MapKeys.LICENSE_PLATFORM_KEY); + if (platform != null) { + strBuf.append(MapKeys.LICENSE_PLATFORM_KEY + MapKeys.COLON_SPACE + platform + MapKeys.DOUBLE_LF); + } + + long clients = License.readValues(inMap, MapKeys.LICENSE_CLIENTS_KEY); + if (clients > 0) { + strBuf.append(MapKeys.LICENSE_CLIENTS_KEY + MapKeys.COLON_SPACE + clients + MapKeys.DOUBLE_LF); + } + + long users = License.readValues(inMap, MapKeys.LICENSE_USERS_KEY); + if (users > 0) { + strBuf.append(MapKeys.LICENSE_USERS_KEY + MapKeys.COLON_SPACE + users + MapKeys.DOUBLE_LF); + } + + if (inMap.get(MapKeys.LICENSE_CAPABILITIES_KEY + 0) != null) { + strBuf.append(MapKeys.LICENSE_CAPABILITIES_KEY + MapKeys.COLON_SPACE + MapKeys.LF); + + for (int i = 0; ; i++) { + String capability = (String) inMap.get(MapKeys.LICENSE_CAPABILITIES_KEY + i); + + if (capability != null) { + strBuf.append(MapKeys.TAB + inMap.get(MapKeys.LICENSE_CAPABILITIES_KEY + i) + MapKeys.LF); + } else { + break; + } + } + } + } + } + + public static void unmapExtensionMap(Map inMap, StringBuffer strBuf) { + if ((inMap != null) && (strBuf != null)) { + + Object extName = inMap.get(MapKeys.EXTENSION_NAME_KEY); + if (extName != null) { + strBuf.append(MapKeys.EXTENSION_NAME_KEY + MapKeys.COLON_SPACE + extName + MapKeys.DOUBLE_LF); + } + + Object extDescription = inMap.get(MapKeys.EXTENSION_EXT_DESCRIPTION_KEY); + if (extDescription != null) { + strBuf.append(MapKeys.EXTENSION_EXT_DESCRIPTION_KEY + MapKeys.COLON_SPACE + extDescription + MapKeys.DOUBLE_LF); + } + + Object extVersion = inMap.get(MapKeys.EXTENSION_VERSION_KEY); + if (extVersion != null) { + strBuf.append(MapKeys.EXTENSION_VERSION_KEY + MapKeys.COLON_SPACE + extVersion + MapKeys.DOUBLE_LF); + } + + Object extUUID = inMap.get(MapKeys.EXTENSION_UUID_KEY); + if (extUUID != null) { + strBuf.append(MapKeys.EXTENSION_UUID_KEY + MapKeys.COLON_SPACE + extUUID + MapKeys.DOUBLE_LF); + } + + Object extRev = inMap.get(MapKeys.EXTENSION_REV_KEY); + if (extRev != null) { + strBuf.append(MapKeys.EXTENSION_REV_KEY + MapKeys.COLON_SPACE + extRev + MapKeys.DOUBLE_LF); + } + + Object extMaxScriptTime = inMap.get(MapKeys.EXTENSION_SCRIPT_TIME_KEY); + if (extMaxScriptTime != null) { + strBuf.append(MapKeys.EXTENSION_SCRIPT_TIME_KEY + MapKeys.COLON_SPACE + extMaxScriptTime + MapKeys.DOUBLE_LF); + } + + Object extMaxScriptMem = inMap.get(MapKeys.EXTENSION_SCRIPT_MEMORY_KEY); + if (extMaxScriptMem != null) { + strBuf.append(MapKeys.EXTENSION_SCRIPT_MEMORY_KEY + MapKeys.COLON_SPACE + extMaxScriptMem + MapKeys.DOUBLE_LF); + } + + Object extEnabled = inMap.get(MapKeys.EXTENSION_ENABLED_KEY); + if (extEnabled != null) { + strBuf.append(MapKeys.EXTENSION_ENABLED_KEY + MapKeys.COLON_SPACE + extEnabled + MapKeys.DOUBLE_LF); + } + + Object name = inMap.get(MapKeys.EXTENSION_NAME_SPACE_KEY); + if (name != null) { + strBuf.append(MapKeys.EXTENSION_NAME_SPACE_KEY + MapKeys.COLON_SPACE + name + MapKeys.DOUBLE_LF); + } + + Object owner = inMap.get(MapKeys.EXTENSION_OWNER_KEY); + if (owner != null) { + strBuf.append(MapKeys.EXTENSION_OWNER_KEY + MapKeys.COLON_SPACE + owner + MapKeys.DOUBLE_LF); + } + + Object update = inMap.get(MapKeys.EXTENSION_UPDATE_KEY); + if (update != null) { + strBuf.append(MapKeys.EXTENSION_UPDATE_KEY + MapKeys.COLON_SPACE + update + MapKeys.DOUBLE_LF); + } + + Object description = inMap.get(MapKeys.EXTENSION_DESCRIPTION_KEY); + if (description != null) { + strBuf.append(MapKeys.EXTENSION_DESCRIPTION_KEY + MapKeys.COLON_SPACE + description + MapKeys.DOUBLE_LF); + } + + Object extConfig = inMap.get(MapKeys.EXTENSION_CONFIG_KEY); + if (extConfig instanceof Map) { + Map extConfigMap = (Map) extConfig; + /* + * ExtConfig: + * auth_token: 00000000-0000-0000-0000-000000000000 + * p4search_url: http://p4search.mydomain.com:4567/api/v1/obliterate + */ + strBuf.append(MapKeys.EXTENSION_CONFIG_KEY + MapKeys.COLON_LF); + for (Object key : extConfigMap.keySet()) { + strBuf.append(MapKeys.TAB + key + MapKeys.COLON_SPACE + extConfigMap.get(key) + MapKeys.LF); + } + } + + Object extAllowedGroups = inMap.get(MapKeys.EXTENSION_GROUPS_KEY); + if (extAllowedGroups != null) { + strBuf.append(MapKeys.EXTENSION_GROUPS_KEY + MapKeys.COLON_SPACE + extAllowedGroups + MapKeys.DOUBLE_LF); + } + + Object extP4USER = inMap.get(MapKeys.EXTENSION_P4USER_KEY); + if (extP4USER != null) { + strBuf.append(MapKeys.EXTENSION_P4USER_KEY + MapKeys.COLON_SPACE + extP4USER + MapKeys.DOUBLE_LF); + } + + Object extDebug = inMap.get(MapKeys.EXTENSION_DEBUG); + if (extDebug != null) { + strBuf.append(MapKeys.EXTENSION_DEBUG + MapKeys.COLON_SPACE + extDebug + MapKeys.DOUBLE_LF); + } + } + + } private static void updateSpecSection(Map inMap, String section, StringBuffer strBuf) { - List keyList = new ArrayList<>(); - for (String key : inMap.keySet()) { - if (key.startsWith(section)) { - keyList.add(key); - } - } - if (keyList.size() > 0) { - strBuf.append(section + MapKeys.COLON_LF); - for (String key : keyList) { - Object value = inMap.get(key); - strBuf.append(MapKeys.TAB + value + MapKeys.LF); - } - } - } - - /** - * Unmap a client map. Similar in intent and execution to unmapJobMap. - * - * @param inMap - * @param strBuf - */ - public static void unmapClientMap(Map inMap, - StringBuffer strBuf) { - if ((inMap != null) && (strBuf != null)) { - strBuf.append(MapKeys.CLIENT_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.CLIENT_KEY) + MapKeys.DOUBLE_LF); - - Object owner = inMap.get(MapKeys.OWNER_KEY); - if (owner != null) { - strBuf.append(MapKeys.OWNER_KEY + MapKeys.COLON_SPACE + owner + MapKeys.DOUBLE_LF); - } - - // Fix for job036074, a null Host should not be turned into the - // "null" string but should be omitted from the map string. - Object host = inMap.get(MapKeys.HOST_KEY); - if (host != null) { - strBuf.append(MapKeys.HOST_KEY + MapKeys.COLON_SPACE + host.toString() + MapKeys.DOUBLE_LF); - } - - if (inMap.containsKey(MapKeys.UPDATE_KEY)) { - strBuf.append(MapKeys.UPDATE_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.UPDATE_KEY) + MapKeys.DOUBLE_LF); - } - if (inMap.containsKey(MapKeys.ACCESS_KEY)) { - strBuf.append(MapKeys.ACCESS_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.ACCESS_KEY) + MapKeys.DOUBLE_LF); - } - - if (inMap.containsKey(MapKeys.OPTIONS_KEY)) { - strBuf.append(MapKeys.OPTIONS_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.OPTIONS_KEY) + MapKeys.DOUBLE_LF); - } - if (inMap.containsKey(MapKeys.SUBMITOPTIONS_KEY)) { - strBuf.append(MapKeys.SUBMITOPTIONS_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.SUBMITOPTIONS_KEY) + MapKeys.DOUBLE_LF); - } - strBuf.append(MapKeys.ROOT_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.ROOT_KEY) + MapKeys.DOUBLE_LF); - if (inMap.containsKey(MapKeys.LINEEND_KEY)) { - strBuf.append(MapKeys.LINEEND_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.LINEEND_KEY) + MapKeys.DOUBLE_LF); - } - String descr = replaceNewlines((String) inMap.get(MapKeys.DESCRIPTION_KEY)); - strBuf.append(MapKeys.DESCRIPTION_KEY + MapKeys.COLON_LF + (descr == null ? MapKeys.EMPTY : descr) + MapKeys.LF); - strBuf.append(MapKeys.VIEW_KEY + MapKeys.COLON_LF); - - for (int i = 0; ; i++) { - String fileStr = (String) inMap.get(MapKeys.VIEW_KEY + i); - - if (fileStr != null) { - strBuf.append(MapKeys.TAB + inMap.get(MapKeys.VIEW_KEY + i) + MapKeys.LF); - } else { - break; - } - } - - strBuf.append(MapKeys.LF); - - for (int i = 0; ; i++) { - String fileStr = (String) inMap.get(MapKeys.ALTROOTS_KEY + i); - - if (fileStr != null) { - if (i == 0) { - strBuf.append(MapKeys.ALTROOTS_KEY + MapKeys.COLON_LF); - } - strBuf.append(MapKeys.TAB + inMap.get(MapKeys.ALTROOTS_KEY + i) + MapKeys.LF); - } else { - break; - } - } - - strBuf.append(MapKeys.LF); - - if (inMap.containsKey(MapKeys.STREAM_KEY)) { - strBuf.append(MapKeys.STREAM_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.STREAM_KEY) + MapKeys.DOUBLE_LF); - } - - if (inMap.containsKey(MapKeys.SERVERID_KEY)) { - strBuf.append(MapKeys.SERVERID_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.SERVERID_KEY) + MapKeys.DOUBLE_LF); - } - - if (inMap.containsKey(MapKeys.STREAMATCHANGE_KEY)) { - strBuf.append(MapKeys.STREAMATCHANGE_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.STREAMATCHANGE_KEY) + MapKeys.DOUBLE_LF); - } - - if (inMap.containsKey(MapKeys.TYPE_KEY)) { - strBuf.append(MapKeys.TYPE_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.TYPE_KEY) + MapKeys.DOUBLE_LF); - } - - for (int i = 0; ; i++) { - String fileStr = (String) inMap.get(MapKeys.CHANGE_VIEW_KEY + i); - - if (fileStr != null) { - if (i == 0) { - strBuf.append(MapKeys.CHANGE_VIEW_KEY + MapKeys.COLON_LF); - } - strBuf.append(MapKeys.TAB + inMap.get(MapKeys.CHANGE_VIEW_KEY + i) + MapKeys.LF); - } else { - break; - } - } - - strBuf.append(MapKeys.LF); - - if (inMap.containsKey(MapKeys.CLIENT_BACKUP_KEY)) { - strBuf.append(MapKeys.CLIENT_BACKUP_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.CLIENT_BACKUP_KEY) + MapKeys.DOUBLE_LF); - } - } - } - - /** - * Unmap a Perforce user map. - * - * @param inMap - * @param strBuf - */ - public static void unmapUserMap(Map inMap, - StringBuffer strBuf) { - if ((inMap != null) && (strBuf != null)) { - strBuf.append(MapKeys.USER_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.USER_KEY) + MapKeys.DOUBLE_LF); - if (inMap.containsKey(MapKeys.EMAIL_KEY)) { - strBuf.append(MapKeys.EMAIL_KEY + MapKeys.COLON_SPACE - + inMap.get(MapKeys.EMAIL_KEY) + MapKeys.DOUBLE_LF); - } - if (inMap.containsKey(MapKeys.FULLNAME_KEY)) { - strBuf.append(MapKeys.FULLNAME_KEY + MapKeys.COLON_SPACE - + inMap.get(MapKeys.FULLNAME_KEY) + MapKeys.DOUBLE_LF); - } - if (inMap.containsKey(MapKeys.JOBVIEW_KEY)) { - strBuf.append(MapKeys.JOBVIEW_KEY + MapKeys.COLON_SPACE - + inMap.get(MapKeys.JOBVIEW_KEY) + MapKeys.DOUBLE_LF); - } - if (inMap.containsKey(MapKeys.PASSWORD_KEY)) { - strBuf.append(MapKeys.PASSWORD_KEY + MapKeys.COLON_SPACE - + inMap.get(MapKeys.PASSWORD_KEY) + MapKeys.DOUBLE_LF); - } - - if (inMap.containsKey(MapKeys.TYPE_KEY)) { - strBuf.append(MapKeys.TYPE_KEY + MapKeys.COLON_SPACE - + inMap.get(MapKeys.TYPE_KEY) + MapKeys.DOUBLE_LF); - } - - for (int i = 0; ; i++) { - String mapStr = (String) inMap.get(MapKeys.REVIEWS_KEY + i); - - if (mapStr != null) { - if (i == 0) { - strBuf.append(MapKeys.REVIEWS_KEY + MapKeys.COLON_LF); - } - strBuf.append(MapKeys.TAB + mapStr + MapKeys.LF); - } else { - break; - } - } - } - } - - /** - * Unmap a Perforce user group map. - * - * @param inMap - * @param strBuf - */ - public static void unmapUserGroupMap(Map inMap, - StringBuffer strBuf) { - if ((inMap != null) && (strBuf != null)) { - strBuf.append(MapKeys.GROUP_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.GROUP_KEY) + MapKeys.DOUBLE_LF); - if (inMap.containsKey(MapKeys.MAXRESULTS_KEY)) { - strBuf.append(MapKeys.MAXRESULTS_KEY + MapKeys.COLON_SPACE - + inMap.get(MapKeys.MAXRESULTS_KEY) + MapKeys.DOUBLE_LF); - } - if (inMap.containsKey(MapKeys.MAXSCANROWS_KEY)) { - strBuf.append(MapKeys.MAXSCANROWS_KEY + MapKeys.COLON_SPACE - + inMap.get(MapKeys.MAXSCANROWS_KEY) + MapKeys.DOUBLE_LF); - } - if (inMap.containsKey(MapKeys.MAXLOCKTIME_KEY)) { - strBuf.append(MapKeys.MAXLOCKTIME_KEY + MapKeys.COLON_SPACE - + inMap.get(MapKeys.MAXLOCKTIME_KEY) + MapKeys.DOUBLE_LF); - } - if (inMap.containsKey(MapKeys.TIMEOUT_KEY)) { - strBuf.append(MapKeys.TIMEOUT_KEY + MapKeys.COLON_SPACE - + inMap.get(MapKeys.TIMEOUT_KEY) + MapKeys.DOUBLE_LF); - } - if (inMap.containsKey(MapKeys.PASSWORD_TIMEOUT_KEY)) { - strBuf.append(MapKeys.PASSWORD_TIMEOUT_KEY + MapKeys.COLON_SPACE - + inMap.get(MapKeys.PASSWORD_TIMEOUT_KEY) + MapKeys.DOUBLE_LF); - } + List keyList = new ArrayList<>(); + for (String key : inMap.keySet()) { + if (key.startsWith(section)) { + keyList.add(key); + } + } + if (keyList.size() > 0) { + strBuf.append(section + MapKeys.COLON_LF); + for (String key : keyList) { + Object value = inMap.get(key); + strBuf.append(MapKeys.TAB + value + MapKeys.LF); + } + } + } + + /** + * Unmap a client map. Similar in intent and execution to unmapJobMap. + * + * @param inMap inMap + * @param strBuf strBuf + */ + public static void unmapClientMap(Map inMap, StringBuffer strBuf) { + if ((inMap != null) && (strBuf != null)) { + strBuf.append(MapKeys.CLIENT_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.CLIENT_KEY) + MapKeys.DOUBLE_LF); + + Object owner = inMap.get(MapKeys.OWNER_KEY); + if (owner != null) { + strBuf.append(MapKeys.OWNER_KEY + MapKeys.COLON_SPACE + owner + MapKeys.DOUBLE_LF); + } + + // Fix for job036074, a null Host should not be turned into the + // "null" string but should be omitted from the map string. + Object host = inMap.get(MapKeys.HOST_KEY); + if (host != null) { + strBuf.append(MapKeys.HOST_KEY + MapKeys.COLON_SPACE + host.toString() + MapKeys.DOUBLE_LF); + } + + if (inMap.containsKey(MapKeys.UPDATE_KEY)) { + strBuf.append(MapKeys.UPDATE_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.UPDATE_KEY) + MapKeys.DOUBLE_LF); + } + if (inMap.containsKey(MapKeys.ACCESS_KEY)) { + strBuf.append(MapKeys.ACCESS_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.ACCESS_KEY) + MapKeys.DOUBLE_LF); + } + + if (inMap.containsKey(MapKeys.OPTIONS_KEY)) { + strBuf.append(MapKeys.OPTIONS_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.OPTIONS_KEY) + MapKeys.DOUBLE_LF); + } + if (inMap.containsKey(MapKeys.SUBMITOPTIONS_KEY)) { + strBuf.append(MapKeys.SUBMITOPTIONS_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.SUBMITOPTIONS_KEY) + MapKeys.DOUBLE_LF); + } + strBuf.append(MapKeys.ROOT_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.ROOT_KEY) + MapKeys.DOUBLE_LF); + if (inMap.containsKey(MapKeys.LINEEND_KEY)) { + strBuf.append(MapKeys.LINEEND_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.LINEEND_KEY) + MapKeys.DOUBLE_LF); + } + String descr = replaceNewlines((String) inMap.get(MapKeys.DESCRIPTION_KEY)); + strBuf.append(MapKeys.DESCRIPTION_KEY + MapKeys.COLON_LF + (descr == null ? MapKeys.EMPTY : descr) + MapKeys.LF); + strBuf.append(MapKeys.VIEW_KEY + MapKeys.COLON_LF); + + for (int i = 0; ; i++) { + String fileStr = (String) inMap.get(MapKeys.VIEW_KEY + i); + + if (fileStr != null) { + strBuf.append(MapKeys.TAB + inMap.get(MapKeys.VIEW_KEY + i) + MapKeys.LF); + } else { + break; + } + } + + strBuf.append(MapKeys.LF); + + for (int i = 0; ; i++) { + String fileStr = (String) inMap.get(MapKeys.ALTROOTS_KEY + i); + + if (fileStr != null) { + if (i == 0) { + strBuf.append(MapKeys.ALTROOTS_KEY + MapKeys.COLON_LF); + } + strBuf.append(MapKeys.TAB + inMap.get(MapKeys.ALTROOTS_KEY + i) + MapKeys.LF); + } else { + break; + } + } + + strBuf.append(MapKeys.LF); + + if (inMap.containsKey(MapKeys.STREAM_KEY)) { + strBuf.append(MapKeys.STREAM_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.STREAM_KEY) + MapKeys.DOUBLE_LF); + } + + if (inMap.containsKey(MapKeys.SERVERID_KEY)) { + strBuf.append(MapKeys.SERVERID_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.SERVERID_KEY) + MapKeys.DOUBLE_LF); + } + + if (inMap.containsKey(MapKeys.STREAMATCHANGE_KEY)) { + strBuf.append(MapKeys.STREAMATCHANGE_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.STREAMATCHANGE_KEY) + MapKeys.DOUBLE_LF); + } + + if (inMap.containsKey(MapKeys.TYPE_KEY)) { + strBuf.append(MapKeys.TYPE_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.TYPE_KEY) + MapKeys.DOUBLE_LF); + } + + for (int i = 0; ; i++) { + String fileStr = (String) inMap.get(MapKeys.CHANGE_VIEW_KEY + i); + + if (fileStr != null) { + if (i == 0) { + strBuf.append(MapKeys.CHANGE_VIEW_KEY + MapKeys.COLON_LF); + } + strBuf.append(MapKeys.TAB + inMap.get(MapKeys.CHANGE_VIEW_KEY + i) + MapKeys.LF); + } else { + break; + } + } + + strBuf.append(MapKeys.LF); + + if (inMap.containsKey(MapKeys.CLIENT_BACKUP_KEY)) { + strBuf.append(MapKeys.CLIENT_BACKUP_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.CLIENT_BACKUP_KEY) + MapKeys.DOUBLE_LF); + } + } + } + + /** + * Unmap a Perforce user map. + * + * @param inMap inMap + * @param strBuf strBuf + */ + public static void unmapUserMap(Map inMap, StringBuffer strBuf) { + if ((inMap != null) && (strBuf != null)) { + strBuf.append(MapKeys.USER_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.USER_KEY) + MapKeys.DOUBLE_LF); + if (inMap.containsKey(MapKeys.EMAIL_KEY)) { + strBuf.append(MapKeys.EMAIL_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.EMAIL_KEY) + MapKeys.DOUBLE_LF); + } + if (inMap.containsKey(MapKeys.FULLNAME_KEY)) { + strBuf.append(MapKeys.FULLNAME_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.FULLNAME_KEY) + MapKeys.DOUBLE_LF); + } + if (inMap.containsKey(MapKeys.JOBVIEW_KEY)) { + strBuf.append(MapKeys.JOBVIEW_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.JOBVIEW_KEY) + MapKeys.DOUBLE_LF); + } + if (inMap.containsKey(MapKeys.PASSWORD_KEY)) { + strBuf.append(MapKeys.PASSWORD_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.PASSWORD_KEY) + MapKeys.DOUBLE_LF); + } + + if (inMap.containsKey(MapKeys.TYPE_KEY)) { + strBuf.append(MapKeys.TYPE_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.TYPE_KEY) + MapKeys.DOUBLE_LF); + } + + for (int i = 0; ; i++) { + String mapStr = (String) inMap.get(MapKeys.REVIEWS_KEY + i); + + if (mapStr != null) { + if (i == 0) { + strBuf.append(MapKeys.REVIEWS_KEY + MapKeys.COLON_LF); + } + strBuf.append(MapKeys.TAB + mapStr + MapKeys.LF); + } else { + break; + } + } + } + } + + /** + * Unmap a Perforce user group map. + * + * @param inMap inMap + * @param strBuf strBuf + */ + public static void unmapUserGroupMap(Map inMap, StringBuffer strBuf) { + if ((inMap != null) && (strBuf != null)) { + strBuf.append(MapKeys.GROUP_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.GROUP_KEY) + MapKeys.DOUBLE_LF); + if (inMap.containsKey(MapKeys.MAXRESULTS_KEY)) { + strBuf.append(MapKeys.MAXRESULTS_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.MAXRESULTS_KEY) + MapKeys.DOUBLE_LF); + } + if (inMap.containsKey(MapKeys.MAXSCANROWS_KEY)) { + strBuf.append(MapKeys.MAXSCANROWS_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.MAXSCANROWS_KEY) + MapKeys.DOUBLE_LF); + } + if (inMap.containsKey(MapKeys.MAXLOCKTIME_KEY)) { + strBuf.append(MapKeys.MAXLOCKTIME_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.MAXLOCKTIME_KEY) + MapKeys.DOUBLE_LF); + } + if (inMap.containsKey(MapKeys.TIMEOUT_KEY)) { + strBuf.append(MapKeys.TIMEOUT_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.TIMEOUT_KEY) + MapKeys.DOUBLE_LF); + } + if (inMap.containsKey(MapKeys.PASSWORD_TIMEOUT_KEY)) { + strBuf.append(MapKeys.PASSWORD_TIMEOUT_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.PASSWORD_TIMEOUT_KEY) + MapKeys.DOUBLE_LF); + } if (inMap.containsKey(MapKeys.MAXOPENFILES_KEY)) { - strBuf.append(MapKeys.MAXOPENFILES_KEY + MapKeys.COLON_SPACE - + inMap.get(MapKeys.MAXOPENFILES_KEY) + MapKeys.DOUBLE_LF); - } - for (int i = 0; ; i++) { - String mapStr = (String) inMap.get(MapKeys.SUBGROUPS_KEY + i); - - if (mapStr != null) { - if (i == 0) { - strBuf.append(MapKeys.SUBGROUPS_KEY + MapKeys.COLON_LF); - } - strBuf.append(MapKeys.TAB + mapStr + MapKeys.LF); - } else { - break; - } - } - for (int i = 0; ; i++) { - String mapStr = (String) inMap.get(MapKeys.OWNERS_KEY + i); - - if (mapStr != null) { - if (i == 0) { - strBuf.append(MapKeys.OWNERS_KEY + MapKeys.COLON_LF); - } - strBuf.append(MapKeys.TAB + mapStr + MapKeys.LF); - } else { - break; - } - } - for (int i = 0; ; i++) { - String mapStr = (String) inMap.get(MapKeys.USERS_KEY + i); - - if (mapStr != null) { - if (i == 0) { - strBuf.append(MapKeys.USERS_KEY + MapKeys.COLON_LF); - } - strBuf.append(MapKeys.TAB + mapStr + MapKeys.LF); - } else { - break; - } - } - } - } - - /** - * Unmap a Label Perforce label. - * - * @param inMap - * @param strBuf - */ - public static void unmapLabelMap(Map inMap, - StringBuffer strBuf) { - if ((inMap != null) && (strBuf != null)) { - strBuf.append(MapKeys.LABEL_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.LABEL_KEY) + MapKeys.DOUBLE_LF); - strBuf.append(MapKeys.OWNER_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.OWNER_KEY) + MapKeys.DOUBLE_LF); - if (inMap.containsKey(MapKeys.UPDATE_KEY)) { - strBuf.append(MapKeys.UPDATE_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.UPDATE_KEY) + MapKeys.DOUBLE_LF); - } - if (inMap.containsKey(MapKeys.ACCESS_KEY)) { - strBuf.append(MapKeys.ACCESS_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.ACCESS_KEY) + MapKeys.DOUBLE_LF); - } - if (inMap.containsKey(MapKeys.REVISION_KEY)) { - strBuf.append(MapKeys.REVISION_KEY + MapKeys.COLON_SPACE - + inMap.get(MapKeys.REVISION_KEY) + MapKeys.DOUBLE_LF); - } - String descr = replaceNewlines((String) inMap.get(MapKeys.DESCRIPTION_KEY)); - strBuf.append(MapKeys.DESCRIPTION_KEY + MapKeys.COLON_LF + (descr == null ? MapKeys.EMPTY : descr) + MapKeys.LF); - if (inMap.containsKey(MapKeys.OPTIONS_KEY)) { - strBuf.append(MapKeys.OPTIONS_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.OPTIONS_KEY) + MapKeys.DOUBLE_LF); - } - - for (int i = 0; ; i++) { - String mapStr = (String) inMap.get(MapKeys.VIEW_KEY + i); - - if (mapStr != null) { - if (i == 0) { - strBuf.append(MapKeys.VIEW_KEY + MapKeys.COLON_LF); - } - strBuf.append(MapKeys.TAB + mapStr + MapKeys.LF); - } else { - break; - } - } - } - } - - /** - * Unmap a BranchSpec spec. - * - * @param inMap - * @param strBuf - */ - public static void unmapBranchMap(Map inMap, - StringBuffer strBuf) { - if ((inMap != null) && (strBuf != null)) { - strBuf.append(MapKeys.BRANCH_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.BRANCH_KEY) + MapKeys.DOUBLE_LF); - - if (inMap.containsKey(MapKeys.OWNER_KEY)) { - strBuf.append(MapKeys.OWNER_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.OWNER_KEY) + MapKeys.DOUBLE_LF); - } - if (inMap.containsKey(MapKeys.UPDATE_KEY)) { - strBuf.append(MapKeys.UPDATE_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.UPDATE_KEY) + MapKeys.DOUBLE_LF); - } - if (inMap.containsKey(MapKeys.ACCESS_KEY)) { - strBuf.append(MapKeys.ACCESS_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.ACCESS_KEY) + MapKeys.DOUBLE_LF); - } - String descr = replaceNewlines((String) inMap.get(MapKeys.DESCRIPTION_KEY)); - strBuf.append(MapKeys.DESCRIPTION_KEY + MapKeys.COLON_LF + (descr == null ? MapKeys.EMPTY : descr) + MapKeys.LF); - if (inMap.containsKey(MapKeys.OPTIONS_KEY)) { - strBuf.append(MapKeys.OPTIONS_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.OPTIONS_KEY) + MapKeys.DOUBLE_LF); - } - - for (int i = 0; ; i++) { - String mapStr = (String) inMap.get(MapKeys.VIEW_KEY + i); - - if (mapStr != null) { - if (i == 0) { - strBuf.append(MapKeys.VIEW_KEY + MapKeys.COLON_LF); - } - strBuf.append(MapKeys.TAB + mapStr + MapKeys.LF); - } else { - break; - } - } - } - } - - /** - * Unmap a depot map. - * - * @param inMap - * @param strBuf - */ - public static void unmapDepotMap(Map inMap, - StringBuffer strBuf) { - if ((inMap != null) && (strBuf != null)) { - strBuf.append(MapKeys.DEPOT_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.DEPOT_KEY) + MapKeys.DOUBLE_LF); - if (inMap.containsKey(MapKeys.OWNER_KEY)) { - strBuf.append(MapKeys.OWNER_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.OWNER_KEY) + MapKeys.DOUBLE_LF); - } - if (inMap.containsKey(MapKeys.DATE_KEY)) { - strBuf.append(MapKeys.DATE_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.DATE_KEY) + MapKeys.DOUBLE_LF); - } - if (inMap.containsKey(MapKeys.TYPE_KEY)) { - strBuf.append(MapKeys.TYPE_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.TYPE_KEY) + MapKeys.DOUBLE_LF); - } - String descr = replaceNewlines((String) inMap.get(MapKeys.DESCRIPTION_KEY)); - strBuf.append(MapKeys.DESCRIPTION_KEY + MapKeys.COLON_LF + (descr == null ? MapKeys.EMPTY : descr) + MapKeys.LF); - - if (inMap.containsKey(MapKeys.ADDRESS_KEY)) { - strBuf.append(MapKeys.ADDRESS_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.ADDRESS_KEY) + MapKeys.DOUBLE_LF); - } - if (inMap.containsKey(MapKeys.SUFFIX_KEY)) { - strBuf.append(MapKeys.SUFFIX_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.SUFFIX_KEY) + MapKeys.DOUBLE_LF); - } - if (inMap.containsKey(MapKeys.STREAM_DEPTH)) { - strBuf.append(MapKeys.STREAM_DEPTH + MapKeys.COLON_SPACE + inMap.get(MapKeys.STREAM_DEPTH) + MapKeys.DOUBLE_LF); - } - if (inMap.containsKey(MapKeys.MAP_KEY)) { - strBuf.append(MapKeys.MAP_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.MAP_KEY) + MapKeys.DOUBLE_LF); - } - - for (int i = 0; ; i++) { - String mapStr = (String) inMap.get(MapKeys.SPEC_MAP_KEY + i); - - if (mapStr != null) { - if (i == 0) { - strBuf.append(MapKeys.SPEC_MAP_KEY + MapKeys.COLON_LF); - } - strBuf.append(MapKeys.TAB + mapStr + MapKeys.LF); - } else { - break; - } - } - } - } - - /** - * Unmap a list of protection entries. - * - * @param inMap - * @param strBuf - */ - public static void unmapProtectionEntriesMap(Map inMap, - StringBuffer strBuf) { - if ((inMap != null) && (strBuf != null)) { - strBuf.append(MapKeys.PROTECTIONS_KEY + MapKeys.COLON_LF); - for (int i = 0; ; i++) { - String mapStr = (String) inMap.get(MapKeys.PROTECTIONS_KEY + i); - - if (mapStr != null) { - strBuf.append(MapKeys.TAB + mapStr + MapKeys.LF); - } else { - break; - } - } - } - } - - /** - * Unmap a stream map. - * - * @param inMap - * @param strBuf - */ - public static void unmapStreamMap(Map inMap, StringBuffer strBuf) { - if (inMap == null || strBuf == null) { - return; - } - - // Remove extraTag keys (like firmerThanParent) - inMap.remove("altArg"); - inMap.remove("specFormatted"); - inMap.remove("Comments"); - for (int i = 0; ; i++) { - String extraTag = (String) inMap.get(MapKeys.EXTRATAG_KEY + i); - if (extraTag != null) { - inMap.remove(extraTag); - } else { - break; - } - } - - for (Map.Entry entry : inMap.entrySet()) { - String key = entry.getKey(); - String value = (String) entry.getValue(); - - Pattern pattern = Pattern.compile("([a-zA-Z]+)([0-9]+)"); - Matcher matcher = pattern.matcher(key); - if (!matcher.matches()) { - value = (value.contains(MapKeys.LF)) ? replaceNewlines(value) : value; - strBuf.append(key + MapKeys.COLON_SPACE + (value == null ? MapKeys.EMPTY : value) + MapKeys.DOUBLE_LF); - } - } - - String[] viewKeys = {MapKeys.PATHS_KEY, MapKeys.REMAPPED_KEY, MapKeys.IGNORED_KEY}; - - for (String key : viewKeys) { - for (int i = 0; ; i++) { - String mapStr = (String) inMap.get(key + i); - String mapStrComment = (String) inMap.get(key + "Comment" + i); - if (mapStrComment == null) { - mapStrComment = ""; - } else { - mapStrComment = mapStrComment; - } - - if (mapStr != null || mapStrComment != "") { - if (i == 0) { - strBuf.append(key + MapKeys.COLON_LF); - } - strBuf.append(MapKeys.TAB + mapStr + mapStrComment + MapKeys.LF); - } else { - break; - } - } - } - } - - /** - * Unmap a list of trigger entries. - * - * @param inMap - * @param strBuf - */ - public static void unmapTriggerEntriesMap(Map inMap, - StringBuffer strBuf) { - if ((inMap != null) && (strBuf != null)) { - strBuf.append(MapKeys.TRIGGERS_KEY + MapKeys.COLON_LF); - for (int i = 0; ; i++) { - String mapStr = (String) inMap.get(MapKeys.TRIGGERS_KEY + i); - - if (mapStr != null) { - strBuf.append(MapKeys.TAB + mapStr + MapKeys.LF); - } else { - break; - } - } - } - } - - /** - * Replace all but the last newline in the incoming string with - * newline / tab pairs. Useful for various multi-line form inputs. - * - * @param str - * @return replaced string - */ - public static String replaceNewlines(String str) { - if (str != null) { - String[] strs = str.split(MapKeys.LF); - - if (strs.length == 1) { - return MapKeys.TAB + str + MapKeys.LF; - } else { - StringBuilder retStr = new StringBuilder(); - - for (String s : strs) { - retStr.append(MapKeys.TAB); - retStr.append(s); - retStr.append(MapKeys.LF); - } - - return retStr.toString(); - } - } - - return null; - } + strBuf.append(MapKeys.MAXOPENFILES_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.MAXOPENFILES_KEY) + MapKeys.DOUBLE_LF); + } + for (int i = 0; ; i++) { + String mapStr = (String) inMap.get(MapKeys.SUBGROUPS_KEY + i); + + if (mapStr != null) { + if (i == 0) { + strBuf.append(MapKeys.SUBGROUPS_KEY + MapKeys.COLON_LF); + } + strBuf.append(MapKeys.TAB + mapStr + MapKeys.LF); + } else { + break; + } + } + for (int i = 0; ; i++) { + String mapStr = (String) inMap.get(MapKeys.OWNERS_KEY + i); + + if (mapStr != null) { + if (i == 0) { + strBuf.append(MapKeys.OWNERS_KEY + MapKeys.COLON_LF); + } + strBuf.append(MapKeys.TAB + mapStr + MapKeys.LF); + } else { + break; + } + } + for (int i = 0; ; i++) { + String mapStr = (String) inMap.get(MapKeys.USERS_KEY + i); + + if (mapStr != null) { + if (i == 0) { + strBuf.append(MapKeys.USERS_KEY + MapKeys.COLON_LF); + } + strBuf.append(MapKeys.TAB + mapStr + MapKeys.LF); + } else { + break; + } + } + } + } + + /** + * Unmap a Label Perforce label. + * + * @param inMap inMap + * @param strBuf strBuf + */ + public static void unmapLabelMap(Map inMap, StringBuffer strBuf) { + if ((inMap != null) && (strBuf != null)) { + strBuf.append(MapKeys.LABEL_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.LABEL_KEY) + MapKeys.DOUBLE_LF); + strBuf.append(MapKeys.OWNER_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.OWNER_KEY) + MapKeys.DOUBLE_LF); + if (inMap.containsKey(MapKeys.UPDATE_KEY)) { + strBuf.append(MapKeys.UPDATE_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.UPDATE_KEY) + MapKeys.DOUBLE_LF); + } + if (inMap.containsKey(MapKeys.ACCESS_KEY)) { + strBuf.append(MapKeys.ACCESS_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.ACCESS_KEY) + MapKeys.DOUBLE_LF); + } + if (inMap.containsKey(MapKeys.REVISION_KEY)) { + strBuf.append(MapKeys.REVISION_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.REVISION_KEY) + MapKeys.DOUBLE_LF); + } + String descr = replaceNewlines((String) inMap.get(MapKeys.DESCRIPTION_KEY)); + strBuf.append(MapKeys.DESCRIPTION_KEY + MapKeys.COLON_LF + (descr == null ? MapKeys.EMPTY : descr) + MapKeys.LF); + if (inMap.containsKey(MapKeys.OPTIONS_KEY)) { + strBuf.append(MapKeys.OPTIONS_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.OPTIONS_KEY) + MapKeys.DOUBLE_LF); + } + + for (int i = 0; ; i++) { + String mapStr = (String) inMap.get(MapKeys.VIEW_KEY + i); + + if (mapStr != null) { + if (i == 0) { + strBuf.append(MapKeys.VIEW_KEY + MapKeys.COLON_LF); + } + strBuf.append(MapKeys.TAB + mapStr + MapKeys.LF); + } else { + break; + } + } + } + } + + /** + * Unmap a BranchSpec spec. + * + * @param inMap inMap + * @param strBuf strBuf + */ + public static void unmapBranchMap(Map inMap, StringBuffer strBuf) { + if ((inMap != null) && (strBuf != null)) { + strBuf.append(MapKeys.BRANCH_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.BRANCH_KEY) + MapKeys.DOUBLE_LF); + + if (inMap.containsKey(MapKeys.OWNER_KEY)) { + strBuf.append(MapKeys.OWNER_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.OWNER_KEY) + MapKeys.DOUBLE_LF); + } + if (inMap.containsKey(MapKeys.UPDATE_KEY)) { + strBuf.append(MapKeys.UPDATE_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.UPDATE_KEY) + MapKeys.DOUBLE_LF); + } + if (inMap.containsKey(MapKeys.ACCESS_KEY)) { + strBuf.append(MapKeys.ACCESS_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.ACCESS_KEY) + MapKeys.DOUBLE_LF); + } + String descr = replaceNewlines((String) inMap.get(MapKeys.DESCRIPTION_KEY)); + strBuf.append(MapKeys.DESCRIPTION_KEY + MapKeys.COLON_LF + (descr == null ? MapKeys.EMPTY : descr) + MapKeys.LF); + if (inMap.containsKey(MapKeys.OPTIONS_KEY)) { + strBuf.append(MapKeys.OPTIONS_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.OPTIONS_KEY) + MapKeys.DOUBLE_LF); + } + + for (int i = 0; ; i++) { + String mapStr = (String) inMap.get(MapKeys.VIEW_KEY + i); + + if (mapStr != null) { + if (i == 0) { + strBuf.append(MapKeys.VIEW_KEY + MapKeys.COLON_LF); + } + strBuf.append(MapKeys.TAB + mapStr + MapKeys.LF); + } else { + break; + } + } + } + } + + /** + * Unmap a depot map. + * + * @param inMap inMap + * @param strBuf strBuf + */ + public static void unmapDepotMap(Map inMap, StringBuffer strBuf) { + if ((inMap != null) && (strBuf != null)) { + strBuf.append(MapKeys.DEPOT_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.DEPOT_KEY) + MapKeys.DOUBLE_LF); + if (inMap.containsKey(MapKeys.OWNER_KEY)) { + strBuf.append(MapKeys.OWNER_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.OWNER_KEY) + MapKeys.DOUBLE_LF); + } + if (inMap.containsKey(MapKeys.DATE_KEY)) { + strBuf.append(MapKeys.DATE_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.DATE_KEY) + MapKeys.DOUBLE_LF); + } + if (inMap.containsKey(MapKeys.TYPE_KEY)) { + strBuf.append(MapKeys.TYPE_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.TYPE_KEY) + MapKeys.DOUBLE_LF); + } + String descr = replaceNewlines((String) inMap.get(MapKeys.DESCRIPTION_KEY)); + strBuf.append(MapKeys.DESCRIPTION_KEY + MapKeys.COLON_LF + (descr == null ? MapKeys.EMPTY : descr) + MapKeys.LF); + + if (inMap.containsKey(MapKeys.ADDRESS_KEY)) { + strBuf.append(MapKeys.ADDRESS_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.ADDRESS_KEY) + MapKeys.DOUBLE_LF); + } + if (inMap.containsKey(MapKeys.SUFFIX_KEY)) { + strBuf.append(MapKeys.SUFFIX_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.SUFFIX_KEY) + MapKeys.DOUBLE_LF); + } + if (inMap.containsKey(MapKeys.STREAM_DEPTH)) { + strBuf.append(MapKeys.STREAM_DEPTH + MapKeys.COLON_SPACE + inMap.get(MapKeys.STREAM_DEPTH) + MapKeys.DOUBLE_LF); + } + if (inMap.containsKey(MapKeys.MAP_KEY)) { + strBuf.append(MapKeys.MAP_KEY + MapKeys.COLON_SPACE + inMap.get(MapKeys.MAP_KEY) + MapKeys.DOUBLE_LF); + } + + for (int i = 0; ; i++) { + String mapStr = (String) inMap.get(MapKeys.SPEC_MAP_KEY + i); + + if (mapStr != null) { + if (i == 0) { + strBuf.append(MapKeys.SPEC_MAP_KEY + MapKeys.COLON_LF); + } + strBuf.append(MapKeys.TAB + mapStr + MapKeys.LF); + } else { + break; + } + } + } + } + + /** + * Unmap a list of protection entries. + * + * @param inMap inMap + * @param strBuf strBuf + */ + public static void unmapProtectionEntriesMap(Map inMap, StringBuffer strBuf) { + if ((inMap != null) && (strBuf != null)) { + strBuf.append(MapKeys.PROTECTIONS_KEY + MapKeys.COLON_LF); + for (int i = 0; ; i++) { + String mapStr = (String) inMap.get(MapKeys.PROTECTIONS_KEY + i); + + if (mapStr != null) { + strBuf.append(MapKeys.TAB + mapStr + MapKeys.LF); + } else { + break; + } + } + } + } + + /** + * Unmap a stream map. + * + * @param inMap inMap + * @param strBuf strBuf + */ + public static void unmapStreamMap(Map inMap, StringBuffer strBuf) { + if (inMap == null || strBuf == null) { + return; + } + + // Remove extraTag keys (like firmerThanParent) + inMap.remove("altArg"); + inMap.remove("specFormatted"); + inMap.remove("Comments"); + for (int i = 0; ; i++) { + String extraTag = (String) inMap.get(MapKeys.EXTRATAG_KEY + i); + if (extraTag != null) { + inMap.remove(extraTag); + } else { + break; + } + } + + for (Map.Entry entry : inMap.entrySet()) { + String key = entry.getKey(); + String value = (String) entry.getValue(); + + Pattern pattern = Pattern.compile("([a-zA-Z]+)([0-9]+)"); + Matcher matcher = pattern.matcher(key); + if (!matcher.matches()) { + value = (value.contains(MapKeys.LF)) ? replaceNewlines(value) : value; + strBuf.append(key + MapKeys.COLON_SPACE + (value == null ? MapKeys.EMPTY : value) + MapKeys.DOUBLE_LF); + } + } + + String[] viewKeys = {MapKeys.PATHS_KEY, MapKeys.REMAPPED_KEY, MapKeys.IGNORED_KEY}; + + for (String key : viewKeys) { + for (int i = 0; ; i++) { + String mapStr = (String) inMap.get(key + i); + String mapStrComment = (String) inMap.get(key + "Comment" + i); + if (mapStrComment == null) { + mapStrComment = ""; + } else { + mapStrComment = mapStrComment; + } + + if (mapStr != null || mapStrComment != "") { + if (i == 0) { + strBuf.append(key + MapKeys.COLON_LF); + } + strBuf.append(MapKeys.TAB + mapStr + mapStrComment + MapKeys.LF); + } else { + break; + } + } + } + } + + /** + * Unmap a list of trigger entries. + * + * @param inMap inMap + * @param strBuf strBuf + */ + public static void unmapTriggerEntriesMap(Map inMap, StringBuffer strBuf) { + if ((inMap != null) && (strBuf != null)) { + strBuf.append(MapKeys.TRIGGERS_KEY + MapKeys.COLON_LF); + for (int i = 0; ; i++) { + String mapStr = (String) inMap.get(MapKeys.TRIGGERS_KEY + i); + + if (mapStr != null) { + strBuf.append(MapKeys.TAB + mapStr + MapKeys.LF); + } else { + break; + } + } + } + } + + /** + * Replace all but the last newline in the incoming string with + * newline / tab pairs. Useful for various multi-line form inputs. + * + * @param str string + * @return replaced string + */ + public static String replaceNewlines(String str) { + if (str != null) { + String[] strs = str.split(MapKeys.LF); + + if (strs.length == 1) { + return MapKeys.TAB + str + MapKeys.LF; + } else { + StringBuilder retStr = new StringBuilder(); + + for (String s : strs) { + retStr.append(MapKeys.TAB); + retStr.append(s); + retStr.append(MapKeys.LF); + } + + return retStr.toString(); + } + } + + return null; + } } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/helper/StringHelper.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/helper/StringHelper.java index af526a0..d76f700 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/helper/StringHelper.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/helper/StringHelper.java @@ -1,5 +1,5 @@ /** - * + * */ package com.perforce.p4java.impl.mapbased.rpc.func.helper; @@ -11,36 +11,37 @@ */ public class StringHelper { - + private static final Random rand = new Random(System.currentTimeMillis()); - + /** * Return the integer value of the passed-in char interpreted * as a hex digit. - * + * * FIXME: return -1 on bad conversion -- HR. + * @param c char + * @return integer value */ - public static int hexcharToInt(char c) { - return c - ( c > '9' ? ( c >= 'a' ? 'a' - 10 : 'A' - 10 ) : '0' ); + return c - (c > '9' ? (c >= 'a' ? 'a' - 10 : 'A' - 10) : '0'); } - + /** * Return a plausibly-random number string in hex form. * Used mostly for temp filename generation.

- * + * * Not (yet) synchronised as unlikely to be problem * with threads and contention. + * @return hex string */ - public static String getRandomHexString() { long n = rand.nextLong(); - if (n == Long.MIN_VALUE) { - n = 0; // corner case - } else { - n = Math.abs(n); - } - - return Long.toString(n, 16); + if (n == Long.MIN_VALUE) { + n = 0; // corner case + } else { + n = Math.abs(n); + } + + return Long.toString(n, 16); } } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/proto/FlowControl.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/proto/FlowControl.java index 7c34237..c2ae1b4 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/proto/FlowControl.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/func/proto/FlowControl.java @@ -3,10 +3,6 @@ */ package com.perforce.p4java.impl.mapbased.rpc.func.proto; -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; - import com.perforce.p4java.Log; import com.perforce.p4java.exception.ConnectionException; import com.perforce.p4java.exception.NullPointerError; @@ -18,24 +14,26 @@ import com.perforce.p4java.impl.mapbased.rpc.packet.RpcPacket; import com.perforce.p4java.impl.mapbased.rpc.packet.RpcPacketDispatcher; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + /** * Process and implement the various Perforce flow control commands, - * in particular the flush1 / flush2 pair.

- * + * in particular the flush1 / flush2 pair. + *

* In general, we keep a count of outstanding bytes and send * a flush1 when it gets above the high water mark (hwm); we * then wait for a corresponding flush2 before doing much else. * The server does the same thing in reverse. This will all be * explained in more detail later when the full implementation * is much clearer... (HR). - * - * */ public class FlowControl { - + public static final String TRACE_PREFIX = "FlowControl"; - + /** * Length in bytes of a flush command when marshaled. This is actually * a fiction -- it's more like 50 -- but the conservative sizing gives @@ -50,7 +48,7 @@ public class FlowControl { * for an explanation of this and associated gubbins. */ public static final int DEFAULT_LO_MARK = 700; - + /** * Default maximum number of bytes allowed to be outstanding before we start * worrying that we haven't seen a suitable flush2 response. @@ -58,23 +56,23 @@ public class FlowControl { * associated gubbins. */ public static final long DEFAULT_HI_MARK = 2000; - - private long loMark = DEFAULT_LO_MARK; // flow control low mark as calculated at init time - private long hiMark = DEFAULT_HI_MARK; // flow control high mark as calculated at init time - - private long currentLoMark = 0; // bytes outstanding going to server - private long currentHiMark = 0; // bytes outstanding coming from server without flush2 - + + private long loMark = DEFAULT_LO_MARK; // flow control low mark as calculated at init time + private long hiMark = DEFAULT_HI_MARK; // flow control high mark as calculated at init time + + private long currentLoMark = 0; // bytes outstanding going to server + private long currentHiMark = 0; // bytes outstanding coming from server without flush2 + @SuppressWarnings("unused") // used for debugging private RpcPacketDispatcher mainDispatcher = null; @SuppressWarnings("unused") // used for debugging private Properties props = null; - + public FlowControl(RpcPacketDispatcher mainDispatcher, Properties props) { this.mainDispatcher = mainDispatcher; this.props = props; } - + /** * Given a map passed-in from the main dispatcher that represents * a flush command received from the Perforce server, respond @@ -83,22 +81,26 @@ public FlowControl(RpcPacketDispatcher mainDispatcher, Properties props) { * flush2 with the same sequence number. If we see a flush2 we try * to match it up with any outstanding flush1's we've already sent. * This can get arbitrarily complex... + * + * @param rpcConnection connection + * @param funcSpec spec + * @param resultsMap map + * @throws ConnectionException on error */ - public void processFlushCommandFromServer(RpcConnection rpcConnection, - RpcFunctionSpec funcSpec, Map resultsMap) - throws ConnectionException { + RpcFunctionSpec funcSpec, Map resultsMap) + throws ConnectionException { if (rpcConnection == null) { throw new NullPointerError( - "Null rpc connection passed to FlowControl.processFlushCommandFromServer()"); + "Null rpc connection passed to FlowControl.processFlushCommandFromServer()"); } if (resultsMap == null) { throw new NullPointerError( - "Null results map passed to FlowControl.processFlushCommandFromServer()"); + "Null results map passed to FlowControl.processFlushCommandFromServer()"); } if (funcSpec == null) { throw new NullPointerError( - "Null function name passed to FlowControl.processFlushCommandFromServer()"); + "Null function name passed to FlowControl.processFlushCommandFromServer()"); } if (funcSpec == RpcFunctionSpec.PROTOCOL_FLUSH1) { @@ -111,17 +113,17 @@ public void processFlushCommandFromServer(RpcConnection rpcConnection, // Bad format or cast error; either way, this is very wrong... Log.exception(exc); throw new ProtocolError( - "Format error in FlowControl.processFlushCommandFromServer"); + "Format error in FlowControl.processFlushCommandFromServer"); } } else if (funcSpec == RpcFunctionSpec.PROTOCOL_FLUSH2) { throw new UnimplementedError("Unimplemented flush2 handler!"); } else { - + // Can't really happen, but never mind -- it *will* happen one day... - + throw new ProtocolError( "Unexpected flow command in processFlushCommandFromServer: '" - + funcSpec + "'"); + + funcSpec + "'"); } } @@ -134,11 +136,11 @@ public void sendFlush1(RpcConnection rpcConnection, Map resultsM throw new NullPointerError( "Null rpc result map passed to FlowControl.sendFlush1()"); } - + String hwmStr = (String) resultsMap.get(RpcFunctionMapKey.FLUSH_HWM); String seqNumStr = (String) resultsMap.get(RpcFunctionMapKey.FLUSH_SEQ); String rseqNumStr = (String) resultsMap.get(RpcFunctionMapKey.FLUSH_RSEQ); - + Map flushMap = new HashMap(); if (hwmStr != null) { flushMap.put(RpcFunctionMapKey.FLUSH_HWM, "" + new Long(hwmStr)); @@ -149,14 +151,14 @@ public void sendFlush1(RpcConnection rpcConnection, Map resultsM if (rseqNumStr != null) { flushMap.put(RpcFunctionMapKey.FLUSH_RSEQ, "" + new Long(rseqNumStr)); } - + RpcPacket.constructRpcPacket( RpcFunctionSpec.PROTOCOL_FLUSH1, flushMap, null); - + } - + public void sendFlush2(RpcConnection rpcConnection, Map resultsMap) - throws ConnectionException { + throws ConnectionException { if (rpcConnection == null) { throw new NullPointerError( "Null rpc connection passed to FlowControl.sendFlush2()"); @@ -169,7 +171,7 @@ public void sendFlush2(RpcConnection rpcConnection, Map resultsM String hwmStr = (String) resultsMap.get(RpcFunctionMapKey.FLUSH_HWM); String seqNumStr = (String) resultsMap.get(RpcFunctionMapKey.FLUSH_SEQ); String rseqNumStr = (String) resultsMap.get(RpcFunctionMapKey.FLUSH_RSEQ); - + Map flushMap = new HashMap(); if (hwmStr != null) { flushMap.put(RpcFunctionMapKey.FLUSH_HWM, "" + new Long(hwmStr)); @@ -180,17 +182,17 @@ public void sendFlush2(RpcConnection rpcConnection, Map resultsM if (rseqNumStr != null) { flushMap.put(RpcFunctionMapKey.FLUSH_RSEQ, "" + new Long(rseqNumStr)); } - + RpcPacket flush2Packet = RpcPacket.constructRpcPacket( RpcFunctionSpec.PROTOCOL_FLUSH2, flushMap, null); - + rpcConnection.putRpcPacket(flush2Packet); } - + public void incrementCurrentHiMark(int incr) { this.currentHiMark += incr; } - + public void decrementCurrentHiMark(int decr) { this.currentHiMark -= decr; } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/msg/RpcMessage.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/msg/RpcMessage.java index f636220..f534d92 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/msg/RpcMessage.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/msg/RpcMessage.java @@ -3,11 +3,6 @@ */ package com.perforce.p4java.impl.mapbased.rpc.msg; -import java.util.HashMap; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - import com.perforce.p4java.Log; import com.perforce.p4java.exception.MessageGenericCode; import com.perforce.p4java.exception.MessageSeverityCode; @@ -17,11 +12,16 @@ import com.perforce.p4java.impl.mapbased.rpc.func.client.ClientMessage; import com.perforce.p4java.impl.mapbased.rpc.func.client.ClientMessage.ClientMessageId; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + /** * Definitions and methods for processing, encapsulating, and - * handling RPC error and info codes on and off the wire.

- * + * handling RPC error and info codes on and off the wire. + *

* The Perforce RPC scheme encodes messages for the client -- warnings, * fatal errors, user errors, infomercials, etc., with an integer code * (usually codeX in the incoming packet, where X is 0, 1, 2, etc., @@ -29,41 +29,39 @@ * formatted message (keyed with fmtX, where the X corresponds to the * code, etc.). The integer code encodes severity and generic levels, * at least, and needs to be unpacked carefully before interpretation, - * especially as it comes across the wire as a string.

- * + * especially as it comes across the wire as a string. + *

* The apparent generic packing for codes looks like this: - *

+ * 
{@code
  * ((sev<<28)|(arg<<24)|(gen<<16)|(sub<<10)|cod)
- * 
+ * }
* where sev == severity, arg == arg count, gen == generic code, * sub == subsystem (client vs. server. etc.), and cod is the - * actual individual error code.

- * + * actual individual error code. + *

* The integer code is assumed by all sides of the wire to decode into * four bytes. We attempt to make this so.... - * - * */ public class RpcMessage { - + /** * What getGeneric() returns if it can't find a plausible * error generic level in a candidate string. */ public static final int NO_GENERIC_CODE_FOUND = -1; - + /** * CODE - code */ public static final String CODE = "code"; - + /** * FMT - fmt */ public static final String FMT = "fmt"; - - + + private int severity = MessageGenericCode.EV_NONE; private int subSystem = MessageSubsystemCode.ES_CLIENT; // FIXME -- safe default? -- HR private int generic = 0; @@ -71,18 +69,18 @@ public class RpcMessage { private String[] fmtStrs = null; private String[] argNameStrs = null; private String[] argStrs = null; - + // Pattern matching defs for error / info (etc.) message parsing: - + private static final String ALT_PATTERN = "\\[[^\\[^\\]]*\\]"; private static final String PC_PATTERN = "%[^%]*%"; private static final String SPLIT_PATTERN = "\\|"; private static final String SPLIT_MARKER = "|"; private static final String PC_MARKER = "%"; - + private static Pattern altPat = Pattern.compile(ALT_PATTERN); private static Pattern pcPat = Pattern.compile(PC_PATTERN); - + /** * Try to fill in the %...% bits in a typical server text message. Example: *

@@ -97,27 +95,28 @@ public class RpcMessage {
 	 * 
fmtStr=%change% created[ with %workCount% open file(s)][ fixing %jobCount% job(s)]
 	 * 
* Typically used in this implementation for error messages coming back from - * the server, but can have broader uses with untagged server output in general.

- * + * the server, but can have broader uses with untagged server output in general. + *

* FIXME: this is a rather ad-hoc and not particularly efficient algorithm, * which will be replaced by a better implementation when I get more experience - * with relative efficiencies, etc. -- (HR).

- * + * with relative efficiencies, etc. -- (HR). + *

* FIXME: provide a version that works with multiple format strings -- HR. + * + * @param fmtStr fmtStr + * @param map map + * @return formatted string */ - public static String interpolateArgs(String fmtStr, Map map) { - + if ((fmtStr != null) && (map != null) && (fmtStr.contains("%") || fmtStr.contains("|"))) { return doParse(fmtStr, map); } - + return fmtStr; } - - public RpcMessage(int subSystem, int code, - int severity, int generic, - String[] fmtStrs, String[] argNameStrs, String[] argStrs) { + + public RpcMessage(int subSystem, int code, int severity, int generic, String[] fmtStrs, String[] argNameStrs, String[] argStrs) { this.subSystem = subSystem; this.code = code; this.severity = severity; @@ -126,15 +125,18 @@ public RpcMessage(int subSystem, int code, this.argNameStrs = argNameStrs; this.argStrs = argStrs; } - - public RpcMessage(ClientMessageId id, - int severity, int generic, - String[] argStrs) { + + /** + * @param id id + * @param severity severity + * @param generic generic + * @param argStrs argStrs + */ + public RpcMessage(ClientMessageId id, int severity, int generic, String[] argStrs) { if (id == null) { - throw new NullPointerError( - "Null client message ID passed to RpcMessage constructor"); + throw new NullPointerError("Null client message ID passed to RpcMessage constructor"); } - + this.subSystem = MessageSubsystemCode.ES_CLIENT; ClientMessage msg = ClientMessage.getClientMessage(id); this.code = msg.getCode(); @@ -143,24 +145,22 @@ public RpcMessage(ClientMessageId id, this.argStrs = argStrs; this.fmtStrs = msg.getMsgs(); this.argNameStrs = msg.getMsgParamNames(); - - if ((this.argNameStrs != null) && (this.argStrs != null) - && (this.argNameStrs.length != this.argStrs.length)) { + + if ((this.argNameStrs != null) && (this.argStrs != null) && (this.argNameStrs.length != this.argStrs.length)) { // FIXME: too draconian? -- HR. throw new P4JavaError("Spec length mismatch in RpcMessage constructor"); } } - + /** - * Return a Map'd version of this error in the format expected + * @return a Map'd version of this error in the format expected * by the upper levels of the API. */ - - public Map toMap() { + public Map toMap() { Map retMap = new HashMap(); - + retMap.put("code0", makeErrorCodeString()); - + if (fmtStrs != null) { int i = 0; for (String fmtStr : fmtStrs) { @@ -169,13 +169,12 @@ public Map toMap() { } } } - + if (argNameStrs != null) { int i = 0; - + for (String argNameStr : argNameStrs) { - if ((argNameStr != null) && (argStrs != null) - && (argStrs.length > i) && (argStrs[i] != null)) { + if ((argNameStr != null) && (argStrs != null) && (argStrs.length > i) && (argStrs[i] != null)) { retMap.put(argNameStr, argStrs[i]); } else { retMap.put(argNameStr, ""); @@ -183,23 +182,22 @@ public Map toMap() { i++; } } - + return retMap; } - + /** * Given a string encoding of a complete error code off the wire, * return its severity level, if possible. Will return NONE if it * can't decode the string into a suitable level (or if it was null). - * + * * @param codeStr candidate error code * @return corresponding MessageSeverityCode level, or MessageSeverityCode.E_EMPTY */ - public static int getSeverity(String codeStr) { if (codeStr != null) { try { - int rawNum = new Integer(codeStr); // Really need an unsigned here... + int rawNum = new Integer(codeStr); // Really need an unsigned here... return ((rawNum >> 28) & 0x0f); } catch (Exception exc) { @@ -209,24 +207,24 @@ public static int getSeverity(String codeStr) { } return MessageSeverityCode.E_EMPTY; } - + /** * Given a string encoding of a complete error code, return * its generic error code value ("generic" being Perforce's * rather odd name for the specific error value). Will return * NO_GENERIC_CODE_FOUND if it can't find a suitable value * in the passed-in string (or if the string was null). - * - * @param codeStr candidate error code + * + * @param codeStr candidate error code * @return corresponding generic level, or NO_GENERIC_CODE_FOUND */ - + public static int getGeneric(String codeStr) { if (codeStr != null) { try { - int rawNum = new Integer(codeStr); // Really need an unsigned here... + int rawNum = new Integer(codeStr); // Really need an unsigned here... int severity = ((rawNum >> 16) & 0x0FF); - + return severity; } catch (Exception exc) { @@ -234,57 +232,54 @@ public static int getGeneric(String codeStr) { // just let it return default below } } - + return MessageGenericCode.EV_NONE; } - + /** * Given a string encoding of a complete error code, return * its subsystem error code value. Will return * CLIENT if it can't find a suitable value * in the passed-in string (or if the string was null). - * - * @param codeStr candidate error code + * + * @param codeStr candidate error code * @return corresponding subsystem, or CLIENT if none found (FIXME? -- HR) */ - + public static int getSubsystem(String codeStr) { - + if (codeStr != null) { try { - int rawNum = new Integer(codeStr); // Really need an unsigned here... + int rawNum = new Integer(codeStr); // Really need an unsigned here... int subSystem = ((rawNum >> 10) & 0x3F); - + // FIXME -- HR. - + return subSystem; } catch (Exception exc) { // just let it fall through below Log.exception(exc); } } - + return MessageSubsystemCode.ES_CLIENT; // FIXME -- HR. } - + /** * Encode the various error code subcodes as a string * as seen on the wire. The general encoding (taken straight * from the C++ API) is as follows: - *

+	 * 
{@code
 	 * # define ErrorOf( sub, cod, sev, gen, arg ) \
 	 * ((sev<<28)|(arg<<24)|(gen<<16)|(sub<<10)|cod)
-	 * 
+ * }
+ * @return error code */ - public String makeErrorCodeString() { // We use Long here to try to force non-negative values before // conversion. This may change -- HR. - - return "" + new Long( - ((this.severity << 28) - | ((this.argStrs == null ? 0 : this.argStrs.length) << 24) - | (this.generic << 16) | (this.subSystem << 10) | this.code )); + + return "" + new Long(((this.severity << 28) | ((this.argStrs == null ? 0 : this.argStrs.length) << 24) | (this.generic << 16) | (this.subSystem << 10) | this.code)); } public int getSeverity() { @@ -342,34 +337,34 @@ public String[] getArgNameStrs() { public void setArgNameStrs(String[] argNameStrs) { this.argNameStrs = argNameStrs; } - + private static String doParse(String fmtStr, Map argMap) { - + // Note also that a format string containing "[" ... "]" pairs is // (usually, as far as I can tell) a simple alternate message element // keyed on the existence of the contained args; this complicates things // a little but is crucial for correct string interpretation. - + StringBuilder strBuf = new StringBuilder(); StringBuilder outBuf = new StringBuilder(); - + Matcher altMatcher = altPat.matcher(fmtStr); int i = 0; while (altMatcher.find()) { String match = altMatcher.group(); - + strBuf.append(fmtStr.subSequence(i, altMatcher.start())); - + String matchStr = (String) match.subSequence(1, match.length() - 1); - + if (matchStr.contains(SPLIT_MARKER)) { String[] splitMatch = matchStr.split(SPLIT_PATTERN); if ((splitMatch.length == 2) && (splitMatch[0] != null) && (splitMatch[1] != null)) { // Only one of these should contain % match markers... - + int useIndx = -1; - + if (splitMatch[0].contains(PC_MARKER)) { if (containsValueMatches(splitMatch[0], argMap)) { useIndx = 0; @@ -383,9 +378,9 @@ private static String doParse(String fmtStr, Map argMap) { useIndx = 0; } } - + if ((useIndx < 0) || (useIndx > 1)) { - strBuf.append("[").append(matchStr).append("]"); + strBuf.append("[").append(matchStr).append("]"); } else { strBuf.append(splitMatch[useIndx]); } @@ -394,13 +389,13 @@ private static String doParse(String fmtStr, Map argMap) { if (containsValueMatches(matchStr, argMap)) { strBuf.append(matchStr); } else if (!matchStr.contains(PC_MARKER)) { - strBuf.append("[").append(matchStr).append("]"); + strBuf.append("[").append(matchStr).append("]"); } } i = altMatcher.start(); i += (match.length()); } - + if (i == 0) { strBuf.append(fmtStr); } else { @@ -408,31 +403,31 @@ private static String doParse(String fmtStr, Map argMap) { strBuf.append(fmtStr.subSequence(i, fmtStr.length())); } } - + Matcher pcMatcher = pcPat.matcher(strBuf); - + int j = 0; while (pcMatcher.find()) { String match = pcMatcher.group(); String repl = null; - + outBuf.append(strBuf.subSequence(j, pcMatcher.start())); - if(isUniquote(match)) { + if (isUniquote(match)) { repl = match.substring(2, match.length() - 2); } else { repl = (String) argMap.get(match.subSequence(1, match.length() - 1)); } - + if (repl != null) { outBuf.append(repl); } else { outBuf.append(match); } - + j = pcMatcher.start(); j += match.length(); } - + if (j == 0) { outBuf.append(strBuf); } else { @@ -440,25 +435,24 @@ private static String doParse(String fmtStr, Map argMap) { outBuf.append(strBuf.subSequence(j, strBuf.length())); } } - + return outBuf.toString(); } - + private static boolean containsValueMatches(String str, Map map) { - + if ((str != null) && (map != null)) { Pattern pcPat = Pattern.compile(PC_PATTERN); Matcher pcMatcher = pcPat.matcher(str); - + while (pcMatcher.find()) { String pcMatch = pcMatcher.group(); - if(isUniquote(pcMatch)) { + if (isUniquote(pcMatch)) { return true; } - - String repl = (String) map.get( - pcMatch.subSequence(1, pcMatch.length() - 1)); - + + String repl = (String) map.get(pcMatch.subSequence(1, pcMatch.length() - 1)); + if (repl != null && repl.length() > 0) { return true; } @@ -466,13 +460,10 @@ private static boolean containsValueMatches(String str, Map map) } return false; } - + private static boolean isUniquote(String str) { // Handle non-translated literals. // These look like %'value'% and the %' and '% should just be removed - return str != null && - str.length() >= 4 && - str.charAt(1) == '\''&& - str.charAt(str.length() - 2) == '\''; + return str != null && str.length() >= 4 && str.charAt(1) == '\'' && str.charAt(str.length() - 2) == '\''; } } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/packet/RpcPacket.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/packet/RpcPacket.java index bd5ca3d..e3805ea 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/packet/RpcPacket.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/packet/RpcPacket.java @@ -3,12 +3,6 @@ */ package com.perforce.p4java.impl.mapbased.rpc.packet; -import java.nio.ByteBuffer; -import java.nio.charset.Charset; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.atomic.AtomicBoolean; - import com.perforce.p4java.Log; import com.perforce.p4java.exception.NullPointerError; import com.perforce.p4java.exception.P4JavaError; @@ -19,11 +13,17 @@ import com.perforce.p4java.impl.mapbased.rpc.packet.helper.RpcPacketFieldRule; import com.perforce.p4java.server.callback.IFilterCallback; +import java.nio.ByteBuffer; +import java.nio.charset.Charset; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; + /** * Describes the format of, and implements a bunch of methods for, * Perforce RPC packets as pushed across the wire between - * Perforce clients and servers.

- * + * Perforce clients and servers. + *

* Each RPC packet consists of the following elements (as cribbed from * the C++ API code and byte-level TCP/IP packet analysis done on p4 * server network traffic): @@ -52,168 +52,159 @@ * All elements except the preamble are actually serialized arrays of text or byte * fields in the format described in the RpcPacketField class. This makes the * overall format fairly uniform and relatively straightforward to pick off - * the wire in most cases.

- * + * the wire in most cases. + *

* Note that the order of individual fields within the overall scheme * is theoretically unimportant (with the obvious exception of the preamble, * which has to be first), but there may be unknown server dependencies on * element order, so we try to closely follow the C++ API's ordering in our - * implementation.

- * + * implementation. + *

* Note that RPC packets are not in any way synonymous with TCP * packets or any underlying transport layer packet mechanism -- text * packets can span TCP packets or several RPC packets can be packed into a - * single TCP packet, for example.

- * - * + * single TCP packet, for example. */ public class RpcPacket { - + public static final int DEFAULT_RPC_PACKET_BUFFER_SIZE = 2048; // and why not? - + /** * Length in bytes of the RPC packet length fields. This is a very * fundamental constant; changing this will probably cause catastrophic * P4Java misbehavior. */ public static final int RPC_LENGTH_FIELD_LENGTH = 4; - + public static final String TRACE_PREFIX = "RpcPacket"; @SuppressWarnings("unused") - private RpcFunctionSpec funcName = null; // NOTE: do not use this field - // unless you know what you're doing... + private RpcFunctionSpec funcName = null; // NOTE: do not use this field + // unless you know what you're doing... private String funcNameString = null; private ExternalEnv env = null; private String[] strArgs = null; private Map mapArgs = null; // for named args going to the wire - private Map resultsMap = null; // for results off the wire + private Map resultsMap = null; // for results off the wire private int packetLength = 0; - + /** * Return a four byte array ready for sending across the wire that - * represents in Perforce standard wire form the integer passed in.

- * + * represents in Perforce standard wire form the integer passed in. + *

* Used extensively in the Perforce RPC protocol to encode ints before * sending them across the wire. + * + * @param i i + * @return bytes */ - public static byte[] encodeInt4(int i) { byte[] bytes = new byte[RPC_LENGTH_FIELD_LENGTH]; - - bytes[0] = (byte) ((i / 0x1 ) % 0x100); - bytes[1] = (byte) ((i / 0x100 ) % 0x100); - bytes[2] = (byte) ((i / 0x10000 ) % 0x100); - bytes[3] = (byte) ((i / 0x1000000 ) % 0x100); - + + bytes[0] = (byte) ((i / 0x1) % 0x100); + bytes[1] = (byte) ((i / 0x100) % 0x100); + bytes[2] = (byte) ((i / 0x10000) % 0x100); + bytes[3] = (byte) ((i / 0x1000000) % 0x100); + return bytes; } - + /** * Decode a Java int from the passed-in 4 byte Perforce encoded - * integer value.

- * + * integer value. + *

* Used extensively in the Perforce RPC protocol to decode ints * coming in off the wire. Note that we have to go to some length * to convince Java that we want unsigned byte (it's amazing that * Java still doesn't have unsigned integral types...); this - * helps explain the seemingly-redundant "& 0xFF"'s in the code + * helps explain the seemingly-redundant {@code "& 0xFF"'s} in the code * below. + * + * @param bytes bytes + * @return decoded */ - public static int decodeInt4(byte[] bytes) { if (bytes == null) { - throw new NullPointerError( - "Null bytes passed to RpcPacket.decodeInt"); + throw new NullPointerError("Null bytes passed to RpcPacket.decodeInt"); } if (bytes.length != RPC_LENGTH_FIELD_LENGTH) { - throw new ProtocolError( - "Bad byte array size in RpcPacket.decodeInt: " - + bytes.length); + throw new ProtocolError("Bad byte array size in RpcPacket.decodeInt: " + bytes.length); } - - return ((bytes[0] & 0xFF) * 0x1) - + ((bytes[1] & 0xFF) * 0x100) - + ((bytes[2] & 0xFF) * 0x10000) - + ((bytes[3] & 0xFF) * 0x1000000); + + return ((bytes[0] & 0xFF) * 0x1) + ((bytes[1] & 0xFF) * 0x100) + ((bytes[2] & 0xFF) * 0x10000) + ((bytes[3] & 0xFF) * 0x1000000); } - + /** * Construct an RPC packet for a user command. - * + * * @param funcName non-null function name - * @param args potentially-null function arguments as a string array - * @param env potentially-null command environment + * @param realName realName + * @param args potentially-null function arguments as a string array + * @param env potentially-null command environment * @return non-null text packet ready for marshaling (or whatever) */ - - public static RpcPacket constructRpcPacket( - RpcFunctionSpec funcName, - String realName, - String[] args, - ExternalEnv env) { + public static RpcPacket constructRpcPacket(RpcFunctionSpec funcName, String realName, String[] args, ExternalEnv env) { return new RpcPacket(funcName, realName, args, env); } - + /** * Construct an RPC packet for a user command. - * + * * @param funcName non-null function name - * @param args potentially-null function arguments in map form - * @param env potentially-null command environment + * @param args potentially-null function arguments in map form + * @param env potentially-null command environment * @return non-null text packet ready for marshaling (or whatever) */ - - public static RpcPacket constructRpcPacket( - RpcFunctionSpec funcName, - Map args, - ExternalEnv env) { + public static RpcPacket constructRpcPacket(RpcFunctionSpec funcName, Map args, ExternalEnv env) { return new RpcPacket(funcName, args, env); } - + /** * Construct an RPC packet for a user command. - * + * * @param funcName non-null function name - * @param args potentially-null function arguments in map form - * @param env potentially-null command environment + * @param args potentially-null function arguments in map form + * @param env potentially-null command environment * @return non-null text packet ready for marshaling (or whatever) */ - - public static RpcPacket constructRpcPacket( - String funcName, - Map args, - ExternalEnv env) { + public static RpcPacket constructRpcPacket(String funcName, Map args, ExternalEnv env) { return new RpcPacket(funcName, args, env); } - + /** * Construct an RPC packet from the passed-in preamble, bytes, and charset. + * + * @param preamble preamble + * @param bytes bytes + * @param isUnicodeServer isUnicodeServer + * @param charset charset + * @return RpcPacket */ - public static RpcPacket constructRpcPacket(RpcPacketPreamble preamble, - byte[] bytes, boolean isUnicodeServer, - Charset charset) { + public static RpcPacket constructRpcPacket(RpcPacketPreamble preamble, byte[] bytes, boolean isUnicodeServer, Charset charset) { return constructRpcPacket(preamble, bytes, isUnicodeServer, charset, null, null); } /** * Construct an RPC packet from the passed-in preamble, bytes, charset and fieldRule. + * + * @param preamble preamble + * @param bytes bytes + * @param isUnicodeServer isUnicodeServer + * @param charset charset + * @param fieldRule fieldRule + * @param filterCallback filterCallback + * @return RpcPacket */ - public static RpcPacket constructRpcPacket(RpcPacketPreamble preamble, - byte[] bytes, boolean isUnicodeServer, - Charset charset, RpcPacketFieldRule fieldRule, - IFilterCallback filterCallback) { + public static RpcPacket constructRpcPacket(RpcPacketPreamble preamble, byte[] bytes, boolean isUnicodeServer, Charset charset, RpcPacketFieldRule fieldRule, IFilterCallback filterCallback) { return new RpcPacket(preamble, bytes, isUnicodeServer, charset, fieldRule, filterCallback); } - private RpcPacket(RpcFunctionSpec funcName, String realName, String[] args, - ExternalEnv env) { + private RpcPacket(RpcFunctionSpec funcName, String realName, String[] args, ExternalEnv env) { if (funcName == null) { - throw new NullPointerError( - "Null function name passed to RpcPacket constructor"); + throw new NullPointerError("Null function name passed to RpcPacket constructor"); } - + this.funcName = funcName; if (funcName == RpcFunctionSpec.USER_SPECIFIED) { // Special case for relaxed user command checking... @@ -224,30 +215,28 @@ private RpcPacket(RpcFunctionSpec funcName, String realName, String[] args, this.strArgs = args; this.env = env; } - + private RpcPacket(RpcFunctionSpec funcName, Map args, ExternalEnv env) { if (funcName == null) { - throw new NullPointerError( - "Null function name passed to RpcPacket constructor"); + throw new NullPointerError("Null function name passed to RpcPacket constructor"); } - + this.funcName = funcName; this.funcNameString = funcName.getEncoding(); this.mapArgs = args; this.env = env; } - + private RpcPacket(String funcName, Map args, ExternalEnv env) { if (funcName == null) { - throw new NullPointerError( - "Null function name passed to RpcPacket constructor"); + throw new NullPointerError("Null function name passed to RpcPacket constructor"); } - + this.funcNameString = funcName; this.mapArgs = args; this.env = env; } - + private RpcPacket(Map resultsMap, int packetLength) { this.resultsMap = resultsMap; this.packetLength = packetLength; @@ -255,34 +244,30 @@ private RpcPacket(Map resultsMap, int packetLength) { this.funcNameString = (String) resultsMap.get(RpcFunctionMapKey.FUNCTION); } } - - private RpcPacket(RpcPacketPreamble preamble, byte[] payloadBytes, - boolean isUnicodeServer, Charset charset, - RpcPacketFieldRule fieldRule, IFilterCallback filterCallback) { + + private RpcPacket(RpcPacketPreamble preamble, byte[] payloadBytes, boolean isUnicodeServer, Charset charset, RpcPacketFieldRule fieldRule, IFilterCallback filterCallback) { if (preamble == null) { throw new NullPointerError("null RPC preamble passed to RpcPacket constructor"); } if (!preamble.isValidChecksum()) { - throw new ProtocolError( - "Bad checksum in RPC preamble passed to RpcPacket constructor"); + throw new ProtocolError("Bad checksum in RPC preamble passed to RpcPacket constructor"); } if (payloadBytes == null) { throw new NullPointerError("null payload byte array passed to RpcPacket constructor"); } - + int payloadLength = preamble.getPayloadSize(); if (payloadLength != payloadBytes.length) { - throw new P4JavaError("bad byte array size in RpcPacket constructor; byte array length: " - + payloadBytes.length + "; from preamble: " + payloadLength); + throw new P4JavaError("bad byte array size in RpcPacket constructor; byte array length: " + payloadBytes.length + "; from preamble: " + payloadLength); } - + try { resultsMap = new HashMap(); ByteBuffer packetBuf = ByteBuffer.wrap(payloadBytes); - + final Map doNotSkipKeysMap = filterCallback != null ? filterCallback.getDoNotSkipKeysMap() : null; final AtomicBoolean skipSubsequent = new AtomicBoolean(false); - + while (packetBuf.position() < packetBuf.limit()) { Object[] fields = RpcPacketField.retrievePacketField(packetBuf, isUnicodeServer, charset, fieldRule); @@ -290,34 +275,32 @@ private RpcPacket(RpcPacketPreamble preamble, byte[] payloadBytes, if (filterCallback != null) { // Check for RPC protocol related keys which cannot be skipped. // Also, check for do-not-skip keys passed-in by the callback. - if (!RpcFunctionMapKey.RPC_KEYS_MAP.containsKey((String)fields[RpcPacketField.NAME_FIELD]) && - !(doNotSkipKeysMap != null && doNotSkipKeysMap.containsKey((String)fields[RpcPacketField.NAME_FIELD]))) { - if (skipSubsequent != null && skipSubsequent.get()) { + if (!RpcFunctionMapKey.RPC_KEYS_MAP.containsKey((String) fields[RpcPacketField.NAME_FIELD]) && !(doNotSkipKeysMap != null && doNotSkipKeysMap.containsKey((String) fields[RpcPacketField.NAME_FIELD]))) { + if (skipSubsequent != null && skipSubsequent.get()) { // Skip continue; } else { - if (filterCallback.skip((String)fields[RpcPacketField.NAME_FIELD], - fields[RpcPacketField.VALUE_FIELD], skipSubsequent)) { + if (filterCallback.skip((String) fields[RpcPacketField.NAME_FIELD], fields[RpcPacketField.VALUE_FIELD], skipSubsequent)) { // Skip continue; } } } } - + if (fields[RpcPacketField.NAME_FIELD] == null) { resultsMap.put(null, fields[RpcPacketField.VALUE_FIELD]); } else { // Assumes zeroth field is always a string; this assumption has yet // to be broken, but keep a good look out in any case... -- HR. - + String fieldName = (String) fields[RpcPacketField.NAME_FIELD]; // func2 detection below is related to job037970 -- the server is incorrectly // sending *two* func2 fields in certain proxy-related circumstances; only the // first value is correct. This should be fixed in the server, but this quick // fix should help out in the field and with older servers -- HR. - + if (fieldName.equalsIgnoreCase(RpcFunctionMapKey.FUNC2)) { if (!resultsMap.containsKey(fieldName)) { resultsMap.put(fieldName, fields[RpcPacketField.VALUE_FIELD]); @@ -344,11 +327,11 @@ private RpcPacket(RpcPacketPreamble preamble, byte[] payloadBytes, } } } - + this.packetLength = payloadLength; if (resultsMap != null) { this.funcNameString = (String) resultsMap.get(RpcFunctionMapKey.FUNCTION); - } + } // Callback reset() if (filterCallback != null) { diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/packet/RpcPacketDispatcher.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/packet/RpcPacketDispatcher.java index 179f8d2..127cad9 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/packet/RpcPacketDispatcher.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/packet/RpcPacketDispatcher.java @@ -3,12 +3,6 @@ */ package com.perforce.p4java.impl.mapbased.rpc.packet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.concurrent.CopyOnWriteArrayList; - import com.perforce.p4java.Log; import com.perforce.p4java.exception.AccessException; import com.perforce.p4java.exception.ConnectionException; @@ -24,115 +18,125 @@ import com.perforce.p4java.impl.mapbased.rpc.func.proto.FlowControl; import com.perforce.p4java.impl.mapbased.rpc.func.proto.ProtocolFunctionDispatcher; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.CopyOnWriteArrayList; + /** * Top-level client-side packet dispatcher. Responsible for dispatching * packets (and their contents) to the correct processor classes or * methods as the packets come in from the server. Also responsible for * flow control and sundry other things as explained below. There is * one RpcPacketDispatcher object for each RpcServer object. - * - * */ public class RpcPacketDispatcher { - + /** * An enum used by subsidiary function and packet dispatchers to * tell this level of dispatcher what to do. Individual values * are hopefully somewhat self-explanatory. */ public enum RpcPacketDispatcherResult { - NONE, - CONTINUE, // continue without changing dispatch mode - CONTINUE_LOOP, // continue in dispatch loop mode - CONTINUE_DUPLEX, // continue in dispatch duplex mode - STOP_NORMAL, // stop dispatch in normal way (no errors, etc.). + NONE, CONTINUE, // continue without changing dispatch mode + CONTINUE_LOOP, // continue in dispatch loop mode + CONTINUE_DUPLEX, // continue in dispatch duplex mode + STOP_NORMAL, // stop dispatch in normal way (no errors, etc.). STOP_ERROR; - }; - + } + + ; + /** * Specifies the mode the dispatcher's currently running in. * Names are taken from the informal README explanation of * the C++ API's dispatch models, so don't blame me... */ public enum RpcPacketDispatcherMode { - NONE, // Strictly speaking, a grave error... - PRIMAL, // Client sends initial command - CALLBACK, // Server instructing client; continues until server sends release; used for - // output-only commands (typically, anyway) - LOOP, // Server instructed client to send another message back to the server - // to continue flow of control; typically used for client-side things like - // logins, spec edits, etc. where the client should interact with the end user - // (which we typically fake in the upper levels of P4Java) - DUPLEX, // Perforce server instructs client to send simple acks of operations. - DUPLEXREV // Not currently used here - }; - + NONE, // Strictly speaking, a grave error... + PRIMAL, // Client sends initial command + CALLBACK, // Server instructing client; continues until server sends release; used for + // output-only commands (typically, anyway) + LOOP, // Server instructed client to send another message back to the server + // to continue flow of control; typically used for client-side things like + // logins, spec edits, etc. where the client should interact with the end user + // (which we typically fake in the upper levels of P4Java) + DUPLEX, // Perforce server instructs client to send simple acks of operations. + DUPLEXREV // Not currently used here + } + + ; + public static final String TRACE_PREFIX = "RpcPacketDispatcher"; private FlowControl flowController = null; - + private ProtocolFunctionDispatcher protocolDispatcher = null; private ClientFunctionDispatcher clientDispatcher = null; private Properties props = null; - + public RpcPacketDispatcher(Properties props, RpcServer server) { this.props = props; this.protocolDispatcher = new ProtocolFunctionDispatcher(this, this.props); this.clientDispatcher = new ClientFunctionDispatcher(this, this.props, server); this.flowController = new FlowControl(this, this.props); } - + /** - * Top-level dispatcher method.

- * + * Top-level dispatcher method. + *

* Dispatch (i.e. process) commands sent from the Perforce server in * response to the original user command. This is an arbitrarily complex - * process, and may or may not involve traffic management, etc., so - * the implementation here may be less than transparent...

- * + * process, and may or may not involve traffic management, etc., so + * the implementation here may be less than transparent... + *

* This method only returns when the entire original command was finished; * basically, if it returns at all, things went well; otherwise it throws * a suitable exception. Extensive work is actually passed off to the * various sub dispatchers, which may do their own client / server messaging. + * + * @param cmdEnv cmdEnv + * @return dispatcher + * @throws ConnectionException on error + * @throws AccessException on error */ - - public List> dispatch(CommandEnv cmdEnv) - throws ConnectionException, AccessException { - + public List> dispatch(CommandEnv cmdEnv) throws ConnectionException, AccessException { + // Basic idea is to sit in the receive loop processing commands until we see // a release command come back from the Perforce server. - + if (cmdEnv == null) { throw new NullPointerError("Null command environment passed to main dispatcher"); } - + if (cmdEnv.getRpcConnection() == null) { throw new NullPointerError("Null rpc connection passed to main dispatcher"); } - + int cmdCallBackKey = cmdEnv.getCmdCallBackKey(); RpcConnection rpcConnection = cmdEnv.getRpcConnection(); - + List> resultMaps = new CopyOnWriteArrayList<>(new LinkedList>()); cmdEnv.setResultMaps(resultMaps); - + try { RpcPacketDispatcherMode dispatchMode = RpcPacketDispatcherMode.PRIMAL; RpcPacket packet = null; - + if (cmdEnv.getProgressCallback() != null) { cmdEnv.getProgressCallback().start(cmdCallBackKey); } - + while ((packet = rpcConnection.getRpcPacket(cmdEnv.getFieldRule(), cmdEnv.getFilterCallback())) != null) { // User cancelled command if (cmdEnv.isUserCanceled()) { return resultMaps; } - - Map paramMap = null; // contains the incoming packet's parameter map, - // if any. + + Map paramMap = null; // contains the incoming packet's parameter map, + // if any. String funcNameStr = null; RpcFunctionSpec func = RpcFunctionSpec.NONE; @@ -140,25 +144,23 @@ public List> dispatch(CommandEnv cmdEnv) if (paramMap == null) { throw new ProtocolError("Null results map in P4JRpcTextPacket"); } - - funcNameStr = packet.getFuncNameString(); - + + funcNameStr = packet.getFuncNameString(); + if (funcNameStr == null) { throw new ProtocolError("Null function value string in dispatch text packet"); } - - func = RpcFunctionSpec.decode(funcNameStr); - + + func = RpcFunctionSpec.decode(funcNameStr); + if (func == RpcFunctionSpec.NONE) { - throw new ProtocolError("Unable to decode function in RpcPacket;" - + " func string: " + funcNameStr); + throw new ProtocolError("Unable to decode function in RpcPacket;" + " func string: " + funcNameStr); } - + switch (func.getType()) { - + case CLIENT: - switch (clientDispatcher.dispatch(dispatchMode, - func, cmdEnv, paramMap)) { + switch (clientDispatcher.dispatch(dispatchMode, func, cmdEnv, paramMap)) { case CONTINUE: break; case CONTINUE_LOOP: @@ -172,22 +174,15 @@ public List> dispatch(CommandEnv cmdEnv) } break; - + case USER: - throw new ProtocolError( - "Unexpected user function in dispatch: '" - + funcNameStr + "'"); - + throw new ProtocolError("Unexpected user function in dispatch: '" + funcNameStr + "'"); + case SERVER: - throw new UnimplementedError( - "Unexpected server function '" - + funcNameStr - + "' encountered in RPC dispatch" - ); - - case PROTOCOL: - switch (protocolDispatcher.dispatch(dispatchMode, - func, cmdEnv, paramMap)) { + throw new UnimplementedError("Unexpected server function '" + funcNameStr + "' encountered in RPC dispatch"); + + case PROTOCOL: + switch (protocolDispatcher.dispatch(dispatchMode, func, cmdEnv, paramMap)) { case CONTINUE: break; case CONTINUE_LOOP: @@ -199,24 +194,21 @@ public List> dispatch(CommandEnv cmdEnv) default: break; } - + break; - + default: - throw new ProtocolError( - "Unrecognized function string type in RPC packet: '" - + funcNameStr + "'"); + throw new ProtocolError("Unrecognized function string type in RPC packet: '" + funcNameStr + "'"); } - + } - + // If we get here, we got a non-positive return from the recv, which almost // always means the other end unexpectedly shut down the connection (timed out or // whatever). - throw new ConnectionNotConnectedException( - "Perforce server disconnected at server end; unknown cause."); - + throw new ConnectionNotConnectedException("Perforce server disconnected at server end; unknown cause."); + } catch (ConnectionNotConnectedException cnce) { throw cnce; } catch (Throwable thr) { @@ -225,20 +217,21 @@ public List> dispatch(CommandEnv cmdEnv) throw new ConnectionException(thr.getLocalizedMessage(), thr); } } - + /** * Attempt to cleanly shut down the dispatcher; this should involve * sending a release2 packet, but this is not always possible, and * we suppress any resulting errors. + * + * @param rpcConnection rpcConnection + * @throws ConnectionException on error */ - - public void shutdown(RpcConnection rpcConnection) throws ConnectionException { + public void shutdown(RpcConnection rpcConnection) throws ConnectionException { if ((this.protocolDispatcher != null) && (rpcConnection != null)) { try { this.protocolDispatcher.sendRelease2(rpcConnection); } catch (Exception exc) { - Log.warn("Unexpected exception in RPC packet dispatch shutdown: " - + exc.getLocalizedMessage()); + Log.warn("Unexpected exception in RPC packet dispatch shutdown: " + exc.getLocalizedMessage()); Log.exception(exc); } } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/packet/RpcPacketField.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/packet/RpcPacketField.java index 3f13fc0..5273d23 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/packet/RpcPacketField.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/packet/RpcPacketField.java @@ -3,11 +3,6 @@ */ package com.perforce.p4java.impl.mapbased.rpc.packet; -import java.io.UnsupportedEncodingException; -import java.nio.BufferOverflowException; -import java.nio.ByteBuffer; -import java.nio.charset.Charset; - import com.perforce.p4java.CharsetDefs; import com.perforce.p4java.Log; import com.perforce.p4java.exception.NullPointerError; @@ -16,54 +11,57 @@ import com.perforce.p4java.impl.mapbased.rpc.connection.RpcConnection; import com.perforce.p4java.impl.mapbased.rpc.packet.helper.RpcPacketFieldRule; +import java.io.UnsupportedEncodingException; +import java.nio.BufferOverflowException; +import java.nio.ByteBuffer; +import java.nio.charset.Charset; + /** * Describes a value / name packet pair as marshaled - * on to or off the RPC wire between Perforce clients and servers.

- * + * on to or off the RPC wire between Perforce clients and servers. + *

* Format on wire (from C++ API source), in bytes: - *

+ * 
{@code
  *         var<00>value<00>
- * 
- * + * }
+ *

* where either or both var and value can be empty (null), * and where value can be interpreted as text (utf-8 or ascii, * depending on settings) binary bytes, and where * the four byte value length spec does not include the terminating * null byte, and is encoded as per RpcPacket.encodeInt4(). - * - * */ public class RpcPacketField { - + public static final String TRACE_PREFIX = "RpcPacketField"; - + /** * How many elements in each packet field. Changing this will probably * cause havoc. */ public static final int NUM_ELEMENTS = 2; - + /** * Which element will contain (or not) the field's name. */ public static final int NAME_FIELD = 0; - + /** * Which element will contain (or not) the field's value. */ public static final int VALUE_FIELD = 1; - + private String name = null; private Object value = null; /** * Construct a packet field from the passed-n name / value pair. - * - * @param name possibly-null name + * + * @param name possibly-null name * @param value possibly-null value */ - + public RpcPacketField(String name, Object value) { this.name = name; this.value = value; @@ -76,43 +74,50 @@ public RpcPacketField(String name, Object value) { * will always be text (a string) if it's not null; element one is the corresponding * value, and (if it's not null) will be a byte array whose interpretation must be * done by the caller in the light of what's expected in context -- it might represent - * a normal string or it might actually be binary bytes.

- * + * a normal string or it might actually be binary bytes. + *

* Updates the buffer's position accordingly. Have to be careful * to use charsets with bytes and strings properly here and in the caller * to keep internationalization and localization straight. + * + * @param buf buf + * @param isUnicodeServer isUnicodeServer + * @param charset charset + * @return packet fields */ - - public static Object[] retrievePacketField(ByteBuffer buf, boolean isUnicodeServer, - Charset charset) { + public static Object[] retrievePacketField(ByteBuffer buf, boolean isUnicodeServer, Charset charset) { return retrievePacketField(buf, isUnicodeServer, charset, null); } /** * Attempt to pick off a name / value field pair from the passed-in byte * buffer with an optional rule to handle the RPC packet fields. + * + * @param buf buf + * @param isUnicodeServer isUnicodeServer + * @param charset charset + * @param fieldRule fieldRule + * @return packet fields */ - public static Object[] retrievePacketField(ByteBuffer buf, boolean isUnicodeServer, - Charset charset, RpcPacketFieldRule fieldRule) { - + public static Object[] retrievePacketField(ByteBuffer buf, boolean isUnicodeServer, Charset charset, RpcPacketFieldRule fieldRule) { + if (buf == null) { - throw new NullPointerError( - "Null byte buffer passed to RpcPacketField.retrievePacketField()"); + throw new NullPointerError("Null byte buffer passed to RpcPacketField.retrievePacketField()"); } - + Object[] retVal; retVal = new Object[NUM_ELEMENTS]; retVal[NAME_FIELD] = null; retVal[VALUE_FIELD] = null; - + // Get name string; may be empty (i.e. first byte is null); also have // to deal with the fact that the name string may be arbitrarily large... - + final int INITIAL_BYTEARRAY_SIZE = 128; // bytes - + byte[] bytes = new byte[INITIAL_BYTEARRAY_SIZE]; - + int i = 0; while ((bytes[i] = buf.get()) != 0) { i++; @@ -123,49 +128,43 @@ public static Object[] retrievePacketField(ByteBuffer buf, boolean isUnicodeServ bytes = newBytes; } } - + if (i > 0) { // Field names are currently always assumed to be in the default // charset, i.e. RpcConnection.NON_UNICODE_SERVER_CHARSET unless // the server is in Unicode mode. try { - retVal[NAME_FIELD] = new String(bytes, 0, i, charset == null ? - RpcConnection.NON_UNICODE_SERVER_CHARSET_NAME : - (isUnicodeServer ? CharsetDefs.UTF8_NAME : charset.name())); + retVal[NAME_FIELD] = new String(bytes, 0, i, charset == null ? RpcConnection.NON_UNICODE_SERVER_CHARSET_NAME : (isUnicodeServer ? CharsetDefs.UTF8_NAME : charset.name())); } catch (UnsupportedEncodingException e) { // This should never be reached since we already have the Charset // object needed. Log.exception(e); } } - + // Get value string length which may be zero): - + int remaining = buf.remaining(); if (remaining < RpcPacket.RPC_LENGTH_FIELD_LENGTH) { - throw new ProtocolError( - "Insufficient bytes in buffer to retrieve text value field length"); + throw new ProtocolError("Insufficient bytes in buffer to retrieve text value field length"); } - + byte[] lengthBytes = new byte[RpcPacket.RPC_LENGTH_FIELD_LENGTH]; buf.get(lengthBytes); - + int valLength = RpcPacket.decodeInt4(lengthBytes); - + if (valLength < 0) { - throw new ProtocolError( - "Negative text field value length in P4JRpcTextField initializer: " - + valLength); + throw new ProtocolError("Negative text field value length in P4JRpcTextField initializer: " + valLength); } - + // Get value (may be empty); at least here we know the // supposed number of the incoming bytes for the value: - + if (remaining < valLength) { - throw new ProtocolError( - "Insufficient bytes in buffer to retrieve text value field"); + throw new ProtocolError("Insufficient bytes in buffer to retrieve text value field"); } - + byte[] valBytes = new byte[valLength]; buf.get(valBytes); @@ -178,17 +177,14 @@ public static Object[] retrievePacketField(ByteBuffer buf, boolean isUnicodeServ fieldRule.update(fieldName); skipConversion = fieldRule.isSkipConversion(); } - - if (!skipConversion && - RpcPacketFieldType.getFieldType((String) retVal[NAME_FIELD]) == RpcPacketFieldType.TEXT) { - + + if (!skipConversion && RpcPacketFieldType.getFieldType((String) retVal[NAME_FIELD]) == RpcPacketFieldType.TEXT) { + // Incoming string is encoded in UTF-8 if we're talking to a Unicode server; // otherwise it's in the specified charset, or maybe some 8 bit ASCI variant). - + try { - retVal[VALUE_FIELD] = new String(valBytes, charset == null ? - RpcConnection.NON_UNICODE_SERVER_CHARSET_NAME : - (isUnicodeServer ? CharsetDefs.UTF8_NAME : charset.name())); + retVal[VALUE_FIELD] = new String(valBytes, charset == null ? RpcConnection.NON_UNICODE_SERVER_CHARSET_NAME : (isUnicodeServer ? CharsetDefs.UTF8_NAME : charset.name())); } catch (UnsupportedEncodingException e) { // This should never be reached since we already have the Charset // object needed. @@ -196,80 +192,87 @@ public static Object[] retrievePacketField(ByteBuffer buf, boolean isUnicodeServ } } else { retVal[VALUE_FIELD] = valBytes; // If unicode is involved here (as, e.g., file contents), - // it'll be converted elsewhere... + // it'll be converted elsewhere... } - buf.get(); // Step over the terminating null - + buf.get(); // Step over the terminating null + return retVal; } - + public String getName() { return this.name; } - + public void setName(String name) { this.name = name; } - + public Object getValue() { return this.value; } - + public void setValue(Object value) { this.value = value; } - + /** * Marshal the passed-in packet fields onto a ByteBuffer. Affects * the buffer's position, etc., accordingly.

- * @throws UnsupportedEncodingException + * + * @param buf buf + * @param name name + * @param value value + * @param charset charset + * @throws UnsupportedEncodingException on error + * @throws BufferOverflowException on error */ - - public static void marshal(ByteBuffer buf, String name, String value, Charset charset) - throws BufferOverflowException, UnsupportedEncodingException { - marshal(buf, name, - (value == null ? null : value.getBytes( - charset == null ? CharsetDefs.DEFAULT.name() : charset.name()))); + public static void marshal(ByteBuffer buf, String name, String value, Charset charset) throws BufferOverflowException, UnsupportedEncodingException { + marshal(buf, name, (value == null ? null : value.getBytes(charset == null ? CharsetDefs.DEFAULT.name() : charset.name()))); } - + /** * Marshal the passed-in packet fields onto a ByteBuffer. Affects * the buffer's position, etc., accordingly.

- * @throws UnsupportedEncodingException + * + * @param buf buf + * @param name name + * @param value value + * @param charset charset + * @throws UnsupportedEncodingException on error + * @throws BufferOverflowException on error */ - - public static void marshal(ByteBuffer buf, String name, StringBuffer value, Charset charset) - throws BufferOverflowException, UnsupportedEncodingException { - marshal(buf, name, - (value == null ? null : value.toString().getBytes( - charset == null ? CharsetDefs.DEFAULT.name() : charset.name()))); + public static void marshal(ByteBuffer buf, String name, StringBuffer value, Charset charset) throws BufferOverflowException, UnsupportedEncodingException { + marshal(buf, name, (value == null ? null : value.toString().getBytes(charset == null ? CharsetDefs.DEFAULT.name() : charset.name()))); } + /** * Marshal the passed-in packet fields onto a ByteBuffer. Affects * the buffer's position, etc., accordingly. + * + * @param buf buf + * @param name name + * @param value value + * @throws BufferOverflowException on error */ - - public static void marshal(ByteBuffer buf, String name, byte[] value) - throws BufferOverflowException { + public static void marshal(ByteBuffer buf, String name, byte[] value) throws BufferOverflowException { if (buf == null) { - throw new NullPointerError( - "Null byte buffer passed to RpcPacketField.marshal()"); + throw new NullPointerError("Null byte buffer passed to RpcPacketField.marshal()"); } - + try { if (name != null) { buf.put(name.getBytes(CharsetDefs.DEFAULT.name())); } buf.put((byte) 0); - + int valLength = 0; - + if (value != null) { valLength = value.length; } buf.put(RpcPacket.encodeInt4(valLength)); - + if (value != null) { buf.put(value); } @@ -277,35 +280,37 @@ public static void marshal(ByteBuffer buf, String name, byte[] value) } catch (BufferOverflowException boe) { // Will attempt to increase the size of the buffer in the caller // (some time in the future, at any rate...) - + throw boe; } catch (Throwable thr) { // Should be buffer overflow errors only; in any case, // this is really a panic... - + Log.error("Unexpected exception: " + thr.getLocalizedMessage()); Log.exception(thr); throw new P4JavaError(thr.getLocalizedMessage()); } } - + /** * Marshal the passed-in packet fields onto a ByteBuffer. Affects * the buffer's position, etc., accordingly. Since this one uses * special ByteBuffer to ByteBuffer methods, it gets its own - * version rather than using the byte[] method.

- * + * version rather than using the byte[] method. + *

* Note: incoming value ByteBuffer must have been flipped ready for - * sending; value's position will be updated by this method, so + * sending; value's position will be updated by this method, so * if the buffer is to be reused, you must flip or reset (or whatever) - * it yourself.

+ * it yourself. + * + * @param buf buf + * @param name name + * @param value value + * @throws BufferOverflowException on error */ - - public static void marshal(ByteBuffer buf, String name, ByteBuffer value) - throws BufferOverflowException { + public static void marshal(ByteBuffer buf, String name, ByteBuffer value) throws BufferOverflowException { if (buf == null) { - throw new NullPointerError( - "Null byte buffer passed to RpcPacketField.marshal()"); + throw new NullPointerError("Null byte buffer passed to RpcPacketField.marshal()"); } try { @@ -313,15 +318,15 @@ public static void marshal(ByteBuffer buf, String name, ByteBuffer value) buf.put(name.getBytes(CharsetDefs.DEFAULT.name())); } buf.put((byte) 0); - + int valLength = 0; - + if (value != null) { valLength = value.limit(); } buf.put(RpcPacket.encodeInt4(valLength)); - + if (value != null) { buf.put(value); } @@ -329,13 +334,11 @@ public static void marshal(ByteBuffer buf, String name, ByteBuffer value) } catch (Throwable thr) { Log.error("Unexpected exception: " + thr.getLocalizedMessage()); Log.exception(thr); - throw new P4JavaError("Unexpected exception in RpcPacketField.marshal(ByteBuffer): " - + thr.getLocalizedMessage(), thr); + throw new P4JavaError("Unexpected exception in RpcPacketField.marshal(ByteBuffer): " + thr.getLocalizedMessage(), thr); } } - - public static void marshal(byte[] buf, String name, byte[] value) - throws BufferOverflowException { + + public static void marshal(byte[] buf, String name, byte[] value) throws BufferOverflowException { throw new P4JavaError("Called unimplemented marshall method"); } } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/packet/RpcPacketFieldType.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/packet/RpcPacketFieldType.java index 9536f21..2c79831 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/packet/RpcPacketFieldType.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/packet/RpcPacketFieldType.java @@ -11,33 +11,33 @@ * as a string or bytes; most fields are strings, but things like worKRec * or depotRec fields are binary pass-throughs from the point of view of * the client (they're state keys and / or state records used by the server). - * - * */ public enum RpcPacketFieldType { - + /** * Field type is unknown. Field should probably not be used. */ NONE, - + /** * Field is text; possibly UTF-8 encoded. */ TEXT, - + /** * Field is bytes, not interpreted. */ BINARY; - + /** * Return the field type associated with the passed-in name, if any. + * + * @param fieldName fieldName + * @return RpcPacketFieldType */ - public static RpcPacketFieldType getFieldType(String fieldName) { - + if (fieldName != null) { if (fieldName.equalsIgnoreCase(RpcFunctionMapKey.DATA)) { return BINARY; @@ -52,14 +52,14 @@ public static RpcPacketFieldType getFieldType(String fieldName) { } else if (fieldName.equalsIgnoreCase(RpcFunctionMapKey.BASEDEPOTREC)) { return BINARY; } else if (fieldName.equalsIgnoreCase(RpcFunctionMapKey.HAVEREC)) { - return BINARY; - } else if (fieldName.startsWith(RpcFunctionMapKey.ATTR_PREFIX)){ + return BINARY; + } else if (fieldName.startsWith(RpcFunctionMapKey.ATTR_PREFIX)) { return BINARY; } else { return TEXT; } } - + return NONE; } } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/packet/RpcPacketPreamble.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/packet/RpcPacketPreamble.java index e53bc98..0a91e5a 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/packet/RpcPacketPreamble.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/packet/RpcPacketPreamble.java @@ -3,16 +3,16 @@ */ package com.perforce.p4java.impl.mapbased.rpc.packet; -import java.nio.BufferUnderflowException; -import java.nio.ByteBuffer; - import com.perforce.p4java.exception.NullPointerError; import com.perforce.p4java.exception.P4JavaError; import com.perforce.p4java.exception.ProtocolError; +import java.nio.BufferUnderflowException; +import java.nio.ByteBuffer; + /** - * The five byte preamble appended to every text packet payload.

- * + * The five byte preamble appended to every text packet payload. + *

* The format (as divined from the C++ API) is designed to provide * a very simple sanity check checksum and encode the length in bytes * of the accompanying RPC payload: @@ -25,187 +25,172 @@ *

* This can generally only be calculated after the other packet elements * have been serialized, which is irritating but not too annoying. - * - * */ public class RpcPacketPreamble { - + /** * Size in bytes of the preamble checksum. This is a very fundamental * value; changing it will probably cause total destruction within * P4Java... */ public static final int RPC_PREAMBLE_CHKSUM_SIZE = 1; - + /** * The size in bytes of the standard text packet RPC packet preamble. */ - public static final int RPC_PREAMBLE_SIZE = RpcPacket.RPC_LENGTH_FIELD_LENGTH - + RPC_PREAMBLE_CHKSUM_SIZE; - + public static final int RPC_PREAMBLE_SIZE = RpcPacket.RPC_LENGTH_FIELD_LENGTH + RPC_PREAMBLE_CHKSUM_SIZE; + private byte[] preLengthBytes = null; private byte[] preChksumBytes = null; - + /** * Calculate and construct a suitable preamble for the passed-in * payload buffer. Does not affect the incoming buffer at all (i.e. * marks and limits, etc. are unaffected). Assumes the payload starts at * buffer byte position zero and uses the buffer's limit as the length. - * + * * @param payload non-null byte buffer representing the payload * @return new RpcPacketPreamble for the payload */ - public static RpcPacketPreamble constructPreamble(ByteBuffer payload) { return new RpcPacketPreamble(payload.position()); } - + /** * Calculate and construct a suitable preamble for the passed-in * payload buffer length. + * + * @param payloadLength payloadLength + * @return RpcPacketPreamble */ - public static RpcPacketPreamble constructPreamble(int payloadLength) { return new RpcPacketPreamble(payloadLength); } - + /** * Retrieve a preamble from the passed-in payload byte buffer. Will move * the byte buffer pointer accordingly. - * + * * @param payload non-null payload * @return new RpcPacketPreamble as retrieved from the payload buffer. */ - public static RpcPacketPreamble retrievePreamble(ByteBuffer payload) { if (payload == null) { - throw new NullPointerError( - "Null payload buffer passed to RpcPacketPreamble.retrievePreamble()"); + throw new NullPointerError("Null payload buffer passed to RpcPacketPreamble.retrievePreamble()"); } - + byte[] bytes = new byte[RPC_PREAMBLE_SIZE]; - + try { payload.get(bytes); } catch (BufferUnderflowException bue) { throw new ProtocolError(bue.getLocalizedMessage(), bue); } - + return new RpcPacketPreamble(bytes); } - + /** * Retrieve the preamble from raw bytes. Most sanity checking is done in * the RpcPacketPreamble constructor. + * + * @param bytes bytes + * @return RpcPacketPreamble */ public static RpcPacketPreamble retrievePreamble(byte[] bytes) { return new RpcPacketPreamble(bytes); } - + /** * Construct a suitable preamble for the passed-in payload * buffer. - * + * * @param payload non-null byte buffer representing the payload - * to be preambleated. + * to be preambleated. */ - private RpcPacketPreamble(ByteBuffer payload) { if (payload == null) { - throw new NullPointerError( - "Null payload buffer passed to RpcPacketPreamble constructor"); + throw new NullPointerError("Null payload buffer passed to RpcPacketPreamble constructor"); } - + preChksumBytes = new byte[RPC_PREAMBLE_CHKSUM_SIZE]; preLengthBytes = RpcPacket.encodeInt4(payload.position()); - - preChksumBytes[0] = (byte) (preLengthBytes[0] - ^ preLengthBytes[1] - ^ preLengthBytes[2] - ^ preLengthBytes[3]); + + preChksumBytes[0] = (byte) (preLengthBytes[0] ^ preLengthBytes[1] ^ preLengthBytes[2] ^ preLengthBytes[3]); } - + /** * Construct a preamble for the passed-in payload length. + * + * @param length length */ - private RpcPacketPreamble(int length) { - + preChksumBytes = new byte[RPC_PREAMBLE_CHKSUM_SIZE]; preLengthBytes = RpcPacket.encodeInt4(length); - - preChksumBytes[0] = (byte) (preLengthBytes[0] - ^ preLengthBytes[1] - ^ preLengthBytes[2] - ^ preLengthBytes[3]); + + preChksumBytes[0] = (byte) (preLengthBytes[0] ^ preLengthBytes[1] ^ preLengthBytes[2] ^ preLengthBytes[3]); } - + /** * Construct a suitable preamble object by reading the raw values * from the passed-in byte array. - * + * * @param bytes non-null byte array exactly RPC_PREAMBLE_SIZE bytes long. */ - private RpcPacketPreamble(byte[] bytes) { if (bytes == null) { - throw new NullPointerError( - "Null payload bytes passed to RpcPacketPreamble constructor"); + throw new NullPointerError("Null payload bytes passed to RpcPacketPreamble constructor"); } - + if (bytes.length != RPC_PREAMBLE_SIZE) { - throw new P4JavaError( - "Incorrect byte array size passed to RpcPacketPreamble constructor: " - + bytes.length); + throw new P4JavaError("Incorrect byte array size passed to RpcPacketPreamble constructor: " + bytes.length); } - + this.preChksumBytes = new byte[RPC_PREAMBLE_CHKSUM_SIZE]; this.preChksumBytes[0] = bytes[0]; - + this.preLengthBytes = new byte[RpcPacket.RPC_LENGTH_FIELD_LENGTH]; - + for (int i = 0; i < RpcPacket.RPC_LENGTH_FIELD_LENGTH; i++) { this.preLengthBytes[i] = bytes[i + RPC_PREAMBLE_CHKSUM_SIZE]; } } - + /** * Return the payload size (in bytes) specified by this preamble. - * + * * @return the associated payload size in bytes. */ - public int getPayloadSize() { return RpcPacket.decodeInt4(preLengthBytes); } - + /** - * Return true iff the simple checksum checks out. + * @return true iff the simple checksum checks out. */ - public boolean isValidChecksum() { - return (preChksumBytes[0] == - (preLengthBytes[0] ^ preLengthBytes[1] ^ preLengthBytes[2] ^ preLengthBytes[3])); + return (preChksumBytes[0] == (preLengthBytes[0] ^ preLengthBytes[1] ^ preLengthBytes[2] ^ preLengthBytes[3])); } - + /** * Return a ByteBuffer representing the marshaled version * of this preamble. Buffer will need to be flipped before sending... - * + * * @return non-null ByteBuffer ready for sending */ public ByteBuffer marshal() { return ByteBuffer.allocate(RPC_PREAMBLE_SIZE).put(this.preChksumBytes).put(this.preLengthBytes); } - + public byte[] marshalAsBytes() { byte[] retVal = new byte[RPC_PREAMBLE_SIZE]; retVal[0] = this.preChksumBytes[0]; for (int i = 0; i < RpcPacket.RPC_LENGTH_FIELD_LENGTH; i++) { - retVal[i+1] = this.preLengthBytes[i]; + retVal[i + 1] = this.preLengthBytes[i]; } - + return retVal; } } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/packet/helper/RpcPacketFieldRule.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/packet/helper/RpcPacketFieldRule.java index a870838..94fee3e 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/packet/helper/RpcPacketFieldRule.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/packet/helper/RpcPacketFieldRule.java @@ -8,20 +8,26 @@ /** * Super class representing the rule for skipping the charset conversion of the * RPC packet field values (bytes). Leave those field values as bytes instead of - * converting them to strings.

+ * converting them to strings. */ public abstract class RpcPacketFieldRule { - /** The key for storing the field pattern in a command map. */ + /** + * The key for storing the field pattern in a command map. + */ public static final String FIELD_PATTERN = "fieldPattern"; - - /** The key for storing the start field name in a command map. */ + + /** + * The key for storing the start field name in a command map. + */ public static final String START_FIELD = "startField"; - /** The key for storing the stop field name in a command map. */ + /** + * The key for storing the stop field name in a command map. + */ public static final String STOP_FIELD = "stopField"; - + /** * If true, skip charset conversion; leave the value as is in bytes. */ @@ -30,40 +36,39 @@ public abstract class RpcPacketFieldRule { /** * Factory static method to create an instance of a subclass based on the * content of a command map. Note that the instance creation will be - * processed in the order listed below.

- * + * processed in the order listed below. + *

* The existing of a FIELD_PATTERN key with a string value will create a - * RpcPacketFieldPatternRule object.

- * + * RpcPacketFieldPatternRule object. + *

* The existing of both the START_FIELD and STOP_FIELD keys with string * values will create a RpcPacketFieldRangeRule object. + * + * @param cmdMap cmdMap + * @return RpcPacketFieldRule */ public static RpcPacketFieldRule getInstance(Map cmdMap) { if (cmdMap.containsKey(FIELD_PATTERN)) { - return new RpcPacketFieldPatternRule( - (String) cmdMap.get(FIELD_PATTERN)); + return new RpcPacketFieldPatternRule((String) cmdMap.get(FIELD_PATTERN)); } if (cmdMap.containsKey(START_FIELD) && cmdMap.containsKey(STOP_FIELD)) { - return new RpcPacketFieldRangeRule( - (String) cmdMap.get(START_FIELD), - (String) cmdMap.get(STOP_FIELD)); + return new RpcPacketFieldRangeRule((String) cmdMap.get(START_FIELD), (String) cmdMap.get(STOP_FIELD)); } return null; } - + /** * Updates the conversion rule. - * - * @param fieldName - * the field name + * + * @param fieldName the field name */ public abstract void update(String fieldName); /** * Checks if is skip conversion. - * + * * @return true, if is skip conversion */ public boolean isSkipConversion() { diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/stream/RpcGZIPInputStream.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/stream/RpcGZIPInputStream.java index b4358e1..0a3751e 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/stream/RpcGZIPInputStream.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/stream/RpcGZIPInputStream.java @@ -5,32 +5,33 @@ import java.io.IOException; import java.io.InputStream; -import java.util.zip.InflaterInputStream; -import com.jcraft.jzlib.ZInputStream; +import com.jcraft.jzlib.InflaterInputStream; + +import com.jcraft.jzlib.Inflater; import com.perforce.p4java.exception.NullPointerError; import com.perforce.p4java.exception.P4JavaError; import com.perforce.p4java.exception.UnimplementedError; /** - * A lightweight wrapper around the JZlib GZIP input stream for + * A lightweight wrapper around the JZlib ZIP input stream for * processing compressed streams being sent from Perforce servers - * when the client "client compress" mode is enabled.

- * + * when the client "client compress" mode is enabled. + *

* Note that the Perforce version of the GZIP stream dispenses with * headers and trailers, but is otherwise fairly standard (which is why * this works). */ public class RpcGZIPInputStream extends InflaterInputStream { - - private ZInputStream jzInStream = null; - + + private InflaterInputStream jzInStream = null; + public RpcGZIPInputStream(InputStream in) throws IOException { super(in); - this.jzInStream = new ZInputStream(in, true); + this.jzInStream = new InflaterInputStream(in, new Inflater(true)); } - + @Override public int read(byte[] bytes) throws IOException { if (bytes == null) { @@ -39,7 +40,7 @@ public int read(byte[] bytes) throws IOException { } return read(bytes, 0, bytes.length); } - + @Override public int read(byte[] bytes, int offset, int len) throws IOException { if (bytes == null) { @@ -52,15 +53,15 @@ public int read(byte[] bytes, int offset, int len) throws IOException { } return this.jzInStream.read(bytes, offset, len); } - + @Override public int read() throws IOException { // NOTE: exception is here out of curiosity -- this shouldn't be // called from anywhere -- HR. - + throw new UnimplementedError("single-byte RpcGZIPInputStream.read()"); } - + @Override public void close() throws IOException { this.jzInStream.close(); diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/stream/RpcGZIPOutputStream.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/stream/RpcGZIPOutputStream.java index c944050..edc706e 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/stream/RpcGZIPOutputStream.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/stream/RpcGZIPOutputStream.java @@ -3,16 +3,16 @@ */ package com.perforce.p4java.impl.mapbased.rpc.stream; -import java.io.FilterOutputStream; -import java.io.IOException; -import java.io.OutputStream; - +import com.jcraft.jzlib.Deflater; import com.jcraft.jzlib.JZlib; -import com.jcraft.jzlib.ZStream; import com.perforce.p4java.exception.NullPointerError; import com.perforce.p4java.exception.P4JavaError; import com.perforce.p4java.exception.UnimplementedError; +import java.io.FilterOutputStream; +import java.io.IOException; +import java.io.OutputStream; + /** * A fairly lightweight filter output stream that implements Perforce's @@ -46,12 +46,12 @@ public class RpcGZIPOutputStream extends FilterOutputStream { private static final int ZBITS = 15; // Don't change this, it's fundamental... private static final int ZBUF_SIZE = 10240; // Might want to play with this a bit... - private ZStream jzOutputSream = null; + private Deflater jzOutputSream = null; private byte[] jzBytes = null; public RpcGZIPOutputStream(OutputStream out) throws IOException { super(out); - this.jzOutputSream = new ZStream(); + this.jzOutputSream = new Deflater(); this.jzOutputSream.deflateInit(JZlib.Z_DEFAULT_COMPRESSION, ZBITS, true); this.jzBytes = new byte[ZBUF_SIZE]; this.jzOutputSream.next_out = this.jzBytes; @@ -171,6 +171,7 @@ public void flush() throws IOException { done = true; } } + this.out.flush(); } /** @@ -184,11 +185,14 @@ public void flush() throws IOException { public void close() throws IOException { this.jzOutputSream.deflateEnd(); } - + /** - * Provide a more human-readable form of the underlying JZlib compression errors.

- * + * Provide a more human-readable form of the underlying JZlib compression errors. + *

* Should be made even more human-readable sometime later -- HR. + * + * @param errNum errNum + * @return error message */ protected String getJZlibErrorStr(int errNum) { switch (errNum) { diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/stream/RpcRshInputStream.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/stream/RpcRshInputStream.java index bec96dd..66233d0 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/stream/RpcRshInputStream.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/stream/RpcRshInputStream.java @@ -3,130 +3,123 @@ */ package com.perforce.p4java.impl.mapbased.rpc.stream; -import java.io.IOException; -import java.io.InputStream; - import com.perforce.p4java.exception.NullPointerError; import com.perforce.p4java.impl.mapbased.rpc.ServerStats; +import java.io.IOException; +import java.io.InputStream; + /** - * Implements the lowest level of the P4Java RPC 'rsh' input stream architecture.

- * + * Implements the lowest level of the P4Java RPC 'rsh' input stream architecture. + *

* This class does the most basic conversion from incoming bytes on the (TCP/IP) - * wire to a Java IO input stream whose contents are further decoded upstream.

+ * wire to a Java IO input stream whose contents are further decoded upstream. */ - public class RpcRshInputStream extends InputStream { public static final String TRACE_PREFIX = "RpcRshInputStream"; - + private InputStream rshStream = null; private ServerStats stats = null; - + /** * Construct a suitable stream for the passed-in inputstream. No assumptions * are made about the passed-in inputstream except that a) it's not null, and * b) it's been initialized and set up for reading by the caller. - * + * * @param inputstream non-null InputStream - * @param stats non-null ServerStats + * @param stats non-null ServerStats */ public RpcRshInputStream(InputStream inputstream, ServerStats stats) { super(); if (inputstream == null) { - throw new NullPointerError( - "null inputstream passed to RpcRshInputStream constructor"); + throw new NullPointerError("null inputstream passed to RpcRshInputStream constructor"); } this.stats = stats; this.rshStream = inputstream; } - + @Override public int read() throws IOException { if (this.rshStream == null) { - throw new NullPointerError( - "null socket stream in RpcRshInputStream.read()"); + throw new NullPointerError("null socket stream in RpcRshInputStream.read()"); } - + int retVal = this.rshStream.read(); - + if ((stats != null) && (stats.largestRecv.get() < retVal)) { stats.largestRecv.set(retVal); } return retVal; } - + @Override public int read(byte[] bytes) throws IOException { if (this.rshStream == null) { - throw new NullPointerError( - "null socket stream in RpcRshInputStream.read()"); + throw new NullPointerError("null socket stream in RpcRshInputStream.read()"); } if (bytes == null) { - throw new NullPointerError( - "null byte array in RpcRshInputStream.read()"); + throw new NullPointerError("null byte array in RpcRshInputStream.read()"); } int retVal = this.rshStream.read(bytes); - + if ((stats != null) && (stats.largestRecv.get() < retVal)) { stats.largestRecv.set(retVal); } return retVal; } - + @Override public int read(byte[] bytes, int offset, int len) throws IOException { if (this.rshStream == null) { - throw new NullPointerError( - "null rsh stream in RpcRshInputStream.read()"); + throw new NullPointerError("null rsh stream in RpcRshInputStream.read()"); } if (bytes == null) { - throw new NullPointerError( - "null byte array in RpcRshInputStream.read()"); + throw new NullPointerError("null byte array in RpcRshInputStream.read()"); } int retVal = this.rshStream.read(bytes, offset, len); - + if ((stats != null) && (stats.largestRecv.get() < retVal)) { stats.largestRecv.set(retVal); } return retVal; } - @Override - public long skip(long n) throws IOException { - return this.rshStream.skip(n); - } - - @Override - public int available() throws IOException { - return this.rshStream.available(); - } - - @Override - public void close() throws IOException { - this.rshStream.close(); - } - - @Override - public synchronized void mark(int readlimit) { - this.rshStream.mark(readlimit); - } - - @Override - public synchronized void reset() throws IOException { - this.rshStream.reset(); - } - - @Override - public boolean markSupported() { - return rshStream.markSupported(); - } - - @Override - public String toString() { - return "RpcRshInputStream[" + this.rshStream + ']'; - } - + @Override + public long skip(long n) throws IOException { + return this.rshStream.skip(n); + } + + @Override + public int available() throws IOException { + return this.rshStream.available(); + } + + @Override + public void close() throws IOException { + this.rshStream.close(); + } + + @Override + public synchronized void mark(int readlimit) { + this.rshStream.mark(readlimit); + } + + @Override + public synchronized void reset() throws IOException { + this.rshStream.reset(); + } + + @Override + public boolean markSupported() { + return rshStream.markSupported(); + } + + @Override + public String toString() { + return "RpcRshInputStream[" + this.rshStream + ']'; + } + protected InputStream getRshStream() { return this.rshStream; } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/stream/RpcRshOutputStream.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/stream/RpcRshOutputStream.java index 3a99eb1..79aefb5 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/stream/RpcRshOutputStream.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/stream/RpcRshOutputStream.java @@ -13,9 +13,8 @@ * Implements the lowest level of the P4Java RPC 'rsh' output stream architecture.

* * This class does the most basic conversion of outgoing bytes to the (TCP/IP) - * wire from a Java IO output stream whose contents have been encoded upstream.

+ * wire from a Java IO output stream whose contents have been encoded upstream. */ - public class RpcRshOutputStream extends OutputStream { public static final String TRACE_PREFIX = "RpcRshOutputStream"; diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/stream/RpcSSLSocketFactory.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/stream/RpcSSLSocketFactory.java index 23a4240..6937558 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/stream/RpcSSLSocketFactory.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/stream/RpcSSLSocketFactory.java @@ -46,6 +46,7 @@ private RpcSSLSocketFactory(Properties properties) { /** * Gets the single instance of RpcSSLSocketFactory. * + * @param properties properties * @return single instance of RpcSSLSocketFactory */ public static synchronized RpcSSLSocketFactory getInstance(Properties properties) { diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/stream/RpcSocketInputStream.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/stream/RpcSocketInputStream.java index 7b2cb5f..12c8434 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/stream/RpcSocketInputStream.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/stream/RpcSocketInputStream.java @@ -3,20 +3,20 @@ */ package com.perforce.p4java.impl.mapbased.rpc.stream; -import java.io.IOException; -import java.io.InputStream; -import java.net.Socket; - import com.perforce.p4java.Log; import com.perforce.p4java.exception.NullPointerError; import com.perforce.p4java.exception.P4JavaError; import com.perforce.p4java.impl.mapbased.rpc.ServerStats; +import java.io.IOException; +import java.io.InputStream; +import java.net.Socket; + /** * Implements the lowest level of the P4Java RPC input socket stream architecture.

* * This class does the most basic conversion from incoming bytes on the (TCP/IP) - * wire to a Java IO input stream whose contents are further decoded upstream.

+ * wire to a Java IO input stream whose contents are further decoded upstream. */ public class RpcSocketInputStream extends InputStream { @@ -26,14 +26,15 @@ public class RpcSocketInputStream extends InputStream { private Socket socket = null; private InputStream socketStream = null; private ServerStats stats = null; - + /** * Construct a suitable stream for the passed-in socket. No assumptions * are made about the passed-in socket except that a) it's not null, and * b) it's been initialized and set up for reading (or at least the successful * retrieval of a suitable input stream) by the caller. - * + * * @param socket non-null socket + * @param stats stats */ public RpcSocketInputStream(Socket socket, ServerStats stats) { super(); diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/stream/RpcSocketOutputStream.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/stream/RpcSocketOutputStream.java index 2371d56..6562fc7 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/stream/RpcSocketOutputStream.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/stream/RpcSocketOutputStream.java @@ -3,107 +3,102 @@ */ package com.perforce.p4java.impl.mapbased.rpc.stream; -import java.io.IOException; -import java.io.OutputStream; -import java.net.Socket; - import com.perforce.p4java.Log; import com.perforce.p4java.exception.NullPointerError; import com.perforce.p4java.exception.P4JavaError; import com.perforce.p4java.impl.mapbased.rpc.ServerStats; +import java.io.IOException; +import java.io.OutputStream; +import java.net.Socket; + /** - * Implements the lowest level of the P4Java RPC output stream architecture.

- * + * Implements the lowest level of the P4Java RPC output stream architecture. + *

* This class does the most basic conversion of outgoing bytes to the (TCP/IP) - * wire from a Java IO output stream whose contents have been encoded upstream.

+ * wire from a Java IO output stream whose contents have been encoded upstream. */ public class RpcSocketOutputStream extends OutputStream { public static final String TRACE_PREFIX = "RpcSocketOutputStream"; - + private Socket socket = null; private OutputStream socketStream = null; private ServerStats stats = null; - + /** * Construct a suitable stream for the passed-in socket. No assumptions * are made about the passed-in socket except that a) it's not null, and * b) it's been initialized and set up for reading (or at least the successful * retrieval of a suitable input stream) by the caller. - * + * * @param socket non-null socket + * @param stats stats */ public RpcSocketOutputStream(Socket socket, ServerStats stats) { super(); if (socket == null) { - throw new NullPointerError( - "null RPC socket passed to RpcSocketInputStream constructor"); + throw new NullPointerError("null RPC socket passed to RpcSocketInputStream constructor"); } this.socket = socket; this.stats = stats; try { this.socketStream = socket.getOutputStream(); } catch (IOException ioexc) { - Log.error("Unexpected I/O exception thrown during output stream retrieval" - + " in RpcSocketInputStream constructor: " + ioexc.getLocalizedMessage()); + Log.error("Unexpected I/O exception thrown during output stream retrieval" + " in RpcSocketInputStream constructor: " + ioexc.getLocalizedMessage()); Log.exception(ioexc); - throw new P4JavaError( - "Unexpected I/O exception thrown during output stream retrieval" - + " in RpcSocketInputStream constructor: " + ioexc.getLocalizedMessage()); + throw new P4JavaError("Unexpected I/O exception thrown during output stream retrieval" + " in RpcSocketInputStream constructor: " + ioexc.getLocalizedMessage()); } } @Override public void write(int b) throws IOException { if (this.socketStream == null) { - throw new NullPointerError( - "null socket stream in RpcSocketOutputStream.write()"); + throw new NullPointerError("null socket stream in RpcSocketOutputStream.write()"); } this.socketStream.write(b); } - + @Override public void write(byte[] bytes) throws IOException { if (this.socketStream == null) { - throw new NullPointerError( - "null socket stream in RpcSocketOutputStream.write()"); + throw new NullPointerError("null socket stream in RpcSocketOutputStream.write()"); } if (bytes == null) { - throw new NullPointerError( - "null byte array in RpcSocketOutputStream.write()"); + throw new NullPointerError("null byte array in RpcSocketOutputStream.write()"); } if ((stats != null) && (stats.largestSend.get() < bytes.length)) { stats.largestSend.set(bytes.length); } this.socketStream.write(bytes); } - + @Override public void write(byte[] bytes, int offset, int len) throws IOException { if (this.socketStream == null) { - throw new NullPointerError( - "null socket stream in RpcSocketOutputStream.write()"); + throw new NullPointerError("null socket stream in RpcSocketOutputStream.write()"); } if (bytes == null) { - throw new NullPointerError( - "null byte array in RpcSocketOutputStream.write()"); + throw new NullPointerError("null byte array in RpcSocketOutputStream.write()"); } if ((stats != null) && (stats.largestSend.get() < len)) { stats.largestSend.set(len); } this.socketStream.write(bytes, offset, len); } - + protected Socket getSocket() { return this.socket; } + protected void setSocket(Socket socket) { this.socket = socket; } + protected OutputStream getSocketStream() { return this.socketStream; } + protected void setSocketStream(OutputStream socketStream) { this.socketStream = socketStream; } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/stream/RpcSocketPool.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/stream/RpcSocketPool.java index c82cb2a..6c798d9 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/stream/RpcSocketPool.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/stream/RpcSocketPool.java @@ -18,7 +18,7 @@ * @author Kevin Sawicki (ksawicki@perforce.com) */ public class RpcSocketPool { - + /** * Shutdown handler for cleaning up before a socket is closed */ @@ -27,8 +27,8 @@ public static interface ShutdownHandler { /** * Callback for before the socket is closed to do any pre-close work. * Implementors should not directly close the socket parameter. - * - * @param socket + * + * @param socket socket */ void shutdown(Socket socket); @@ -37,7 +37,6 @@ public static interface ShutdownHandler { /** * Pool manager that closes sockets that have been left open for more than * the idle time allowed. - * */ private static class PoolManager implements Runnable { @@ -120,8 +119,7 @@ public void run() { } RpcSocketPool[] pools = null; synchronized (this) { - pools = this.pools.toArray(new RpcSocketPool[this.pools - .size()]); + pools = this.pools.toArray(new RpcSocketPool[this.pools.size()]); } for (RpcSocketPool pool : pools) { pool.timeout(this.idleTime); @@ -144,8 +142,8 @@ private class SocketEntry { /** * Create a new socket entry with the specified socket with a release * time of the current system time - * - * @param socket + * + * @param socket socket */ public SocketEntry(Socket socket) { this.socket = socket; @@ -160,20 +158,18 @@ public SocketEntry(Socket socket) { private ShutdownHandler shutdownHandler; private Queue pool; private boolean secure = false; - + /** * Create a new socket pool indicating whether it is secure (SSL) or not. - * - * @param poolSize - * @param host - * @param port - * @param socketProperties - * @param shutdownHandler - * @param secure + * + * @param poolSize poolSize + * @param host host + * @param port port + * @param socketProperties socketProperties + * @param shutdownHandler shutdownHandler + * @param secure secure */ - public RpcSocketPool(int poolSize, String host, int port, - Properties socketProperties, ShutdownHandler shutdownHandler, - boolean secure) { + public RpcSocketPool(int poolSize, String host, int port, Properties socketProperties, ShutdownHandler shutdownHandler, boolean secure) { this(poolSize, host, port, socketProperties, shutdownHandler); this.secure = secure; } @@ -181,15 +177,14 @@ public RpcSocketPool(int poolSize, String host, int port, /** * Create a new socket pool with a max pool size, host, port, and socket * properties, and an optional shutdown handler - * - * @param poolSize - * @param host - * @param port - * @param socketProperties - * @param shutdownHandler + * + * @param poolSize poolSize + * @param host host + * @param port port + * @param socketProperties socketProperties + * @param shutdownHandler shutdownHandler */ - public RpcSocketPool(int poolSize, String host, int port, - Properties socketProperties, ShutdownHandler shutdownHandler) { + public RpcSocketPool(int poolSize, String host, int port, Properties socketProperties, ShutdownHandler shutdownHandler) { this.size = poolSize; this.host = host; this.port = port; @@ -201,9 +196,9 @@ public RpcSocketPool(int poolSize, String host, int port, /** * Acquire a socket to the configured server address - * + * * @return - socket - * @throws IOException + * @throws IOException on error */ public Socket acquire() throws IOException { Socket socket = null; @@ -238,20 +233,17 @@ private void quietClose(Socket socket) { } private boolean isAlive(Socket socket) { - return socket != null && socket.isBound() && !socket.isClosed() - && socket.isConnected() && !socket.isInputShutdown() - && !socket.isOutputShutdown(); + return socket != null && socket.isBound() && !socket.isClosed() && socket.isConnected() && !socket.isInputShutdown() && !socket.isOutputShutdown(); } /** * Release a socket back to the pool as no longer using - * - * @param socket - * @param shutdownHandler - * @throws IOException + * + * @param socket socket + * @param shutdownHandler shutdownHandler + * @throws IOException on error */ - public void release(Socket socket, ShutdownHandler shutdownHandler) - throws IOException { + public void release(Socket socket, ShutdownHandler shutdownHandler) throws IOException { if (isAlive(socket)) { boolean close = false; synchronized (this.pool) { @@ -321,8 +313,8 @@ public void disconnect() { /** * Timeout any sockets idle for greater than or equal to the milliseconds * value specified - * - * @param idleDuration + * + * @param idleDuration idleDuration */ public void timeout(int idleDuration) { synchronized (this.pool) { diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/stream/RpcStreamConnection.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/stream/RpcStreamConnection.java index 93eec60..ae3fb34 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/stream/RpcStreamConnection.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/stream/RpcStreamConnection.java @@ -38,7 +38,6 @@ import java.net.UnknownHostException; import java.security.NoSuchAlgorithmException; import java.security.PublicKey; -import java.security.cert.Certificate; import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateNotYetValidException; import java.security.cert.X509Certificate; @@ -60,689 +59,669 @@ /** * Socket stream I/O based implementation of the RpcConnection class. *

- * * The implementation here uses a small stack of input and output streams based * on socket streams at the lowest level, with (at least) an optional connection * compression stream on top of that layer, and with charset conversion where * necessary. - *

*/ public class RpcStreamConnection extends RpcConnection { - public static final String TRACE_PREFIX = "RpcStreamConnection"; - - /** - * Number of bytes we allocate for initial byte arrays for sending RPC - * packets. In general we don't know how big the final buffer is, so this - * figure is a bit of a guessed compromise between over-allocation and - * frequent resizing. - */ - protected static final int INITIAL_SENDBUF_SIZE = 2048; - - /** - * When we run out of send buffer space in putPacket, we allocate another, - * larger, buffer; this constant determines how much larger than the - * existing buffer the new one should be, or, alternatively, how much bigger - * than the incoming field length the new buffer should be. Should probably - * be more tunable... - */ - protected static final int SENDBUF_REALLOC_INCR = 1024; - - private RpcSocketPool pool = null; - private Socket socket = null; - private InputStream inputStream = null; - private OutputStream outputStream = null; - private InputStream topInputStream = null; - private OutputStream topOutputStream = null; - - // 'rsh' mode server launch command - private String rsh = null; - - /** - * Construct a new Perforce RPC connection to the named Perforce server - * using java.io socket streams at the lowest level. This constructor sets - * up the default non-compressed stack; in general this means just a couple - * of simple socket streams. - */ - public RpcStreamConnection(String serverHost, int serverPort, Properties props, - ServerStats stats, P4Charset p4Charset, boolean secure) throws ConnectionException { - this(serverHost, serverPort, props, stats, p4Charset, (Socket) null, secure); - } - - /** - * Construct a new Perforce RPC connection to the named Perforce server - * using java.io socket streams at the lowest level. This constructor sets - * up the default non-compressed stack; in general this means just a couple - * of simple socket streams. - */ - private RpcStreamConnection(String serverHost, int serverPort, Properties props, - ServerStats stats, P4Charset p4Charset, Socket socket, boolean secure) - throws ConnectionException { - this(serverHost, serverPort, props, stats, p4Charset, socket, null, secure); - } - - /** - * Construct a new Perforce RPC connection to the named Perforce server - * using java.io socket streams at the lowest level. This constructor sets - * up the default non-compressed stack; in general this means just a couple - * of simple socket streams. - */ - private RpcStreamConnection(String serverHost, int serverPort, Properties props, - ServerStats stats, P4Charset p4Charset, Socket socket, RpcSocketPool pool, boolean secure) - throws ConnectionException { - this(serverHost, serverPort, props, stats, p4Charset, socket, pool, secure, null); - } - - /** - * Construct a new Perforce RPC connection to the named Perforce server - * using java.io socket streams at the lowest level. This constructor sets - * up the default non-compressed stack; in general this means just a couple - * of simple socket streams. - */ - public RpcStreamConnection(String serverHost, int serverPort, Properties props, - ServerStats stats, P4Charset p4Charset, Socket socket, RpcSocketPool pool, boolean secure, - String rsh) throws ConnectionException { - super(serverHost, serverPort, props, stats, p4Charset, secure); - this.socket = socket; - this.pool = pool; - this.rsh = rsh; - init(); - } - - /** - * Initialize actual connection to the server. - */ - private void init() throws ConnectionException { - if (isNotBlank(rsh)) { - initRshModeServer(); - } else { - initSocketBasedServer(); - } - - topInputStream = inputStream; - topOutputStream = outputStream; - } - - private void initRshModeServer() throws ConnectionException { - try { - String[] command = new String[] { Server.isRunningOnWindows() ? "cmd.exe" : "/bin/sh", - Server.isRunningOnWindows() ? "/c" : "-c", rsh }; - - ProcessBuilder builder = new ProcessBuilder(command); - // builder.redirectErrorStream(true); // redirect error stream to - // output stream - Process process = builder.start(); - InputStream in = process.getInputStream(); - OutputStream out = process.getOutputStream(); - // InputStream err = process.getErrorStream(); - - inputStream = new RpcRshInputStream(in, stats); - outputStream = new RpcRshOutputStream(out, stats); - } catch (Throwable thr) { - Log.error("Unexpected exception: %s", thr.getLocalizedMessage()); - Log.exception(thr); - throwConnectionException(thr); - } - } - - private void initSocketBasedServer() throws ConnectionException { - try { - if (isNull(socket)) { - if (nonNull(pool)) { - socket = pool.acquire(); - } else { - socket = RpcSocketHelper.createSocket(hostName, hostPort, props, secure); - } - } - } catch (UnknownHostException exc) { - throwConnectionException(exc, - "Unable to resolve Perforce server host name '%s' for RPC connection", - hostName); - } catch (IOException exc) { - throwConnectionException(exc, "Unable to connect to Perforce server at %s:%s", hostName, - hostPort); - } catch (Throwable thr) { - Log.error("Unexpected exception: %s", thr.getLocalizedMessage()); - Log.exception(thr); - throwConnectionException(thr); - } - - getIpAddressFromSocketConnection(); - - // Initialize SSL connection - if (secure) { - initSSL(); - } - - initRpcSocketInputAndOutputStreamIfSocketBasedServer(); - } - - private void getIpAddressFromSocketConnection() { - if (nonNull(socket)) { - InetAddress inetAddress = socket.getInetAddress(); - if (nonNull(inetAddress)) { - // Check if it is an IPv6 address - String hostAddress = inetAddress.getHostAddress(); - if (Inet6Address.class.isAssignableFrom(inetAddress.getClass())) { - // Add the square brackets for IPv6 address - hostIp = "[" + hostAddress + "]"; - } else { - hostIp = hostAddress; - } - } - if (socket.isBound()) { - InetAddress address = socket.getLocalAddress(); - // Check if it is an IPv6 address - if (Inet6Address.class.isAssignableFrom(address.getClass())) { - // Add the square brackets for IPv6 address - this.ourIp = "[" + address.getHostAddress() + "]"; - } else { - this.ourIp = address.getHostAddress(); - } - this.ourPort = socket.getLocalPort(); - } - } - } - - private void initSSL() throws ConnectionException { - // Start SSL handshake - if (nonNull(socket)) { - try { - // The SSLSocket.getSession() method will initiate the initial - // handshake if necessary. Thus, the SSLSocket.startHandshake() - // call is not necessary. - SSLSession sslSession = ((SSLSocket) socket).getSession(); - - /* - * If an error occurs during the initial handshake, this method - * returns an invalid session object which reports an invalid - * cipher suite of "SSL_NULL_WITH_NULL_NULL". - */ - throwConnectionExceptionIfConditionFails(sslSession.isValid(), - "Error occurred during the SSL handshake: invalid SSL session"); - - // Get the certificates - serverCerts = sslSession.getPeerCertificates(); - - throwConnectionExceptionIfConditionFails( - nonNull(serverCerts) && (serverCerts.length != 0) - && nonNull(serverCerts[0]), - "Error occurred during the SSL handshake: no certificate retrieved from SSL session"); - - X509Certificate siteCert = (X509Certificate) serverCerts[0]; - - // Check that the certificate is currently valid. Check the - // current date and time are within the validity period given - // in the certificate. - siteCert.checkValidity(); - - // Get the public key from the first certificate - PublicKey serverPubKey = siteCert.getPublicKey(); - throwConnectionExceptionIfConditionFails(nonNull(serverPubKey), - "Error occurred during the SSL handshake: no public key retrieved from server certificate"); - - // check if it's a self signed cert. - selfSigned = siteCert.getSubjectDN().getName().equals(siteCert.getIssuerDN().getName()); - - // Generate the fingerprint - fingerprint = ClientTrust.generateFingerprint(serverPubKey); - - } catch (CertificateExpiredException e) { - throwConnectionException(e, - "Error occurred during the SSL handshake: certificate expired:"); - } catch (CertificateNotYetValidException e) { - throwConnectionException(e, - "Error occurred during the SSL handshake: certificate not yet valid"); - } catch (NoSuchAlgorithmException e) { - throwConnectionException(e, - "Error occurred while generating the fingerprint for the Perforce SSL connection"); - } catch (IOException e) { - String errorMessage = format( - "Error occurred during SSL hankshake. Please check the release notes for known SSL issues"); - Log.error(errorMessage); - Log.exception(e); - throwConnectionException(e, errorMessage); - } - } - } - - private void initRpcSocketInputAndOutputStreamIfSocketBasedServer() throws ConnectionException { - try { - inputStream = new RpcSocketInputStream(socket, stats); - outputStream = new RpcSocketOutputStream(socket, stats); - } catch (Throwable thr) { - Log.error("Unexpected exception: %s", thr.getLocalizedMessage()); - Log.exception(thr); - throwConnectionException(thr); - } - } - - public String getServerIpPort() { - String serverIpPort = null; - if (!StringUtils.equals(hostIp, UNKNOWN_SERVER_HOST)) { - serverIpPort = hostIp; - if (hostPort != UNKNOWN_SERVER_PORT) { - serverIpPort += ":" + String.valueOf(hostPort); - } - } else if (hostPort != UNKNOWN_SERVER_PORT) { - serverIpPort = Integer.toString(hostPort); - } - return serverIpPort; - } - - public String getServerHostNamePort() { - return hostName + ":" + String.valueOf(hostPort); - } - /** - * @see com.perforce.p4java.impl.mapbased.rpc.connection.RpcConnection#getClientIpPort() - */ - public String getClientIpPort() { - String clientIpPort = null; - if (this.ourIp != UNKNOWN_SERVER_HOST) { - clientIpPort = this.ourIp; - if (this.ourPort != UNKNOWN_SERVER_PORT) { - clientIpPort += ":" + Integer.toString(this.ourPort); - } - } else if (this.ourPort != UNKNOWN_SERVER_PORT) { - clientIpPort = Integer.toString(this.ourPort); - } - return clientIpPort; - } - - public void disconnect(final RpcPacketDispatcher dispatcher) throws ConnectionException { - try { - // NOTE: don't do gratuitous (any) flushes here -- this has all been - // handled already and will often cause errors in compressed client - // connection setups -- HR. - ShutdownHandler handler = new ShutdownHandler() { - @Override - public void shutdown(Socket theSocket) { - if (nonNull(dispatcher)) { - try { - dispatcher.shutdown(RpcStreamConnection.this); - } catch (ConnectionException e) { - Log.exception(e); - } - } - } - }; - // Handle 'rsh' mode server shutdown - if (isNotBlank(rsh)) { - try { - dispatcher.shutdown(RpcStreamConnection.this); - } catch (ConnectionException e) { - Log.exception(e); - } - topInputStream.close(); - topOutputStream.close(); - } else { - if (nonNull(pool)) { - pool.release(socket, handler); - } else { - handler.shutdown(socket); - topInputStream.close(); - topOutputStream.close(); - if (nonNull(socket)) { - socket.close(); - } - } - } - } catch (IOException exc) { - throwConnectionException(exc, "RPC disconnection error: %s", exc.getLocalizedMessage()); - } - } - - /** - * Get a Perforce RPC packet from the underlying stream. If we're talking to - * a Unicode-enabled Perforce server, we attempt to translate the incoming - * bytes to the relevant client-side charsets where appropriate based on - * packet field type, etc. - */ - public RpcPacket getRpcPacket() throws ConnectionException { - return getRpcPacket(null, null); - } - - /** - * Get a Perforce RPC packet from the underlying stream with an optional - * rule to handle the RPC packet fields. - */ - public RpcPacket getRpcPacket(final RpcPacketFieldRule fieldRule, - final IFilterCallback filterCallback) throws ConnectionException { - byte[] preambleBytes = new byte[RpcPacketPreamble.RPC_PREAMBLE_SIZE]; - RpcPacket packet = null; - - try { - int bytesRead = topInputStream.read(preambleBytes); - throwConnectionExceptionIfConditionFails(bytesRead >= 0, - "server connection unexpectedly closed"); - AtomicLong streamRecvs = stats.streamRecvs; - streamRecvs.incrementAndGet(); - - bytesRead = continueReadIfGetPartialRead(preambleBytes, bytesRead, streamRecvs); - throwConnectionExceptionIfConditionFails(bytesRead == preambleBytes.length, - "Incomplete RPC packet preamble read from Perforce server; connection probably broken. bytes read: %s", - bytesRead); - stats.totalBytesRecv.getAndAdd(bytesRead); - - RpcPacketPreamble preamble = RpcPacketPreamble.retrievePreamble(preambleBytes); - throwProtocolErrorIfConditionFails(preamble.isValidChecksum(), - "Bad checksum in RPC preamble"); - - int payloadLength = preamble.getPayloadSize(); // Note: size is for - // the *rest of the - // packet*... - // FIXME: really should sanity check the size better here -- HR. - throwProtocolErrorIfConditionFails(payloadLength > 0, - "Bad payload size in RPC preamble: %s", payloadLength); - - // We know how many bytes to expect for the rest of this packet, so - // try to read this in. This can be a ginormous packet in some - // pathological - // cases, so we need to be flexible... - byte[] packetBytes = new byte[payloadLength]; - int packetBytesRead = topInputStream.read(packetBytes, 0, payloadLength); - throwConnectionExceptionIfConditionFails(packetBytesRead > 0, - "Perforce server network connection closed unexpectedly"); - streamRecvs.incrementAndGet(); - stats.totalBytesRecv.getAndAdd(packetBytesRead); - - packetBytesRead = continueReadIfIncompleteRead(streamRecvs, payloadLength, packetBytes, - packetBytesRead); - throwP4JavaErrorIfConditionFails(packetBytesRead == payloadLength, - "RPC packet payload read size mismatch; expected: %s; got: %s", payloadLength, - packetBytesRead); - - packet = RpcPacket.constructRpcPacket(preamble, packetBytes, unicodeServer, - p4Charset.getCharset(), fieldRule, filterCallback); - stats.packetsRecv.incrementAndGet(); - stats.largestRpcPacketRecv - .set(Math.max(stats.largestRpcPacketRecv.get(), packet.getPacketLength())); - } catch (IOException exc) { - throwConnectionException(exc); - } catch (ConnectionException | P4JavaError p4jexc) { - throw p4jexc; - } catch (Throwable thr) { - // Never a good sign; typically a buffer overflow or positioning - // problem, and almost always unrecoverable. - Log.error("Unexpected exception: %s", thr.getLocalizedMessage()); - Log.exception(thr); - throwP4JavaError(thr, thr.getLocalizedMessage()); - } - - return packet; - } - - /** - * If we get a partial read, try again until something goes wrong... - */ - private int continueReadIfGetPartialRead(@Nonnull final byte[] preambleBytes, - final int bytesRead, @Nonnull final AtomicLong streamRecvs) - throws IOException, ConnectionException { - int totalBytesRead = bytesRead; - while ((totalBytesRead >= 0) && (totalBytesRead < preambleBytes.length)) { - int moreBytesRead = topInputStream.read(preambleBytes, totalBytesRead, - preambleBytes.length - totalBytesRead); - throwConnectionExceptionIfConditionFails(moreBytesRead >= 0, - "server connection unexpectedly closed"); - - streamRecvs.incrementAndGet(); - totalBytesRead += moreBytesRead; - } - return totalBytesRead; - } - - /** - * Incomplete read; just try until we get a complete or something goes - * wrong... - */ - private int continueReadIfIncompleteRead(@Nonnull final AtomicLong streamRecvs, - final int payloadLength, @Nonnull final byte[] packetBytes, final int packetBytesRead) - throws IOException, ConnectionException { - int totalPacketBytesRead = packetBytesRead; - while (totalPacketBytesRead < payloadLength) { - stats.incompleteReads.incrementAndGet(); - int moreBytesRead = topInputStream.read(packetBytes, totalPacketBytesRead, - payloadLength - totalPacketBytesRead); - throwConnectionExceptionIfConditionFails(moreBytesRead >= 0, - "Perforce server network connection closed unexpectedly"); - - streamRecvs.incrementAndGet(); - stats.totalBytesRecv.getAndAdd(moreBytesRead); - totalPacketBytesRead += moreBytesRead; - } - return totalPacketBytesRead; - } - - public int getSystemRecvBufferSize() { - if (nonNull(socket)) { - try { - return socket.getReceiveBufferSize(); - } catch (SocketException exc) { - Log.error("unexpected exception: %s", exc.getLocalizedMessage()); - Log.exception(exc); - } - } - - return 0; - } - - public int getSystemSendBufferSize() { - if (nonNull(socket)) { - try { - return socket.getSendBufferSize(); - } catch (SocketException exc) { - Log.error("unexpected exception: %s", exc.getLocalizedMessage()); - Log.exception(exc); - } - } - - return 0; - } - - public long putRpcPackets(@Nonnull RpcPacket[] packets) throws ConnectionException { - Validate.notNull(packets); - int retVal = 0; - - for (RpcPacket packet : packets) { - if (nonNull(packet)) { - retVal += putRpcPacket(packet); - } - } - return retVal; - } - - /** - * Put a Perforce RPC packet onto the output stream. In some cases this may - * require considerable processing and things like charset translation here - * and downstream, but it's normally fairly straightforward. - * - *

-     * Note that in general, we don't know how large the packet's output byte
-     * buffer is going to have to be until we've finished the packet contents
-     * marshaling, so we implement buffer resizing when needed. Our initial
-     * guess is INITIAL_SENDBUF_SIZE bytes; we grow the buffer by increasing
-     * it SENDBUF_REALLOC_INCR times each buffer increase.
-     * 
- */ - public long putRpcPacket(@Nonnull RpcPacket packet) throws ConnectionException { - Validate.notNull(packet); - throwP4JavaErrorIfConditionFails(nonNull(packet.getFuncNameString()), - "Unmapped / unmappable function in RpcPacket.put()"); - - // Skip over the first few bytes for the preamble, - // which we'll come back to fill in later when we know the marshaled - // length. - int startPos = RpcPacketPreamble.RPC_PREAMBLE_SIZE; - - RpcPacketSupplier supplier = new RpcPacketSupplier(); - supplier.sendBytes(new byte[INITIAL_SENDBUF_SIZE]).sendPos(startPos); - - // FixedOrder - processNameArgs(packet, supplier); - processStringArgs(packet, supplier); - processExternalEnv(packet, supplier); - processFuncName(packet, supplier); - - calculatePreambleBytesAndSendtoDownstream(supplier); - return 0; - } - - private void processNameArgs(@Nonnull RpcPacket packet, - @Nonnull final RpcPacketSupplier argsSupplier) { - Map mapArgs = packet.getMapArgs(); - if (nonNull(mapArgs)) { - for (Map.Entry entry : mapArgs.entrySet()) { - reallocateSendBufferInPutPacketIfRunOut(argsSupplier, - marshalPacketField(entry.getKey(), entry.getValue()), SENDBUF_REALLOC_INCR); - } - } - } - - private void reallocateSendBufferInPutPacketIfRunOut(@Nonnull final RpcPacketSupplier supplier, - @Nonnull final byte[] fieldBytes, final int reallocateIncrement) { - byte[] sendBytes = supplier.sendBytes(); - int sendPos = supplier.sendPos(); - - byte[] newSendBytes = sendBytes; - if ((sendBytes.length - sendPos) <= fieldBytes.length) { - stats.bufferCompacts.getAndIncrement(); // We're overloading the - // meaning here... - int newBytesLength = sendBytes.length + fieldBytes.length + reallocateIncrement; - newSendBytes = new byte[newBytesLength]; - System.arraycopy(sendBytes, 0, newSendBytes, 0, sendPos); - } - - System.arraycopy(fieldBytes, 0, newSendBytes, sendPos, fieldBytes.length); - supplier.sendBytes(newSendBytes).sendPos(sendPos + fieldBytes.length); - } - - private void processStringArgs(@Nonnull RpcPacket packet, - @Nonnull final RpcPacketSupplier argsSupplier) { - String[] strArgs = packet.getStrArgs(); - if (nonNull(strArgs)) { - for (String arg : strArgs) { - if (isNotBlank(arg)) { - reallocateSendBufferInPutPacketIfRunOut(argsSupplier, - marshalPacketField(null, arg), SENDBUF_REALLOC_INCR); - } - } - } - } - - private void processExternalEnv(@Nonnull RpcPacket packet, - @Nonnull final RpcPacketSupplier argsSupplier) { - ExternalEnv externalEnv = packet.getEnv(); - if (nonNull(externalEnv)) { - reallocateSendBufferInPutPacketIfRunOut(argsSupplier, externalEnv.marshal(), - SENDBUF_REALLOC_INCR); - } - } - - private void processFuncName(@Nonnull RpcPacket packet, @Nonnull RpcPacketSupplier supplier) { - byte[] nameBytes = marshalPacketField(RpcFunctionMapKey.FUNCTION, - packet.getFuncNameString()); - reallocateSendBufferInPutPacketIfRunOut(supplier, nameBytes, nameBytes.length); - } - - /** - * Now go back and calculate the preamble bytes and sending it to downstream - */ - private void calculatePreambleBytesAndSendtoDownstream( - @Nonnull final RpcPacketSupplier argsSupplier) throws ConnectionException { - byte[] sendBytes = argsSupplier.sendBytes(); - int sendPos = argsSupplier.sendPos(); - - byte[] preambleBytes = RpcPacketPreamble - .constructPreamble(sendPos - RpcPacketPreamble.RPC_PREAMBLE_SIZE).marshalAsBytes(); - System.arraycopy(preambleBytes, 0, sendBytes, 0, preambleBytes.length); - try { - topOutputStream.write(sendBytes, 0, sendPos); - topOutputStream.flush(); - stats.streamSends.incrementAndGet(); - stats.totalBytesSent.getAndAdd(sendPos); - stats.packetsSent.incrementAndGet(); - if (stats.largestRpcPacketSent.get() < sendPos) { - stats.largestRpcPacketSent.set(sendPos); - } - } catch (IOException exc) { - Log.exception(exc); - StringBuilder message = new StringBuilder(); - if (exc instanceof SocketTimeoutException && secure) { - message.append(MessageFormat.format( - "SSL connect to ssl:{0}:{1,number,#} failed.\nRemove SSL protocol prefix.\n", - hostName, hostPort)); - } else { - message.append("Unable to send command to Perforce server: "); - } - message.append(exc.getMessage()); - throwConnectionException(exc, message.toString()); - } - } - - @Override - public void useConnectionCompression() throws ConnectionException { - if (!usingCompression) { - super.useConnectionCompression(); - - try { - topOutputStream.flush(); - // We do this here immediately to avoid having the compress2 - // itself compressed... - putRpcPacket(RpcPacket.constructRpcPacket(RpcFunctionSpec.PROTOCOL_COMPRESS2, - "compress2", null, null)); - topOutputStream.flush(); - topOutputStream = new RpcGZIPOutputStream(outputStream); - topInputStream = new RpcGZIPInputStream(inputStream); - } catch (IOException exc) { - Log.error("I/O exception encountered while setting up GZIP streaming: %s", - exc.getLocalizedMessage()); - Log.exception(exc); - throwConnectionException(exc, - "unable to set up client compression streaming to Perforce server: %s", - exc.getLocalizedMessage()); - } - } - } - - RpcStreamConnection rsh(String rsh) { - this.rsh = rsh; - return this; - } - - RpcStreamConnection socket(Socket socket) { - this.socket = socket; - return this; - } - - RpcStreamConnection topInputStream(InputStream topInputStream) { - this.topInputStream = topInputStream; - return this; - } - - RpcStreamConnection topOutputStream(OutputStream topOutputStream) { - this.topOutputStream = topOutputStream; - return this; - } - - static class RpcPacketSupplier { - private byte[] sendBytes = new byte[INITIAL_SENDBUF_SIZE]; - private int sendPos = 0; - - RpcPacketSupplier sendBytes(final byte[] sendBytes) { - this.sendBytes = sendBytes; - return this; - } - - RpcPacketSupplier sendPos(final int sendPos) { - this.sendPos = sendPos; - return this; - } - - byte[] sendBytes() { - return sendBytes; - } - - int sendPos() { - return sendPos; - } - } + public static final String TRACE_PREFIX = "RpcStreamConnection"; + + /** + * Number of bytes we allocate for initial byte arrays for sending RPC + * packets. In general we don't know how big the final buffer is, so this + * figure is a bit of a guessed compromise between over-allocation and + * frequent resizing. + */ + protected static final int INITIAL_SENDBUF_SIZE = 2048; + + /** + * When we run out of send buffer space in putPacket, we allocate another, + * larger, buffer; this constant determines how much larger than the + * existing buffer the new one should be, or, alternatively, how much bigger + * than the incoming field length the new buffer should be. Should probably + * be more tunable... + */ + protected static final int SENDBUF_REALLOC_INCR = 1024; + + private RpcSocketPool pool = null; + private Socket socket = null; + private InputStream inputStream = null; + private OutputStream outputStream = null; + private InputStream topInputStream = null; + private OutputStream topOutputStream = null; + + // 'rsh' mode server launch command + private String rsh = null; + + /** + * Construct a new Perforce RPC connection to the named Perforce server + * using java.io socket streams at the lowest level. This constructor sets + * up the default non-compressed stack; in general this means just a couple + * of simple socket streams. + * + * @param serverHost serverHost + * @param serverPort serverPort + * @param props props + * @param stats stats + * @param p4Charset p4Charset + * @param secure secure + * @throws ConnectionException on error + */ + public RpcStreamConnection(String serverHost, int serverPort, Properties props, ServerStats stats, P4Charset p4Charset, boolean secure) throws ConnectionException { + this(serverHost, serverPort, props, stats, p4Charset, (Socket) null, secure); + } + + /** + * Construct a new Perforce RPC connection to the named Perforce server + * using java.io socket streams at the lowest level. This constructor sets + * up the default non-compressed stack; in general this means just a couple + * of simple socket streams. + * + * @param serverHost serverHost + * @param serverPort serverPort + * @param props props + * @param stats stats + * @param p4Charset p4Charset + * @param socket socket + * @param secure secure + * @throws ConnectionException on error + */ + private RpcStreamConnection(String serverHost, int serverPort, Properties props, ServerStats stats, P4Charset p4Charset, Socket socket, boolean secure) throws ConnectionException { + this(serverHost, serverPort, props, stats, p4Charset, socket, null, secure); + } + + /** + * Construct a new Perforce RPC connection to the named Perforce server + * using java.io socket streams at the lowest level. This constructor sets + * up the default non-compressed stack; in general this means just a couple + * of simple socket streams. + * + * @param serverHost serverHost + * @param serverPort serverPort + * @param props props + * @param stats stats + * @param p4Charset p4Charset + * @param socket socket + * @param pool pool + * @param secure secure + * @throws ConnectionException on error + */ + private RpcStreamConnection(String serverHost, int serverPort, Properties props, ServerStats stats, P4Charset p4Charset, Socket socket, RpcSocketPool pool, boolean secure) throws ConnectionException { + this(serverHost, serverPort, props, stats, p4Charset, socket, pool, secure, null); + } + + /** + * Construct a new Perforce RPC connection to the named Perforce server + * using java.io socket streams at the lowest level. This constructor sets + * up the default non-compressed stack; in general this means just a couple + * of simple socket streams. + * + * @param serverHost serverHost + * @param serverPort serverPort + * @param props props + * @param stats stats + * @param p4Charset p4Charset + * @param socket socket + * @param pool pool + * @param secure secure + * @param rsh rsh + * @throws ConnectionException on error + */ + public RpcStreamConnection(String serverHost, int serverPort, Properties props, ServerStats stats, P4Charset p4Charset, Socket socket, RpcSocketPool pool, boolean secure, String rsh) throws ConnectionException { + super(serverHost, serverPort, props, stats, p4Charset, secure); + this.socket = socket; + this.pool = pool; + this.rsh = rsh; + init(); + } + + /** + * Initialize actual connection to the server. + */ + private void init() throws ConnectionException { + if (isNotBlank(rsh)) { + initRshModeServer(); + } else { + initSocketBasedServer(); + } + + topInputStream = inputStream; + topOutputStream = outputStream; + } + + private void initRshModeServer() throws ConnectionException { + try { + String[] command = new String[]{Server.isRunningOnWindows() ? "cmd.exe" : "/bin/sh", Server.isRunningOnWindows() ? "/c" : "-c", rsh}; + + ProcessBuilder builder = new ProcessBuilder(command); + // builder.redirectErrorStream(true); // redirect error stream to + // output stream + Process process = builder.start(); + InputStream in = process.getInputStream(); + OutputStream out = process.getOutputStream(); + // InputStream err = process.getErrorStream(); + + inputStream = new RpcRshInputStream(in, stats); + outputStream = new RpcRshOutputStream(out, stats); + } catch (Throwable thr) { + Log.error("Unexpected exception: %s", thr.getLocalizedMessage()); + Log.exception(thr); + throwConnectionException(thr); + } + } + + private void initSocketBasedServer() throws ConnectionException { + try { + if (isNull(socket)) { + if (nonNull(pool)) { + socket = pool.acquire(); + } else { + socket = RpcSocketHelper.createSocket(hostName, hostPort, props, secure); + } + } + } catch (UnknownHostException exc) { + throwConnectionException(exc, "Unable to resolve Perforce server host name '%s' for RPC connection", hostName); + } catch (IOException exc) { + throwConnectionException(exc, "Unable to connect to Perforce server at %s:%s", hostName, hostPort); + } catch (Throwable thr) { + Log.error("Unexpected exception: %s", thr.getLocalizedMessage()); + Log.exception(thr); + throwConnectionException(thr); + } + + getIpAddressFromSocketConnection(); + + // Initialize SSL connection + if (secure) { + initSSL(); + } + + initRpcSocketInputAndOutputStreamIfSocketBasedServer(); + } + + private void getIpAddressFromSocketConnection() { + if (nonNull(socket)) { + InetAddress inetAddress = socket.getInetAddress(); + if (nonNull(inetAddress)) { + // Check if it is an IPv6 address + String hostAddress = inetAddress.getHostAddress(); + if (Inet6Address.class.isAssignableFrom(inetAddress.getClass())) { + // Add the square brackets for IPv6 address + hostIp = "[" + hostAddress + "]"; + } else { + hostIp = hostAddress; + } + } + if (socket.isBound()) { + InetAddress address = socket.getLocalAddress(); + // Check if it is an IPv6 address + if (Inet6Address.class.isAssignableFrom(address.getClass())) { + // Add the square brackets for IPv6 address + this.ourIp = "[" + address.getHostAddress() + "]"; + } else { + this.ourIp = address.getHostAddress(); + } + this.ourPort = socket.getLocalPort(); + } + } + } + + private void initSSL() throws ConnectionException { + // Start SSL handshake + if (nonNull(socket)) { + try { + // The SSLSocket.getSession() method will initiate the initial + // handshake if necessary. Thus, the SSLSocket.startHandshake() + // call is not necessary. + SSLSession sslSession = ((SSLSocket) socket).getSession(); + + /* + * If an error occurs during the initial handshake, this method + * returns an invalid session object which reports an invalid + * cipher suite of "SSL_NULL_WITH_NULL_NULL". + */ + throwConnectionExceptionIfConditionFails(sslSession.isValid(), "Error occurred during the SSL handshake: invalid SSL session"); + + // Get the certificates + serverCerts = sslSession.getPeerCertificates(); + + throwConnectionExceptionIfConditionFails(nonNull(serverCerts) && (serverCerts.length != 0) && nonNull(serverCerts[0]), "Error occurred during the SSL handshake: no certificate retrieved from SSL session"); + + X509Certificate siteCert = (X509Certificate) serverCerts[0]; + + // Check that the certificate is currently valid. Check the + // current date and time are within the validity period given + // in the certificate. + siteCert.checkValidity(); + + // Get the public key from the first certificate + PublicKey serverPubKey = siteCert.getPublicKey(); + throwConnectionExceptionIfConditionFails(nonNull(serverPubKey), "Error occurred during the SSL handshake: no public key retrieved from server certificate"); + + // check if it's a self signed cert. + selfSigned = siteCert.getSubjectDN().getName().equals(siteCert.getIssuerDN().getName()); + + // Generate the fingerprint + fingerprint = ClientTrust.generateFingerprint(serverPubKey); + + } catch (CertificateExpiredException e) { + throwConnectionException(e, "Error occurred during the SSL handshake: certificate expired:"); + } catch (CertificateNotYetValidException e) { + throwConnectionException(e, "Error occurred during the SSL handshake: certificate not yet valid"); + } catch (NoSuchAlgorithmException e) { + throwConnectionException(e, "Error occurred while generating the fingerprint for the Perforce SSL connection"); + } catch (IOException e) { + String errorMessage = format("Error occurred during SSL hankshake. Please check the release notes for known SSL issues"); + Log.error(errorMessage); + Log.exception(e); + throwConnectionException(e, errorMessage); + } + } + } + + private void initRpcSocketInputAndOutputStreamIfSocketBasedServer() throws ConnectionException { + try { + inputStream = new RpcSocketInputStream(socket, stats); + outputStream = new RpcSocketOutputStream(socket, stats); + } catch (Throwable thr) { + Log.error("Unexpected exception: %s", thr.getLocalizedMessage()); + Log.exception(thr); + throwConnectionException(thr); + } + } + + public String getServerIpPort() { + String serverIpPort = null; + if (!StringUtils.equals(hostIp, UNKNOWN_SERVER_HOST)) { + serverIpPort = hostIp; + if (hostPort != UNKNOWN_SERVER_PORT) { + serverIpPort += ":" + String.valueOf(hostPort); + } + } else if (hostPort != UNKNOWN_SERVER_PORT) { + serverIpPort = Integer.toString(hostPort); + } + return serverIpPort; + } + + public String getServerHostNamePort() { + return hostName + ":" + String.valueOf(hostPort); + } + + /** + * @see com.perforce.p4java.impl.mapbased.rpc.connection.RpcConnection#getClientIpPort() + */ + public String getClientIpPort() { + String clientIpPort = null; + if (this.ourIp != UNKNOWN_SERVER_HOST) { + clientIpPort = this.ourIp; + if (this.ourPort != UNKNOWN_SERVER_PORT) { + clientIpPort += ":" + Integer.toString(this.ourPort); + } + } else if (this.ourPort != UNKNOWN_SERVER_PORT) { + clientIpPort = Integer.toString(this.ourPort); + } + return clientIpPort; + } + + public void disconnect(final RpcPacketDispatcher dispatcher) throws ConnectionException { + try { + // NOTE: don't do gratuitous (any) flushes here -- this has all been + // handled already and will often cause errors in compressed client + // connection setups -- HR. + ShutdownHandler handler = new ShutdownHandler() { + @Override + public void shutdown(Socket theSocket) { + if (nonNull(dispatcher)) { + try { + dispatcher.shutdown(RpcStreamConnection.this); + } catch (ConnectionException e) { + Log.exception(e); + } + } + } + }; + // Handle 'rsh' mode server shutdown + if (isNotBlank(rsh)) { + try { + dispatcher.shutdown(RpcStreamConnection.this); + } catch (ConnectionException e) { + Log.exception(e); + } + topInputStream.close(); + topOutputStream.close(); + } else { + if (nonNull(pool)) { + pool.release(socket, handler); + } else { + handler.shutdown(socket); + topInputStream.close(); + topOutputStream.close(); + if (nonNull(socket)) { + socket.close(); + } + } + } + } catch (IOException exc) { + throwConnectionException(exc, "RPC disconnection error: %s", exc.getLocalizedMessage()); + } + } + + /** + * Get a Perforce RPC packet from the underlying stream. If we're talking to + * a Unicode-enabled Perforce server, we attempt to translate the incoming + * bytes to the relevant client-side charsets where appropriate based on + * packet field type, etc. + */ + public RpcPacket getRpcPacket() throws ConnectionException { + return getRpcPacket(null, null); + } + + /** + * Get a Perforce RPC packet from the underlying stream with an optional + * rule to handle the RPC packet fields. + */ + public RpcPacket getRpcPacket(final RpcPacketFieldRule fieldRule, final IFilterCallback filterCallback) throws ConnectionException { + byte[] preambleBytes = new byte[RpcPacketPreamble.RPC_PREAMBLE_SIZE]; + RpcPacket packet = null; + + try { + int bytesRead = topInputStream.read(preambleBytes); + throwConnectionExceptionIfConditionFails(bytesRead >= 0, "server connection unexpectedly closed"); + AtomicLong streamRecvs = stats.streamRecvs; + streamRecvs.incrementAndGet(); + + bytesRead = continueReadIfGetPartialRead(preambleBytes, bytesRead, streamRecvs); + throwConnectionExceptionIfConditionFails(bytesRead == preambleBytes.length, "Incomplete RPC packet preamble read from Perforce server; connection probably broken. bytes read: %s", bytesRead); + stats.totalBytesRecv.getAndAdd(bytesRead); + + RpcPacketPreamble preamble = RpcPacketPreamble.retrievePreamble(preambleBytes); + throwProtocolErrorIfConditionFails(preamble.isValidChecksum(), "Bad checksum in RPC preamble"); + + int payloadLength = preamble.getPayloadSize(); // Note: size is for + // the *rest of the + // packet*... + // FIXME: really should sanity check the size better here -- HR. + throwProtocolErrorIfConditionFails(payloadLength > 0, "Bad payload size in RPC preamble: %s", payloadLength); + + // We know how many bytes to expect for the rest of this packet, so + // try to read this in. This can be a ginormous packet in some + // pathological + // cases, so we need to be flexible... + byte[] packetBytes = new byte[payloadLength]; + int packetBytesRead = topInputStream.read(packetBytes, 0, payloadLength); + throwConnectionExceptionIfConditionFails(packetBytesRead > 0, "Perforce server network connection closed unexpectedly"); + streamRecvs.incrementAndGet(); + stats.totalBytesRecv.getAndAdd(packetBytesRead); + + packetBytesRead = continueReadIfIncompleteRead(streamRecvs, payloadLength, packetBytes, packetBytesRead); + throwP4JavaErrorIfConditionFails(packetBytesRead == payloadLength, "RPC packet payload read size mismatch; expected: %s; got: %s", payloadLength, packetBytesRead); + + packet = RpcPacket.constructRpcPacket(preamble, packetBytes, unicodeServer, p4Charset.getCharset(), fieldRule, filterCallback); + stats.packetsRecv.incrementAndGet(); + stats.largestRpcPacketRecv.set(Math.max(stats.largestRpcPacketRecv.get(), packet.getPacketLength())); + } catch (IOException exc) { + throwConnectionException(exc); + } catch (ConnectionException | P4JavaError p4jexc) { + throw p4jexc; + } catch (Throwable thr) { + // Never a good sign; typically a buffer overflow or positioning + // problem, and almost always unrecoverable. + Log.error("Unexpected exception: %s", thr.getLocalizedMessage()); + Log.exception(thr); + throwP4JavaError(thr, thr.getLocalizedMessage()); + } + + return packet; + } + + /** + * If we get a partial read, try again until something goes wrong... + */ + private int continueReadIfGetPartialRead(@Nonnull final byte[] preambleBytes, final int bytesRead, @Nonnull final AtomicLong streamRecvs) throws IOException, ConnectionException { + int totalBytesRead = bytesRead; + while ((totalBytesRead >= 0) && (totalBytesRead < preambleBytes.length)) { + int moreBytesRead = topInputStream.read(preambleBytes, totalBytesRead, preambleBytes.length - totalBytesRead); + throwConnectionExceptionIfConditionFails(moreBytesRead >= 0, "server connection unexpectedly closed"); + + streamRecvs.incrementAndGet(); + totalBytesRead += moreBytesRead; + } + return totalBytesRead; + } + + /** + * Incomplete read; just try until we get a complete or something goes + * wrong... + */ + private int continueReadIfIncompleteRead(@Nonnull final AtomicLong streamRecvs, final int payloadLength, @Nonnull final byte[] packetBytes, final int packetBytesRead) throws IOException, ConnectionException { + int totalPacketBytesRead = packetBytesRead; + while (totalPacketBytesRead < payloadLength) { + stats.incompleteReads.incrementAndGet(); + int moreBytesRead = topInputStream.read(packetBytes, totalPacketBytesRead, payloadLength - totalPacketBytesRead); + throwConnectionExceptionIfConditionFails(moreBytesRead >= 0, "Perforce server network connection closed unexpectedly"); + + streamRecvs.incrementAndGet(); + stats.totalBytesRecv.getAndAdd(moreBytesRead); + totalPacketBytesRead += moreBytesRead; + } + return totalPacketBytesRead; + } + + public int getSystemRecvBufferSize() { + if (nonNull(socket)) { + try { + return socket.getReceiveBufferSize(); + } catch (SocketException exc) { + Log.error("unexpected exception: %s", exc.getLocalizedMessage()); + Log.exception(exc); + } + } + + return 0; + } + + public int getSystemSendBufferSize() { + if (nonNull(socket)) { + try { + return socket.getSendBufferSize(); + } catch (SocketException exc) { + Log.error("unexpected exception: %s", exc.getLocalizedMessage()); + Log.exception(exc); + } + } + + return 0; + } + + public long putRpcPackets(@Nonnull RpcPacket[] packets) throws ConnectionException { + Validate.notNull(packets); + int retVal = 0; + + for (RpcPacket packet : packets) { + if (nonNull(packet)) { + retVal += putRpcPacket(packet); + } + } + return retVal; + } + + /** + * Put a Perforce RPC packet onto the output stream. In some cases this may + * require considerable processing and things like charset translation here + * and downstream, but it's normally fairly straightforward. + * + *
+	 * Note that in general, we don't know how large the packet's output byte
+	 * buffer is going to have to be until we've finished the packet contents
+	 * marshaling, so we implement buffer resizing when needed. Our initial
+	 * guess is INITIAL_SENDBUF_SIZE bytes; we grow the buffer by increasing
+	 * it SENDBUF_REALLOC_INCR times each buffer increase.
+	 * 
+ */ + public long putRpcPacket(@Nonnull RpcPacket packet) throws ConnectionException { + Validate.notNull(packet); + throwP4JavaErrorIfConditionFails(nonNull(packet.getFuncNameString()), "Unmapped / unmappable function in RpcPacket.put()"); + + // Skip over the first few bytes for the preamble, + // which we'll come back to fill in later when we know the marshaled + // length. + int startPos = RpcPacketPreamble.RPC_PREAMBLE_SIZE; + + RpcPacketSupplier supplier = new RpcPacketSupplier(); + supplier.sendBytes(new byte[INITIAL_SENDBUF_SIZE]).sendPos(startPos); + + // FixedOrder + processNameArgs(packet, supplier); + processStringArgs(packet, supplier); + processExternalEnv(packet, supplier); + processFuncName(packet, supplier); + + calculatePreambleBytesAndSendtoDownstream(supplier); + return 0; + } + + private void processNameArgs(@Nonnull RpcPacket packet, @Nonnull final RpcPacketSupplier argsSupplier) { + Map mapArgs = packet.getMapArgs(); + if (nonNull(mapArgs)) { + for (Map.Entry entry : mapArgs.entrySet()) { + reallocateSendBufferInPutPacketIfRunOut(argsSupplier, marshalPacketField(entry.getKey(), entry.getValue()), SENDBUF_REALLOC_INCR); + } + } + } + + private void reallocateSendBufferInPutPacketIfRunOut(@Nonnull final RpcPacketSupplier supplier, @Nonnull final byte[] fieldBytes, final int reallocateIncrement) { + byte[] sendBytes = supplier.sendBytes(); + int sendPos = supplier.sendPos(); + + byte[] newSendBytes = sendBytes; + if ((sendBytes.length - sendPos) <= fieldBytes.length) { + stats.bufferCompacts.getAndIncrement(); // We're overloading the + // meaning here... + int newBytesLength = sendBytes.length + fieldBytes.length + reallocateIncrement; + newSendBytes = new byte[newBytesLength]; + System.arraycopy(sendBytes, 0, newSendBytes, 0, sendPos); + } + + System.arraycopy(fieldBytes, 0, newSendBytes, sendPos, fieldBytes.length); + supplier.sendBytes(newSendBytes).sendPos(sendPos + fieldBytes.length); + } + + private void processStringArgs(@Nonnull RpcPacket packet, @Nonnull final RpcPacketSupplier argsSupplier) { + String[] strArgs = packet.getStrArgs(); + if (nonNull(strArgs)) { + for (String arg : strArgs) { + if (isNotBlank(arg)) { + reallocateSendBufferInPutPacketIfRunOut(argsSupplier, marshalPacketField(null, arg), SENDBUF_REALLOC_INCR); + } + } + } + } + + private void processExternalEnv(@Nonnull RpcPacket packet, @Nonnull final RpcPacketSupplier argsSupplier) { + ExternalEnv externalEnv = packet.getEnv(); + if (nonNull(externalEnv)) { + reallocateSendBufferInPutPacketIfRunOut(argsSupplier, externalEnv.marshal(), SENDBUF_REALLOC_INCR); + } + } + + private void processFuncName(@Nonnull RpcPacket packet, @Nonnull RpcPacketSupplier supplier) { + byte[] nameBytes = marshalPacketField(RpcFunctionMapKey.FUNCTION, packet.getFuncNameString()); + reallocateSendBufferInPutPacketIfRunOut(supplier, nameBytes, nameBytes.length); + } + + /** + * Now go back and calculate the preamble bytes and sending it to downstream + */ + private void calculatePreambleBytesAndSendtoDownstream(@Nonnull final RpcPacketSupplier argsSupplier) throws ConnectionException { + byte[] sendBytes = argsSupplier.sendBytes(); + int sendPos = argsSupplier.sendPos(); + + byte[] preambleBytes = RpcPacketPreamble.constructPreamble(sendPos - RpcPacketPreamble.RPC_PREAMBLE_SIZE).marshalAsBytes(); + System.arraycopy(preambleBytes, 0, sendBytes, 0, preambleBytes.length); + try { + topOutputStream.write(sendBytes, 0, sendPos); + topOutputStream.flush(); + stats.streamSends.incrementAndGet(); + stats.totalBytesSent.getAndAdd(sendPos); + stats.packetsSent.incrementAndGet(); + if (stats.largestRpcPacketSent.get() < sendPos) { + stats.largestRpcPacketSent.set(sendPos); + } + } catch (IOException exc) { + Log.exception(exc); + StringBuilder message = new StringBuilder(); + if (exc instanceof SocketTimeoutException && secure) { + message.append(MessageFormat.format("SSL connect to ssl:{0}:{1,number,#} failed.\nRemove SSL protocol prefix.\n", hostName, hostPort)); + } else { + message.append("Unable to send command to Perforce server: "); + } + message.append(exc.getMessage()); + throwConnectionException(exc, message.toString()); + } + } + + @Override + public void useConnectionCompression() throws ConnectionException { + if (!usingCompression) { + super.useConnectionCompression(); + + try { + topOutputStream.flush(); + // We do this here immediately to avoid having the compress2 + // itself compressed... + putRpcPacket(RpcPacket.constructRpcPacket(RpcFunctionSpec.PROTOCOL_COMPRESS2, "compress2", null, null)); + topOutputStream.flush(); + topOutputStream = new RpcGZIPOutputStream(outputStream); + topInputStream = new RpcGZIPInputStream(inputStream); + } catch (IOException exc) { + Log.error("I/O exception encountered while setting up GZIP streaming: %s", exc.getLocalizedMessage()); + Log.exception(exc); + throwConnectionException(exc, "unable to set up client compression streaming to Perforce server: %s", exc.getLocalizedMessage()); + } + } + } + + RpcStreamConnection rsh(String rsh) { + this.rsh = rsh; + return this; + } + + RpcStreamConnection socket(Socket socket) { + this.socket = socket; + return this; + } + + RpcStreamConnection topInputStream(InputStream topInputStream) { + this.topInputStream = topInputStream; + return this; + } + + RpcStreamConnection topOutputStream(OutputStream topOutputStream) { + this.topOutputStream = topOutputStream; + return this; + } + + static class RpcPacketSupplier { + private byte[] sendBytes = new byte[INITIAL_SENDBUF_SIZE]; + private int sendPos = 0; + + RpcPacketSupplier sendBytes(final byte[] sendBytes) { + this.sendBytes = sendBytes; + return this; + } + + RpcPacketSupplier sendPos(final int sendPos) { + this.sendPos = sendPos; + return this; + } + + byte[] sendBytes() { + return sendBytes; + } + + int sendPos() { + return sendPos; + } + } } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/stream/helper/RpcSocketHelper.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/stream/helper/RpcSocketHelper.java index 9d625bc..d202101 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/stream/helper/RpcSocketHelper.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/stream/helper/RpcSocketHelper.java @@ -3,22 +3,25 @@ */ package com.perforce.p4java.impl.mapbased.rpc.stream.helper; +import com.perforce.p4java.Log; +import com.perforce.p4java.impl.mapbased.rpc.RpcPropertyDefs; +import com.perforce.p4java.impl.mapbased.rpc.stream.RpcSSLSocketFactory; + import java.io.IOException; import java.net.InetSocketAddress; import java.net.Socket; import java.util.Properties; -import com.perforce.p4java.Log; -import com.perforce.p4java.impl.mapbased.rpc.RpcPropertyDefs; -import com.perforce.p4java.impl.mapbased.rpc.stream.RpcSSLSocketFactory; - /** * Helper class for creating and configuring sockets. */ public class RpcSocketHelper { - + /** * Configure a socket with specified properties. + * + * @param socket socket + * @param properties properties */ public static void configureSocket(Socket socket, Properties properties) { if (socket == null || properties == null) { @@ -27,22 +30,14 @@ public static void configureSocket(Socket socket, Properties properties) { try { // Enable/disable TCP_NODELAY (disable/enable Nagle's algorithm). - boolean tcpNoDelay = RpcPropertyDefs.getPropertyAsBoolean(properties, - RpcPropertyDefs.RPC_SOCKET_TCP_NO_DELAY_NICK, - RpcPropertyDefs.RPC_SOCKET_TCP_NO_DELAY_DEFAULT); + boolean tcpNoDelay = RpcPropertyDefs.getPropertyAsBoolean(properties, RpcPropertyDefs.RPC_SOCKET_TCP_NO_DELAY_NICK, RpcPropertyDefs.RPC_SOCKET_TCP_NO_DELAY_DEFAULT); socket.setTcpNoDelay(tcpNoDelay); - - String keepAlive = RpcPropertyDefs.getProperty(properties, - RpcPropertyDefs.RPC_SOCKET_USE_KEEPALIVE_NICK); - int timeouts = RpcPropertyDefs.getPropertyAsInt(properties, - RpcPropertyDefs.RPC_SOCKET_SO_TIMEOUT_NICK, - RpcPropertyDefs.RPC_SOCKET_SO_TIMEOUT_DEFAULT); + String keepAlive = RpcPropertyDefs.getProperty(properties, RpcPropertyDefs.RPC_SOCKET_USE_KEEPALIVE_NICK); - int[] perfPrefs = RpcPropertyDefs.getPropertyAsIntArray(properties, - RpcPropertyDefs.RPC_SOCKET_PERFORMANCE_PREFERENCES_NICK, - RpcPropertyDefs.RPC_DEFAULT_PROPERTY_DELIMITER, - RpcPropertyDefs.RPC_SOCKET_PERFORMANCE_PREFERENCES_DEFAULT); + int timeouts = RpcPropertyDefs.getPropertyAsInt(properties, RpcPropertyDefs.RPC_SOCKET_SO_TIMEOUT_NICK, RpcPropertyDefs.RPC_SOCKET_SO_TIMEOUT_DEFAULT); + + int[] perfPrefs = RpcPropertyDefs.getPropertyAsIntArray(properties, RpcPropertyDefs.RPC_SOCKET_PERFORMANCE_PREFERENCES_NICK, RpcPropertyDefs.RPC_DEFAULT_PROPERTY_DELIMITER, RpcPropertyDefs.RPC_SOCKET_PERFORMANCE_PREFERENCES_DEFAULT); // Setting the socket performance preferences, described by three // integers whose values indicate the relative importance of short @@ -52,25 +47,19 @@ public static void configureSocket(Socket socket, Properties properties) { // This gives the highest importance to low latency, followed by // short connection time, and least importance to high bandwidth. if (perfPrefs != null && perfPrefs.length == 3) { - socket.setPerformancePreferences( - perfPrefs[0], - perfPrefs[1], - perfPrefs[2]); + socket.setPerformancePreferences(perfPrefs[0], perfPrefs[1], perfPrefs[2]); } - + socket.setSoTimeout(timeouts); - if ((keepAlive != null) - && (keepAlive.startsWith("n") || keepAlive.startsWith("N"))) { + if ((keepAlive != null) && (keepAlive.startsWith("n") || keepAlive.startsWith("N"))) { socket.setKeepAlive(false); } else { socket.setKeepAlive(true); } - int sockRecvBufSize = RpcPropertyDefs.getPropertyAsInt(properties, - RpcPropertyDefs.RPC_SOCKET_RECV_BUF_SIZE_NICK, 0); - int sockSendBufSize = RpcPropertyDefs.getPropertyAsInt(properties, - RpcPropertyDefs.RPC_SOCKET_SEND_BUF_SIZE_NICK, 0); + int sockRecvBufSize = RpcPropertyDefs.getPropertyAsInt(properties, RpcPropertyDefs.RPC_SOCKET_RECV_BUF_SIZE_NICK, 0); + int sockSendBufSize = RpcPropertyDefs.getPropertyAsInt(properties, RpcPropertyDefs.RPC_SOCKET_SEND_BUF_SIZE_NICK, 0); if (sockRecvBufSize != 0) { socket.setReceiveBufferSize(sockRecvBufSize); @@ -80,15 +69,20 @@ public static void configureSocket(Socket socket, Properties properties) { socket.setSendBufferSize(sockSendBufSize); } } catch (Throwable exc) { - Log - .warn("Unexpected exception while setting Perforce RPC socket options: " - + exc.getLocalizedMessage()); + Log.warn("Unexpected exception while setting Perforce RPC socket options: " + exc.getLocalizedMessage()); Log.exception(exc); } } - + /** * Create a socket with the specified properties and connect to the specified host and port. + * + * @param host host + * @param port port + * @param properties properties + * @param secure secure + * @return Socket + * @throws IOException on error */ public static Socket createSocket(String host, int port, Properties properties, boolean secure) throws IOException { Socket socket = null; @@ -98,12 +92,12 @@ public static Socket createSocket(String host, int port, Properties properties, } else { socket = new Socket(); } - + configureSocket(socket, properties); socket.bind(new InetSocketAddress(0)); socket.connect(new InetSocketAddress(host, port)); - + return socket; } } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/sys/RpcInflaterOutputStream.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/sys/RpcInflaterOutputStream.java index 22ec5f9..6797ea5 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/sys/RpcInflaterOutputStream.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/sys/RpcInflaterOutputStream.java @@ -1,5 +1,5 @@ /** - * + * */ package com.perforce.p4java.impl.mapbased.rpc.sys; @@ -9,6 +9,8 @@ * intuition); may disappear in the longer-term. */ +import com.perforce.p4java.impl.mapbased.rpc.func.helper.MD5Digester; + import java.io.FilterOutputStream; import java.io.IOException; import java.io.OutputStream; @@ -16,251 +18,249 @@ import java.util.zip.Inflater; import java.util.zip.ZipException; -import com.perforce.p4java.impl.mapbased.rpc.func.helper.MD5Digester; - public class RpcInflaterOutputStream extends FilterOutputStream { - /** Decompressor for this stream. */ - protected final Inflater inf; - - /** Output buffer for writing uncompressed data. */ - protected final byte[] buf; - - /** Temporary write buffer. */ - private final byte[] wbuf = new byte[1]; - - /** Default decompressor is used. */ - private boolean usesDefaultInflater = false; - - /** true iff {@link #close()} has been called. */ - private boolean closed = false; - - private MD5Digester localDigester = null; // Used for the 10.2 sync integrity checking feature. - - /** - * Checks to make sure that this stream has not been closed. - */ - private void ensureOpen() throws IOException { - if (closed) { - throw new IOException("Stream closed"); - } - } - - /** - * Creates a new output stream with a default decompressor and buffer - * size. - * - * @param out output stream to write the uncompressed data to - * @throws NullPointerException if {@code out} is null - */ - public RpcInflaterOutputStream(OutputStream out, MD5Digester digester) { - this(out, new Inflater(), digester); - usesDefaultInflater = true; - } - - /** - * Creates a new output stream with the specified decompressor and a - * default buffer size. - * - * @param out output stream to write the uncompressed data to - * @param infl decompressor ("inflater") for this stream - * @throws NullPointerException if {@code out} or {@code infl} is null - */ - public RpcInflaterOutputStream(OutputStream out, Inflater infl, MD5Digester digester) { - this(out, infl, 512, digester); - } - - /** - * Creates a new output stream with the specified decompressor and - * buffer size. - * - * @param out output stream to write the uncompressed data to - * @param infl decompressor ("inflater") for this stream - * @param bufLen decompression buffer size - * @throws IllegalArgumentException if {@code bufLen} is <= 0 - * @throws NullPointerException if {@code out} or {@code infl} is null - */ - public RpcInflaterOutputStream(OutputStream out, Inflater infl, int bufLen, MD5Digester digester) { - super(out); - this.localDigester = digester; - - // Sanity checks - if (out == null) - throw new NullPointerException("Null output"); - if (infl == null) - throw new NullPointerException("Null inflater"); - if (bufLen <= 0) - throw new IllegalArgumentException("Buffer size < 1"); - - // Initialize - inf = infl; - buf = new byte[bufLen]; - } - - /** - * Writes any remaining uncompressed data to the output stream and closes - * the underlying output stream. - * - * @throws IOException if an I/O error occurs - */ - public void close() throws IOException { - if (!closed) { - // Complete the uncompressed output - try { - finish(); - } finally { - out.close(); - closed = true; - } - } - } - - /** - * Flushes this output stream, forcing any pending buffered output bytes to be - * written. - * - * @throws IOException if an I/O error occurs or this stream is already - * closed - */ - public void flush() throws IOException { - ensureOpen(); - - // Finish decompressing and writing pending output data - if (!inf.finished()) { - try { - while (!inf.finished() && !inf.needsInput()) { - int n; - - // Decompress pending output data - n = inf.inflate(buf, 0, buf.length); - if (n < 1) { - break; - } - - // Write the uncompressed output data block - out.write(buf, 0, n); - updateDigest(buf, 0, n); - } - super.flush(); - } catch (DataFormatException ex) { - // Improperly formatted compressed (ZIP) data - String msg = ex.getMessage(); - if (msg == null) { - msg = "Invalid ZLIB data format"; - } - throw new ZipException(msg); - } - } - } - - /** - * Finishes writing uncompressed data to the output stream without closing - * the underlying stream. Use this method when applying multiple filters in - * succession to the same output stream. - * - * @throws IOException if an I/O error occurs or this stream is already - * closed - */ - public void finish() throws IOException { - ensureOpen(); - - // Finish decompressing and writing pending output data - flush(); - if (usesDefaultInflater) { - inf.end(); - } - } - - /** - * Writes a byte to the uncompressed output stream. - * - * @param b a single byte of compressed data to decompress and write to - * the output stream - * @throws IOException if an I/O error occurs or this stream is already - * closed - * @throws ZipException if a compression (ZIP) format error occurs - */ - public void write(int b) throws IOException { - // Write a single byte of data - wbuf[0] = (byte) b; - write(wbuf, 0, 1); - } - - /** - * Writes an array of bytes to the uncompressed output stream. - * - * @param b buffer containing compressed data to decompress and write to - * the output stream - * @param off starting offset of the compressed data within {@code b} - * @param len number of bytes to decompress from {@code b} - * @throws IndexOutOfBoundsException if {@code off} < 0, or if - * {@code len} < 0, or if {@code len} > {@code b.length - off} - * @throws IOException if an I/O error occurs or this stream is already - * closed - * @throws NullPointerException if {@code b} is null - * @throws ZipException if a compression (ZIP) format error occurs - */ - public void write(byte[] b, int off, int len) throws IOException { - // Sanity checks - ensureOpen(); - if (b == null) { - throw new NullPointerException("Null buffer for read"); - } else if (off < 0 || len < 0 || len > b.length - off) { - throw new IndexOutOfBoundsException(); - } else if (len == 0) { - return; - } - - // Write uncompressed data to the output stream - try { - for (;;) { - int n; - - // Fill the decompressor buffer with output data - if (inf.needsInput()) { - int part; - - if (len < 1) { - break; - } - - part = (len < 512 ? len : 512); - inf.setInput(b, off, part); - off += part; - len -= part; - } - - // Decompress and write blocks of output data - do { - n = inf.inflate(buf, 0, buf.length); - if (n > 0) { - out.write(buf, 0, n); - updateDigest(buf, 0, n); - } - } while (n > 0); - - // Check the decompressor - if (inf.finished()) { - break; - } - if (inf.needsDictionary()) { - throw new ZipException("ZLIB dictionary missing"); - } - } - } catch (DataFormatException ex) { - // Improperly formatted compressed (ZIP) data - String msg = ex.getMessage(); - if (msg == null) { - msg = "Invalid ZLIB data format"; - } - throw new ZipException(msg); - } - } - - private void updateDigest(byte[] bytes, int offset, int count) { - if ((this.localDigester != null) && (bytes != null)) { - this.localDigester.update(bytes, offset, count); - } - } + /** Decompressor for this stream. */ + protected final Inflater inf; + + /** Output buffer for writing uncompressed data. */ + protected final byte[] buf; + + /** Temporary write buffer. */ + private final byte[] wbuf = new byte[1]; + + /** Default decompressor is used. */ + private boolean usesDefaultInflater = false; + + /** true iff {@link #close()} has been called. */ + private boolean closed = false; + + private MD5Digester localDigester = null; // Used for the 10.2 sync integrity checking feature. + + /** + * Checks to make sure that this stream has not been closed. + */ + private void ensureOpen() throws IOException { + if (closed) { + throw new IOException("Stream closed"); + } + } + + /** + * Creates a new output stream with a default decompressor and buffer + * size. + * + * @param out output stream to write the uncompressed data to + * @param digester m5d digester + * @throws NullPointerException if {@code out} is null + */ + public RpcInflaterOutputStream(OutputStream out, MD5Digester digester) { + this(out, new Inflater(), digester); + usesDefaultInflater = true; + } + + /** + * Creates a new output stream with the specified decompressor and a + * default buffer size. + * + * @param out output stream to write the uncompressed data to + * @param infl decompressor ("inflater") for this stream + * @param digester m5d digester + * @throws NullPointerException if {@code out} or {@code infl} is null + */ + public RpcInflaterOutputStream(OutputStream out, Inflater infl, MD5Digester digester) { + this(out, infl, 512, digester); + } + + /** + * Creates a new output stream with the specified decompressor and + * buffer size. + * + * @param out output stream to write the uncompressed data to + * @param infl decompressor ("inflater") for this stream + * @param bufLen decompression buffer size + * @param digester m5d digester + * @throws IllegalArgumentException if {@code bufLen} is <= 0 + * @throws NullPointerException if {@code out} or {@code infl} is null + */ + public RpcInflaterOutputStream(OutputStream out, Inflater infl, int bufLen, MD5Digester digester) { + super(out); + this.localDigester = digester; + + // Sanity checks + if (out == null) throw new NullPointerException("Null output"); + if (infl == null) throw new NullPointerException("Null inflater"); + if (bufLen <= 0) throw new IllegalArgumentException("Buffer size < 1"); + + // Initialize + inf = infl; + buf = new byte[bufLen]; + } + + /** + * Writes any remaining uncompressed data to the output stream and closes + * the underlying output stream. + * + * @throws IOException if an I/O error occurs + */ + public void close() throws IOException { + if (!closed) { + // Complete the uncompressed output + try { + finish(); + } finally { + out.close(); + closed = true; + } + } + } + + /** + * Flushes this output stream, forcing any pending buffered output bytes to be + * written. + * + * @throws IOException if an I/O error occurs or this stream is already + * closed + */ + public void flush() throws IOException { + ensureOpen(); + + // Finish decompressing and writing pending output data + if (!inf.finished()) { + try { + while (!inf.finished() && !inf.needsInput()) { + int n; + + // Decompress pending output data + n = inf.inflate(buf, 0, buf.length); + if (n < 1) { + break; + } + + // Write the uncompressed output data block + out.write(buf, 0, n); + updateDigest(buf, 0, n); + } + super.flush(); + } catch (DataFormatException ex) { + // Improperly formatted compressed (ZIP) data + String msg = ex.getMessage(); + if (msg == null) { + msg = "Invalid ZLIB data format"; + } + throw new ZipException(msg); + } + } + } + + /** + * Finishes writing uncompressed data to the output stream without closing + * the underlying stream. Use this method when applying multiple filters in + * succession to the same output stream. + * + * @throws IOException if an I/O error occurs or this stream is already + * closed + */ + public void finish() throws IOException { + ensureOpen(); + + // Finish decompressing and writing pending output data + flush(); + if (usesDefaultInflater) { + inf.end(); + } + } + + /** + * Writes a byte to the uncompressed output stream. + * + * @param b a single byte of compressed data to decompress and write to + * the output stream + * @throws IOException if an I/O error occurs or this stream is already + * closed + * @throws ZipException if a compression (ZIP) format error occurs + */ + public void write(int b) throws IOException { + // Write a single byte of data + wbuf[0] = (byte) b; + write(wbuf, 0, 1); + } + + /** + * Writes an array of bytes to the uncompressed output stream. + * + * @param b buffer containing compressed data to decompress and write to + * the output stream + * @param off starting offset of the compressed data within {@code b} + * @param len number of bytes to decompress from {@code b} + * @throws IndexOutOfBoundsException if {@code off} < 0, or if + * {@code len} < 0, or if {@code len} > {@code b.length - off} + * @throws IOException if an I/O error occurs or this stream is already + * closed + * @throws NullPointerException if {@code b} is null + * @throws ZipException if a compression (ZIP) format error occurs + */ + public void write(byte[] b, int off, int len) throws IOException { + // Sanity checks + ensureOpen(); + if (b == null) { + throw new NullPointerException("Null buffer for read"); + } else if (off < 0 || len < 0 || len > b.length - off) { + throw new IndexOutOfBoundsException(); + } else if (len == 0) { + return; + } + + // Write uncompressed data to the output stream + try { + for (; ; ) { + int n; + + // Fill the decompressor buffer with output data + if (inf.needsInput()) { + int part; + + if (len < 1) { + break; + } + + part = (len < 512 ? len : 512); + inf.setInput(b, off, part); + off += part; + len -= part; + } + + // Decompress and write blocks of output data + do { + n = inf.inflate(buf, 0, buf.length); + if (n > 0) { + out.write(buf, 0, n); + updateDigest(buf, 0, n); + } + } while (n > 0); + + // Check the decompressor + if (inf.finished()) { + break; + } + if (inf.needsDictionary()) { + throw new ZipException("ZLIB dictionary missing"); + } + } + } catch (DataFormatException ex) { + // Improperly formatted compressed (ZIP) data + String msg = ex.getMessage(); + if (msg == null) { + msg = "Invalid ZLIB data format"; + } + throw new ZipException(msg); + } + } + + private void updateDigest(byte[] bytes, int offset, int count) { + if ((this.localDigester != null) && (bytes != null)) { + this.localDigester.update(bytes, offset, count); + } + } public MD5Digester getLocalDigester() { return localDigester; diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/sys/RpcInputStream.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/sys/RpcInputStream.java index b08fb7d..a602194 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/sys/RpcInputStream.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/sys/RpcInputStream.java @@ -28,7 +28,7 @@ /** * Provides a Perforce-specific extension to the basic Java * InputStream to allow us to intercept methods and implement - * our own extensions.

+ * our own extensions. *

* The current main use is for line-end processing with the * RpcLineEndFilterInputStream filter class; more uses diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/sys/RpcOutputStream.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/sys/RpcOutputStream.java index bacf21c..bb96508 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/sys/RpcOutputStream.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/sys/RpcOutputStream.java @@ -39,19 +39,18 @@ * end processing for text files where needed; everything else is just currently * handled in the superclass without real intervention. *

- *

* Note that for the unzipping we use a contained file output stream rather than * ourself, mostly to avoid recursion... *

* Some of the raw GZUNZIP methods and definitions are copied pretty much as-is - * from the original gkzip stuff.

+ * from the original gkzip stuff. *

* The 10.2 sync / transfer integrity checks are basically implemented here, with * help from the RpcInflaterOutputStream class. The way this is done is the MD5 hashing * has to be done against the incoming 'raw' bytes (i.e. the normalized server-side * form of the file) unless the incoming file type is compressed binary, in which case * we have to hash the uncompressed version. The non-binary hashing is done here; the - * compressed stuff is done in RpcInflaterOutputStream.

+ * compressed stuff is done in RpcInflaterOutputStream. */ public class RpcOutputStream extends FileOutputStream { @@ -92,6 +91,12 @@ public class RpcOutputStream extends FileOutputStream { private MD5Digester localDigester = null; // Also used in the 10.2+ transfer // integrity checks. + private ByteArrayOutputStream tempBufferToStoreCompressedBytes; // Temp Buffer to store de-compressed bytes + + // Temp variables used in "writeConverted" + private int len = 0; + private int start = 0; + public static RpcOutputStream getTmpOutputStream(RpcPerforceFile file) throws IOException { return new RpcOutputStream(file, null, false, false, 1); } @@ -105,8 +110,7 @@ private RpcOutputStream(RpcPerforceFile file, P4Charset p4Charset, boolean isUni super(file); if (file == null) { - throw new NullPointerError( - "Null RpcPerforceFile passed to RpcOutputStream constructor"); + throw new NullPointerError("Null RpcPerforceFile passed to RpcOutputStream constructor"); } if (useLocalDigester) { @@ -132,34 +136,60 @@ private RpcOutputStream(RpcPerforceFile file, P4Charset p4Charset, boolean isUni switch (this.fileType) { case FST_UTF16: case FST_XUTF16: + case FST_UTF16_GUNZIP: + case FST_XUTF16_GUNZIP: converterCharset = CharsetDefs.UTF16; case FST_UTF8: case FST_XUTF8: + case FST_UTF8_GUNZIP: + case FST_XUTF8_GUNZIP: // We only write a UTF8 BOM if no charset was set or it is set to a value other // than UTF8 boolean addBOM = (filesys_utf8bom == 1 || (filesys_utf8bom == 2 && SystemInfo.isWindows())); this.writeUtf8Bom = (converterCharset == null) && addBOM; case FST_UNICODE: case FST_XUNICODE: + case FST_UNICODE_GUNZIP: + case FST_XUNICODE_GUNZIP: if ((converterCharset != null) && (isUnicodeServer || (converterCharset == CharsetDefs.UTF16))) { this.converter = new CharsetConverter(CharsetDefs.UTF8, converterCharset); } this.writeUtf8Bom |= p4Charset != null && p4Charset.isClientBOM(); case FST_TEXT: case FST_XTEXT: + case FST_TEXT_GUNZIP: + case FST_XTEXT_GUNZIP: if (ClientLineEnding.needsLineEndFiltering(lineEnding)) { this.lineEndStream = new RpcLineEndFilterOutputStream(this, this.lineEnding); } + this.inflater = new Inflater(true); + this.crc = new RpcCRC32Checksum(); + tempBufferToStoreCompressedBytes = new ByteArrayOutputStream(); + this.checkedOutStream = new CheckedOutputStream(tempBufferToStoreCompressedBytes, this.crc); + this.outStream = new RpcInflaterOutputStream(this.checkedOutStream, this.inflater, this.localDigester); + this.headerRead = false; + this.footerBytes = new byte[TRAILER_SIZE]; break; + case FST_BINARY_GUNZIP: + case FST_XBINARY_GUNZIP: + case FST_SYMLINK_GUNZIP: + case FST_RESOURCE_GUNZIP: + case FST_XSYMLINK_GUNZIP: + case FST_XRESOURCE_GUNZIP: + case FST_RTEXT_GUNZIP: + case FST_XRTEXT_GUNZIP: + case FST_APPLETEXT_GUNZIP: + case FST_APPLEFILE_GUNZIP: + case FST_XAPPLETEXT_GUNZIP: + case FST_XAPPLEFILE_GUNZIP: case FST_GUNZIP: case FST_XGUNZIP: this.inflater = new Inflater(true); this.crc = new RpcCRC32Checksum(); this.checkedOutStream = new CheckedOutputStream(new BufferedOutputStream(this), this.crc); - this.outStream = new RpcInflaterOutputStream(this.checkedOutStream, this.inflater, - this.localDigester); + this.outStream = new RpcInflaterOutputStream(this.checkedOutStream, this.inflater, this.localDigester); this.headerRead = false; this.footerBytes = new byte[TRAILER_SIZE]; break; @@ -177,6 +207,17 @@ public void close() throws IOException { if (!closed) { closed = true; switch (this.fileType) { + case FST_UTF16_GUNZIP: + case FST_XUTF16_GUNZIP: + case FST_UTF8_GUNZIP: + case FST_XUTF8_GUNZIP: + case FST_UNICODE_GUNZIP: + case FST_XUNICODE_GUNZIP: + case FST_TEXT_GUNZIP: + case FST_XTEXT_GUNZIP: + readTrailer(this.footerBytes); + this.outStream.close(); + this.checkedOutStream.close(); case FST_UTF16: case FST_XUTF16: case FST_UTF8: @@ -192,6 +233,18 @@ public void close() throws IOException { case FST_GUNZIP: case FST_XGUNZIP: + case FST_BINARY_GUNZIP: + case FST_XBINARY_GUNZIP: + case FST_SYMLINK_GUNZIP: + case FST_RESOURCE_GUNZIP: + case FST_XSYMLINK_GUNZIP: + case FST_XRESOURCE_GUNZIP: + case FST_RTEXT_GUNZIP: + case FST_XRTEXT_GUNZIP: + case FST_APPLETEXT_GUNZIP: + case FST_APPLEFILE_GUNZIP: + case FST_XAPPLETEXT_GUNZIP: + case FST_XAPPLEFILE_GUNZIP: readTrailer(this.footerBytes); this.outStream.close(); this.checkedOutStream.close(); @@ -209,30 +262,29 @@ public void close() throws IOException { * This map is assumed to have been constructed as part of the writeFile() * method or something similar. * - * @throws FileEncoderException - * @throws FileDecoderException + * @param map map + * @return source bytes + * @throws FileEncoderException on error + * @throws FileDecoderException on error + * @throws IOException on error */ - public long write(Map map) throws IOException, FileDecoderException, FileEncoderException { if (map == null) { - throw new NullPointerError( - "Null map passed to RpcOutputStream.write(map)"); + throw new NullPointerError("Null map passed to RpcOutputStream.write(map)"); } try { byte[] sourceBytes = (byte[]) map.get(RpcFunctionMapKey.DATA); return writeConverted(sourceBytes); } catch (ClassCastException exc) { - throw new P4JavaError( - "RpcFunctionMapKey.DATA value not byte[] type"); + throw new P4JavaError("RpcFunctionMapKey.DATA value not byte[] type"); } } @Override public void write(byte[] sourceBytes, int off, int len) throws IOException { if (sourceBytes == null) { - throw new NullPointerError( - "Null bytes passed to RpcOutputStream.write()"); + throw new NullPointerError("Null bytes passed to RpcOutputStream.write()"); } if (off < 0) { throw new P4JavaError("Negative offset in RpcOutputStream.write()"); @@ -246,8 +298,7 @@ public void write(byte[] sourceBytes, int off, int len) throws IOException { @Override public void write(byte[] b) throws IOException { if (b == null) { - throw new NullPointerError( - "Null bytes passed to RpcOutputStream.write()"); + throw new NullPointerError("Null bytes passed to RpcOutputStream.write()"); } super.write(b, 0, b.length); } @@ -258,14 +309,15 @@ public void write(byte[] b) throws IOException { * done either here or in the unzip's stream, but (definitely) not * in both places. * - * @param sourceBytes - * @throws IOException - * @throws FileEncoderException - * @throws FileDecoderException + * @param sourceBytes sourceBytes + * @return bytes written + * @throws IOException on error + * @throws FileEncoderException on error + * @throws FileDecoderException on error */ public long writeConverted(byte[] sourceBytes) throws IOException, FileDecoderException, FileEncoderException { - int len = sourceBytes.length; - int start = 0; + len = sourceBytes.length; + start = 0; int bom = 0; if (writeUtf8Bom) { @@ -290,30 +342,9 @@ public long writeConverted(byte[] sourceBytes) throws IOException, FileDecoderEx if (this.localDigester != null) { this.localDigester.update(sourceBytes); } - //Convert line endings before converting to unicode - if (this.lineEndStream != null) { - // Use intermediate buffer to hold line ending converted - // source bytes - ByteArrayOutputStream out = new ByteArrayOutputStream( - RpcPropertyDefs.RPC_DEFAULT_FILE_BUF_SIZE); - this.lineEndStream.write(out, sourceBytes, start, len); - - sourceBytes = out.toByteArray(); - len = sourceBytes.length; - start = 0; - } - - ByteBuffer sourceBuffer = ByteBuffer.wrap(sourceBytes); - - ByteBuffer converted = this.converter.convert(sourceBuffer); - if (converted != null) { - sourceBytes = converted.array(); - start = converted.position(); - len = converted.limit(); - } else { - len = 0; - } - + // Convert line endings before converting to unicode + sourceBytes = convertLineEnding(sourceBytes); + sourceBytes = convertCharset(sourceBytes); if (len <= 0) { return 0; } @@ -338,8 +369,51 @@ public long writeConverted(byte[] sourceBytes) throws IOException, FileDecoderEx bytesWritten = len + bom - start; break; + case FST_UNICODE_GUNZIP: + case FST_UTF16_GUNZIP: + case FST_XUTF16_GUNZIP: + case FST_XUNICODE_GUNZIP: + sourceBytes = decompressSourceBytes(sourceBytes); + // Convert to local charset if set + if (this.converter != null) { + // Convert line endings before converting to unicode + sourceBytes = convertLineEnding(sourceBytes); + sourceBytes = convertCharset(sourceBytes); + if (len <= 0) { + return 0; + } + this.write(sourceBytes, start, len); + bytesWritten = len + bom - start; + break; + } + + case FST_TEXT_GUNZIP: + case FST_UTF8_GUNZIP: + case FST_XTEXT_GUNZIP: + case FST_XUTF8_GUNZIP: + sourceBytes = decompressSourceBytes(sourceBytes); + if (this.lineEndStream != null) { + this.lineEndStream.write(sourceBytes, start, len); + } else { + this.write(sourceBytes, start, len); + } + bytesWritten = len + bom - start; + break; + case FST_GUNZIP: case FST_XGUNZIP: + case FST_BINARY_GUNZIP: + case FST_XBINARY_GUNZIP: + case FST_SYMLINK_GUNZIP: + case FST_RESOURCE_GUNZIP: + case FST_XSYMLINK_GUNZIP: + case FST_XRESOURCE_GUNZIP: + case FST_RTEXT_GUNZIP: + case FST_XRTEXT_GUNZIP: + case FST_APPLETEXT_GUNZIP: + case FST_APPLEFILE_GUNZIP: + case FST_XAPPLETEXT_GUNZIP: + case FST_XAPPLEFILE_GUNZIP: // NOTE: We always copy the last eight bytes of what's passed into // us here so we can use it for trailer / footer calculation @@ -351,69 +425,7 @@ public long writeConverted(byte[] sourceBytes) throws IOException, FileDecoderEx // can almost certainly be reworked in a more efficient way // in later versions (using FilterOutputStream?) --- HR. - long bytesWrittenPrior = this.outStream.getBytesWritten(); - - if (!headerRead) { - ByteArrayInputStream byteStream - = new ByteArrayInputStream(sourceBytes, 0, len); - readHeader(byteStream, new RpcCRC32Checksum()); - headerRead = true; - int bytesAvailable = byteStream.available(); - if (bytesAvailable > 0) { - this.outStream.write(sourceBytes, (len - bytesAvailable), - bytesAvailable); - - if (bytesAvailable >= TRAILER_SIZE) { - System.arraycopy( - sourceBytes, - (len - TRAILER_SIZE), - this.footerBytes, - 0, - TRAILER_SIZE); - } else { - // Copy what we can; if it turns out the rest was in the next - // packet, we'll detect that then... - - System.arraycopy( - sourceBytes, - (len - bytesAvailable), - this.footerBytes, - 0, - bytesAvailable); - } - } - } else { - this.outStream.write(sourceBytes, 0, len); - - if (len >= TRAILER_SIZE) { - System.arraycopy( - sourceBytes, - (len - TRAILER_SIZE), - this.footerBytes, - 0, - TRAILER_SIZE); - } else { - // first move the last (TRAILER_SIZE-len) bytes to the - // beginning of the footer - - System.arraycopy( - this.footerBytes, - len, - this.footerBytes, - 0, - TRAILER_SIZE - len); - - // Add to what's (hopefully) there already... - - System.arraycopy( - sourceBytes, - 0, - this.footerBytes, - TRAILER_SIZE - len, - len); - } - } - + long bytesWrittenPrior = decompress(sourceBytes, len); bytesWritten = this.outStream.getBytesWritten() - bytesWrittenPrior; break; @@ -428,6 +440,104 @@ public long writeConverted(byte[] sourceBytes) throws IOException, FileDecoderEx return bytesWritten; } + /** + * Uncompress the source bytes and store them in "tempBufferToStoreCompressedBytes" + * + * @param sourceBytes + * @return + * @throws IOException + */ + private byte[] decompressSourceBytes(byte[] sourceBytes) throws IOException { + decompress(sourceBytes, len); + byte[] uncompressedBytes = tempBufferToStoreCompressedBytes.toByteArray(); + len = uncompressedBytes.length; + tempBufferToStoreCompressedBytes.close(); + return uncompressedBytes; + } + + /** + * Extracted the code to method because of redundancy + * + * @param sourceBytes + * @return + * @throws FileDecoderException + * @throws FileEncoderException + */ + private byte[] convertCharset(byte[] sourceBytes) throws FileDecoderException, FileEncoderException { + ByteBuffer sourceBuffer = ByteBuffer.wrap(sourceBytes); + ByteBuffer converted = this.converter.convert(sourceBuffer); + if (converted != null) { + sourceBytes = converted.array(); + start = converted.position(); + len = converted.limit(); + } else { + len = 0; + } + return sourceBytes; + } + + /** + * Extracted the code to method because of redundancy + * + * @param sourceBytes + * @return + * @throws IOException + */ + private byte[] convertLineEnding(byte[] sourceBytes) throws IOException { + if (this.lineEndStream != null) { + // Use intermediate buffer to hold line ending converted + // source bytes + ByteArrayOutputStream out = new ByteArrayOutputStream(RpcPropertyDefs.RPC_DEFAULT_FILE_BUF_SIZE); + this.lineEndStream.write(out, sourceBytes, start, len); + + sourceBytes = out.toByteArray(); + len = sourceBytes.length; + start = 0; + } + return sourceBytes; + } + + private long decompress(byte[] sourceBytes, int len) throws IOException { + long bytesWrittenPrior = this.outStream.getBytesWritten(); + + if (!headerRead) { + int bytesAvailable; + try (ByteArrayInputStream byteStream = new ByteArrayInputStream(sourceBytes, 0, len)) { + readHeader(byteStream, new RpcCRC32Checksum()); + headerRead = true; + bytesAvailable = byteStream.available(); + } + if (bytesAvailable > 0) { + this.outStream.write(sourceBytes, (len - bytesAvailable), bytesAvailable); + + if (bytesAvailable >= TRAILER_SIZE) { + System.arraycopy(sourceBytes, (len - TRAILER_SIZE), this.footerBytes, 0, TRAILER_SIZE); + } else { + // Copy what we can; if it turns out the rest was in the next + // packet, we'll detect that then... + + System.arraycopy(sourceBytes, (len - bytesAvailable), this.footerBytes, 0, bytesAvailable); + } + } + } else { + this.outStream.write(sourceBytes, 0, len); + + if (len >= TRAILER_SIZE) { + System.arraycopy(sourceBytes, (len - TRAILER_SIZE), this.footerBytes, 0, TRAILER_SIZE); + } else { + // first move the last (TRAILER_SIZE-len) bytes to the + // beginning of the footer + + System.arraycopy(this.footerBytes, len, this.footerBytes, 0, TRAILER_SIZE - len); + + // Add to what's (hopefully) there already... + + System.arraycopy(sourceBytes, 0, this.footerBytes, TRAILER_SIZE - len, len); + } + } + return bytesWrittenPrior; + } + @Override public void write(int b) throws IOException { super.write(b); diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/sys/RpcPerforceFile.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/sys/RpcPerforceFile.java index 51a9622..4e4f1e7 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/sys/RpcPerforceFile.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/sys/RpcPerforceFile.java @@ -9,12 +9,17 @@ import com.perforce.p4java.impl.generic.sys.ISystemFileCommandsHelper; import com.perforce.p4java.impl.mapbased.rpc.sys.helper.SymbolicLinkHelper; import com.perforce.p4java.impl.mapbased.rpc.sys.helper.SysFileHelperBridge; +import org.apache.commons.io.FileUtils; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.nio.channels.FileChannel; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.UUID; /** * Encapsulates and implements a lot of Perforce-specific information @@ -47,13 +52,11 @@ public static String createTempFileName(String tmpDirName) { tmpDir = new File(tmpDirName); } - File tmpFile = File.createTempFile(TMP_FILE_PFX, TMP_FILE_SFX, - tmpDir); + File tmpFile = File.createTempFile(TMP_FILE_PFX, TMP_FILE_SFX, tmpDir); return tmpFile.getPath(); } catch (IOException ioexc) { - Log.error( - "Unable to create temporary file: " + ioexc.getLocalizedMessage()); + Log.error("Unable to create temporary file: " + ioexc.getLocalizedMessage()); } return null; @@ -63,34 +66,29 @@ public RpcPerforceFile(String fileName, String fileTypeStr) { super(fileName); if (fileName == null) { // We don't need or want (much less expect) null paths in the API: - throw new NullPointerError( - "Null file name passed to RpcPerforceFile constructor"); + throw new NullPointerError("Null file name passed to RpcPerforceFile constructor"); } this.fileType = RpcPerforceFileType.decodeFromServerString(fileTypeStr); - this.lineEnding = ClientLineEnding.decodeFromServerString( - fileTypeStr, this.fileType); + this.lineEnding = ClientLineEnding.decodeFromServerString(fileTypeStr, this.fileType); } public RpcPerforceFile(String fileName, RpcPerforceFileType fileType) { super(fileName); if (fileName == null) { // We don't need or want (much less expect) null paths in the API: - throw new NullPointerError( - "Null file name passed to RpcPerforceFile constructor"); + throw new NullPointerError("Null file name passed to RpcPerforceFile constructor"); } this.fileType = fileType; this.lineEnding = ClientLineEnding.FST_L_LOCAL; } - public RpcPerforceFile(String fileName, RpcPerforceFileType fileType, - ClientLineEnding lineEnding) { + public RpcPerforceFile(String fileName, RpcPerforceFileType fileType, ClientLineEnding lineEnding) { super(fileName); if (fileName == null) { // We don't need or want (much less expect) null paths in the API: - throw new NullPointerError( - "Null file name passed to RpcPerforceFile constructor"); + throw new NullPointerError("Null file name passed to RpcPerforceFile constructor"); } this.fileType = fileType; @@ -112,11 +110,14 @@ public boolean renameTo(File targetFile) { * Another special version of renameTo to support RPC implementation- * specific needs. This one allows callers to specify whether to * always copy as-is (no munging). + * + * @param targetFile targetFile + * @param alwaysCopyUnMunged alwaysCopyUnMunged + * @return ok */ public boolean renameTo(File targetFile, boolean alwaysCopyUnMunged) { if (targetFile == null) { - throw new NullPointerError( - "Null target file in RpcPerforceFile.renameTo"); + throw new NullPointerError("Null target file in RpcPerforceFile.renameTo"); } try { if ((this.fileType == null) || alwaysCopyUnMunged || canCopyAsIs()) { @@ -127,6 +128,10 @@ public boolean renameTo(File targetFile, boolean alwaysCopyUnMunged) { targetFile.delete(); if (super.renameTo(targetFile)) { return true; + } else if (this.getCanonicalPath().contains(targetFile.getCanonicalPath()) + || targetFile.getCanonicalPath().contains(this.getCanonicalPath())) { + return renameOverlapping(targetFile); + } else { return copyTo(targetFile); } @@ -135,8 +140,59 @@ public boolean renameTo(File targetFile, boolean alwaysCopyUnMunged) { return decodeTo(targetFile); } } catch (IOException ioexc) { - Log.error("Unexpected problem with renaming / copying file '" - + targetFile.getName() + "': " + ioexc.getLocalizedMessage()); + Log.error("Unexpected problem with renaming / copying file '" + targetFile.getName() + "': " + ioexc.getLocalizedMessage()); + Log.exception(ioexc); + } + return false; + } + + private boolean renameOverlapping(File targetFile) { + // Either target is a substring (directory) of source, + // or source is a substring of target (target has a + // directory subpath which is the as source) + // or source or target has a component which is not a directory. + try { + // Try moving the current name to a temporary name, and then trying again. + if (targetFile.getCanonicalPath().contains(this.getCanonicalPath())) { + // Source is a substring of the target + + // Rename source to tmp + Path tmpFile = Paths.get(this.getParent(), TMP_FILE_PFX + UUID.randomUUID()); + FileUtils.moveFile(this, tmpFile.toFile()); + + // If the old name directory doesn't exist, make it now. + targetFile.getParentFile().mkdirs(); + + // Move and rename to target file + FileUtils.moveFile(tmpFile.toFile(), targetFile); + return true; + } else { + // Target is a substring of the source + + // Scan target for other files + String[] contents = targetFile.list(); + int count = 0; + if (contents != null) { + count = contents.length; + } + if (count > 1) { + return false; + } + + // Change the current name to a temporary name in the directory + Path parentDir = this.getParentFile().toPath(); + Path tempDir = Paths.get(parentDir + TMP_FILE_PFX + UUID.randomUUID()); + Files.move(parentDir, tempDir); + + Path tmpFile = Paths.get(tempDir.toString(), this.getName()); + FileUtils.moveFile(tmpFile.toFile(), targetFile); + + // Remove temp name directory + FileUtils.forceDelete(tempDir.toFile()); + return true; + } + } catch (IOException ioexc) { + Log.error("Unexpected problem with renaming / copying file '" + targetFile.getName() + "': " + ioexc.getLocalizedMessage()); Log.exception(ioexc); } return false; @@ -152,16 +208,17 @@ private boolean setWritable(String filePath) { } /** - * Copy this file to another (target file). Assumes no - * decoding necessary. If the target file exists, + * Copy this file to another (target file). Assumes no decoding necessary. If the target file exists, * it's removed before copying. + * + * @param targetFile targetFile + * @return ok + * @throws IOException on error */ - public boolean copyTo(File targetFile) throws IOException { if (targetFile == null) { - throw new NullPointerError( - "Null target file in RpcPerforceFile.copyTo"); + throw new NullPointerError("Null target file in RpcPerforceFile.copyTo"); } if (targetFile.exists()) { @@ -178,9 +235,7 @@ public boolean copyTo(File targetFile) throws IOException { //Warn if file still exists if (targetFile.exists()) { // FIXME: cope better with delete fail -- HR. - Log - .warn("Unable to delete target file for copy in RpcPerforceFile.copyTo; target: '" - + targetFile.getPath()); + Log.warn("Unable to delete target file for copy in RpcPerforceFile.copyTo; target: '" + targetFile.getPath()); } } } @@ -199,13 +254,10 @@ public boolean copyTo(File targetFile) throws IOException { if ((sourceChannel != null) && (targetChannel != null)) { // Light fuse, stand back... - bytesTransferred = sourceChannel.transferTo( - 0, sourceChannel.size(), targetChannel); + bytesTransferred = sourceChannel.transferTo(0, sourceChannel.size(), targetChannel); if (bytesTransferred != sourceChannel.size()) { - Log.error("channel copy for copyTo operation failed with fewer bytes" - + " transferred than expected; expected: " + sourceChannel.size() - + "; saw: " + bytesTransferred); + Log.error("channel copy for copyTo operation failed with fewer bytes" + " transferred than expected; expected: " + sourceChannel.size() + "; saw: " + bytesTransferred); return false; // FIXME: clean up... } @@ -215,29 +267,25 @@ public boolean copyTo(File targetFile) throws IOException { try { if (sourceChannel != null) sourceChannel.close(); } catch (Exception exc) { - Log.warn("source channel file close error in RpcPerforceFile.copyTo(): " - + exc.getLocalizedMessage()); + Log.warn("source channel file close error in RpcPerforceFile.copyTo(): " + exc.getLocalizedMessage()); Log.exception(exc); } try { if (targetChannel != null) targetChannel.close(); } catch (Exception exc) { - Log.warn("target channel file close error in RpcPerforceFile.copyTo(): " - + exc.getLocalizedMessage()); + Log.warn("target channel file close error in RpcPerforceFile.copyTo(): " + exc.getLocalizedMessage()); Log.exception(exc); } try { if (inStream != null) inStream.close(); } catch (Exception exc) { - Log.warn("instream file close error in RpcPerforceFile.copyTo(): " - + exc.getLocalizedMessage()); + Log.warn("instream file close error in RpcPerforceFile.copyTo(): " + exc.getLocalizedMessage()); Log.exception(exc); } try { if (outStream != null) outStream.close(); } catch (Exception exc) { - Log.warn("outstream file close error in RpcPerforceFile.copyTo(): " - + exc.getLocalizedMessage()); + Log.warn("outstream file close error in RpcPerforceFile.copyTo(): " + exc.getLocalizedMessage()); Log.exception(exc); } } @@ -248,8 +296,7 @@ public boolean copyTo(File targetFile) throws IOException { public boolean decodeTo(File targetFile) throws IOException { if (targetFile == null) { - throw new NullPointerError( - "Null target file in RpcPerforceFile.decodeTo"); + throw new NullPointerError("Null target file in RpcPerforceFile.decodeTo"); } return copyTo(targetFile); @@ -276,20 +323,20 @@ public void setLineEnding(ClientLineEnding lineEnding) { * GKZIP decoding or munging, etc. Currently all file types can * be copied as-is, but this wasn't always true and may not always * be true... + * + * @return ok */ public boolean canCopyAsIs() { return true; } /** - * @see java.io.File#equals() + * @see java.io.File#equals(Object) */ @Override public boolean equals(Object obj) { if ((obj != null) && (obj instanceof RpcPerforceFile)) { - if ((super.equals((File) obj)) && - (((RpcPerforceFile) obj).getFileType() == this.fileType) && - (((RpcPerforceFile) obj).getLineEnding() == this.lineEnding)) { + if ((super.equals((File) obj)) && (((RpcPerforceFile) obj).getFileType() == this.fileType) && (((RpcPerforceFile) obj).getLineEnding() == this.lineEnding)) { return true; } } @@ -313,6 +360,10 @@ public boolean isSymlink() { /** * Check if the file or symbolic link exists. + * + * @param file file + * @param fstSymlink fstSymlink + * @return exists */ public static boolean fileExists(File file, boolean fstSymlink) { diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/sys/RpcPerforceFileType.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/sys/RpcPerforceFileType.java index 8aafa52..7640af6 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/sys/RpcPerforceFileType.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/sys/RpcPerforceFileType.java @@ -3,13 +3,6 @@ */ package com.perforce.p4java.impl.mapbased.rpc.sys; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.nio.ByteBuffer; -import java.nio.charset.Charset; - import com.perforce.p4java.CharsetConverter; import com.perforce.p4java.CharsetDefs; import com.perforce.p4java.Log; @@ -27,9 +20,16 @@ import com.perforce.p4java.impl.mapbased.rpc.sys.helper.TextNormalizationHelper; import com.perforce.p4java.impl.mapbased.server.Server; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.nio.charset.Charset; + /** - * Definitions for Perforce client and server file types.

- * + * Definitions for Perforce client and server file types. + *

* Perforce defines a surprising variety of basic file types * and associated modifiers that determine things like how to * send and receive file contents between the client and the @@ -38,8 +38,8 @@ * file metadata. These types and the associated panoply of * methods, etc., are mostly used in the clientCheckFile, * clientOpen, clientClose, clientWrite, etc. methods on the - * various client function classes.

- * + * various client function classes. + *

* A file's type is stored in the server for all known files, * (see e.g. "p4 help typemap" and "p4 help filetypes"), * and in most cases we simply accept what we're given if we @@ -49,525 +49,517 @@ * process depends on the server's xlevel protocol variable: *

  * 	- xfiles unset: return text, binary.
- * 	- xfiles >= 0: also return xtext, xbinary.
- * 	- xfiles >= 1: also return symlink.
- * 	- xfiles >= 2; also return resource (mac resource file).
- * 	- xfiles >= 3; also return ubinary
- * 	- xfiles >= 4; also return apple
+ * 	- xfiles >= 0: also return xtext, xbinary.
+ * 	- xfiles >= 1: also return symlink.
+ * 	- xfiles >= 2; also return resource (mac resource file).
+ * 	- xfiles >= 3; also return ubinary
+ * 	- xfiles >= 4; also return apple
  * 
* In general, the client has to honour the server's xlevel * capabilities, so the client may have to do a bit of work * to get things right here. - * + *

* Unfortunately, in some cases it's very difficult to know * what Perforce type a file should be, and there's a bunch * of digging around that must be done to intuit the proper - * type for files the server doesn't (yet) know about.

- * + * type for files the server doesn't (yet) know about. + *

* Also somewhat unfortunately, the file type is encoded * quite differently depending on whether it's coming from * the server (usually encoded as a string representation of * hex numbers) or going to the server (where it's usually * done as plain old "text" or "ubinary", etc.). - * - * */ // See p4/client/clientservice.cc public enum RpcPerforceFileType { - - // Basic file types: - - FST_TEXT, // file is text - FST_BINARY, // file is binary - FST_GZIP, // file is gzip - FST_DIRECTORY, // file is a directory - FST_SYMLINK, // it's a symlink - FST_RESOURCE, // Macintosh resource file - FST_SPECIAL, // not a regular file - FST_MISSING, // no file at all - FST_CANTTELL, // can read file to find out - FST_EMPTY, // file is empty - FST_UNICODE, // file is unicode (utf-8?) - FST_GUNZIP, // stream is gzip - FST_UTF8, // stream is utf8 - FST_UTF16, // stream is utf8 convert to utf16 - - // Derived file types (i.e. modified basic types): - // (forbidden types are given below for completeness; - // these are usually weeded out or detected elsewhere) - - FST_ATEXT, // append-only text - FST_XTEXT, // executable text - FST_RTEXT, // raw text - FST_RXTEXT, // executable raw text - FST_CBINARY, // pre-compressed binary - FST_XBINARY, // executable binary - FST_XSYMLINK, // forbidden -- not used - FST_XRESOURCE, // ditto - FST_APPLETEXT, // apple format text - FST_APPLEFILE, // apple format binary - FST_XAPPLEFILE, // executable apple format binary - FST_XAPPLETEXT, // forbidden - FST_XUNICODE, // executable unicode text - FST_XRTEXT, // executable raw text (also forbidden) - FST_XUTF8, // executable utf8 - FST_XUTF16, // executable utf8 convert to utf16 - FST_XGUNZIP, // executable in gkzip form - FST_RCS // RCS temporary file: raw text, sync on close - ; - - public static final String TRACE_PREFIX = "RpcPerforceFileType"; - private static final ISystemFileCommandsHelper fileCommands - = SysFileHelperBridge.getSysFileCommands(); - - private enum CtAction { - OK, // use forceType/the discovered type - ASS, // missing/unreadable/empty: assume it is forceType/text - CHKSZ, // size is to big for default, use alternate - SUBST, // server can't handle it: substitute altType - CANT // just can't be added - } - - public static class RpcServerTypeStringSpec { - - private String serverTypeString = null; - private RpcMessage error = null; + + // Basic file types: + + FST_TEXT, // file is text + FST_BINARY, // file is binary + FST_GZIP, // file is gzip + FST_DIRECTORY, // file is a directory + FST_SYMLINK, // it's a symlink + FST_RESOURCE, // Macintosh resource file + FST_SPECIAL, // not a regular file + FST_MISSING, // no file at all + FST_CANTTELL, // can read file to find out + FST_EMPTY, // file is empty + FST_UNICODE, // file is unicode (utf-8?) + FST_GUNZIP, // stream is gzip (deprecated 2022.1) + FST_UTF8, // stream is utf8 + FST_UTF16, // stream is utf8 convert to utf16 + + // File Type with compression modifier + + FST_TEXT_GUNZIP, // compressed text file + FST_BINARY_GUNZIP, // compressed + FST_XTEXT_GUNZIP, // compressed + FST_XBINARY_GUNZIP, // compressed + FST_SYMLINK_GUNZIP, // compressed + FST_RESOURCE_GUNZIP, // compressed + FST_XSYMLINK_GUNZIP, // compressed + FST_XRESOURCE_GUNZIP, // compressed + FST_UNICODE_GUNZIP, // compressed + FST_RTEXT_GUNZIP, // compressed + FST_XUNICODE_GUNZIP, // compressed + FST_XRTEXT_GUNZIP, // compressed + FST_APPLETEXT_GUNZIP, // compressed + FST_APPLEFILE_GUNZIP, // compressed + FST_XAPPLETEXT_GUNZIP, // compressed + FST_XAPPLEFILE_GUNZIP, // compressed + FST_UTF8_GUNZIP, // compressed + FST_XUTF8_GUNZIP, // compressed + FST_UTF16_GUNZIP, // compressed + FST_XUTF16_GUNZIP, // compressed + + // Derived file types (i.e. modified basic types): + // (forbidden types are given below for completeness; + // these are usually weeded out or detected elsewhere) + + FST_ATEXT, // append-only text + FST_XTEXT, // executable text + FST_RTEXT, // raw text + FST_RXTEXT, // executable raw text + FST_CBINARY, // pre-compressed binary + FST_XBINARY, // executable binary + FST_XSYMLINK, // forbidden -- not used + FST_XRESOURCE, // ditto + FST_APPLETEXT, // apple format text + FST_APPLEFILE, // apple format binary + FST_XAPPLEFILE, // executable apple format binary + FST_XAPPLETEXT, // forbidden + FST_XUNICODE, // executable unicode text + FST_XRTEXT, // executable raw text (also forbidden) + FST_XUTF8, // executable utf8 + FST_XUTF16, // executable utf8 convert to utf16 + FST_XGUNZIP, // executable in gkzip form (deprecated 2022.1) + FST_RCS // RCS temporary file: raw text, sync on close + ; + + public static final String TRACE_PREFIX = "RpcPerforceFileType"; + private static final ISystemFileCommandsHelper fileCommands = SysFileHelperBridge.getSysFileCommands(); + + private enum CtAction { + OK, // use forceType/the discovered type + ASS, // missing/unreadable/empty: assume it is forceType/text + CHKSZ, // size is to big for default, use alternate + SUBST, // server can't handle it: substitute altType + CANT // just can't be added + } + + public static class RpcServerTypeStringSpec { + + private String serverTypeString = null; + private RpcMessage error = null; public RpcServerTypeStringSpec(String str, RpcMessage error) { - this.serverTypeString = str; - this.error = error; - } + this.serverTypeString = str; + this.error = error; + } - public String getServerTypeString() { - return serverTypeString; - } + public String getServerTypeString() { + return serverTypeString; + } - public RpcMessage getMsg() { - return error; - } - } + public RpcMessage getMsg() { + return error; + } + } - private static class ActionTableElement { + private static class ActionTableElement { public RpcPerforceFileType checkType = null; public int xlevel = 0; public CtAction[] ctActions = new CtAction[2]; public String type = null; public String altType = null; - public String cmpType = null; - - ActionTableElement(RpcPerforceFileType checkType, - int xlevel, - CtAction ctActions0, - CtAction ctActions1, - String type, - String altType, - String cmpType) { - - this.checkType = checkType; - this.xlevel = xlevel; - this.ctActions[0] = ctActions0; // action to take if element's xlevel > server's xlevel - this.ctActions[1] = ctActions1; // action to take if element's xlevel <= server's xlevel - this.type = type; - this.altType = altType; - this.cmpType = cmpType; - } - - ActionTableElement(RpcPerforceFileType checkType, - int xlevel, - CtAction ctActions0, - CtAction ctActions1, - String type, - String altType) { - - this(checkType, xlevel, ctActions0, ctActions1, type, altType, null); - } - } - - // Symbolic link capable? + public String cmpType = null; + + ActionTableElement(RpcPerforceFileType checkType, int xlevel, CtAction ctActions0, CtAction ctActions1, String type, String altType, String cmpType) { + + this.checkType = checkType; + this.xlevel = xlevel; + this.ctActions[0] = ctActions0; // action to take if element's xlevel > server's xlevel + this.ctActions[1] = ctActions1; // action to take if element's xlevel <= server's xlevel + this.type = type; + this.altType = altType; + this.cmpType = cmpType; + } + + ActionTableElement(RpcPerforceFileType checkType, int xlevel, CtAction ctActions0, CtAction ctActions1, String type, String altType) { + + this(checkType, xlevel, ctActions0, ctActions1, type, altType, null); + } + } + + // Symbolic link capable? private static CtAction symlinkAction = SymbolicLinkHelper.isSymbolicLinkCapable() ? CtAction.OK : CtAction.CANT; - // See p4/client/clientservice.cc - private static final ActionTableElement[] actionTable = { - new ActionTableElement(FST_TEXT, 0, CtAction.OK, CtAction.CHKSZ, "text", "text", "ctext"), - new ActionTableElement(FST_XTEXT, 0, CtAction.SUBST, CtAction.CHKSZ, "xtext", "text", "text+Cx"), - new ActionTableElement(FST_BINARY, 0, CtAction.OK, CtAction.OK, "binary", "binary"), - new ActionTableElement(FST_XBINARY, 0, CtAction.SUBST, CtAction.OK, "xbinary", "binary"), - new ActionTableElement(FST_APPLEFILE, 4, CtAction.SUBST, CtAction.OK, "apple", "binary"), - new ActionTableElement(FST_XAPPLEFILE, 4, CtAction.SUBST, CtAction.OK, "apple+x", "binary"), - new ActionTableElement(FST_CBINARY, 3, CtAction.SUBST, CtAction.OK, "ubinary", "binary"), - new ActionTableElement(FST_SYMLINK, 1, CtAction.CANT, symlinkAction, "symlink", null), - new ActionTableElement(FST_RESOURCE, 2, CtAction.CANT, CtAction.OK, "resource", null), - new ActionTableElement(FST_SPECIAL, -1, CtAction.CANT, CtAction.CANT, "special", null), - new ActionTableElement(FST_DIRECTORY, -1, CtAction.CANT, CtAction.CANT, "directory", null), - new ActionTableElement(FST_MISSING, -1, CtAction.ASS, CtAction.ASS, "missing", "text"), - new ActionTableElement(FST_CANTTELL, -1, CtAction.ASS, CtAction.ASS, "unreadable", "text"), - new ActionTableElement(FST_EMPTY, -1, CtAction.ASS, CtAction.ASS, "empty", "text"), - new ActionTableElement(FST_UNICODE, 5, CtAction.SUBST, CtAction.CHKSZ, "unicode", "text", "unicode+C"), - new ActionTableElement(FST_XUNICODE, 5, CtAction.SUBST, CtAction.CHKSZ, "xunicode", "text", "xunicode+C"), - new ActionTableElement(FST_UTF16, 6, CtAction.SUBST, CtAction.CHKSZ, "utf16", "binary", "utf16+C"), - new ActionTableElement(FST_XUTF16, 6, CtAction.SUBST, CtAction.CHKSZ, "xutf16", "binary", "xutf16+C"), - new ActionTableElement(FST_UTF8, 7, CtAction.SUBST, CtAction.CHKSZ, "utf8", "text", "utf8+C"), - new ActionTableElement(FST_XUTF8, 7, CtAction.SUBST, CtAction.CHKSZ, "xutf8", "text", "xutf8+C") - }; - - private static final byte[] pdfMagic = { '%', 'P', 'D', 'F', '-' }; - - private static final byte[][] cBinaryMagicTable = { - {'G', 'I', 'F'}, // GIF - {(byte) 0377, (byte) 0330, (byte) 0377, (byte) 0340}, // JPEG - {(byte) 0377, (byte) 0330, (byte) 0377, (byte) 0341}, // EXIF - {(byte) 037, (byte) 0213}, // GZIP - {(byte) 0377, (byte) 037}, // compa (?) - {(byte) 037, (byte) 0235}, // compr (?) - { 'P', 'K', (byte) 003, (byte) 004 }, // normal PKZIP, including JAR, WAR, etc. - {'P', 'K', (byte) 005, (byte) 006}, // empty PKZIP, including JAR, WAR, etc. - {(byte) 0211, 'P', 'N', 'G'}, // PNG - {(byte) 0xCA, (byte) 0xFE, (byte) 0xBA, (byte) 0xBE}, // Java class file, natch... - }; - - /** - * Decode the file type from the string sent by the server. This - * is (usually) a three-character hex encoding, e.g. "101" or - * "01D". - */ - - public static RpcPerforceFileType decodeFromServerString(String str) { - + // See p4/client/clientservice.cc + private static final ActionTableElement[] actionTable = {new ActionTableElement(FST_TEXT, 0, CtAction.OK, CtAction.CHKSZ, "text", "text", "ctext"), new ActionTableElement(FST_XTEXT, 0, CtAction.SUBST, CtAction.CHKSZ, "xtext", "text", "text+Cx"), new ActionTableElement(FST_BINARY, 0, CtAction.OK, CtAction.OK, "binary", "binary"), new ActionTableElement(FST_XBINARY, 0, CtAction.SUBST, CtAction.OK, "xbinary", "binary"), new ActionTableElement(FST_APPLEFILE, 4, CtAction.SUBST, CtAction.OK, "apple", "binary"), new ActionTableElement(FST_XAPPLEFILE, 4, CtAction.SUBST, CtAction.OK, "apple+x", "binary"), new ActionTableElement(FST_CBINARY, 3, CtAction.SUBST, CtAction.OK, "ubinary", "binary"), new ActionTableElement(FST_SYMLINK, 1, CtAction.CANT, symlinkAction, "symlink", null), new ActionTableElement(FST_RESOURCE, 2, CtAction.CANT, CtAction.OK, "resource", null), new ActionTableElement(FST_SPECIAL, -1, CtAction.CANT, CtAction.CANT, "special", null), new ActionTableElement(FST_DIRECTORY, -1, CtAction.CANT, CtAction.CANT, "directory", null), new ActionTableElement(FST_MISSING, -1, CtAction.ASS, CtAction.ASS, "missing", "text"), new ActionTableElement(FST_CANTTELL, -1, CtAction.ASS, CtAction.ASS, "unreadable", "text"), new ActionTableElement(FST_EMPTY, -1, CtAction.ASS, CtAction.ASS, "empty", "text"), new ActionTableElement(FST_UNICODE, 5, CtAction.SUBST, CtAction.CHKSZ, "unicode", "text", "unicode+C"), new ActionTableElement(FST_XUNICODE, 5, CtAction.SUBST, CtAction.CHKSZ, "xunicode", "text", "xunicode+C"), new ActionTableElement(FST_UTF16, 6, CtAction.SUBST, CtAction.CHKSZ, "utf16", "binary", "utf16+C"), new ActionTableElement(FST_XUTF16, 6, CtAction.SUBST, CtAction.CHKSZ, "xutf16", "binary", "xutf16+C"), new ActionTableElement(FST_UTF8, 7, CtAction.SUBST, CtAction.CHKSZ, "utf8", "text", "utf8+C"), new ActionTableElement(FST_XUTF8, 7, CtAction.SUBST, CtAction.CHKSZ, "xutf8", "text", "xutf8+C")}; + + private static final byte[] pdfMagic = {'%', 'P', 'D', 'F', '-'}; + + private static final byte[][] cBinaryMagicTable = {{'G', 'I', 'F'}, // GIF + {(byte) 0377, (byte) 0330, (byte) 0377, (byte) 0340}, // JPEG + {(byte) 0377, (byte) 0330, (byte) 0377, (byte) 0341}, // EXIF + {(byte) 037, (byte) 0213}, // GZIP + {(byte) 0377, (byte) 037}, // compa (?) + {(byte) 037, (byte) 0235}, // compr (?) + {'P', 'K', (byte) 003, (byte) 004}, // normal PKZIP, including JAR, WAR, etc. + {'P', 'K', (byte) 005, (byte) 006}, // empty PKZIP, including JAR, WAR, etc. + {(byte) 0211, 'P', 'N', 'G'}, // PNG + {(byte) 0xCA, (byte) 0xFE, (byte) 0xBA, (byte) 0xBE}, // Java class file, natch... + }; + + /** + * Decode the file type from the string sent by the server. This + * is (usually) a three-character hex encoding, e.g. "101" or + * "01D". + * + * @param str string + * @return type + */ + public static RpcPerforceFileType decodeFromServerString(String str) { + if (str == null) { - return FST_TEXT; - } + return FST_TEXT; + } // Copied wholesale from the C++ API... - // fileType [ lineType [ uncompress ] ] + // fileType [ lineType [ uncompress ] ] - int tf = 0; + int tf = 0; @SuppressWarnings("unused") // See ClientLineEnding.decodeFromServerString() int tl = 0; - int tu = 0; - - switch (str.length()) { - default: - case 3: tu = StringHelper.hexcharToInt(str.charAt(2)); - case 2: tl = StringHelper.hexcharToInt(str.charAt(1)); - case 1: tf = StringHelper.hexcharToInt(str.charAt(0)); - case 0: // nothing??? ; - } - - // Map '[ uncompress ] fileType' into FileSysType. - - switch (( tu << 8 ) | tf) - { - // Normal. - - case 0x000: return FST_TEXT; - case 0x001: return FST_BINARY; - case 0x002: return FST_XTEXT; - case 0x003: return FST_XBINARY; - case 0x004: return FST_SYMLINK; - case 0x005: return FST_RESOURCE; - case 0x006: return FST_XSYMLINK; - case 0x007: return FST_XRESOURCE; - case 0x008: return FST_UNICODE; - case 0x009: return FST_RTEXT; - case 0x00A: return FST_XUNICODE; - case 0x00B: return FST_XRTEXT; - case 0x00C: return FST_APPLETEXT; - case 0x00D: return FST_APPLEFILE; - case 0x00E: return FST_XAPPLETEXT; - case 0x00F: return FST_XAPPLEFILE; - case 0x014: return FST_UTF8; - case 0x016: return FST_XUTF8; - case 0x018: return FST_UTF16; - case 0x01A: return FST_XUTF16; - - // Uncompressing. - - case 0x101: return FST_GUNZIP; - case 0x103: return FST_XGUNZIP; - - // Stop-gap. - - default: return FST_BINARY; - } - } - - /** - * Checking for executable file types - excluding "forbidden" types. - */ - public boolean isExecutable() { - switch (this) { - case FST_XTEXT: - case FST_XRTEXT: - case FST_XAPPLEFILE: - case FST_XBINARY: - case FST_XUNICODE: - case FST_XUTF8: - case FST_XUTF16: - case FST_XGUNZIP: - return true; - default: - return false; - } - } - - /** - * Infer (or even intuit) the Perforce file type of the passed-in - * Perforce file. This is an arbitrarily complex operation, and may - * involve reading in the first few bytes of a file to see what the - * contents say about the type.

- * - * Note that Java does not allow us to directly access most file - * metadata. This probably doesn't matter in most cases, but we do need - * to keep an eye on this -- HR. - */ + int tu = 0; + + switch (str.length()) { + default: + case 3: + tu = StringHelper.hexcharToInt(str.charAt(2)); + case 2: + tl = StringHelper.hexcharToInt(str.charAt(1)); + case 1: + tf = StringHelper.hexcharToInt(str.charAt(0)); + case 0: // nothing??? ; + } + + // Map '[ uncompress ] fileType' into FileSysType. + switch (tf) { + // Normal. + + case 0x000: + return tu == 0 ? FST_TEXT : FST_TEXT_GUNZIP; + case 0x001: + return tu == 0 ? FST_BINARY : FST_BINARY_GUNZIP; + case 0x002: + return tu == 0 ? FST_XTEXT : FST_XTEXT_GUNZIP; + case 0x003: + return tu == 0 ? FST_XBINARY : FST_XBINARY_GUNZIP; + case 0x004: + return tu == 0 ? FST_SYMLINK : FST_SYMLINK_GUNZIP; + case 0x005: + return tu == 0 ? FST_RESOURCE : FST_RESOURCE_GUNZIP; + case 0x006: + return tu == 0 ? FST_XSYMLINK : FST_XSYMLINK_GUNZIP; + case 0x007: + return tu == 0 ? FST_XRESOURCE : FST_XRESOURCE_GUNZIP; + case 0x008: + return tu == 0 ? FST_UNICODE : FST_UNICODE_GUNZIP; + case 0x009: + return tu == 0 ? FST_RTEXT : FST_RTEXT_GUNZIP; + case 0x00A: + return tu == 0 ? FST_XUNICODE : FST_XUNICODE_GUNZIP; + case 0x00B: + return tu == 0 ? FST_XRTEXT : FST_XRTEXT_GUNZIP; + case 0x00C: + return tu == 0 ? FST_APPLETEXT : FST_APPLETEXT_GUNZIP; + case 0x00D: + return tu == 0 ? FST_APPLEFILE : FST_APPLEFILE_GUNZIP; + case 0x00E: + return tu == 0 ? FST_XAPPLETEXT : FST_XAPPLETEXT_GUNZIP; + case 0x00F: + return tu == 0 ? FST_XAPPLEFILE : FST_XAPPLEFILE_GUNZIP; + case 0x014: + return tu == 0 ? FST_UTF8 : FST_UTF8_GUNZIP; + case 0x016: + return tu == 0 ? FST_XUTF8 : FST_XUTF8_GUNZIP; + case 0x018: + return tu == 0 ? FST_UTF16 : FST_UTF16_GUNZIP; + case 0x01A: + return tu == 0 ? FST_XUTF16 : FST_XUTF16_GUNZIP; + + // Uncompressing. + + case 0x101: + return FST_GUNZIP; + case 0x103: + return FST_XGUNZIP; + + // Stop-gap. + + default: + return FST_BINARY; + } + } + + /** + * Checking for executable file types - excluding "forbidden" types. + * + * @return true, if known type + */ + public boolean isExecutable() { + switch (this) { + case FST_XTEXT: + case FST_XRTEXT: + case FST_XAPPLEFILE: + case FST_XBINARY: + case FST_XUNICODE: + case FST_XUTF8: + case FST_XUTF16: + case FST_XGUNZIP: + return true; + default: + return false; + } + } + /** + * Checking for compressed file types - excluding "forbidden" types. + * + * @return true, if known type + */ + public boolean isCompressed() { + switch (this) { + case FST_TEXT_GUNZIP: + case FST_BINARY_GUNZIP: + case FST_XTEXT_GUNZIP: + case FST_XBINARY_GUNZIP: + case FST_SYMLINK_GUNZIP: + case FST_RESOURCE_GUNZIP: + case FST_XSYMLINK_GUNZIP: + case FST_XRESOURCE_GUNZIP: + case FST_UNICODE_GUNZIP: + case FST_RTEXT_GUNZIP: + case FST_XUNICODE_GUNZIP: + case FST_XRTEXT_GUNZIP: + case FST_APPLETEXT_GUNZIP: + case FST_APPLEFILE_GUNZIP: + case FST_XAPPLETEXT_GUNZIP: + case FST_XAPPLEFILE_GUNZIP: + case FST_UTF8_GUNZIP: + case FST_XUTF8_GUNZIP: + case FST_UTF16_GUNZIP: + case FST_XUTF16_GUNZIP: + case FST_GUNZIP: // (deprecated 2022.1) + case FST_XGUNZIP: // (deprecated 2022.1) + return true; + default: + return false; + } + } + + /** + * Infer (or even intuit) the Perforce file type of the passed-in + * Perforce file. This is an arbitrarily complex operation, and may + * involve reading in the first few bytes of a file to see what the + * contents say about the type. + *

+ * Note that Java does not allow us to directly access most file + * metadata. This probably doesn't matter in most cases, but we do need + * to keep an eye on this -- HR. + * + * @param file file + * @param scanSize scanSize + * @param isUnicodeServer isUnicodeServer + * @param clientCharset clientCharset + * @return type + */ public static RpcPerforceFileType inferFileType(File file, int scanSize, boolean isUnicodeServer, Charset clientCharset) { if (file == null) { - throw new NullPointerError( - "Null file handle passed to RpcPerforceFileType.inferFileType()"); - } - - try { - if (isProbablySymLink(file)) { - // Better safe than sorry -- users can always override this explicitly... - return FST_SYMLINK; - } - - if (!file.exists()) { - return FST_MISSING; - } - - if (file.isDirectory()) { - return FST_DIRECTORY; - } - - if (!file.isFile()) { - // Hmmm. This might be a symlink, but we'll just return - // FST_CANTTELL for the moment... (FIXME -- HR). - return FST_CANTTELL; - } - - if (file.length() == 0) { - return FST_EMPTY; - } - - // Otherwise, we have to look inside it: - return inferFileTypeFromContents(file, - fileCommands.canExecute(file.getPath()), - scanSize, - isUnicodeServer, - clientCharset); - } catch (Exception exc) { - // We can probably do better than this in the long term, - // but at the moment this is the safest choice... - Log.exception(exc); - return FST_CANTTELL; - } - } - - /** - * Given a Perforce file type and the Perforce server's xfiles level (from the protocol - * parameters), determine what server file type to send to the server to represent - * the passed-in file type as a string, and / or what error or info message - * to send to the user.

- */ - - public static RpcServerTypeStringSpec getServerFileTypeString( - String clientPath, - boolean overSize, - RpcPerforceFileType fileType, - String forceType, - int xlevel) { - if (fileType != null) { - for (ActionTableElement atElement : actionTable) { - if (atElement.checkType == fileType) { - return getAction(clientPath, overSize, xlevel, atElement, forceType); - } - } - } - - Log.error("Encountered null or unknown filetype in getServerFileTypeString()"); - return new RpcServerTypeStringSpec(null, - new RpcMessage( - ClientMessageId.CANT_ADD_FILE_TYPE, - MessageSeverityCode.E_INFO, - MessageGenericCode.EV_CLIENT, - new String[]{clientPath, "unknown"} - )); - } - - /** - * Return true if there's some reason to believe this file is a - * Unix or Linux symbolic link. This is just a hack that's here - * until I can do something better with native code... - */ - - public static boolean isProbablySymLink(File file) { - - if (file != null) { - // Check with the symbolic link helper class (JDK 7 or above) - if (SymbolicLinkHelper.isSymbolicLinkCapable()) { - return SymbolicLinkHelper.isSymbolicLink(file.getPath()); - } - - // Check with the file helper class... - ISystemFileCommandsHelper helper = SysFileHelperBridge.getSysFileCommands(); - if ((helper != null) && helper.isSymlink(file.getPath())) { - return true; - } - - // Note that if the file path contains high ascii characters and the - // JDK (version 5 or below) is not capable of text normalization, - // then the following logic might give false positives. - // In such case, you should override the file type explicitly - // (i.e. p4 add -t filetype). - - // On Unix variants symlinks often have different absolute and - // canonical paths -- and that's all we have to go on if the helper - // class doesn't help... - if (!Server.isRunningOnWindows()) { - try { - String absoPath = file.getAbsolutePath(); - String canoPath = file.getCanonicalPath(); - - // Normalize the canonical path (JDK 6 or above) - if (TextNormalizationHelper.isNormalizationCapable()) { - canoPath = TextNormalizationHelper.normalize(file.getCanonicalPath()); - } - - // For historical compatibility reasons, Mac file systems - // defaults to case-insensitive directories and files, - // so, we must ignore case here... - if (SystemInfo.isMac()) { - if (!absoPath.equalsIgnoreCase(canoPath)) { - return true; // wish this were always true... - } - } else { - if (!absoPath.equals(canoPath)) { - return true; // wish this were always true... - } - } - - } catch (IOException ioexc) { - Log.warn("unexpected exception in RpcPerforceFileType.isProbablySymLink(): %s", - ioexc.getLocalizedMessage()); - Log.exception(ioexc); - } - } - } - - return false; - } - - private static RpcServerTypeStringSpec getAction( - String clientPath, - boolean overSize, - int xlevel, - ActionTableElement atElement, - String forceType) { - - switch (atElement.ctActions[(xlevel >= atElement.xlevel ? 1 : 0)]) { - case OK: - if (forceType != null) { - return new RpcServerTypeStringSpec(forceType, null); - } else { - return new RpcServerTypeStringSpec(atElement.type, null); - } - - case CHKSZ: - // If server sends a maximum size for file, check it - if (forceType != null) { - return new RpcServerTypeStringSpec(forceType, null); - } else if (overSize) { - return new RpcServerTypeStringSpec(atElement.cmpType, null); - } else { - return new RpcServerTypeStringSpec(atElement.type, null); - } - case ASS: - if (forceType != null) { - return new RpcServerTypeStringSpec(forceType, - new RpcMessage( - ClientMessageId.ASSUMING_FILE_TYPE, - MessageSeverityCode.E_INFO, - MessageGenericCode.EV_CLIENT, - new String[]{clientPath, - atElement.type, - forceType - } - )); - } else { - return new RpcServerTypeStringSpec(atElement.altType, - new RpcMessage( - ClientMessageId.ASSUMING_FILE_TYPE, - MessageSeverityCode.E_INFO, - MessageGenericCode.EV_CLIENT, - new String[]{clientPath, - atElement.type, - atElement.altType - } - )); - } - - case SUBST: - return new RpcServerTypeStringSpec(atElement.altType, - new RpcMessage( - ClientMessageId.SUBSTITUTING_FILE_TYPE, - MessageSeverityCode.E_INFO, - MessageGenericCode.EV_CLIENT, - new String[]{clientPath, - atElement.altType, - atElement.type, - } - )); - - case CANT: - return new RpcServerTypeStringSpec(null, - new RpcMessage( - ClientMessageId.CANT_ADD_FILE_TYPE, - MessageSeverityCode.E_INFO, - MessageGenericCode.EV_CLIENT, - new String[]{clientPath, - atElement.type - } - )); - } - - return new RpcServerTypeStringSpec(null, - new RpcMessage( - ClientMessageId.CANT_ADD_FILE_TYPE, - MessageSeverityCode.E_INFO, - MessageGenericCode.EV_CLIENT, - new String[]{clientPath, - atElement.type - } - )); - } - - private static RpcPerforceFileType getBinaryType(byte[] buffer, int bytesRead, boolean isExecutable) { - if (isKnownCBinary(buffer, bytesRead)) { + throw new NullPointerError("Null file handle passed to RpcPerforceFileType.inferFileType()"); + } + + try { + if (isProbablySymLink(file)) { + // Better safe than sorry -- users can always override this explicitly... + return FST_SYMLINK; + } + + if (!file.exists()) { + return FST_MISSING; + } + + if (file.isDirectory()) { + return FST_DIRECTORY; + } + + if (!file.isFile()) { + // Hmmm. This might be a symlink, but we'll just return + // FST_CANTTELL for the moment... (FIXME -- HR). + return FST_CANTTELL; + } + + if (file.length() == 0) { + return FST_EMPTY; + } + + // Otherwise, we have to look inside it: + return inferFileTypeFromContents(file, fileCommands.canExecute(file.getPath()), scanSize, isUnicodeServer, clientCharset); + } catch (Exception exc) { + // We can probably do better than this in the long term, + // but at the moment this is the safest choice... + Log.exception(exc); + return FST_CANTTELL; + } + } + + /** + * Given a Perforce file type and the Perforce server's xfiles level (from the protocol + * parameters), determine what server file type to send to the server to represent + * the passed-in file type as a string, and / or what error or info message + * to send to the user. + * + * @param clientPath clientPath + * @param overSize overSize + * @param fileType fileType + * @param forceType forceType + * @param xlevel xlevel + * @return RpcServerTypeStringSpec spec + */ + public static RpcServerTypeStringSpec getServerFileTypeString(String clientPath, boolean overSize, RpcPerforceFileType fileType, String forceType, int xlevel) { + if (fileType != null) { + for (ActionTableElement atElement : actionTable) { + if (atElement.checkType == fileType) { + return getAction(clientPath, overSize, xlevel, atElement, forceType); + } + } + } + + Log.error("Encountered null or unknown filetype in getServerFileTypeString()"); + return new RpcServerTypeStringSpec(null, new RpcMessage(ClientMessageId.CANT_ADD_FILE_TYPE, MessageSeverityCode.E_INFO, MessageGenericCode.EV_CLIENT, new String[]{clientPath, "unknown"})); + } + + /** + * Return true if there's some reason to believe this file is a + * Unix or Linux symbolic link. This is just a hack that's here + * until I can do something better with native code... + * + * @param file file + * @return true, if symlink + */ + public static boolean isProbablySymLink(File file) { + + if (file != null) { + // Check with the symbolic link helper class (JDK 7 or above) + if (SymbolicLinkHelper.isSymbolicLinkCapable()) { + return SymbolicLinkHelper.isSymbolicLink(file.getPath()); + } + + // Check with the file helper class... + ISystemFileCommandsHelper helper = SysFileHelperBridge.getSysFileCommands(); + if ((helper != null) && helper.isSymlink(file.getPath())) { + return true; + } + + // Note that if the file path contains high ascii characters and the + // JDK (version 5 or below) is not capable of text normalization, + // then the following logic might give false positives. + // In such case, you should override the file type explicitly + // (i.e. p4 add -t filetype). + + // On Unix variants symlinks often have different absolute and + // canonical paths -- and that's all we have to go on if the helper + // class doesn't help... + if (!Server.isRunningOnWindows()) { + try { + String absoPath = file.getAbsolutePath(); + String canoPath = file.getCanonicalPath(); + + // Normalize the canonical path (JDK 6 or above) + if (TextNormalizationHelper.isNormalizationCapable()) { + canoPath = TextNormalizationHelper.normalize(file.getCanonicalPath()); + } + + // For historical compatibility reasons, Mac file systems + // defaults to case-insensitive directories and files, + // so, we must ignore case here... + if (SystemInfo.isMac()) { + if (!absoPath.equalsIgnoreCase(canoPath)) { + return true; // wish this were always true... + } + } else { + if (!absoPath.equals(canoPath)) { + return true; // wish this were always true... + } + } + } catch (IOException ioexc) { + Log.warn("unexpected exception in RpcPerforceFileType.isProbablySymLink(): %s", ioexc.getLocalizedMessage()); + Log.exception(ioexc); + } + } + } + + return false; + } + + private static RpcServerTypeStringSpec getAction(String clientPath, boolean overSize, int xlevel, ActionTableElement atElement, String forceType) { + + switch (atElement.ctActions[(xlevel >= atElement.xlevel ? 1 : 0)]) { + case OK: + if (forceType != null) { + return new RpcServerTypeStringSpec(forceType, null); + } else { + return new RpcServerTypeStringSpec(atElement.type, null); + } + + case CHKSZ: + // If server sends a maximum size for file, check it + if (forceType != null) { + return new RpcServerTypeStringSpec(forceType, null); + } else if (overSize) { + return new RpcServerTypeStringSpec(atElement.cmpType, null); + } else { + return new RpcServerTypeStringSpec(atElement.type, null); + } + case ASS: + if (forceType != null) { + return new RpcServerTypeStringSpec(forceType, new RpcMessage(ClientMessageId.ASSUMING_FILE_TYPE, MessageSeverityCode.E_INFO, MessageGenericCode.EV_CLIENT, new String[]{clientPath, atElement.type, forceType})); + } else { + return new RpcServerTypeStringSpec(atElement.altType, new RpcMessage(ClientMessageId.ASSUMING_FILE_TYPE, MessageSeverityCode.E_INFO, MessageGenericCode.EV_CLIENT, new String[]{clientPath, atElement.type, atElement.altType})); + } + + case SUBST: + return new RpcServerTypeStringSpec(atElement.altType, new RpcMessage(ClientMessageId.SUBSTITUTING_FILE_TYPE, MessageSeverityCode.E_INFO, MessageGenericCode.EV_CLIENT, new String[]{clientPath, atElement.altType, atElement.type,})); + + case CANT: + return new RpcServerTypeStringSpec(null, new RpcMessage(ClientMessageId.CANT_ADD_FILE_TYPE, MessageSeverityCode.E_INFO, MessageGenericCode.EV_CLIENT, new String[]{clientPath, atElement.type})); + } + + return new RpcServerTypeStringSpec(null, new RpcMessage(ClientMessageId.CANT_ADD_FILE_TYPE, MessageSeverityCode.E_INFO, MessageGenericCode.EV_CLIENT, new String[]{clientPath, atElement.type})); + } + + private static RpcPerforceFileType getBinaryType(byte[] buffer, int bytesRead, boolean isExecutable) { + if (isKnownCBinary(buffer, bytesRead)) { return FST_CBINARY; } return (isExecutable ? FST_XBINARY : FST_BINARY); - } - - - /** - * Need to look inside the file to work out from its contents what - * type it (probably) is. This involves looking for magic numbers, - * etc.

- * - * Much of the binary inferencing logic here is adapted fairly loosely - * from the C++ API equivalent and may share the same errors (or lack of - * them) that that code has.

- */ - - private static RpcPerforceFileType inferFileTypeFromContents(File file, - boolean isExecutable, - int scanSize, - boolean isUnicodeServer, - Charset clientCharset) { + } + + /** + * Need to look inside the file to work out from its contents what + * type it (probably) is. This involves looking for magic numbers, + * etc.

+ *

+ * Much of the binary inferencing logic here is adapted fairly loosely + * from the C++ API equivalent and may share the same errors (or lack of + * them) that that code has.

+ */ + + private static RpcPerforceFileType inferFileTypeFromContents(File file, boolean isExecutable, int scanSize, boolean isUnicodeServer, Charset clientCharset) { byte[] buffer; if (scanSize < 0) { @@ -589,267 +581,237 @@ private static RpcPerforceFileType inferFileTypeFromContents(File file, if (bytesRead == 0) { return FST_EMPTY; } - - if(!isUnicodeServer) { + + if (!isUnicodeServer) { clientCharset = null; } - - + // Look for binary chars. boolean highbit = false; boolean controlchar = false; boolean zero = false; - for (int i = 0; i < bytesRead; i++) - { - highbit |= (0x80 & buffer[i]) != 0; - zero |= buffer[i] == 0; - controlchar |= (0x80 & buffer[i]) == 0 && Character.isISOControl( buffer[i] ) && !Character.isWhitespace( buffer[i] ); + for (int i = 0; i < bytesRead; i++) { + highbit |= (0x80 & buffer[i]) != 0; + zero |= buffer[i] == 0; + controlchar |= (0x80 & buffer[i]) == 0 && Character.isISOControl(buffer[i]) && !Character.isWhitespace(buffer[i]); } - + // Is it a PDF? if (isPDF(buffer, bytesRead)) { return (isExecutable ? FST_XBINARY : FST_BINARY); } - RpcPerforceFileType rettype = (isExecutable ? FST_XTEXT : FST_TEXT); + RpcPerforceFileType rettype = (isExecutable ? FST_XTEXT : FST_TEXT); Bom bom = readBom(buffer, bytesRead); boolean utf8Bom = bom != null && bom == Bom.UTF8; boolean utf16Bom = bom != null && bom == Bom.UTF16; boolean utf32Bom = bom != null && bom == Bom.UTF32; - + if (utf8Bom) { if (controlchar) { - return getBinaryType(buffer, bytesRead, isExecutable); + return getBinaryType(buffer, bytesRead, isExecutable); } - if( testValidUtf8( buffer, bytesRead ) > 0 ) { - rettype = (isExecutable ? FST_XUTF8 : FST_UTF8); + if (testValidUtf8(buffer, bytesRead) > 0) { + rettype = (isExecutable ? FST_XUTF8 : FST_UTF8); } - } - - // is there an UTF16 BOM at the start + } + + // is there an UTF16 BOM at the start // second word of zero means UTF-32: readBom handles that for us! - if( utf16Bom ) { + if (utf16Bom) { // might be utf16... rettype = (isExecutable ? FST_XUTF16 : FST_UTF16); clientCharset = Charset.forName("UTF-16"); - if (!checkConvert( buffer, bytesRead, clientCharset, true )) { + if (!checkConvert(buffer, bytesRead, clientCharset, true)) { return getBinaryType(buffer, bytesRead, isExecutable); } - return rettype; - } - - String charsetName = "none"; - if(clientCharset != null) { - charsetName = clientCharset.name(); - } - - switch(charsetName) { - case "UTF-8": - if (controlchar) { - return getBinaryType(buffer, bytesRead, isExecutable); + return rettype; + } + + String charsetName = "none"; + if (clientCharset != null) { + charsetName = clientCharset.name(); + } + + switch (charsetName) { + case "UTF-8": + if (controlchar) { + return getBinaryType(buffer, bytesRead, isExecutable); } if (highbit && (rettype == FST_TEXT || rettype == FST_XTEXT)) { - // run special UTF_8 validator... - if (testValidUtf8(buffer, bytesRead) > 0) { - rettype = (isExecutable ? FST_XUNICODE : FST_UNICODE); - } + // run special UTF_8 validator... + if (testValidUtf8(buffer, bytesRead) > 0) { + rettype = (isExecutable ? FST_XUNICODE : FST_UNICODE); + } } // else? should we do unicode if no highbit? break; - - case "UTF-32": - case "UTF-32LE": - case "UTF-32BE": - if ((!zero && !highbit && !controlchar) || utf8Bom ) { - break; + + case "UTF-32": + case "UTF-32LE": + case "UTF-32BE": + if ((!zero && !highbit && !controlchar) || utf8Bom) { + break; } - rettype = (isExecutable ? FST_XUNICODE : FST_UNICODE); + rettype = (isExecutable ? FST_XUNICODE : FST_UNICODE); // is there a BOM at the start - if( utf32Bom ) { - break; + if (utf32Bom) { + break; } // is there a UTF16 BOM at start... consider binary... - if( utf16Bom ) { - return getBinaryType(buffer, bytesRead, isExecutable); + if (utf16Bom) { + return getBinaryType(buffer, bytesRead, isExecutable); } - if (!checkConvert( buffer, bytesRead, clientCharset, true )) { + if (!checkConvert(buffer, bytesRead, clientCharset, true)) { return getBinaryType(buffer, bytesRead, isExecutable); } break; - - case "UTF-16": - case "UTF-16LE": - case "UTF-16BE": + + case "UTF-16": + case "UTF-16LE": + case "UTF-16BE": if ((!zero && !highbit && !controlchar) || utf8Bom) { - break; + break; } rettype = (isExecutable ? FST_XUNICODE : FST_UNICODE); // is there a BOM at the start - if( utf16Bom ) { - break; + if (utf16Bom) { + break; } // is there a UTF32 BOM at start... consider binary... - if( utf32Bom ) { - return getBinaryType(buffer, bytesRead, isExecutable); + if (utf32Bom) { + return getBinaryType(buffer, bytesRead, isExecutable); } - if (!checkConvert( buffer, bytesRead, clientCharset, true )) { + if (!checkConvert(buffer, bytesRead, clientCharset, true)) { return getBinaryType(buffer, bytesRead, isExecutable); } - break; - - case "none": - // non-unicode mode goes here... - if (controlchar) { - return getBinaryType(buffer, bytesRead, isExecutable); + break; + + case "none": + // non-unicode mode goes here... + if (controlchar) { + return getBinaryType(buffer, bytesRead, isExecutable); } break; - - default: - // most 8-bit charsets go here... - if (controlchar) { - return getBinaryType(buffer, bytesRead, isExecutable); + + default: + // most 8-bit charsets go here... + if (controlchar) { + return getBinaryType(buffer, bytesRead, isExecutable); } if (utf8Bom) { - break; + break; } - if( highbit && checkConvert( buffer, bytesRead, clientCharset, false ) ) { + if (highbit && checkConvert(buffer, bytesRead, clientCharset, false)) { rettype = (isExecutable ? FST_XUNICODE : FST_UNICODE); } - } - - if (rettype == FST_UNICODE) { - // Is the Unicode just plain UTF8? - if (highbit) { - if (testValidUtf8(buffer, bytesRead) > 0) { - rettype = (isExecutable ? FST_XUTF8 : FST_UTF8); - } + } + + if (rettype == FST_UNICODE) { + // Is the Unicode just plain UTF8? + if (highbit) { + if (testValidUtf8(buffer, bytesRead) > 0) { + rettype = (isExecutable ? FST_XUTF8 : FST_UTF8); + } } - // Option to disable unicode detection... + // Option to disable unicode detection... /*if( rettype == FST_UNICODE && !p4tunable.Get( P4TUNE_FILESYS_DETECTUNICODE ) ) { rettype = FST_TEXT; }*/ } - return rettype; - } - - - private static boolean checkConvert(byte[] buffer, int bytesRead, Charset clientCharset, boolean checkSpaces) { - - byte[] bytes = null; - - try { - CharsetConverter converter = new CharsetConverter(clientCharset, CharsetDefs.UTF8); - ByteBuffer from = ByteBuffer.wrap(buffer, 0, bytesRead); - ByteBuffer to = converter.convert(from); - bytes = to.array(); - } catch (Throwable e) { + return rettype; + } + + private static boolean checkConvert(byte[] buffer, int bytesRead, Charset clientCharset, boolean checkSpaces) { + + byte[] bytes = null; + + try { + CharsetConverter converter = new CharsetConverter(clientCharset, CharsetDefs.UTF8); + ByteBuffer from = ByteBuffer.wrap(buffer, 0, bytesRead); + ByteBuffer to = converter.convert(from); + bytes = to.array(); + } catch (Throwable e) { // XXX: we expect some thrown exceptions here, because we're testing that this works. - return false; - } - - if(!checkSpaces) { - return true; - } - - - // it did convert... see if it looks like utf8 text... - // we think it is text if there are more than - // 1 space character every 40 characters or so... - + return false; + } + + if (!checkSpaces) { + return true; + } + + // it did convert... see if it looks like utf8 text... + // we think it is text if there are more than + // 1 space character every 40 characters or so... + try { String str = new String(bytes, "UTF-8"); - int cnt = 0, ccnt = 0; - - for( ; ccnt < str.length(); ccnt++ ) { - if( Character.isWhitespace( str.charAt(ccnt) ) ) { - ++cnt; + int cnt = 0, ccnt = 0; + + for (; ccnt < str.length(); ccnt++) { + if (Character.isWhitespace(str.charAt(ccnt))) { + ++cnt; } - } - if( 40 * cnt < ccnt ) { - return false; - } + } + if (40 * cnt < ccnt) { + return false; + } } catch (UnsupportedEncodingException e) { - return false; + return false; } - + return true; } /* - * What do these bits mean? - * - * 0x40 Valid single byte code - * 0x80 Part of a multi byte sequence - * 0x08 UTF-16 surrogate - * 0x07 count of following bytes - */ - - static char[] validUtf8map = { - // 0 - 0x7f - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, - // 0x80 - 0x8f - 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, - 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, - // 0x90 - 0x9f - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - // 0xa0 - 0xbf - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - // 0xc0, 0xc1 illegal - 0, 0, - // 0xc2 - 0xdf - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - // 0xe0 - 0xef ( 0xe0 and 0xed are magical ) - 0x72, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x4a, 0x42, 0x42, - // 0xf0 - 0xf4 ( 0xf0 and 0xf4 are magical ) - 0x63, 0x43, 0x43, 0x43, 0x53, - // 0xf5 - 0xff illegal - 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 - }; - - /* - * return values are... - * - * 0 not valid - * 1 valid - * 3 valid so far (following bytes needed to complete a multi-byte char) - */ - + * What do these bits mean? + * + * 0x40 Valid single byte code + * 0x80 Part of a multi byte sequence + * 0x08 UTF-16 surrogate + * 0x07 count of following bytes + */ + + static char[] validUtf8map = { + // 0 - 0x7f + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + // 0x80 - 0x8f + 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, + // 0x90 - 0x9f + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, + // 0xa0 - 0xbf + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + // 0xc0, 0xc1 illegal + 0, 0, + // 0xc2 - 0xdf + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + // 0xe0 - 0xef ( 0xe0 and 0xed are magical ) + 0x72, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x4a, 0x42, 0x42, + // 0xf0 - 0xf4 ( 0xf0 and 0xf4 are magical ) + 0x63, 0x43, 0x43, 0x43, 0x53, + // 0xf5 - 0xff illegal + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + + /* + * return values are... + * + * 0 not valid + * 1 valid + * 3 valid so far (following bytes needed to complete a multi-byte char) + */ + private static int testValidUtf8(byte[] buffer, int bytesRead) { int followcnt = 0; int magic = 0; - for (int i = 0; i < bytesRead; i++ ) { + for (int i = 0; i < bytesRead; i++) { int chflags = validUtf8map[0xff & buffer[i]]; if (followcnt != 0) { @@ -859,26 +821,26 @@ private static int testValidUtf8(byte[] buffer, int bytesRead) { --followcnt; if (magic != 0) { switch (magic) { - case 0x10: // lead is 0xf4 - if ((chflags & 0x20) != 0x20) { - return 0; - } - break; - case 0x20: // lead is 0xf0 - if ((chflags & 0x20) == 0x20) { - return 0; - } - break; - case 0x30: // lead is 0xe0 - if ((chflags & 0x10) == 0x10) { - return 0; - } - break; - case 0x08: // lead is 0xed (UTF-16 surrogates) - if ((chflags & 0x30) == 0x00) { - return 0; - } - break; + case 0x10: // lead is 0xf4 + if ((chflags & 0x20) != 0x20) { + return 0; + } + break; + case 0x20: // lead is 0xf0 + if ((chflags & 0x20) == 0x20) { + return 0; + } + break; + case 0x30: // lead is 0xe0 + if ((chflags & 0x10) == 0x10) { + return 0; + } + break; + case 0x08: // lead is 0xed (UTF-16 surrogates) + if ((chflags & 0x30) == 0x00) { + return 0; + } + break; } magic = 0; } @@ -897,34 +859,32 @@ private static int testValidUtf8(byte[] buffer, int bytesRead) { } enum Bom { - UTF8, - UTF16, - UTF32 + UTF8, UTF16, UTF32 } - + /** * Return file type IFF the contents seem to be Unicode-encoded. */ private static Bom readBom(byte[] bytes, int bytesRead) { - // First check for Unicode BOMs (see e.g. http://unicode.org/faq/utf_bom.html): - if ( (bytesRead >= 4) && (bytes[0] == (byte) 0xFE) && (bytes[1] == (byte) 0xFF) && (bytes[2] == (byte) 0x00) && (bytes[3] == (byte) 0x00)) { - return Bom.UTF32; // UTF-32-LE - } else if ((bytesRead >= 4) && (bytes[0] == (byte) 0x00) && (bytes[1] == (byte) 0x00) && (bytes[2] == (byte) 0xFE) && (bytes[3] == (byte) 0xFF)) { - return Bom.UTF32; // UTF-32-BE - } else if ((bytesRead >= 3) && (bytes[0] == (byte) 0xEF) && (bytes[1] == (byte) 0xBB) && (bytes[2] == (byte) 0xBF)) { - return Bom.UTF8; // UTF-8 - } else if ((bytesRead >= 2) && (bytes[0] == (byte) 0xFF) && (bytes[1] == (byte) 0xFE)) { - return Bom.UTF16; // UTF-16-LE - } else if ((bytesRead >= 2) && (bytes[0] == (byte) 0xFE) && (bytes[1] == (byte) 0xFF)) { - return Bom.UTF16; // UTF-16-BE - } - return null; + // First check for Unicode BOMs (see e.g. http://unicode.org/faq/utf_bom.html): + if ((bytesRead >= 4) && (bytes[0] == (byte) 0xFE) && (bytes[1] == (byte) 0xFF) && (bytes[2] == (byte) 0x00) && (bytes[3] == (byte) 0x00)) { + return Bom.UTF32; // UTF-32-LE + } else if ((bytesRead >= 4) && (bytes[0] == (byte) 0x00) && (bytes[1] == (byte) 0x00) && (bytes[2] == (byte) 0xFE) && (bytes[3] == (byte) 0xFF)) { + return Bom.UTF32; // UTF-32-BE + } else if ((bytesRead >= 3) && (bytes[0] == (byte) 0xEF) && (bytes[1] == (byte) 0xBB) && (bytes[2] == (byte) 0xBF)) { + return Bom.UTF8; // UTF-8 + } else if ((bytesRead >= 2) && (bytes[0] == (byte) 0xFF) && (bytes[1] == (byte) 0xFE)) { + return Bom.UTF16; // UTF-16-LE + } else if ((bytesRead >= 2) && (bytes[0] == (byte) 0xFE) && (bytes[1] == (byte) 0xFF)) { + return Bom.UTF16; // UTF-16-BE + } + return null; } /** * Return true IFF the contents seem to be a PDF. */ - + private static boolean isPDF(byte[] bytes, int bytesRead) { if (bytesRead > pdfMagic.length) { int i = 0; @@ -939,63 +899,66 @@ private static boolean isPDF(byte[] bytes, int bytesRead) { } return false; - } + } - /** + /** * Return true if the passed-in bytes look like ascii text, * i.e. no high bits set, no control characters less than 0x07, * not a PDF, etc.... Not entirely reliable, but Good Enough.

- * + * * NOTE: assumes the PDFs have been weeded out alread... - */ - -// private static boolean isAsciiText(byte[] bytes, int bytesRead) { -// -// if (bytes == null) { -// return false; // Which may be wrong, but we have no reliable way of -// // knowing... -// } -// -// for (int i = 0; i < bytesRead; i++) { -// if (bytes[i] < 7) { -// // Relies on signed promotion here... -// return false; -// } -// } -// -// return true; -// } - - /** - * Return true iff the file appears to start with some known - * magic numbers that we interpret to mean the file is - * pre-compressed binary (FST_CBINARY). Typically things - * like JPEGs and GIFs, etc. - */ - + */ + + // private static boolean isAsciiText(byte[] bytes, int bytesRead) { + // + // if (bytes == null) { + // return false; // Which may be wrong, but we have no reliable way of + // // knowing... + // } + // + // for (int i = 0; i < bytesRead; i++) { + // if (bytes[i] < 7) { + // // Relies on signed promotion here... + // return false; + // } + // } + // + // return true; + // } + + /** + * Return true iff the file appears to start with some known + * magic numbers that we interpret to mean the file is + * pre-compressed binary (FST_CBINARY). Typically things + * like JPEGs and GIFs, etc. + * + * @param bytes bytes + * @param bytesRead bytesRead + * @return if known + */ public static boolean isKnownCBinary(byte[] bytes, int bytesRead) { - - if (bytesRead > 0) { + + if (bytesRead > 0) { for (byte[] magicBytes : cBinaryMagicTable) { - if (bytesRead > magicBytes.length) { - int i = 0; - for (byte b : magicBytes) { - if (bytes[i] != b) { - break; - } - i++; - } - - if (i == magicBytes.length) { - return true; - } - } - } - } - - return false; - } - + if (bytesRead > magicBytes.length) { + int i = 0; + for (byte b : magicBytes) { + if (bytes[i] != b) { + break; + } + i++; + } + + if (i == magicBytes.length) { + return true; + } + } + } + } + + return false; + } + public static byte[][] getBinaryMagicNumberTable() { return cBinaryMagicTable; } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/sys/RpcUnicodeInputStream.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/sys/RpcUnicodeInputStream.java index 27efe72..0b03af9 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/sys/RpcUnicodeInputStream.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/sys/RpcUnicodeInputStream.java @@ -7,7 +7,7 @@ /** * InputStream wrapper that detects and skips the Unicode BOM (Byte Order Mark) * in Unicode encoded text files. - * + * *

  * EF BB BF    = UTF-8 BOM
  * FF FE       = UTF-16, little-endian BOM
@@ -38,47 +38,32 @@ private BOM(final byte bom[], final String description) {
 		/**
 		 * Default to no BOM.
 		 */
-		public static final BOM NONE = new BOM(new byte[] {}, "NONE");
+		public static final BOM NONE = new BOM(new byte[]{}, "NONE");
 
 		/**
 		 * UTF-8 BOM (EF BB BF).
 		 */
-		public static final BOM UTF_8 = new BOM(new byte[] {
-				(byte) 0xEF,
-				(byte) 0xBB,
-				(byte) 0xBF }, "UTF-8");
+		public static final BOM UTF_8 = new BOM(new byte[]{(byte) 0xEF, (byte) 0xBB, (byte) 0xBF}, "UTF-8");
 
 		/**
 		 * UTF-16, little-endian (FF FE).
 		 */
-		public static final BOM UTF_16_LE = new BOM(new byte[] {
-				(byte) 0xFF,
-				(byte) 0xFE }, "UTF-16 little-endian");
+		public static final BOM UTF_16_LE = new BOM(new byte[]{(byte) 0xFF, (byte) 0xFE}, "UTF-16 little-endian");
 
 		/**
 		 * UTF-16, big-endian (FE FF).
 		 */
-		public static final BOM UTF_16_BE = new BOM(new byte[] {
-				(byte) 0xFE,
-				(byte) 0xFF }, "UTF-16 big-endian");
+		public static final BOM UTF_16_BE = new BOM(new byte[]{(byte) 0xFE, (byte) 0xFF}, "UTF-16 big-endian");
 
 		/**
 		 * UTF-32, little-endian (FF FE 00 00).
 		 */
-		public static final BOM UTF_32_LE = new BOM(new byte[] {
-				(byte) 0xFF,
-				(byte) 0xFE,
-				(byte) 0x00,
-				(byte) 0x00 }, "UTF-32 little-endian");
+		public static final BOM UTF_32_LE = new BOM(new byte[]{(byte) 0xFF, (byte) 0xFE, (byte) 0x00, (byte) 0x00}, "UTF-32 little-endian");
 
 		/**
 		 * UTF-32, big-endian (00 00 FE FF).
 		 */
-		public static final BOM UTF_32_BE = new BOM(new byte[] {
-				(byte) 0x00,
-				(byte) 0x00,
-				(byte) 0xFE,
-				(byte) 0xFF }, "UTF-32 big-endian");
+		public static final BOM UTF_32_BE = new BOM(new byte[]{(byte) 0x00, (byte) 0x00, (byte) 0xFE, (byte) 0xFF}, "UTF-32 big-endian");
 
 		/**
 		 * Returns the string representation of this BOM.
@@ -89,6 +74,8 @@ public final String toString() {
 
 		/**
 		 * Returns the bytes of this BOM.
+		 *
+		 * @return bytes
 		 */
 		public final byte[] getBytes() {
 			final int length = bytes.length;
@@ -100,6 +87,10 @@ public final byte[] getBytes() {
 
 	/**
 	 * Constructs a new RpcUnicodeInputStream that wraps the InputStream.
+	 *
+	 * @param inputStream inputStream
+	 * @throws NullPointerException on error
+	 * @throws IOException          on error
 	 */
 	public RpcUnicodeInputStream(final InputStream inputStream) throws NullPointerException, IOException {
 		if (inputStream == null) {
@@ -112,52 +103,43 @@ public RpcUnicodeInputStream(final InputStream inputStream) throws NullPointerEx
 		final int read = in.read(bom);
 
 		switch (read) {
-		
-		case 4:
-			if ((bom[0] == (byte) 0xFF)
-					&& (bom[1] == (byte) 0xFE)
-					&& (bom[2] == (byte) 0x00)
-					&& (bom[3] == (byte) 0x00)) {
-				this.bom = BOM.UTF_32_LE;
-				break;
-			} else if ((bom[0] == (byte) 0x00)
-					&& (bom[1] == (byte) 0x00)
-					&& (bom[2] == (byte) 0xFE)
-					&& (bom[3] == (byte) 0xFF)) {
-				this.bom = BOM.UTF_32_BE;
-				break;
-			}
-
-		case 3:
-			if ((bom[0] == (byte) 0xEF)
-					&& (bom[1] == (byte) 0xBB)
-					&& (bom[2] == (byte) 0xBF)) {
-				this.bom = BOM.UTF_8;
-				break;
-			}
 
-		case 2:
-			if ((bom[0] == (byte) 0xFF)
-					&& (bom[1] == (byte) 0xFE)) {
-				this.bom = BOM.UTF_16_LE;
-				break;
-			} else if ((bom[0] == (byte) 0xFE)
-					&& (bom[1] == (byte) 0xFF)) {
-				this.bom = BOM.UTF_16_BE;
+			case 4:
+				if ((bom[0] == (byte) 0xFF) && (bom[1] == (byte) 0xFE) && (bom[2] == (byte) 0x00) && (bom[3] == (byte) 0x00)) {
+					this.bom = BOM.UTF_32_LE;
+					break;
+				} else if ((bom[0] == (byte) 0x00) && (bom[1] == (byte) 0x00) && (bom[2] == (byte) 0xFE) && (bom[3] == (byte) 0xFF)) {
+					this.bom = BOM.UTF_32_BE;
+					break;
+				}
+
+			case 3:
+				if ((bom[0] == (byte) 0xEF) && (bom[1] == (byte) 0xBB) && (bom[2] == (byte) 0xBF)) {
+					this.bom = BOM.UTF_8;
+					break;
+				}
+
+			case 2:
+				if ((bom[0] == (byte) 0xFF) && (bom[1] == (byte) 0xFE)) {
+					this.bom = BOM.UTF_16_LE;
+					break;
+				} else if ((bom[0] == (byte) 0xFE) && (bom[1] == (byte) 0xFF)) {
+					this.bom = BOM.UTF_16_BE;
+					break;
+				}
+
+			default:
+				this.bom = BOM.NONE;
 				break;
-			}
-
-		default:
-			this.bom = BOM.NONE;
-			break;
 		}
 
-		if (read > 0)
-			in.unread(bom, 0, read);
+		if (read > 0) in.unread(bom, 0, read);
 	}
 
 	/**
 	 * Returns the BOM found in the InputStream.
+	 *
+	 * @return BOM
 	 */
 	public final BOM getBOM() {
 		return bom;
@@ -165,6 +147,9 @@ public final BOM getBOM() {
 
 	/**
 	 * Skips the BOM found in the InputStream.
+	 *
+	 * @return this
+	 * @throws IOException on error
 	 */
 	public final synchronized RpcUnicodeInputStream skipBOM() throws IOException {
 		if (!skipped) {
@@ -191,8 +176,7 @@ public int read(final byte b[]) throws IOException, NullPointerException {
 	/**
 	 * {@inheritDoc}
 	 */
-	public int read(final byte b[], final int off, final int len)
-			throws IOException, NullPointerException {
+	public int read(final byte b[], final int off, final int len) throws IOException, NullPointerException {
 		return in.read(b, off, len);
 	}
 
diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/sys/helper/RpcSystemFileCommandsHelper.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/sys/helper/RpcSystemFileCommandsHelper.java
index c587892..5d7dc0d 100644
--- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/sys/helper/RpcSystemFileCommandsHelper.java
+++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/sys/helper/RpcSystemFileCommandsHelper.java
@@ -2,8 +2,6 @@
 
 import java.io.File;
 import java.nio.file.Files;
-import java.nio.file.LinkOption;
-import java.nio.file.Path;
 import java.nio.file.Paths;
 
 /**
@@ -12,43 +10,41 @@
  * Actual use of this on JDK 5 systems is OK to the extent that things like edit
  * or sync may end up with the wrong permissions on the client, but much else
  * will work just fine.
- *
- * @author sshou clean code & add vargs to log methods, like slf4j
  */
 public class RpcSystemFileCommandsHelper extends SymbolicLinkHelper {
-    @Override
-    public boolean setWritable(String fileName, boolean writable) {
-        // skip symbolic; Java changes the link's target permission not the link
-        if(SymbolicLinkHelper.isSymbolicLink(fileName)) {
-            return true;
-        }
-        return new File(fileName).setWritable(writable);
-    }
+	@Override
+	public boolean setWritable(String fileName, boolean writable) {
+		// skip symbolic; Java changes the link's target permission not the link
+		if (SymbolicLinkHelper.isSymbolicLink(fileName)) {
+			return true;
+		}
+		return new File(fileName).setWritable(writable);
+	}
 
-    @Override
-    public boolean setReadable(String fileName, boolean readable, boolean ownerOnly) {
-        return new File(fileName).setReadable(readable, ownerOnly);
-    }
+	@Override
+	public boolean setReadable(String fileName, boolean readable, boolean ownerOnly) {
+		return new File(fileName).setReadable(readable, ownerOnly);
+	}
 
-    @Override
-    public boolean setOwnerReadOnly(String fileName) {
-        boolean set = setReadable(fileName, false, false);
-        set &= setReadable(fileName, true, true);
-        return set;
-    }
+	@Override
+	public boolean setOwnerReadOnly(String fileName) {
+		boolean set = setReadable(fileName, false, false);
+		set &= setReadable(fileName, true, true);
+		return set;
+	}
 
-    @Override
-    public boolean setExecutable(String fileName, boolean executable, boolean ownerOnly) {
-        return new File(fileName).setExecutable(executable, ownerOnly);
-    }
+	@Override
+	public boolean setExecutable(String fileName, boolean executable, boolean ownerOnly) {
+		return new File(fileName).setExecutable(executable, ownerOnly);
+	}
 
-    @Override
-    public boolean canExecute(String fileName) {
-        return Files.isExecutable(Paths.get(fileName));
-    }
+	@Override
+	public boolean canExecute(String fileName) {
+		return Files.isExecutable(Paths.get(fileName));
+	}
 
-    @Override
-    public boolean isSymlink(String fileName) {
-        return isSymbolicLink(fileName);
-    }
+	@Override
+	public boolean isSymlink(String fileName) {
+		return isSymbolicLink(fileName);
+	}
 }
diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/sys/helper/UnicodeHelper.java b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/sys/helper/UnicodeHelper.java
index d80eaf9..f5427eb 100644
--- a/src/main/java/com/perforce/p4java/impl/mapbased/rpc/sys/helper/UnicodeHelper.java
+++ b/src/main/java/com/perforce/p4java/impl/mapbased/rpc/sys/helper/UnicodeHelper.java
@@ -13,8 +13,6 @@
 /**
  * Provides default and / or bridged (to Eclipse, etc.) Unicode helper
  * methods. May disappear or be moved in a future refactoring.
- * 
- *
  */
 
 public class UnicodeHelper {
@@ -24,14 +22,19 @@ public class UnicodeHelper {
 	 * passed-in charset. Uses inefficient
 	 * heuristics that will be revisited when we're more familiar with likely
 	 * usage patterns.
-	 * 
+	 * 

* Note this has been heavily changed since inception and will * almost certainly disappear in the 10.x timeframe -- HR. + * + * @param bytes bytes + * @param bytesRead bytesRead + * @param clientCharset clientCharset + * @return ok */ public static boolean inferCharset(byte[] bytes, int bytesRead, Charset clientCharset) { ByteBuffer byteBuf = ByteBuffer.wrap(bytes, 0, bytesRead); CharBuffer charBuf = CharBuffer.allocate(byteBuf.capacity() * 2); - + if (clientCharset != null) { CharsetDecoder decoder = clientCharset.newDecoder(); decoder.onMalformedInput(CodingErrorAction.REPORT); @@ -42,11 +45,11 @@ public static boolean inferCharset(byte[] bytes, int bytesRead, Charset clientCh // Wasn't this one... return false; } else { - return true; // Still only *probably* true, dammit... + return true; // Still only *probably* true, dammit... } } } - + return true; } } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/IServerControl.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/IServerControl.java index da027a2..62d997d 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/IServerControl.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/IServerControl.java @@ -1,5 +1,5 @@ /** - * + * */ package com.perforce.p4java.impl.mapbased.server; @@ -15,13 +15,13 @@ */ public interface IServerControl { - + /** * Initialize the server. Called immediately after the server class is * instantiated. The semantics of this method are fairly broad: the result * of calling this method is that a future call to "normal" server calls must * not fail because of any setting-up problems. - * + * * @param host the Perforce server hostname or IP address as passed in to the factory method * @param port the Perforce server port number as passed in to the factory method * @param props the properties passed in to the factory method @@ -37,19 +37,19 @@ public interface IServerControl { * really do connections per se, so they may not consider this an error or even try * connecting during initialisation). */ - - ServerStatus init(String host, int port, Properties props, UsageOptions opts, boolean secure, - String rsh) throws ConfigException, ConnectionException; + + ServerStatus init(String host, int port, Properties props, UsageOptions opts, boolean secure, String rsh) throws ConfigException, ConnectionException; /** * Convenience method for init(host, port, props, opts, secure, null). See init's main Javadoc * for full documentation. - * + * * @param host the Perforce server hostname or IP address as passed in to the factory method * @param port the Perforce server port number as passed in to the factory method * @param props the properties passed in to the factory method * @param opts the UsageOptions object to be associated with the server object; if null, * the server should construct a new default UsageOptions object. + * @param secure secure option * @return the resulting status; should be ACTIVE unless otherwise specified * @throws ConfigException if there's something wrong with the * specified configuration or associated config files, etc. @@ -58,14 +58,12 @@ ServerStatus init(String host, int port, Properties props, UsageOptions opts, bo * really do connections per se, so they may not consider this an error or even try * connecting during initialisation). */ - - ServerStatus init(String host, int port, Properties props, UsageOptions opts, boolean secure) - throws ConfigException, ConnectionException; - + ServerStatus init(String host, int port, Properties props, UsageOptions opts, boolean secure) throws ConfigException, ConnectionException; + /** * Convenience method for init(host, port, props, opts, secure). See init's main Javadoc * for full documentation. - * + * * @param host the Perforce server hostname or IP address as passed in to the factory method * @param port the Perforce server port number as passed in to the factory method * @param props the properties passed in to the factory method @@ -79,9 +77,7 @@ ServerStatus init(String host, int port, Properties props, UsageOptions opts, bo * really do connections per se, so they may not consider this an error or even try * connecting during initialisation). */ - - ServerStatus init(String host, int port, Properties props, UsageOptions opts) - throws ConfigException, ConnectionException; + ServerStatus init(String host, int port, Properties props, UsageOptions opts) throws ConfigException, ConnectionException; /** * Convenience method for init(host, port, props, null). See init's main Javadoc @@ -99,7 +95,5 @@ ServerStatus init(String host, int port, Properties props, UsageOptions opts) * really do connections per se, so they may not consider this an error or even try * connecting during initialisation). */ - - ServerStatus init(String host, int port, Properties props) - throws ConfigException, ConnectionException; + ServerStatus init(String host, int port, Properties props) throws ConfigException, ConnectionException; } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/Parameters.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/Parameters.java index 716aa31..81f47e2 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/Parameters.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/Parameters.java @@ -21,7 +21,6 @@ * at producing the string arrays passed to the various IServer / Server * execMapCmd, etc., methods. *

- *

* This class is not intended for general use by developers or users, but is * documented anyway as it's a public class due to package constraints. Using * this class is not supported by anything other than the P4Java implementation @@ -29,271 +28,277 @@ */ public class Parameters { - /** - * Version of processParameters for those rare methods that have no - * non-Options arguments. - * - * @param opts possibly-null Options object; if null, no options are set. - * @param server possibly-null server object; default behaviour when this is - * null is to ignore it, and no parameter validation will be - * done. - * @return non-null but possibly empty array of strings suitable for using - * as-is with the IServer.execMapCmd etc. methods. - * @throws P4JavaException thrown if any error is detected. - */ - public static String[] processParameters(final Options opts, final IServer server) - throws P4JavaException { - return processParameters(opts, null, null, true, server); - } + /** + * Version of processParameters for those rare methods that have no + * non-Options arguments. + * + * @param opts possibly-null Options object; if null, no options are set. + * @param server possibly-null server object; default behaviour when this is + * null is to ignore it, and no parameter validation will be + * done. + * @return non-null but possibly empty array of strings suitable for using + * as-is with the IServer.execMapCmd etc. methods. + * @throws P4JavaException thrown if any error is detected. + */ + public static String[] processParameters(final Options opts, final IServer server) throws P4JavaException { + return processParameters(opts, null, null, true, server); + } - /** - * Process options and filespecs arguments for common methods that use a - * single file spec list and an options object. Will use file annotation on - * the passed-in file specs (if they exist). - * - * @param opts possibly-null Options object; if null, no options are set. - * @param fileSpecs possibly-null list of file specs; if null, no file specs are - * added; any non-valid file specs in the list are silently - * ignored. - * @param server possibly-null server object; default behaviour when this is - * null is to ignore it, and no parameter validation will be - * done. - * @return non-null but possibly empty array of strings suitable for using - * as-is with the IServer.execMapCmd etc. methods. - * @throws P4JavaException thrown if any error is detected. - */ - public static String[] processParameters(final Options opts, final List fileSpecs, - final IServer server) throws P4JavaException { - return processParameters(opts, fileSpecs, null, true, server); - } + /** + * Process options and filespecs arguments for common methods that use a + * single file spec list and an options object. Will use file annotation on + * the passed-in file specs (if they exist). + * + * @param opts possibly-null Options object; if null, no options are set. + * @param fileSpecs possibly-null list of file specs; if null, no file specs are + * added; any non-valid file specs in the list are silently + * ignored. + * @param server possibly-null server object; default behaviour when this is + * null is to ignore it, and no parameter validation will be + * done. + * @return non-null but possibly empty array of strings suitable for using + * as-is with the IServer.execMapCmd etc. methods. + * @throws P4JavaException thrown if any error is detected. + */ + public static String[] processParameters(final Options opts, final List fileSpecs, final IServer server) throws P4JavaException { + return processParameters(opts, fileSpecs, null, true, server); + } - /** - * Process options, filespecs arguments, and string arguments for common - * methods. Will use file annotation on the passed-in file specs (if they - * exist). - * - * @param opts possibly-null Options object; if null, no options are set. - * @param fileSpecs possibly-null list of file specs; if null, no file specs are - * added; any non-valid file specs in the list are silently - * ignored. - * @param stringParams possibly-null string arrays to be added element by element. - * @param server possibly-null server object; default behaviour when this is - * null is to ignore it, and no parameter validation will be - * done. - * @return non-null but possibly empty array of strings suitable for using - * as-is with the IServer.execMapCmd etc. methods. - * @throws P4JavaException thrown if any error is detected. - */ - public static String[] processParameters(final Options opts, final List fileSpecs, - final String[] stringParams, final IServer server) throws P4JavaException { - return processParameters(opts, fileSpecs, stringParams, true, server); - } + /** + * Process options, filespecs arguments, and string arguments for common + * methods. Will use file annotation on the passed-in file specs (if they + * exist). + * + * @param opts possibly-null Options object; if null, no options are set. + * @param fileSpecs possibly-null list of file specs; if null, no file specs are + * added; any non-valid file specs in the list are silently + * ignored. + * @param stringParams possibly-null string arrays to be added element by element. + * @param server possibly-null server object; default behaviour when this is + * null is to ignore it, and no parameter validation will be + * done. + * @return non-null but possibly empty array of strings suitable for using + * as-is with the IServer.execMapCmd etc. methods. + * @throws P4JavaException thrown if any error is detected. + */ + public static String[] processParameters(final Options opts, final List fileSpecs, final String[] stringParams, final IServer server) throws P4JavaException { + return processParameters(opts, fileSpecs, stringParams, true, server); + } - /** - * Process options, filespecs arguments, and a single string argument for - * common methods. Will use file annotation on the passed-in file specs (if - * they exist). - * - * @param opts possibly-null Options object; if null, no options are set. - * @param fileSpecs possibly-null list of file specs; if null, no file specs are - * added; any non-valid file specs in the list are silently - * ignored. - * @param stringParam possibly-null string parameter to be added. - * @param server possibly-null server object; default behaviour when this is - * null is to ignore it, and no parameter validation will be - * done. - * @return non-null but possibly empty array of strings suitable for using - * as-is with the IServer.execMapCmd etc. methods. - * @throws P4JavaException thrown if any error is detected. - */ - public static String[] processParameters(final Options opts, final List fileSpecs, - final String stringParam, final IServer server) throws P4JavaException { - return processParameters(opts, fileSpecs, new String[]{stringParam}, true, server); - } + /** + * Process options, filespecs arguments, and a single string argument for + * common methods. Will use file annotation on the passed-in file specs (if + * they exist). + * + * @param opts possibly-null Options object; if null, no options are set. + * @param fileSpecs possibly-null list of file specs; if null, no file specs are + * added; any non-valid file specs in the list are silently + * ignored. + * @param stringParam possibly-null string parameter to be added. + * @param server possibly-null server object; default behaviour when this is + * null is to ignore it, and no parameter validation will be + * done. + * @return non-null but possibly empty array of strings suitable for using + * as-is with the IServer.execMapCmd etc. methods. + * @throws P4JavaException thrown if any error is detected. + */ + public static String[] processParameters(final Options opts, final List fileSpecs, final String stringParam, final IServer server) throws P4JavaException { + return processParameters(opts, fileSpecs, new String[]{stringParam}, true, server); + } - /** - * Omnibus processParameters method. - * - * @param opts possibly-null Options object; if null, no options are set. - * @param fileSpecs possibly-null list of file specs; if null, no file specs are - * added; any non-valid file specs in the list are silently - * ignored. - * @param stringParams possibly-null string array whose contents are to be added - * element by element in the array index order. - * @param annotateFiles if true, use the fileSpec's getAnnotatedPreferredPathString - * method rather than its getPreferredPathString. - * @param server possibly-null server object; default behaviour when this is - * null is to ignore it, and no parameter validation will be - * done. - * @return non-null but possibly empty array of strings suitable for using - * as-is with the IServer.execMapCmd etc. methods. - */ - public static String[] processParameters(final Options opts, final List fileSpecs, - final @Nullable String[] stringParams, final boolean annotateFiles, - final IServer server) throws P4JavaException { - List args = new ArrayList<>(); - addOpts(args, opts, server); + /** + * Omnibus processParameters method. + * + * @param opts possibly-null Options object; if null, no options are set. + * @param fileSpecs possibly-null list of file specs; if null, no file specs are + * added; any non-valid file specs in the list are silently + * ignored. + * @param stringParams possibly-null string array whose contents are to be added + * element by element in the array index order. + * @param annotateFiles if true, use the fileSpec's getAnnotatedPreferredPathString + * method rather than its getPreferredPathString. + * @param server possibly-null server object; default behaviour when this is + * null is to ignore it, and no parameter validation will be + * done. + * @return non-null but possibly empty array of strings suitable for using + * as-is with the IServer.execMapCmd etc. methods. + * @throws P4JavaException on error + */ + public static String[] processParameters(final Options opts, final List fileSpecs, final @Nullable String[] stringParams, final boolean annotateFiles, final IServer server) throws P4JavaException { + List args = new ArrayList<>(); + addOpts(args, opts, server); - if (nonNull(stringParams)) { - for (String param : stringParams) { - if (isNotBlank(param)) { - args.add(param); - } - } - } + if (nonNull(stringParams)) { + for (String param : stringParams) { + if (isNotBlank(param)) { + args.add(param); + } + } + } - if (annotateFiles) { - return addFileSpecs(args, fileSpecs); - } else { - return addUnannotatedFileSpecs(args, fileSpecs); - } - } + if (annotateFiles) { + return addFileSpecs(args, fileSpecs); + } else { + return addUnannotatedFileSpecs(args, fileSpecs); + } + } - private static void addOpts(@Nonnull List args, @Nullable Options opts, IServer server) - throws P4JavaException { - if (nonNull(opts)) { - if (opts.isImmutable() && nonNull(opts.getOptions())) { - args.addAll(opts.getOptions()); - } else { - args.addAll(opts.processOptions(server)); - } - } - } + private static void addOpts(@Nonnull List args, @Nullable Options opts, IServer server) throws P4JavaException { + if (nonNull(opts)) { + if (opts.isImmutable() && nonNull(opts.getOptions())) { + args.addAll(opts.getOptions()); + } else { + args.addAll(opts.processOptions(server)); + } + } + } - private static String[] addFileSpecs(@Nonnull final List args, - @Nullable final List fileSpecs) { - Validate.notNull(args); + private static String[] addFileSpecs(@Nonnull final List args, @Nullable final List fileSpecs) { + Validate.notNull(args); - if (nonNull(fileSpecs)) { - for (IFileSpec fSpec : fileSpecs) { - addFileSpec(args, fSpec); - } - } + if (nonNull(fileSpecs)) { + for (IFileSpec fSpec : fileSpecs) { + addFileSpec(args, fSpec); + } + } - return args.toArray(new String[args.size()]); - } + return args.toArray(new String[args.size()]); + } - private static void addFileSpec(@Nonnull final List args, - @Nullable final IFileSpec fileSpec) { - Validate.notNull(args); + private static void addFileSpec(@Nonnull final List args, @Nullable final IFileSpec fileSpec) { + Validate.notNull(args); - if (nonNull(fileSpec)) { - if ((fileSpec.getOpStatus() == VALID)) { - args.add(fileSpec.getAnnotatedPreferredPathString()); - } - } - } + if (nonNull(fileSpec)) { + if ((fileSpec.getOpStatus() == VALID)) { + args.add(fileSpec.getAnnotatedPreferredPathString()); + } + } + } - private static String[] addUnannotatedFileSpecs(@Nonnull final List args, - @Nullable final List fileSpecs) { - Validate.notNull(args); - if (nonNull(fileSpecs)) { - for (IFileSpec fileSpec : fileSpecs) { - if (nonNull(fileSpec) && fileSpec.getOpStatus() == VALID) { - args.add(fileSpec.getPreferredPathString()); - } - } - } + private static String[] addUnannotatedFileSpecs(@Nonnull final List args, @Nullable final List fileSpecs) { + Validate.notNull(args); + if (nonNull(fileSpecs)) { + for (IFileSpec fileSpec : fileSpecs) { + if (nonNull(fileSpec) && fileSpec.getOpStatus() == VALID) { + args.add(fileSpec.getPreferredPathString()); + } + } + } - return args.toArray(new String[args.size()]); - } + return args.toArray(new String[args.size()]); + } - /** - * Specialized parameter processing method for commands with 'fromFile' and - * 'toFiles' parameters. - */ - public static String[] processParameters(final Options opts, final IFileSpec fromFileSpec, - final List toFileSpecs, final String[] stringParams, final IServer server) - throws P4JavaException { - List args = new ArrayList<>(); + /** + * Specialized parameter processing method for commands with 'fromFile' and + * 'toFiles' parameters. + * + * @param opts opts + * @param fromFileSpec fromFileSpec + * @param toFileSpecs toFileSpecs + * @param stringParams stringParams + * @param server server + * @return parameters + * @throws P4JavaException on error + */ + public static String[] processParameters(final Options opts, final IFileSpec fromFileSpec, final List toFileSpecs, final String[] stringParams, final IServer server) throws P4JavaException { + List args = new ArrayList<>(); - addOpts(args, opts, server); - if (nonNull(stringParams)) { - for (String param : stringParams) { - if (isNotBlank(param)) { - args.add(param); - } - } - } + addOpts(args, opts, server); + if (nonNull(stringParams)) { + for (String param : stringParams) { + if (isNotBlank(param)) { + args.add(param); + } + } + } - addFileSpec(args, fromFileSpec); - return addFileSpecs(args, toFileSpecs); - } + addFileSpec(args, fromFileSpec); + return addFileSpecs(args, toFileSpecs); + } - /** - * Specialized parameter processing method for the Client.integrateFiles and - * IOptionsServer.getFileDiffs methods. - *

- *

- * Used due to the need to preserve parameter order in the resulting array; - * don't use or change this method unless you really know what you're - * doing... - */ - public static String[] processParameters(final Options opts, @Nullable final IFileSpec fromFile, - @Nullable final IFileSpec toFile, final String branchSpec, final IServer server) - throws P4JavaException { - List fromFiles = new ArrayList<>(); - List toFiles = new ArrayList<>(); - if (nonNull(fromFile)) { - fromFiles.add(fromFile); - } - if (nonNull(toFile)) { - toFiles.add(toFile); - } - return processParameters(opts, fromFiles, toFiles, branchSpec, server); - } + /** + * Specialized parameter processing method for the Client.integrateFiles and + * IOptionsServer.getFileDiffs methods. + *

+ * Used due to the need to preserve parameter order in the resulting array; + * don't use or change this method unless you really know what you're + * doing... + * + * @param opts opts + * @param fromFile fromFile + * @param toFile toFile + * @param branchSpec branchSpec + * @param server server + * @return parameters + * @throws P4JavaException on error + */ + public static String[] processParameters(final Options opts, @Nullable final IFileSpec fromFile, @Nullable final IFileSpec toFile, final String branchSpec, final IServer server) throws P4JavaException { + List fromFiles = new ArrayList<>(); + List toFiles = new ArrayList<>(); + if (nonNull(fromFile)) { + fromFiles.add(fromFile); + } + if (nonNull(toFile)) { + toFiles.add(toFile); + } + return processParameters(opts, fromFiles, toFiles, branchSpec, server); + } - /** - * Specialized parameter processing method for the - * IOptionsServer.getInterchanges method. Used due to the need to preserve - * parameter order in the resulting array; don't use or change this method - * unless you really know what you're doing... - *

- */ - public static String[] processParameters(final Options opts, - @Nullable final List fromFiles, @Nullable final List toFiles, - final String branchSpec, final IServer server) throws P4JavaException { - String dashS = "-s"; - // Ensure that the -s option, if it exists, is the last option before - // the - // fromFile parameter; interpolate the -b option (if branchSpec isn't - // null) - // before the -s. - List args = new ArrayList<>(); - addOpts(args, opts, server); + /** + * Specialized parameter processing method for the + * IOptionsServer.getInterchanges method. Used due to the need to preserve + * parameter order in the resulting array; don't use or change this method + * unless you really know what you're doing... + * + * @param opts opts + * @param fromFiles fromFiles + * @param toFiles toFiles + * @param branchSpec branchSpec + * @param server server + * @return parameters + * @throws P4JavaException on error + */ + public static String[] processParameters(final Options opts, @Nullable final List fromFiles, @Nullable final List toFiles, final String branchSpec, final IServer server) throws P4JavaException { + String dashS = "-s"; + // Ensure that the -s option, if it exists, is the last option before + // the + // fromFile parameter; interpolate the -b option (if branchSpec isn't + // null) + // before the -s. + List args = new ArrayList<>(); + addOpts(args, opts, server); - // Now back out any -s: - boolean hadS = false; - if (args.contains(dashS)) { - args.remove(dashS); - hadS = true; - } - // See if we need to interpolate a "-b" in there at the end: - if (isNotBlank(branchSpec)) { - args.add("-b"); - args.add(branchSpec); - } + // Now back out any -s: + boolean hadS = false; + if (args.contains(dashS)) { + args.remove(dashS); + hadS = true; + } + // See if we need to interpolate a "-b" in there at the end: + if (isNotBlank(branchSpec)) { + args.add("-b"); + args.add(branchSpec); + } - // Add the "-s" back at the end if needed: - if (hadS) { - args.add(dashS); - } + // Add the "-s" back at the end if needed: + if (hadS) { + args.add(dashS); + } - addFileSpecIfValidFileSpec(args, fromFiles); - addFileSpecIfValidFileSpec(args, toFiles); - return args.toArray(new String[args.size()]); - } + addFileSpecIfValidFileSpec(args, fromFiles); + addFileSpecIfValidFileSpec(args, toFiles); + return args.toArray(new String[args.size()]); + } - private static void addFileSpecIfValidFileSpec(@Nonnull final List args, - @Nullable final List fileSpecs) { - Validate.notNull(args); + private static void addFileSpecIfValidFileSpec(@Nonnull final List args, @Nullable final List fileSpecs) { + Validate.notNull(args); - if (nonNull(fileSpecs)) { - for (IFileSpec fileSpec : fileSpecs) { - if (fileSpec.getOpStatus() == VALID) { - args.add(fileSpec.getAnnotatedPreferredPathString()); - } - } - } - } + if (nonNull(fileSpecs)) { + for (IFileSpec fileSpec : fileSpecs) { + if (fileSpec.getOpStatus() == VALID) { + args.add(fileSpec.getAnnotatedPreferredPathString()); + } + } + } + } } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/Server.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/Server.java index eb577ca..6bd1c8a 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/Server.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/Server.java @@ -366,11 +366,9 @@ * Generic abstract superclass for implementation-specific server * implementations that use a command-style server interface implementation. *

- *

* Normal users should not be creating this class or subclasses of this class * directly; you should use the ServerFactory server factory methods to get a * suitable server implementation class. - *

*/ public abstract class Server extends HelixCommandExecutor implements IServerControl, IOptionsServer { // The _FIELD_NAME names below MUST correspond to the names of the @@ -586,15 +584,12 @@ public static String guardNull(String str) { return (str == null ? nullStr : str); } - public static String[] getPreferredPathArray(final String[] preamble, - final List specList) { + public static String[] getPreferredPathArray(final String[] preamble, final List specList) { return getPreferredPathArray(preamble, specList, true); } - public static String[] getPreferredPathArray(final String[] preamble, - final List specList, final boolean annotate) { - int pathArraySize = (isNull(preamble) ? 0 : preamble.length) - + (isNull(specList) ? 0 : specList.size()); + public static String[] getPreferredPathArray(final String[] preamble, final List specList, final boolean annotate) { + int pathArraySize = (isNull(preamble) ? 0 : preamble.length) + (isNull(specList) ? 0 : specList.size()); String[] pathArray = new String[pathArraySize]; int i = 0; if (nonNull(preamble)) { @@ -620,8 +615,7 @@ public static String[] getPreferredPathArray(final String[] preamble, return pathArray; } - public static String[] populatePathArray(final String[] pathArray, final int start, - final List fileSpecList) { + public static String[] populatePathArray(final String[] pathArray, final int start, final List fileSpecList) { if (isNull(pathArray)) { return null; @@ -630,11 +624,8 @@ public static String[] populatePathArray(final String[] pathArray, final int sta return pathArray; } - throwP4JavaErrorIfConditionFails(start >= 0, - "negative start index in populatePathArray: %s", start); - throwP4JavaErrorIfConditionFails( - start <= pathArray.length && (start + fileSpecList.size() <= pathArray.length), - "pathArray too small in populatePathArray"); + throwP4JavaErrorIfConditionFails(start >= 0, "negative start index in populatePathArray: %s", start); + throwP4JavaErrorIfConditionFails(start <= pathArray.length && (start + fileSpecList.size() <= pathArray.length), "pathArray too small in populatePathArray"); int i = start; for (IFileSpec fSpec : fileSpecList) { @@ -650,7 +641,7 @@ public static String[] populatePathArray(final String[] pathArray, final int sta } /** - * Return true if the JVM indicates that we're running on a Windows + * @return true if the JVM indicates that we're running on a Windows * platform. Not entirely reliable, but good enough for our purposes. */ public static boolean isRunningOnWindows() { @@ -805,6 +796,8 @@ public void setQuietMode(boolean quietMode) { /** * Check if the server is secure (SSL) or not. + * + * @return if secure */ protected boolean isSecure() { return secure; @@ -812,21 +805,13 @@ protected boolean isSecure() { /** * Sets the server to secure (SSL) or non-secure mode. + * + * @param secure secure */ protected void setSecure(boolean secure) { this.secure = secure; } - // Try to get the Perforce server version. This is likely to be the first - // time - // actual connectivity is tested for the server... - // Since this is called before we know much about the state or type of the - // Perforce server, we do virtually no real error checking or recovery -- we - // either get a suitable response and dig out the server version, or we just - // leave things alone. - // - // NOTE: has the side effect of setting the server impl's serverVersion - // field. @Override public int getServerVersion() throws ConnectionException { if (serverVersion != UNKNOWN_SERVER_VERSION) { @@ -865,8 +850,7 @@ public IServerInfo getCurrentServerInfo() { } @Override - public void connect() - throws ConnectionException, AccessException, RequestException, ConfigException { + public void connect() throws ConnectionException, AccessException, RequestException, ConfigException { connected = true; status = ServerStatus.READY; @@ -874,15 +858,9 @@ public void connect() // Try to get and then verify the server version: int serverVersion = getServerVersion(); - throwConnectionExceptionIfConditionFails(serverVersion != UNKNOWN_SERVER_VERSION, - "Unable to determine Perforce server version for connection; " - + "check network connection, connection character set setting, " - + "and / or server status"); + throwConnectionExceptionIfConditionFails(serverVersion != UNKNOWN_SERVER_VERSION, "Unable to determine Perforce server version for connection; " + "check network connection, connection character set setting, " + "and / or server status"); - throwConnectionExceptionIfConditionFails(serverVersion >= minimumSupportedServerVersion, - "Attempted to connect to an unsupported Perforce server version; " - + "target server version: %s; minimum supported version: %s", - serverVersion, minimumSupportedServerVersion); + throwConnectionExceptionIfConditionFails(serverVersion >= minimumSupportedServerVersion, "Attempted to connect to an unsupported Perforce server version; " + "target server version: %s; minimum supported version: %s", serverVersion, minimumSupportedServerVersion); if (loginOnConnect && isNotBlank(userName) && isNotBlank(password)) { login(password); @@ -901,8 +879,7 @@ public void connect() // "none" (same as unsetting P4CHARSET) if (serverInfo.isUnicodeEnabled() && (p4Charset == null || p4Charset.getCharset() == null)) { String p4CharsetStr = getP4Charset(); - if (isBlank(p4CharsetStr) || "none".equalsIgnoreCase(p4CharsetStr) - || "auto".equalsIgnoreCase(p4CharsetStr)) { + if (isBlank(p4CharsetStr) || "none".equalsIgnoreCase(p4CharsetStr) || "auto".equalsIgnoreCase(p4CharsetStr)) { // Get the first matching Perforce charset for the Java default // charset String p4CharsetName = getP4CharsetName(CharsetDefs.DEFAULT_NAME); @@ -1031,9 +1008,7 @@ public boolean supportsUnicode() throws ConnectionException, RequestException, A } @Override - public ServerStatus init(final String host, final int port, final Properties properties, - final UsageOptions opts, final boolean secure) - throws ConfigException, ConnectionException { + public ServerStatus init(final String host, final int port, final Properties properties, final UsageOptions opts, final boolean secure) throws ConfigException, ConnectionException { serverHost = host; serverPort = port; this.secure = secure; @@ -1045,8 +1020,7 @@ public ServerStatus init(final String host, final int port, final Properties pro // form keys for // program name and version (done as a favour to testers and users // everywhere...). - tmpDirName = RpcPropertyDefs.getProperty(props, P4JAVA_TMP_DIR_KEY, - System.getProperty("java.io.tmpdir")); + tmpDirName = RpcPropertyDefs.getProperty(props, P4JAVA_TMP_DIR_KEY, System.getProperty("java.io.tmpdir")); if (isBlank(tmpDirName)) { // This can really only happen if someone has nuked or played with @@ -1055,12 +1029,10 @@ public ServerStatus init(final String host, final int port, final Properties pro // work for most non-Windows boxes in most cases, and may not be // needed in many cases anyway. tmpDirName = "/tmp"; - Log.warn("Unable to get tmp name from P4 properties or System; using %s instead", - tmpDirName); + Log.warn("Unable to get tmp name from P4 properties or System; using %s instead", tmpDirName); } - Log.info("Using program name: '%s'; program version: '%s'", usageOptions.getProgramName(), - usageOptions.getProgramVersion()); + Log.info("Using program name: '%s'; program version: '%s'", usageOptions.getProgramName(), usageOptions.getProgramVersion()); Log.info("Using tmp file directory: %s", tmpDirName); setUserName(getPropertyByKeys(props, USER_NAME_KEY_SHORTFORM, USER_NAME_KEY, getP4User())); @@ -1081,8 +1053,7 @@ public ServerStatus init(final String host, final int port, final Properties pro // Attempt to get the P4IGNORE file name from the passed-in properties // or the system environment variable 'P4IGNORE' - ignoreFileName = getPropertyByKeys(props, IGNORE_FILE_NAME_KEY_SHORT_FORM, - IGNORE_FILE_NAME_KEY, System.getenv(P4IGNORE_ENV_VAR)); + ignoreFileName = getPropertyByKeys(props, IGNORE_FILE_NAME_KEY_SHORT_FORM, IGNORE_FILE_NAME_KEY, System.getenv(P4IGNORE_ENV_VAR)); // Instantiate the delegators attributeDelegator = new AttributeDelegator(this); branchDelegator = new BranchDelegator(this); @@ -1166,15 +1137,13 @@ public ServerStatus init(final String host, final int port, final Properties pro } @Override - public ServerStatus init(final String host, final int port, final Properties props, - final UsageOptions opts) throws ConfigException, ConnectionException { + public ServerStatus init(final String host, final int port, final Properties props, final UsageOptions opts) throws ConfigException, ConnectionException { return init(host, port, props, opts, false); } @Override - public ServerStatus init(final String host, final int port, final Properties props) - throws ConfigException, ConnectionException { + public ServerStatus init(final String host, final int port, final Properties props) throws ConfigException, ConnectionException { return init(host, port, props, null); } @@ -1248,6 +1217,9 @@ protected String getInfoServerAddress() { * version string. Instead of using regex or anything too complex we just * keep splitting the string and recombining; this could be optimised or * flexibilised fairly easily on one of those long rainy days... (HR). + * + * @param versionString versionString + * @return version */ protected int parseVersionString(final String versionString) { // Format: P4D/LINUX26X86/2007.3/142194 (2007/12/17), @@ -1264,8 +1236,7 @@ protected int parseVersionString(final String versionString) { try { return Integer.parseInt(candidateParts[0] + candidateParts[1]); } catch (NumberFormatException nfe) { - Log.error("Unexpected exception in P4CmdServerImpl.parseVersionString: %s", - nfe); + Log.error("Unexpected exception in P4CmdServerImpl.parseVersionString: %s", nfe); } } } @@ -1275,7 +1246,7 @@ protected int parseVersionString(final String versionString) { } /** - * Returns the next positive pseudo random int. + * @return the next positive pseudo random int. */ protected int getRandomInt() { return Math.abs(rand.nextInt(Integer.MAX_VALUE)); @@ -1297,6 +1268,32 @@ protected boolean isUnicode() { return isNotBlank(charsetName); } + // Command delegators + /* + * (non-Javadoc) + * + * @see com.perforce.p4java.server.delegator.IAttributeDelegator# + * unsetFileAttribute(java.util.List, java.util.Map, + * com.perforce.p4java.option.server.SetFileAttributesOptions) + */ + @Override + public List unsetFileAttribute(List files, String attribute, SetFileAttributesOptions opts) throws P4JavaException { + return attributeDelegator.unsetFileAttribute(files, attribute, opts); + } + + // Command delegators + /* + * (non-Javadoc) + * + * @see com.perforce.p4java.server.delegator.IAttributeDelegator# + * unsetFileAttributes(java.util.List, java.util.Map, + * com.perforce.p4java.option.server.SetFileAttributesOptions) + */ + @Override + public List unsetFileAttributes(List files, List attributes, SetFileAttributesOptions opts) throws P4JavaException { + return attributeDelegator.unsetFileAttributes(files, attributes, opts); + } + // Command delegators /* * (non-Javadoc) @@ -1306,8 +1303,7 @@ protected boolean isUnicode() { * com.perforce.p4java.option.server.SetFileAttributesOptions) */ @Override - public List setFileAttributes(List files, Map attributes, - SetFileAttributesOptions opts) throws P4JavaException { + public List setFileAttributes(List files, Map attributes, SetFileAttributesOptions opts) throws P4JavaException { return attributeDelegator.setFileAttributes(files, attributes, opts); } @@ -1319,11 +1315,7 @@ public List setFileAttributes(List files, Map setFileAttributes( - List files, - @Nonnull String attributeName, - @Nonnull InputStream inStream, - SetFileAttributesOptions opts) throws P4JavaException { + public List setFileAttributes(List files, @Nonnull String attributeName, @Nonnull InputStream inStream, SetFileAttributesOptions opts) throws P4JavaException { return attributeDelegator.setFileAttributes(files, attributeName, inStream, opts); } @@ -1335,8 +1327,7 @@ public List setFileAttributes( * com.perforce.p4java.option.server.GetBranchSpecsOptions) */ @Override - public List getBranchSpecs(GetBranchSpecsOptions opts) - throws P4JavaException { + public List getBranchSpecs(GetBranchSpecsOptions opts) throws P4JavaException { return branchesDelegator.getBranchSpecs(opts); } @@ -1347,8 +1338,7 @@ public List getBranchSpecs(GetBranchSpecsOptions opts) * java.lang.String, int) */ @Override - public List getBranchSpecs(String userName, String nameFilter, - int maxReturns) throws ConnectionException, RequestException, AccessException { + public List getBranchSpecs(String userName, String nameFilter, int maxReturns) throws ConnectionException, RequestException, AccessException { return branchesDelegator.getBranchSpecs(userName, nameFilter, maxReturns); } @@ -1359,8 +1349,7 @@ public List getBranchSpecs(String userName, String nameFilte * String, com.perforce.p4java.option.server.GetBranchSpecOptions) */ @Override - public IBranchSpec getBranchSpec(String name, GetBranchSpecOptions opts) - throws P4JavaException { + public IBranchSpec getBranchSpec(String name, GetBranchSpecOptions opts) throws P4JavaException { return branchDelegator.getBranchSpec(name, opts); } @@ -1372,8 +1361,7 @@ public IBranchSpec getBranchSpec(String name, GetBranchSpecOptions opts) * String, com.perforce.p4java.option.server.DeleteBranchSpecOptions) */ @Override - public String deleteBranchSpec(String branchSpecName, DeleteBranchSpecOptions opts) - throws P4JavaException { + public String deleteBranchSpec(String branchSpecName, DeleteBranchSpecOptions opts) throws P4JavaException { return branchDelegator.deleteBranchSpec(branchSpecName, opts); } @@ -1384,8 +1372,7 @@ public String deleteBranchSpec(String branchSpecName, DeleteBranchSpecOptions op * String) */ @Override - public IBranchSpec getBranchSpec(String name) - throws ConnectionException, RequestException, AccessException { + public IBranchSpec getBranchSpec(String name) throws ConnectionException, RequestException, AccessException { return branchDelegator.getBranchSpec(name); } @@ -1397,8 +1384,7 @@ public IBranchSpec getBranchSpec(String name) * .p4java.core.IBranchSpec) */ @Override - public String createBranchSpec(@Nonnull IBranchSpec branchSpec) - throws ConnectionException, RequestException, AccessException { + public String createBranchSpec(@Nonnull IBranchSpec branchSpec) throws ConnectionException, RequestException, AccessException { return branchDelegator.createBranchSpec(branchSpec); } @@ -1410,24 +1396,21 @@ public String createBranchSpec(@Nonnull IBranchSpec branchSpec) * .p4java.core.IBranchSpec) */ @Override - public String updateBranchSpec(@Nonnull IBranchSpec branchSpec) - throws ConnectionException, RequestException, AccessException { + public String updateBranchSpec(@Nonnull IBranchSpec branchSpec) throws ConnectionException, RequestException, AccessException { return branchDelegator.updateBranchSpec(branchSpec); } /* * (non-Javadoc) * - * @see - * com.perforce.p4java.server.IBranchDelegator#deleteBranchSpec(java.lang. - * String, boolean) + * @see com.perforce.p4java.server.IBranchDelegator#deleteBranchSpec(java.lang.String, boolean) + * @deprecated use {@link IBranchDelegator#deleteBranchSpec(String, DeleteBranchSpecOptions)} instead */ + @Deprecated @Override - public String deleteBranchSpec(String branchSpecName, boolean force) - throws ConnectionException, RequestException, AccessException { + public String deleteBranchSpec(String branchSpecName, boolean force) throws ConnectionException, RequestException, AccessException { try { - return branchDelegator.deleteBranchSpec(branchSpecName, - new DeleteBranchSpecOptions(force)); + return branchDelegator.deleteBranchSpec(branchSpecName, new DeleteBranchSpecOptions(force)); } catch (P4JavaException p4je) { throw new RequestException(p4je); } @@ -1439,8 +1422,7 @@ public String deleteBranchSpec(String branchSpecName, boolean force) * @see com.perforce.p4java.server.IServer#deletePendingChangelist(int) */ @Override - public String deletePendingChangelist(int id) - throws ConnectionException, RequestException, AccessException { + public String deletePendingChangelist(int id) throws ConnectionException, RequestException, AccessException { return changeDelegator.deletePendingChangelist(id); } @@ -1450,8 +1432,7 @@ public String deletePendingChangelist(int id) * @see com.perforce.p4java.server.IServer#getChangelist(int) */ @Override - public IChangelist getChangelist(int id) - throws ConnectionException, RequestException, AccessException { + public IChangelist getChangelist(int id) throws ConnectionException, RequestException, AccessException { return changeDelegator.getChangelist(id); } @@ -1487,12 +1468,8 @@ public IChangelist getChangelist(int id, ChangelistOptions opts) throws P4JavaEx * com.perforce.p4java.core.IChangelist.Type, boolean) */ @Override - public List getChangelists(final int maxMostRecent, - final List fileSpecs, final String clientName, final String userName, - final boolean includeIntegrated, final Type type, final boolean longDesc) - throws ConnectionException, RequestException, AccessException { - return changesDelegator.getChangelists(maxMostRecent, fileSpecs, clientName, userName, - includeIntegrated, type, longDesc); + public List getChangelists(final int maxMostRecent, final List fileSpecs, final String clientName, final String userName, final boolean includeIntegrated, final Type type, final boolean longDesc) throws ConnectionException, RequestException, AccessException { + return changesDelegator.getChangelists(maxMostRecent, fileSpecs, clientName, userName, includeIntegrated, type, longDesc); } /* @@ -1503,13 +1480,9 @@ public List getChangelists(final int maxMostRecent, * boolean, boolean) */ @Override - public List getChangelists(final int maxMostRecent, - final List fileSpecs, final String clientName, final String userName, - final boolean includeIntegrated, final boolean submittedOnly, final boolean pendingOnly, - final boolean longDesc) throws ConnectionException, RequestException, AccessException { + public List getChangelists(final int maxMostRecent, final List fileSpecs, final String clientName, final String userName, final boolean includeIntegrated, final boolean submittedOnly, final boolean pendingOnly, final boolean longDesc) throws ConnectionException, RequestException, AccessException { - return changesDelegator.getChangelists(maxMostRecent, fileSpecs, clientName, userName, - includeIntegrated, submittedOnly, pendingOnly, longDesc); + return changesDelegator.getChangelists(maxMostRecent, fileSpecs, clientName, userName, includeIntegrated, submittedOnly, pendingOnly, longDesc); } /* @@ -1519,8 +1492,7 @@ public List getChangelists(final int maxMostRecent, * com.perforce.p4java.server.delegator.IChangesDelegator#getChangelists( * java.util.List, com.perforce.p4java.option.server.GetChangelistsOptions) */ - public List getChangelists(final List fileSpecs, - final GetChangelistsOptions opts) throws P4JavaException { + public List getChangelists(final List fileSpecs, final GetChangelistsOptions opts) throws P4JavaException { return changesDelegator.getChangelists(fileSpecs, opts); } @@ -1532,8 +1504,7 @@ public List getChangelists(final List fileSpecs, * com.perforce.p4java.option.server.GetChangelistDiffsOptions) */ @Override - public InputStream getChangelistDiffs(int id, GetChangelistDiffsOptions opts) - throws P4JavaException { + public InputStream getChangelistDiffs(int id, GetChangelistDiffsOptions opts) throws P4JavaException { return describeDelegator.getChangelistDiffs(id, opts); } @@ -1545,8 +1516,7 @@ public InputStream getChangelistDiffs(int id, GetChangelistDiffsOptions opts) * com.perforce.p4java.option.server.DescribeOptions) */ @Override - public InputStream getChangelistDiffsStream(int id, DescribeOptions options) - throws ConnectionException, RequestException, AccessException { + public InputStream getChangelistDiffsStream(int id, DescribeOptions options) throws ConnectionException, RequestException, AccessException { return describeDelegator.getChangelistDiffsStream(id, options); } @@ -1581,8 +1551,7 @@ public List getShelvedFiles(int changelistId, int max) throws P4JavaE * com.perforce.p4java.core.file.DiffType) */ @Override - public InputStream getChangelistDiffs(int id, DiffType diffType) - throws ConnectionException, RequestException, AccessException { + public InputStream getChangelistDiffs(int id, DiffType diffType) throws ConnectionException, RequestException, AccessException { return describeDelegator.getChangelistDiffs(id, diffType); } @@ -1592,8 +1561,7 @@ public InputStream getChangelistDiffs(int id, DiffType diffType) * @see com.perforce.p4java.server.IServer#getChangelistFiles(int) */ @Override - public List getChangelistFiles(int id) - throws ConnectionException, RequestException, AccessException { + public List getChangelistFiles(int id) throws ConnectionException, RequestException, AccessException { return describeDelegator.getChangelistFiles(id); } @@ -1603,8 +1571,7 @@ public List getChangelistFiles(int id) * @see com.perforce.p4java.server.IServer#getChangelistFiles(int, int) */ @Override - public List getChangelistFiles(int id, int max) - throws ConnectionException, RequestException, AccessException { + public List getChangelistFiles(int id, int max) throws ConnectionException, RequestException, AccessException { return describeDelegator.getChangelistFiles(id, max); } @@ -1614,8 +1581,7 @@ public List getChangelistFiles(int id, int max) * @see com.perforce.p4java.server.IServer#getChangelistExtendedFiles(int) */ @Override - public List getChangelistExtendedFiles(int id) - throws ConnectionException, RequestException, AccessException { + public List getChangelistExtendedFiles(int id) throws ConnectionException, RequestException, AccessException { return describeDelegator.getChangelistExtendedFiles(id); } @@ -1625,8 +1591,7 @@ public List getChangelistExtendedFiles(int id) * @see com.perforce.p4java.server.IServer#getChangelistExtendedFiles(int, int) */ @Override - public List getChangelistExtendedFiles(int id, int max) - throws ConnectionException, RequestException, AccessException { + public List getChangelistExtendedFiles(int id, int max) throws ConnectionException, RequestException, AccessException { return describeDelegator.getChangelistExtendedFiles(id, max); } @@ -1636,8 +1601,7 @@ public List getChangelistExtendedFiles(int id, int max) * @see com.perforce.p4java.server.IServer#getCommitFiles(String, String) */ @Override - public List getCommitFiles(final String repo, final String commit) - throws ConnectionException, RequestException, AccessException { + public List getCommitFiles(final String repo, final String commit) throws ConnectionException, RequestException, AccessException { return describeDelegator.getCommitFiles(repo, commit); } @@ -1648,8 +1612,7 @@ public List getCommitFiles(final String repo, final String commit) * setOrUnsetServerConfigurationValue(java.lang.String, java.lang.String) */ @Override - public String setOrUnsetServerConfigurationValue(@Nonnull final String name, - @Nullable final String value) throws P4JavaException { + public String setOrUnsetServerConfigurationValue(@Nonnull final String name, @Nullable final String value) throws P4JavaException { return configureDelegator.setOrUnsetServerConfigurationValue(name, value); } @@ -1660,8 +1623,7 @@ public String setOrUnsetServerConfigurationValue(@Nonnull final String name, * showServerConfiguration(java.lang.String, java.lang.String) */ @Override - public List showServerConfiguration(final String serverName, - final String variableName) throws P4JavaException { + public List showServerConfiguration(final String serverName, final String variableName) throws P4JavaException { return configureDelegator.showServerConfiguration(serverName, variableName); } @@ -1676,32 +1638,27 @@ public List getDbSchema(List tableSpecs) throws P4JavaExcepti } @Override - public IClient getClient(String clientName) - throws ConnectionException, RequestException, AccessException { + public IClient getClient(String clientName) throws ConnectionException, RequestException, AccessException { return clientDelegator.getClient(clientName); } @Override - public IClient getClient(@Nonnull IClientSummary clientSummary) - throws ConnectionException, RequestException, AccessException { + public IClient getClient(@Nonnull IClientSummary clientSummary) throws ConnectionException, RequestException, AccessException { return clientDelegator.getClient(clientSummary); } @Override - public IClient getClientTemplate(String clientName) - throws ConnectionException, RequestException, AccessException { + public IClient getClientTemplate(String clientName) throws ConnectionException, RequestException, AccessException { return clientDelegator.getClientTemplate(clientName); } @Override - public IClient getClientTemplate(String clientName, boolean allowExistent) - throws ConnectionException, RequestException, AccessException { + public IClient getClientTemplate(String clientName, boolean allowExistent) throws ConnectionException, RequestException, AccessException { return clientDelegator.getClientTemplate(clientName, allowExistent); } @Override - public IClient getClientTemplate(String clientName, GetClientTemplateOptions opts) - throws P4JavaException { + public IClient getClientTemplate(String clientName, GetClientTemplateOptions opts) throws P4JavaException { return clientDelegator.getClientTemplate(clientName, opts); } @@ -1715,8 +1672,7 @@ public IClient getClientTemplate(String clientName, GetClientTemplateOptions opt * com.perforce.p4java.option.server.GetInterchangesOptions) */ @Override - public List getInterchanges(IFileSpec fromFile, IFileSpec toFile, - GetInterchangesOptions opts) throws P4JavaException { + public List getInterchanges(IFileSpec fromFile, IFileSpec toFile, GetInterchangesOptions opts) throws P4JavaException { return interchangesDelegator.getInterchanges(fromFile, toFile, opts); } @@ -1729,10 +1685,8 @@ public List getInterchanges(IFileSpec fromFile, IFileSpec toFile, * com.perforce.p4java.option.server.GetInterchangesOptions) */ @Override - public List getInterchanges(String branchSpecName, List fromFileList, - List toFileList, GetInterchangesOptions opts) throws P4JavaException { - return interchangesDelegator.getInterchanges(branchSpecName, fromFileList, toFileList, - opts); + public List getInterchanges(String branchSpecName, List fromFileList, List toFileList, GetInterchangesOptions opts) throws P4JavaException { + return interchangesDelegator.getInterchanges(branchSpecName, fromFileList, toFileList, opts); } /* @@ -1744,11 +1698,8 @@ public List getInterchanges(String branchSpecName, List * boolean, int) */ @Override - public List getInterchanges(IFileSpec fromFile, IFileSpec toFile, - boolean showFiles, boolean longDesc, int maxChangelistId) - throws ConnectionException, RequestException, AccessException { - return interchangesDelegator.getInterchanges(fromFile, toFile, showFiles, longDesc, - maxChangelistId); + public List getInterchanges(IFileSpec fromFile, IFileSpec toFile, boolean showFiles, boolean longDesc, int maxChangelistId) throws ConnectionException, RequestException, AccessException { + return interchangesDelegator.getInterchanges(fromFile, toFile, showFiles, longDesc, maxChangelistId); } /* @@ -1758,35 +1709,27 @@ public List getInterchanges(IFileSpec fromFile, IFileSpec toFile, * java.util.List, java.util.List, boolean, boolean, int, boolean, boolean) */ @Override - public List getInterchanges(String branchSpecName, List fromFileList, - List toFileList, boolean showFiles, boolean longDesc, int maxChangelistId, - boolean reverseMapping, boolean biDirectional) - throws ConnectionException, RequestException, AccessException { - return interchangesDelegator.getInterchanges(branchSpecName, fromFileList, toFileList, - showFiles, longDesc, maxChangelistId, reverseMapping, biDirectional); + public List getInterchanges(String branchSpecName, List fromFileList, List toFileList, boolean showFiles, boolean longDesc, int maxChangelistId, boolean reverseMapping, boolean biDirectional) throws ConnectionException, RequestException, AccessException { + return interchangesDelegator.getInterchanges(branchSpecName, fromFileList, toFileList, showFiles, longDesc, maxChangelistId, reverseMapping, biDirectional); } @Override - public String createClient(@Nonnull IClient newClient) - throws ConnectionException, RequestException, AccessException { + public String createClient(@Nonnull IClient newClient) throws ConnectionException, RequestException, AccessException { return clientDelegator.createClient(newClient); } @Override - public void createTempClient(@Nonnull IClient newClient) - throws ConnectionException, RequestException, AccessException { + public void createTempClient(@Nonnull IClient newClient) throws ConnectionException, RequestException, AccessException { clientDelegator.createTempClient(newClient); } @Override - public String updateClient(@Nonnull IClient client) - throws ConnectionException, RequestException, AccessException { + public String updateClient(@Nonnull IClient client) throws ConnectionException, RequestException, AccessException { return clientDelegator.updateClient(client); } @Override - public String updateClient(IClient client, boolean force) - throws ConnectionException, RequestException, AccessException { + public String updateClient(IClient client, boolean force) throws ConnectionException, RequestException, AccessException { return clientDelegator.updateClient(client, force); } @@ -1796,8 +1739,7 @@ public String updateClient(IClient client, UpdateClientOptions opts) throws P4Ja } @Override - public String deleteClient(String clientName, boolean force) - throws ConnectionException, RequestException, AccessException { + public String deleteClient(String clientName, boolean force) throws ConnectionException, RequestException, AccessException { return clientDelegator.deleteClient(clientName, force); } @@ -1808,14 +1750,12 @@ public String deleteClient(String clientName, DeleteClientOptions opts) throws P } @Override - public String switchClientView(String templateClientName, String targetClientName, - SwitchClientViewOptions opts) throws P4JavaException { + public String switchClientView(String templateClientName, String targetClientName, SwitchClientViewOptions opts) throws P4JavaException { return clientDelegator.switchClientView(templateClientName, targetClientName, opts); } @Override - public String switchStreamView(String streamPath, String targetClientName, - SwitchClientViewOptions opts) throws P4JavaException { + public String switchStreamView(String streamPath, String targetClientName, SwitchClientViewOptions opts) throws P4JavaException { return clientDelegator.switchStreamView(streamPath, targetClientName, opts); } @@ -1825,42 +1765,33 @@ public List getClients(final GetClientsOptions opts) throws P4Ja } @Override - public List getClients( - final String userName, - final String nameFilter, - final int maxResults) throws ConnectionException, RequestException, AccessException { + public List getClients(final String userName, final String nameFilter, final int maxResults) throws ConnectionException, RequestException, AccessException { return clientsDelegator.getClients(userName, nameFilter, maxResults); } @Override - public String getCounter(final String counterName) - throws ConnectionException, RequestException, AccessException { + public String getCounter(final String counterName) throws ConnectionException, RequestException, AccessException { return counterDelegator.getCounter(counterName); } @Override - public String getCounter(final String counterName, final CounterOptions opts) - throws P4JavaException { + public String getCounter(final String counterName, final CounterOptions opts) throws P4JavaException { return counterDelegator.getCounter(counterName, opts); } @Override - public void setCounter(final String counterName, final String value, - final boolean perforceCounter) - throws ConnectionException, RequestException, AccessException { + public void setCounter(final String counterName, final String value, final boolean perforceCounter) throws ConnectionException, RequestException, AccessException { counterDelegator.setCounter(counterName, value, perforceCounter); } @Override - public String setCounter(final String counterName, final String value, - final CounterOptions opts) throws P4JavaException { + public String setCounter(final String counterName, final String value, final CounterOptions opts) throws P4JavaException { return counterDelegator.setCounter(counterName, value, opts); } @Override - public void deleteCounter(final String counterName, final boolean perforceCounter) - throws ConnectionException, RequestException, AccessException { + public void deleteCounter(final String counterName, final boolean perforceCounter) throws ConnectionException, RequestException, AccessException { counterDelegator.deleteCounter(counterName, perforceCounter); } @@ -1874,7 +1805,9 @@ public Map getCounters(GetCountersOptions opts) throws P4JavaExc /* (non-Javadoc) * @see com.perforce.p4java.server.delegator.ICountersDelegator#getCounters(com.perforce.p4java.option.server.CounterOptions) + * @deprecated replaced by {@link #getCounters(com.perforce.p4java.option.server.GetCountersOptions)} */ + @Deprecated @Override public Map getCounters(CounterOptions opts) throws P4JavaException { return countersDelegator.getCounters(opts); @@ -1884,8 +1817,7 @@ public Map getCounters(CounterOptions opts) throws P4JavaExcepti * @see com.perforce.p4java.server.IServer#getCounters() */ @Override - public Map getCounters() - throws ConnectionException, RequestException, AccessException { + public Map getCounters() throws ConnectionException, RequestException, AccessException { return countersDelegator.getCounters(); } @@ -1893,8 +1825,7 @@ public Map getCounters() * @see com.perforce.p4java.impl.mapbased.server.IServerControl#init(java.lang.String, int, java.util.Properties, com.perforce.p4java.option.UsageOptions, boolean, java.lang.String) */ @Override - public ServerStatus init(String host, int port, Properties props, UsageOptions opts, - boolean secure, String rsh) throws ConfigException, ConnectionException { + public ServerStatus init(String host, int port, Properties props, UsageOptions opts, boolean secure, String rsh) throws ConfigException, ConnectionException { // TODO Auto-generated method stub return null; } @@ -1964,63 +1895,27 @@ public List getRepos(String clientName) throws ConnectionException, Reque } @Override - public List getFileDiffs( - final IFileSpec file1, - final IFileSpec file2, - final String branchSpecName, - final GetFileDiffsOptions opts) throws P4JavaException { + public List getFileDiffs(final IFileSpec file1, final IFileSpec file2, final String branchSpecName, final GetFileDiffsOptions opts) throws P4JavaException { return diff2Delegator.getFileDiffs(file1, file2, branchSpecName, opts); } @Override - public InputStream getFileDiffsStream( - final IFileSpec file1, - final IFileSpec file2, - final String branchSpecName, - final GetFileDiffsOptions opts) throws P4JavaException { + public InputStream getFileDiffsStream(final IFileSpec file1, final IFileSpec file2, final String branchSpecName, final GetFileDiffsOptions opts) throws P4JavaException { return diff2Delegator.getFileDiffsStream(file1, file2, branchSpecName, opts); } @Override - public List getFileDiffs( - final IFileSpec file1, - final IFileSpec file2, - final String branchSpecName, - final DiffType diffType, - final boolean quiet, - final boolean includeNonTextDiffs, - final boolean gnuDiffs) throws ConnectionException, RequestException, AccessException { + public List getFileDiffs(final IFileSpec file1, final IFileSpec file2, final String branchSpecName, final DiffType diffType, final boolean quiet, final boolean includeNonTextDiffs, final boolean gnuDiffs) throws ConnectionException, RequestException, AccessException { - return diff2Delegator.getFileDiffs( - file1, - file2, - branchSpecName, - diffType, - quiet, - includeNonTextDiffs, - gnuDiffs); + return diff2Delegator.getFileDiffs(file1, file2, branchSpecName, diffType, quiet, includeNonTextDiffs, gnuDiffs); } @Override - public InputStream getServerFileDiffs( - final IFileSpec file1, - final IFileSpec file2, - final String branchSpecName, - final DiffType diffType, - final boolean quiet, - final boolean includeNonTextDiffs, - final boolean gnuDiffs) throws ConnectionException, RequestException, AccessException { + public InputStream getServerFileDiffs(final IFileSpec file1, final IFileSpec file2, final String branchSpecName, final DiffType diffType, final boolean quiet, final boolean includeNonTextDiffs, final boolean gnuDiffs) throws ConnectionException, RequestException, AccessException { - return diff2Delegator.getServerFileDiffs( - file1, - file2, - branchSpecName, - diffType, - quiet, - includeNonTextDiffs, - gnuDiffs); + return diff2Delegator.getServerFileDiffs(file1, file2, branchSpecName, diffType, quiet, includeNonTextDiffs, gnuDiffs); } @Override @@ -2029,179 +1924,111 @@ public List getDiskSpace(final List filesystems) throws P4Ja } @Override - public List duplicateRevisions( - final IFileSpec fromFile, - final IFileSpec toFile, - final DuplicateRevisionsOptions opts) throws P4JavaException { + public List duplicateRevisions(final IFileSpec fromFile, final IFileSpec toFile, final DuplicateRevisionsOptions opts) throws P4JavaException { return duplicateDelegator.duplicateRevisions(fromFile, toFile, opts); } @Override - public List> getExportRecords(final ExportRecordsOptions opts) - throws P4JavaException { + public List> getExportRecords(final ExportRecordsOptions opts) throws P4JavaException { return exportDelegator.getExportRecords(opts); } @Override - public void getStreamingExportRecords( - final ExportRecordsOptions opts, - @Nonnull final IStreamingCallback callback, - final int key) throws P4JavaException { + public void getStreamingExportRecords(final ExportRecordsOptions opts, @Nonnull final IStreamingCallback callback, final int key) throws P4JavaException { exportDelegator.getStreamingExportRecords(opts, callback, key); } @Override - public List> getExportRecords( - final boolean useJournal, - final long maxRecs, - final int sourceNum, - final long offset, - final boolean format, - final String journalPrefix, - final String filter) throws ConnectionException, RequestException, AccessException { + public List> getExportRecords(final boolean useJournal, final long maxRecs, final int sourceNum, final long offset, final boolean format, final String journalPrefix, final String filter) throws ConnectionException, RequestException, AccessException { - return exportDelegator.getExportRecords( - useJournal, - maxRecs, - sourceNum, - offset, - format, - journalPrefix, - filter); + return exportDelegator.getExportRecords(useJournal, maxRecs, sourceNum, offset, format, journalPrefix, filter); } @Override - public List getFileAnnotations( - final List fileSpecs, - @Nonnull final DiffType wsOpts, - final boolean allResults, - final boolean useChangeNumbers, - final boolean followBranches) throws ConnectionException, RequestException, AccessException { + public List getFileAnnotations(final List fileSpecs, @Nonnull final DiffType wsOpts, final boolean allResults, final boolean useChangeNumbers, final boolean followBranches) throws ConnectionException, RequestException, AccessException { - return fileAnnotateDelegator.getFileAnnotations( - fileSpecs, - wsOpts, - allResults, - useChangeNumbers, - followBranches); + return fileAnnotateDelegator.getFileAnnotations(fileSpecs, wsOpts, allResults, useChangeNumbers, followBranches); } @Override - public List getFileAnnotations( - final List fileSpecs, - final GetFileAnnotationsOptions opts) throws P4JavaException { + public List getFileAnnotations(final List fileSpecs, final GetFileAnnotationsOptions opts) throws P4JavaException { return fileAnnotateDelegator.getFileAnnotations(fileSpecs, opts); } @Override - public Map> getRevisionHistory( - final List fileSpecs, - final GetRevisionHistoryOptions opts) throws P4JavaException { + public Map> getRevisionHistory(final List fileSpecs, final GetRevisionHistoryOptions opts) throws P4JavaException { return fileLogDelegator.getRevisionHistory(fileSpecs, opts); } @Override - public Map> getRevisionHistory( - final List fileSpecs, - final int maxRevs, - final boolean contentHistory, - final boolean includeInherited, - final boolean longOutput, - final boolean truncatedLongOutput) throws ConnectionException, AccessException { + public Map> getRevisionHistory(final List fileSpecs, final int maxRevs, final boolean contentHistory, final boolean includeInherited, final boolean longOutput, final boolean truncatedLongOutput) throws ConnectionException, AccessException { - return fileLogDelegator.getRevisionHistory( - fileSpecs, - maxRevs, - contentHistory, - includeInherited, - longOutput, - truncatedLongOutput); + return fileLogDelegator.getRevisionHistory(fileSpecs, maxRevs, contentHistory, includeInherited, longOutput, truncatedLongOutput); } @Override - public List getDirectories(@Nonnull final List fileSpecs, - final boolean clientOnly, final boolean deletedOnly, final boolean haveListOnly) - throws ConnectionException, AccessException { + public List getDirectories(@Nonnull final List fileSpecs, final boolean clientOnly, final boolean deletedOnly, final boolean haveListOnly) throws ConnectionException, AccessException { return dirsDelegator.getDirectories(fileSpecs, clientOnly, deletedOnly, haveListOnly); } @Override - public List getDirectories(final List fileSpecs, - final GetDirectoriesOptions opts) throws P4JavaException { + public List getDirectories(final List fileSpecs, final GetDirectoriesOptions opts) throws P4JavaException { return dirsDelegator.getDirectories(fileSpecs, opts); } @Override - public List getDepotFiles(@Nonnull final List fileSpecs, - final boolean allRevs) throws ConnectionException, AccessException { + public List getDepotFiles(@Nonnull final List fileSpecs, final boolean allRevs) throws ConnectionException, AccessException { return filesDelegator.getDepotFiles(fileSpecs, allRevs); } @Override - public List getDepotFiles(@Nonnull final List fileSpecs, - final GetDepotFilesOptions opts) throws P4JavaException { + public List getDepotFiles(@Nonnull final List fileSpecs, final GetDepotFilesOptions opts) throws P4JavaException { return filesDelegator.getDepotFiles(fileSpecs, opts); } @Override - public List fixJobs(final List jobIds, final int changeListId, - final String status, final boolean delete) - throws ConnectionException, RequestException, AccessException { + public List fixJobs(final List jobIds, final int changeListId, final String status, final boolean delete) throws ConnectionException, RequestException, AccessException { return fixDelegator.fixJobs(jobIds, changeListId, status, delete); } @Override - public List fixJobs(@Nonnull final List jobIds, final int changeListId, - final FixJobsOptions opts) throws P4JavaException { + public List fixJobs(@Nonnull final List jobIds, final int changeListId, final FixJobsOptions opts) throws P4JavaException { return fixDelegator.fixJobs(jobIds, changeListId, opts); } @Override - public List getFixList(final List fileSpecs, final int changeListId, - final String jobId, final boolean includeIntegrations, final int maxFixes) - throws ConnectionException, RequestException, AccessException { - return fixesDelegator.getFixList(fileSpecs, changeListId, jobId, - includeIntegrations, maxFixes); + public List getFixList(final List fileSpecs, final int changeListId, final String jobId, final boolean includeIntegrations, final int maxFixes) throws ConnectionException, RequestException, AccessException { + return fixesDelegator.getFixList(fileSpecs, changeListId, jobId, includeIntegrations, maxFixes); } @Override - public List getFixes(final List fileSpecs, final GetFixesOptions opts) - throws P4JavaException { + public List getFixes(final List fileSpecs, final GetFixesOptions opts) throws P4JavaException { return fixesDelegator.getFixes(fileSpecs, opts); } @Override - public List getExtendedFiles(final List fileSpecs, - final int maxFiles, final int sinceChangelist, final int affectedByChangelist, - final FileStatOutputOptions outputOptions, - final FileStatAncilliaryOptions ancilliaryOptions) - throws ConnectionException, AccessException { - return fstatDelegator.getExtendedFiles(fileSpecs, maxFiles, sinceChangelist, - affectedByChangelist, outputOptions, ancilliaryOptions); + public List getExtendedFiles(final List fileSpecs, final int maxFiles, final int sinceChangelist, final int affectedByChangelist, final FileStatOutputOptions outputOptions, final FileStatAncilliaryOptions ancilliaryOptions) throws ConnectionException, AccessException { + return fstatDelegator.getExtendedFiles(fileSpecs, maxFiles, sinceChangelist, affectedByChangelist, outputOptions, ancilliaryOptions); } @Override - public List getExtendedFiles(final List fileSpecs, - final GetExtendedFilesOptions opts) throws P4JavaException { + public List getExtendedFiles(final List fileSpecs, final GetExtendedFilesOptions opts) throws P4JavaException { return fstatDelegator.getExtendedFiles(fileSpecs, opts); } @Override - public List getMatchingLines(List fileSpecs, - String pattern, MatchingLinesOptions options) throws P4JavaException { + public List getMatchingLines(List fileSpecs, String pattern, MatchingLinesOptions options) throws P4JavaException { return grepDelegator.getMatchingLines(fileSpecs, pattern, options); } @Override - public List getMatchingLines(@Nonnull List fileSpecs, - @Nonnull String pattern, @Nullable List infoLines, - MatchingLinesOptions options) throws P4JavaException { + public List getMatchingLines(@Nonnull List fileSpecs, @Nonnull String pattern, @Nullable List infoLines, MatchingLinesOptions options) throws P4JavaException { return grepDelegator.getMatchingLines(fileSpecs, pattern, infoLines, options); } @@ -2211,81 +2038,67 @@ public IServerInfo getServerInfo() throws ConnectionException, RequestException, } @Override - public String createUserGroup(IUserGroup group) - throws ConnectionException, RequestException, AccessException { + public String createUserGroup(IUserGroup group) throws ConnectionException, RequestException, AccessException { return groupDelegator.createUserGroup(group); } @Override - public String createUserGroup(IUserGroup group, UpdateUserGroupOptions opts) - throws P4JavaException { + public String createUserGroup(IUserGroup group, UpdateUserGroupOptions opts) throws P4JavaException { return groupDelegator.createUserGroup(group, opts); } @Override - public String deleteUserGroup(IUserGroup group) - throws ConnectionException, RequestException, AccessException { + public String deleteUserGroup(IUserGroup group) throws ConnectionException, RequestException, AccessException { return groupDelegator.deleteUserGroup(group); } @Override - public String deleteUserGroup(IUserGroup group, UpdateUserGroupOptions opts) - throws P4JavaException { + public String deleteUserGroup(IUserGroup group, UpdateUserGroupOptions opts) throws P4JavaException { return groupDelegator.deleteUserGroup(group, opts); } @Override - public IUserGroup getUserGroup(String name) - throws ConnectionException, RequestException, AccessException { + public IUserGroup getUserGroup(String name) throws ConnectionException, RequestException, AccessException { return groupDelegator.getUserGroup(name); } @Override - public String updateUserGroup(IUserGroup group, boolean updateIfOwner) - throws ConnectionException, RequestException, AccessException { + public String updateUserGroup(IUserGroup group, boolean updateIfOwner) throws ConnectionException, RequestException, AccessException { return groupDelegator.updateUserGroup(group, updateIfOwner); } @Override - public String updateUserGroup(IUserGroup group, UpdateUserGroupOptions opts) - throws P4JavaException { + public String updateUserGroup(IUserGroup group, UpdateUserGroupOptions opts) throws P4JavaException { return groupDelegator.updateUserGroup(group, opts); } @Override - public List getUserGroups(String userOrGroupName, GetUserGroupsOptions opts) - throws P4JavaException { + public List getUserGroups(String userOrGroupName, GetUserGroupsOptions opts) throws P4JavaException { return groupsDelegator.getUserGroups(userOrGroupName, opts); } @Override - public List getUserGroups(String userOrGroupName, boolean indirect, - boolean displayValues, int maxGroups) - throws ConnectionException, RequestException, AccessException { + public List getUserGroups(String userOrGroupName, boolean indirect, boolean displayValues, int maxGroups) throws ConnectionException, RequestException, AccessException { return groupsDelegator.getUserGroups(userOrGroupName, indirect, displayValues, maxGroups); } @Override - public List getSubmittedIntegrations(List fileSpecs, String branchSpec, - boolean reverseMappings) throws ConnectionException, RequestException, AccessException { + public List getSubmittedIntegrations(List fileSpecs, String branchSpec, boolean reverseMappings) throws ConnectionException, RequestException, AccessException { return integratedDelegator.getSubmittedIntegrations(fileSpecs, branchSpec, reverseMappings); } @Override - public List getSubmittedIntegrations(List fileSpecs, - GetSubmittedIntegrationsOptions opts) throws P4JavaException { + public List getSubmittedIntegrations(List fileSpecs, GetSubmittedIntegrationsOptions opts) throws P4JavaException { return integratedDelegator.getSubmittedIntegrations(fileSpecs, opts); } @Override - public IStreamIntegrationStatus getStreamIntegrationStatus(final String stream, - final StreamIntegrationStatusOptions opts) throws P4JavaException { + public IStreamIntegrationStatus getStreamIntegrationStatus(final String stream, final StreamIntegrationStatusOptions opts) throws P4JavaException { return statDelegator.getStreamIntegrationStatus(stream, opts); } @Override - public IJob createJob(@Nonnull Map fieldMap) - throws ConnectionException, RequestException, AccessException { + public IJob createJob(@Nonnull Map fieldMap) throws ConnectionException, RequestException, AccessException { return jobDelegator.createJob(fieldMap); } @@ -2300,22 +2113,17 @@ public IJob getJob(String jobId) throws ConnectionException, RequestException, A } @Override - public String updateJob(@Nonnull IJob job) - throws ConnectionException, RequestException, AccessException { + public String updateJob(@Nonnull IJob job) throws ConnectionException, RequestException, AccessException { return jobDelegator.updateJob(job); } @Override - public List getJobs(final List fileSpecs, final int maxJobs, - final boolean longDescriptions, final boolean reverseOrder, - final boolean includeIntegrated, final String jobView) - throws ConnectionException, RequestException, AccessException { + public List getJobs(final List fileSpecs, final int maxJobs, final boolean longDescriptions, final boolean reverseOrder, final boolean includeIntegrated, final String jobView) throws ConnectionException, RequestException, AccessException { return jobsDelegator.getJobs(fileSpecs, maxJobs, longDescriptions, reverseOrder, includeIntegrated, jobView); } @Override - public List getJobs(final List fileSpecs, final GetJobsOptions opts) - throws P4JavaException { + public List getJobs(final List fileSpecs, final GetJobsOptions opts) throws P4JavaException { return jobsDelegator.getJobs(fileSpecs, opts); } @@ -2330,8 +2138,7 @@ public String deleteKey(final String keyName) throws P4JavaException { } @Override - public String setKey(final String keyName, final String value, final KeyOptions opts) - throws P4JavaException { + public String setKey(final String keyName, final String value, final KeyOptions opts) throws P4JavaException { return keyDelegator.setKey(keyName, value, opts); } @@ -2347,55 +2154,43 @@ public Map getKeys(final GetKeysOptions opts) throws P4JavaExcep } @Override - public String createLabel(@Nonnull final ILabel label) - throws ConnectionException, RequestException, AccessException { + public String createLabel(@Nonnull final ILabel label) throws ConnectionException, RequestException, AccessException { return labelDelegator.createLabel(label); } @Override - public String deleteLabel(final String labelName, final boolean force) - throws ConnectionException, RequestException, AccessException { + public String deleteLabel(final String labelName, final boolean force) throws ConnectionException, RequestException, AccessException { return labelDelegator.deleteLabel(labelName, force); } @Override - public String deleteLabel(final String labelName, final DeleteLabelOptions opts) - throws P4JavaException { + public String deleteLabel(final String labelName, final DeleteLabelOptions opts) throws P4JavaException { return labelDelegator.deleteLabel(labelName, opts); } @Override - public ILabel getLabel(final String labelName) - throws ConnectionException, RequestException, AccessException { + public ILabel getLabel(final String labelName) throws ConnectionException, RequestException, AccessException { return labelDelegator.getLabel(labelName); } @Override - public String updateLabel(@Nonnull final ILabel label) - throws ConnectionException, RequestException, AccessException { + public String updateLabel(@Nonnull final ILabel label) throws ConnectionException, RequestException, AccessException { return labelDelegator.updateLabel(label); } @Override - public List getLabels( - final String user, - final int maxLabels, - final String nameFilter, - final List fileList) - throws ConnectionException, RequestException, AccessException { + public List getLabels(final String user, final int maxLabels, final String nameFilter, final List fileList) throws ConnectionException, RequestException, AccessException { return labelsDelegator.getLabels(user, maxLabels, nameFilter, fileList); } @Override - public List getLabels( - final List fileList, - final GetLabelsOptions opts) throws P4JavaException { + public List getLabels(final List fileList, final GetLabelsOptions opts) throws P4JavaException { return labelsDelegator.getLabels(fileList, opts); } @@ -2411,14 +2206,12 @@ public String getLoginStatus() throws P4JavaException { } @Override - public void login(final String password) - throws ConnectionException, RequestException, AccessException, ConfigException { + public void login(final String password) throws ConnectionException, RequestException, AccessException, ConfigException { loginDelegator.login(password); } @Override - public void login(final String password, final boolean allHosts) - throws ConnectionException, RequestException, AccessException, ConfigException { + public void login(final String password, final boolean allHosts) throws ConnectionException, RequestException, AccessException, ConfigException { loginDelegator.login(password, allHosts); } @@ -2428,14 +2221,12 @@ public void login(final String password, final LoginOptions opts) throws P4JavaE } @Override - public void login(final String password, final StringBuffer ticket, final LoginOptions opts) - throws P4JavaException { + public void login(final String password, final StringBuffer ticket, final LoginOptions opts) throws P4JavaException { loginDelegator.login(password, ticket, opts); } @Override - public void login(@Nonnull final IUser user, final StringBuffer ticket, final LoginOptions opts) - throws P4JavaException { + public void login(@Nonnull final IUser user, final StringBuffer ticket, final LoginOptions opts) throws P4JavaException { loginDelegator.login(user, ticket, opts); } @@ -2480,8 +2271,7 @@ public String login2(IUser user, Login2Options opts) throws P4JavaException { } @Override - public void logout() - throws ConnectionException, RequestException, AccessException, ConfigException { + public void logout() throws ConnectionException, RequestException, AccessException, ConfigException { logoutDelegator.logout(); } @@ -2491,15 +2281,13 @@ public void logout(final LoginOptions opts) throws P4JavaException { } @Override - public List getServerProcesses() - throws ConnectionException, RequestException, AccessException { + public List getServerProcesses() throws ConnectionException, RequestException, AccessException { return monitorDelegator.getServerProcesses(); } @Override - public List getServerProcesses(final GetServerProcessesOptions opts) - throws P4JavaException { + public List getServerProcesses(final GetServerProcessesOptions opts) throws P4JavaException { return monitorDelegator.getServerProcesses(opts); } @@ -2510,114 +2298,76 @@ public ILogTail getLogTail(final LogTailOptions opts) throws P4JavaException { } @Override - public List getOpenedFiles(final List fileSpecs, final boolean allClients, - final String clientName, final int maxFiles, final int changeListId) - throws ConnectionException, AccessException { + public List getOpenedFiles(final List fileSpecs, final boolean allClients, final String clientName, final int maxFiles, final int changeListId) throws ConnectionException, AccessException { return openedDelegator.getOpenedFiles(fileSpecs, allClients, clientName, maxFiles, changeListId); } @Override - public List getOpenedFiles(final List fileSpecs, - final OpenedFilesOptions opts) throws P4JavaException { + public List getOpenedFiles(final List fileSpecs, final OpenedFilesOptions opts) throws P4JavaException { return openedDelegator.getOpenedFiles(fileSpecs, opts); } @Override - public List moveFile( - final int changelistId, - final boolean listOnly, - final boolean noClientMove, - final String fileType, - @Nonnull final IFileSpec fromFile, - @Nonnull final IFileSpec toFile) - throws ConnectionException, RequestException, AccessException { + public List moveFile(final int changelistId, final boolean listOnly, final boolean noClientMove, final String fileType, @Nonnull final IFileSpec fromFile, @Nonnull final IFileSpec toFile) throws ConnectionException, RequestException, AccessException { - return moveDelegator.moveFile( - changelistId, - listOnly, - noClientMove, - fileType, - fromFile, - toFile); + return moveDelegator.moveFile(changelistId, listOnly, noClientMove, fileType, fromFile, toFile); } @Override - public List moveFile( - @Nonnull IFileSpec fromFile, - @Nonnull IFileSpec toFile, - @Nullable MoveFileOptions opts) throws P4JavaException { + public List moveFile(@Nonnull IFileSpec fromFile, @Nonnull IFileSpec toFile, @Nullable MoveFileOptions opts) throws P4JavaException { return moveDelegator.moveFile(fromFile, toFile, opts); } @Override - public List obliterateFiles( - @Nonnull final List fileSpecs, - final ObliterateFilesOptions opts) throws P4JavaException { + public List obliterateFiles(@Nonnull final List fileSpecs, final ObliterateFilesOptions opts) throws P4JavaException { return obliterateDelegator.obliterateFiles(fileSpecs, opts); } @Override - public String changePassword( - final String oldPassword, - final String newPassword, - final String userName) throws P4JavaException { + public String changePassword(final String oldPassword, final String newPassword, final String userName) throws P4JavaException { return passwdDelegator.changePassword(oldPassword, newPassword, userName); } @Override - public InputStream getFileContents( - final List fileSpecs, - final GetFileContentsOptions opts) throws P4JavaException { + public InputStream getFileContents(final List fileSpecs, final GetFileContentsOptions opts) throws P4JavaException { return printDelegator.getFileContents(fileSpecs, opts); } @Override - public InputStream getFileContents( - final List fileSpecs, - final boolean allrevs, - final boolean noHeaderLine) - throws ConnectionException, RequestException, AccessException { + public InputStream getFileContents(final List fileSpecs, final boolean allrevs, final boolean noHeaderLine) throws ConnectionException, RequestException, AccessException { return printDelegator.getFileContents(fileSpecs, allrevs, noHeaderLine); } @Override - public String setProperty( - final String name, - final String value, - final PropertyOptions opts) throws P4JavaException { + public String setProperty(final String name, final String value, final PropertyOptions opts) throws P4JavaException { return propertyDelegator.setProperty(name, value, opts); } @Override - public List getProperty(final GetPropertyOptions opts) - throws P4JavaException { + public List getProperty(final GetPropertyOptions opts) throws P4JavaException { return propertyDelegator.getProperty(opts); } @Override - public String deleteProperty( - final String name, - final PropertyOptions opts) throws P4JavaException { + public String deleteProperty(final String name, final PropertyOptions opts) throws P4JavaException { return propertyDelegator.deleteProperty(name, opts); } @Override - public String createProtectionEntries(@Nonnull final List entryList) - throws P4JavaException { + public String createProtectionEntries(@Nonnull final List entryList) throws P4JavaException { return protectDelegator.createProtectionEntries(entryList); } @Override - public String updateProtectionEntries(@Nonnull final List entryList) - throws P4JavaException { + public String updateProtectionEntries(@Nonnull final List entryList) throws P4JavaException { return protectDelegator.updateProtectionEntries(entryList); } @@ -2628,28 +2378,15 @@ public InputStream getProtectionsTable() throws P4JavaException { } @Override - public List getProtectionEntries( - final List fileList, - final GetProtectionEntriesOptions opts) throws P4JavaException { + public List getProtectionEntries(final List fileList, final GetProtectionEntriesOptions opts) throws P4JavaException { return protectsDelegator.getProtectionEntries(fileList, opts); } @Override - public List getProtectionEntries( - final boolean allUsers, - final String hostName, - final String userName, - final String groupName, - final List fileList) - throws ConnectionException, RequestException, AccessException { + public List getProtectionEntries(final boolean allUsers, final String hostName, final String userName, final String groupName, final List fileList) throws ConnectionException, RequestException, AccessException { - return protectsDelegator.getProtectionEntries( - allUsers, - hostName, - userName, - groupName, - fileList); + return protectsDelegator.getProtectionEntries(allUsers, hostName, userName, groupName, fileList); } @Override @@ -2658,49 +2395,37 @@ public String reload(final ReloadOptions opts) throws P4JavaException { } @Override - public String renameUser( - final String oldUserName, - final String newUserName) throws P4JavaException { + public String renameUser(final String oldUserName, final String newUserName) throws P4JavaException { return renameUserDelegator.renameUser(oldUserName, newUserName); } @Override - public List getReviewChangelists(final GetReviewChangelistsOptions opts) - throws P4JavaException { + public List getReviewChangelists(final GetReviewChangelistsOptions opts) throws P4JavaException { return reviewDelegator.getReviewChangelists(opts); } @Override - public List getReviews( - final int changelistId, - final List fileSpecs) - throws ConnectionException, RequestException, AccessException { + public List getReviews(final int changelistId, final List fileSpecs) throws ConnectionException, RequestException, AccessException { return reviewsDelegator.getReviews(changelistId, fileSpecs); } @Override - public List getReviews( - final List fileSpecs, - final GetReviewsOptions opts) throws P4JavaException { + public List getReviews(final List fileSpecs, final GetReviewsOptions opts) throws P4JavaException { return reviewsDelegator.getReviews(fileSpecs, opts); } @Override - public List searchJobs( - final String words, - final SearchJobsOptions opts) throws P4JavaException { + public List searchJobs(final String words, final SearchJobsOptions opts) throws P4JavaException { return searchDelegator.searchJobs(words, opts); } @Override - public List getFileSizes( - final List fileSpecs, - final GetFileSizesOptions opts) throws P4JavaException { + public List getFileSizes(final List fileSpecs, final GetFileSizesOptions opts) throws P4JavaException { return sizesDelegator.getFileSizes(fileSpecs, opts); } @@ -2716,59 +2441,43 @@ public IStream getStream(@Nonnull final String streamPath) throws P4JavaExceptio } @Override - public IStream getStream( - final String streamPath, - final GetStreamOptions opts) throws P4JavaException { + public IStream getStream(final String streamPath, final GetStreamOptions opts) throws P4JavaException { return streamDelegator.getStream(streamPath, opts); } @Override - public String updateStream( - final IStream stream, - final StreamOptions opts) throws P4JavaException { + public String updateStream(final IStream stream, final StreamOptions opts) throws P4JavaException { return streamDelegator.updateStream(stream, opts); } @Override - public String deleteStream( - final String streamPath, - final StreamOptions opts) throws P4JavaException { + public String deleteStream(final String streamPath, final StreamOptions opts) throws P4JavaException { return streamDelegator.deleteStream(streamPath, opts); } @Override - public List getStreams( - final List streamPaths, - final GetStreamsOptions opts) throws P4JavaException { + public List getStreams(final List streamPaths, final GetStreamsOptions opts) throws P4JavaException { return streamsDelegator.getStreams(streamPaths, opts); } @Override - public List tagFiles( - List fileSpecs, - String labelName, - boolean listOnly, - boolean delete) throws ConnectionException, RequestException, AccessException { + public List tagFiles(List fileSpecs, String labelName, boolean listOnly, boolean delete) throws ConnectionException, RequestException, AccessException { return tagDelegator.tagFiles(fileSpecs, labelName, listOnly, delete); } @Override - public List tagFiles( - final List fileSpecs, - final String labelName, - final TagFilesOptions opts) throws P4JavaException { + public List tagFiles(final List fileSpecs, final String labelName, final TagFilesOptions opts) throws P4JavaException { return tagDelegator.tagFiles(fileSpecs, labelName, opts); } @Override - public String createTriggerEntries(@Nonnull final List entryList) - throws P4JavaException { + public String createTriggerEntries(@Nonnull final List entryList) throws P4JavaException { return triggersDelegator.createTriggerEntries(entryList); } @@ -2779,8 +2488,7 @@ public List getTriggerEntries() throws P4JavaException { } @Override - public String updateTriggerEntries(@Nonnull final List entryList) - throws P4JavaException { + public String updateTriggerEntries(@Nonnull final List entryList) throws P4JavaException { return triggersDelegator.updateTriggerEntries(entryList); } @@ -2791,74 +2499,55 @@ public InputStream getTriggersTable() throws P4JavaException { } @Override - public String createUser( - @Nonnull final IUser user, - final boolean force) throws ConnectionException, RequestException, AccessException { + public String createUser(@Nonnull final IUser user, final boolean force) throws ConnectionException, RequestException, AccessException { return userDelegator.createUser(user, force); } @Override - public String createUser( - @Nonnull final IUser user, - final UpdateUserOptions opts) throws P4JavaException { + public String createUser(@Nonnull final IUser user, final UpdateUserOptions opts) throws P4JavaException { return userDelegator.createUser(user, opts); } @Override - public String updateUser( - @Nonnull final IUser user, - final UpdateUserOptions opts) throws P4JavaException { + public String updateUser(@Nonnull final IUser user, final UpdateUserOptions opts) throws P4JavaException { return userDelegator.updateUser(user, opts); } @Override - public String updateUser( - @Nonnull final IUser user, - final boolean force) - throws ConnectionException, RequestException, AccessException { + public String updateUser(@Nonnull final IUser user, final boolean force) throws ConnectionException, RequestException, AccessException { return userDelegator.updateUser(user, force); } @Override - public String deleteUser( - final String userName, - final boolean force) throws ConnectionException, RequestException, AccessException { + public String deleteUser(final String userName, final boolean force) throws ConnectionException, RequestException, AccessException { return userDelegator.deleteUser(userName, force); } @Override - public String deleteUser( - String userName, - UpdateUserOptions opts) throws P4JavaException { + public String deleteUser(String userName, UpdateUserOptions opts) throws P4JavaException { return userDelegator.deleteUser(userName, opts); } @Override - public IUser getUser(final String userName) - throws ConnectionException, RequestException, AccessException { + public IUser getUser(final String userName) throws ConnectionException, RequestException, AccessException { return userDelegator.getUser(userName); } @Override - public List getUsers( - final List userList, - final int maxUsers) - throws ConnectionException, RequestException, AccessException { + public List getUsers(final List userList, final int maxUsers) throws ConnectionException, RequestException, AccessException { return usersDelegator.getUsers(userList, maxUsers); } @Override - public List getUsers( - final List userList, - final GetUsersOptions opts) throws P4JavaException { + public List getUsers(final List userList, final GetUsersOptions opts) throws P4JavaException { return usersDelegator.getUsers(userList, opts); } @@ -2869,9 +2558,7 @@ public String unload(final UnloadOptions opts) throws P4JavaException { } @Override - public List verifyFiles( - final List fileSpecs, - final VerifyFilesOptions opts) throws P4JavaException { + public List verifyFiles(final List fileSpecs, final VerifyFilesOptions opts) throws P4JavaException { return verifyDelegator.verifyFiles(fileSpecs, opts); } @@ -3061,20 +2748,27 @@ public IGraphObject getGraphObject(String sha) throws P4JavaException { } /** + * @param map map + * @return IFileSpec + * @throws AccessException on error + * @throws ConnectionException on error * @deprecated use {@link com.perforce.p4java.impl.mapbased.server.cmd.ResultListBuilder} */ @Deprecated - public IFileSpec handleFileReturn(Map map) - throws AccessException, ConnectionException { + public IFileSpec handleFileReturn(Map map) throws AccessException, ConnectionException { return ResultListBuilder.handleFileReturn(map, this); } /** + * @param map map + * @param client client + * @return IFileSpec + * @throws AccessException on error + * @throws ConnectionException on error * @deprecated use {@link com.perforce.p4java.impl.mapbased.server.cmd.ResultListBuilder} */ @Deprecated - public IFileSpec handleFileReturn(Map map, IClient client) - throws AccessException, ConnectionException { + public IFileSpec handleFileReturn(Map map, IClient client) throws AccessException, ConnectionException { return ResultListBuilder.handleFileReturn(map, this); } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/ServerAddressBuilder.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/ServerAddressBuilder.java index d5aeb37..0b5387b 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/ServerAddressBuilder.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/ServerAddressBuilder.java @@ -3,11 +3,11 @@ */ package com.perforce.p4java.impl.mapbased.server; +import com.perforce.p4java.server.IServerAddress.Protocol; + import java.net.URISyntaxException; import java.util.Properties; -import com.perforce.p4java.server.IServerAddress.Protocol; - /** * The purpose of this class is for building a server address object. */ @@ -24,19 +24,18 @@ public class ServerAddressBuilder { /** * Instantiates an empty server address builder. */ - public ServerAddressBuilder() {} - + public ServerAddressBuilder() { + } + /** * Instantiates a new server address builder from a string. - * - * @param serverAddress - * the server address - * @throws URISyntaxException + * + * @param serverAddress the server address + * @throws URISyntaxException on error */ public ServerAddressBuilder(String serverAddress) throws URISyntaxException { if (serverAddress == null) { - throw new IllegalArgumentException( - "The server address cannot be null."); + throw new IllegalArgumentException("The server address cannot be null."); } parseUri(serverAddress); } @@ -44,26 +43,22 @@ public ServerAddressBuilder(String serverAddress) throws URISyntaxException { /** * Parse the URI. *

- * * Note: assume the URI string is not encoded. - * - * @param query - * the query - * @throws URISyntaxException + * + * @param uri the uri + * @throws URISyntaxException on error */ private void parseUri(String uri) throws URISyntaxException { this.uri = uri; - + int protoPartEnd = uri.indexOf("://"); if (protoPartEnd < 0) { - throw new URISyntaxException(uri, - "missing or malformed Perforce scheme / protocol part"); + throw new URISyntaxException(uri, "missing or malformed Perforce scheme / protocol part"); } String protoPart = uri.substring(0, protoPartEnd); if ((protoPart.length() + 3) >= uri.length()) { - throw new URISyntaxException(uri, - "missing or malformed Perforce server hostname"); + throw new URISyntaxException(uri, "missing or malformed Perforce server hostname"); } this.protocol = Protocol.fromString(protoPart); if (protocol == null) { @@ -79,22 +74,19 @@ private void parseUri(String uri) throws URISyntaxException { int portStart = restStr.lastIndexOf(":"); int queryStart = restStr.indexOf("?"); if (portStart == 0) { - throw new URISyntaxException(uri, - "missing or malformed Perforce server hostname"); + throw new URISyntaxException(uri, "missing or malformed Perforce server hostname"); } if ((portStart < 0) || ((queryStart > 0) && (queryStart < portStart))) { - throw new URISyntaxException(uri, - "missing or malformed Perforce server port specifier"); + throw new URISyntaxException(uri, "missing or malformed Perforce server port specifier"); } this.host = restStr.substring(0, portStart); - + String portPart = null; if (queryStart > 0) { portPart = restStr.substring(portStart + 1, queryStart); - + if (queryStart >= restStr.length()) { - throw new URISyntaxException(uri, - "empty or malformed P4Java query string"); + throw new URISyntaxException(uri, "empty or malformed P4Java query string"); } this.query = restStr.substring(queryStart + 1); } else { @@ -103,10 +95,9 @@ private void parseUri(String uri) throws URISyntaxException { try { this.port = new Integer(portPart); } catch (NumberFormatException nfe) { - throw new URISyntaxException(uri, - "non-numeric Perforce server port specifier"); + throw new URISyntaxException(uri, "non-numeric Perforce server port specifier"); } - + if (this.query != null) { if (this.properties == null) { this.properties = new Properties(); @@ -134,7 +125,7 @@ private void parseUri(String uri) throws URISyntaxException { /** * Builds the server address. - * + * * @return the server address */ public ServerAddress build() { @@ -143,7 +134,7 @@ public ServerAddress build() { /** * Gets the protocol. - * + * * @return the protocol */ public Protocol getProtocol() { @@ -152,7 +143,7 @@ public Protocol getProtocol() { /** * Sets the protocol. - * + * * @param protocol the protocol */ public void setProtocol(Protocol protocol) { @@ -161,7 +152,7 @@ public void setProtocol(Protocol protocol) { /** * Gets the host. - * + * * @return the host */ public String getHost() { @@ -170,7 +161,7 @@ public String getHost() { /** * Sets the host. - * + * * @param host the host */ public void setHost(String host) { @@ -179,7 +170,7 @@ public void setHost(String host) { /** * Gets the port. - * + * * @return the port */ public int getPort() { @@ -188,7 +179,7 @@ public int getPort() { /** * Sets the port. - * + * * @param port the port */ public void setPort(int port) { @@ -197,7 +188,7 @@ public void setPort(int port) { /** * Gets the query. - * + * * @return the query */ public String getQuery() { @@ -206,7 +197,7 @@ public String getQuery() { /** * Gets the properties (parsed from the query string). - * + * * @return the properties */ public Properties getProperties() { @@ -215,13 +206,12 @@ public Properties getProperties() { /** * Gets the uri. - * + * * @return the uri */ public String getUri() { - if (this.uri != null) - return this.uri; - + if (this.uri != null) return this.uri; + String newUri = protocol.toString() + "://"; if (protocol == Protocol.P4JRSH || protocol == Protocol.P4JRSHNTS) { newUri += this.rsh; @@ -233,7 +223,7 @@ public String getUri() { /** * Gets the rsh command. - * + * * @return the rsh command */ public String getRsh() { @@ -242,7 +232,7 @@ public String getRsh() { /** * Sets the rsh command. - * + * * @param rsh the rsh command */ public void setRsh(String rsh) { diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/ServerInfo.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/ServerInfo.java index c109238..5bc5263 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/ServerInfo.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/ServerInfo.java @@ -1,8 +1,10 @@ /** - * + * */ package com.perforce.p4java.impl.mapbased.server; +import com.perforce.p4java.server.IServerInfo; + import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; @@ -11,8 +13,6 @@ import java.util.List; import java.util.Map; -import com.perforce.p4java.server.IServerInfo; - /** * Default simple implementation for server info interface. */ @@ -22,7 +22,7 @@ public class ServerInfo implements IServerInfo { // Perforce server info date pattern with time zone // Example: "2014/06/05 17:28:14 -0700 PDT" public static final String SERVER_INFO_DATE_PATTERN = "yyyy/MM/dd HH:mm:ss Z z"; - + private String clientName = null; private String clientHost = null; private String clientRoot = null; @@ -40,7 +40,7 @@ public class ServerInfo implements IServerInfo { private boolean serverEncrypted = false; private String serverId = null; private String serverCluster = null; - + private String replica = null; private boolean passwordEnabled = false; private boolean caseSensitive = false; @@ -69,16 +69,27 @@ public ServerInfo() { /** * Explicit-value all-fields constructor. - * + * + * @param clientName clientName + * @param clientHost clientHost + * @param clientRoot clientRoot + * @param clientAddress clientAddress + * @param clientCurrentDirectory clientCurrentDirectory + * @param serverAddress serverAddress + * @param serverDate serverDate + * @param serverLicense serverLicense + * @param serverRoot serverRoot + * @param serverUptime serverUptime + * @param serverVersion serverVersion + * @param serverLicenseIp serverLicenseIp + * @param proxyVersion proxyVersion + * @param userName userName + * @param unicodeEnabled unicodeEnabled + * @param monitorEnabled monitorEnabled * @deprecated Use constructor with map parameter to initialize all fields. */ @Deprecated - public ServerInfo(String clientName, String clientHost, String clientRoot, - String clientAddress, String clientCurrentDirectory, - String serverAddress, String serverDate, String serverLicense, - String serverRoot, String serverUptime, String serverVersion, - String serverLicenseIp, String proxyVersion, String userName, - boolean unicodeEnabled, boolean monitorEnabled) { + public ServerInfo(String clientName, String clientHost, String clientRoot, String clientAddress, String clientCurrentDirectory, String serverAddress, String serverDate, String serverLicense, String serverRoot, String serverUptime, String serverVersion, String serverLicenseIp, String proxyVersion, String userName, boolean unicodeEnabled, boolean monitorEnabled) { this.clientName = clientName; this.clientHost = clientHost; this.clientRoot = clientRoot; @@ -99,8 +110,9 @@ public ServerInfo(String clientName, String clientHost, String clientRoot, /** * Constructor for use with maps passed back from the Perforce server only. - * + * * When a broker is involved, there will be more than one map. + * @param maps maps */ public ServerInfo(List> maps) { for (Map map : maps) { @@ -110,6 +122,7 @@ public ServerInfo(List> maps) { /** * Constructor for use with maps passed back from the Perforce server only. + * @param map map */ public ServerInfo(Map map) { if (map != null) { @@ -119,6 +132,7 @@ public ServerInfo(Map map) { /** * add any fields that are set in map; don't clear fields that are missing from map + * @param map map */ private void setFromMap(Map map) { this.userName = setFromMap(map, "userName", this.userName); @@ -127,7 +141,7 @@ private void setFromMap(Map map) { this.clientRoot = setFromMap(map, "clientRoot", this.clientRoot); this.clientHost = setFromMap(map, "clientHost", this.clientHost); this.clientAddress = setFromMap(map, "clientAddress", this.clientAddress); - + this.serverAddress = setFromMap(map, "serverAddress", this.serverAddress); this.serverDate = setFromMap(map, "serverDate", this.serverDate); this.serverLicense = setFromMap(map, "serverLicense", this.serverLicense); @@ -137,13 +151,13 @@ private void setFromMap(Map map) { this.serverLicenseIp = setFromMap(map, "serverLicense-ip", this.serverLicenseIp); this.serverId = setFromMap(map, "ServerID", this.serverId); this.serverCluster = setFromMap(map, "serverCluster", this.serverCluster); - + this.replica = setFromMap(map, "replica", this.replica); this.proxyVersion = setFromMap(map, "proxyVersion", this.proxyVersion); this.proxyAddress = setFromMap(map, "proxyAddress", this.proxyAddress); this.proxyRoot = setFromMap(map, "proxyRoot", this.proxyRoot); - + this.brokerVersion = setFromMap(map, "brokerVersion", this.brokerVersion); this.brokerAddress = setFromMap(map, "brokerAddress", this.brokerAddress); this.sandboxVersion = setFromMap(map, "p4sandboxBrokerVersion", this.sandboxVersion); @@ -153,9 +167,9 @@ private void setFromMap(Map map) { this.ssoAuth = setFromMap(map, "ssoAuth", this.ssoAuth); if (map.get("serverDate") != null) { - DateFormat df = new SimpleDateFormat(SERVER_INFO_DATE_PATTERN); - try { - Date d = df.parse((String)map.get("serverDate")); + DateFormat df = new SimpleDateFormat(SERVER_INFO_DATE_PATTERN); + try { + Date d = df.parse((String) map.get("serverDate")); if (d != null) { this.serverCalendar = Calendar.getInstance(); this.serverCalendar.setTime(d); @@ -165,47 +179,37 @@ private void setFromMap(Map map) { } } - if (map.containsKey("serverEncryption") - && ((String) map.get("serverEncryption")).equalsIgnoreCase("encrypted")) { + if (map.containsKey("serverEncryption") && ((String) map.get("serverEncryption")).equalsIgnoreCase("encrypted")) { this.serverEncrypted = true; } - if (map.containsKey("proxyEncryption") - && ((String) map.get("proxyEncryption")).equalsIgnoreCase("encrypted")) { + if (map.containsKey("proxyEncryption") && ((String) map.get("proxyEncryption")).equalsIgnoreCase("encrypted")) { this.proxyEncrypted = true; } - if (map.containsKey("brokerEncryption") - && ((String) map.get("brokerEncryption")).equalsIgnoreCase("encrypted")) { + if (map.containsKey("brokerEncryption") && ((String) map.get("brokerEncryption")).equalsIgnoreCase("encrypted")) { this.brokerEncrypted = true; } - if (map.containsKey("password") - && ((String) map.get("password")).equalsIgnoreCase("enabled")) { + if (map.containsKey("password") && ((String) map.get("password")).equalsIgnoreCase("enabled")) { this.passwordEnabled = true; } - if (map.containsKey("caseHandling") - && ((String) map.get("caseHandling")).equalsIgnoreCase("sensitive")) { + if (map.containsKey("caseHandling") && ((String) map.get("caseHandling")).equalsIgnoreCase("sensitive")) { this.caseSensitive = true; } - if (map.containsKey("unicode") - && ((String) map.get("unicode")).equalsIgnoreCase("enabled")) { + if (map.containsKey("unicode") && ((String) map.get("unicode")).equalsIgnoreCase("enabled")) { this.unicodeEnabled = true; } - if (map.containsKey("monitor") - && ((String) map.get("monitor")).equalsIgnoreCase("enabled")) { + if (map.containsKey("monitor") && ((String) map.get("monitor")).equalsIgnoreCase("enabled")) { this.monitorEnabled = true; } - if (map.containsKey("move") - && ((String) map.get("move")).equalsIgnoreCase("disabled")) { + if (map.containsKey("move") && ((String) map.get("move")).equalsIgnoreCase("disabled")) { this.moveDisabled = true; } } - + private String setFromMap(Map map, String key, String defaultValue) { - if (map.containsKey(key)) - return (String)map.get(key); - else - return defaultValue; + if (map.containsKey(key)) return (String) map.get(key); + else return defaultValue; } - + public String getServerAddress() { return this.serverAddress; } @@ -455,11 +459,9 @@ public void setSandboxPort(String sandboxPort) { } public boolean isEncrypted() { - return (this.serverEncrypted || - this.proxyEncrypted || - this.brokerEncrypted); + return (this.serverEncrypted || this.proxyEncrypted || this.brokerEncrypted); } - + public String getServerId() { return serverId; } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/AttributeDelegator.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/AttributeDelegator.java index 87d6420..98dd836 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/AttributeDelegator.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/AttributeDelegator.java @@ -13,6 +13,7 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.io.InputStream; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -31,145 +32,175 @@ */ public class AttributeDelegator extends BaseDelegator implements IAttributeDelegator { - /** - * Instantiate a new AttributeDelegator, providing the server object that will be used to - * execute Perforce Helix attribute commands. - * - * @param server a concrete implementation of a Perforce Helix Server - */ - public AttributeDelegator(IOptionsServer server) { - super(server); - } - - @Override - public List setFileAttributes( - final List files, - @Nonnull final Map attributes, - final SetFileAttributesOptions opts) throws P4JavaException { - - Validate.notNull(attributes); - - /* - * Note the rather odd parameter processing below, required due to the - * rather odd way attributes are passed to the server (or not) -- each - * name must have a -n flag attached, and each value a corresponding -v - * flag; it's unclear what happens when these don't match up, but never - * mind... in any case, after some experimentation, it seems safest to - * bunch all the names first, then the values. This may change with - * further experimentation. - */ - List args = new ArrayList<>(); - for (String name : attributes.keySet()) { - args.add("-n" + name); - } - - for (Map.Entry entry : attributes.entrySet()) { - if (isNotBlank(entry.getValue())) { - args.add("-v" + entry.getValue()); - } - } - - /* - * Note that this is the one command that doesn't adhere to the - * (admittedly loose) rules about multiple returns and tag names, etc, - * meaning that we anomalously return a list of result strings rather - * than file specs; the reason underlying this is that each attribute - * set causes a result row, meaning we may get multiple results back - * from the server for the same file, and several error messages, etc. - * -- all from the single request. This seems less than optimal to me... - */ - List> resultMaps = execMapCmdList( - ATTRIBUTE, - processParameters( - opts, - files, - args.toArray(new String[args.size()]), - true, - server), - null); - - return buildSetFileAttributesFileSpecsFromCommandResultMaps( - resultMaps, - rethrowFunction( - new FunctionWithException, IFileSpec>() { - @Override - public IFileSpec apply(Map map) throws P4JavaException { - return ResultListBuilder.handleFileReturn(map, server); - } - } - ) - ); - } - - @Override - public List setFileAttributes( - final List files, - @Nonnull final String attributeName, - @Nonnull final InputStream inStream, - final SetFileAttributesOptions opts) throws P4JavaException { - - Validate.notNull(inStream); - Validate.notBlank(attributeName, "Attribute name shouldn't blank"); - /* - * Note that we use the map argument here to pass in a single stream; - * this can be expanded later if the server introduces multiple streams - * for attributes (not likely for the attributes command, but other - * commands may do this in the distant future, and anyway, it's the - * thought that counts...). - */ - Map inputMap = new HashMap<>(); - inputMap.put(IOptionsServer.ATTRIBUTE_STREAM_MAP_KEY, inStream); - - List> resultMaps = execMapCmdList( - ATTRIBUTE, - processParameters( - opts, - files, - new String[]{"-i", "-n" + attributeName}, - true, - server), - inputMap); - - return buildSetFileAttributesFileSpecsFromCommandResultMaps( - resultMaps, - rethrowFunction( - new FunctionWithException, IFileSpec>() { - @Override - public IFileSpec apply(Map map) throws P4JavaException { - return ResultListBuilder.handleFileReturn(map, server); - } - } - ) - ); - } - - /** - * Inner utility class to convert a resultmaps list into attribute filespec objects. - * TODO: this doesn't belong in here, maybe filespecbuilder? - */ - private List buildSetFileAttributesFileSpecsFromCommandResultMaps( - @Nullable final List> resultMaps, - @Nonnull final Function, IFileSpec> handle) - throws RequestException { - - List resultList = new ArrayList<>(); - if (nonNull(resultMaps)) { - List filesSeen = new ArrayList<>(); - for (Map map : resultMaps) { - IFileSpec spec = handle.apply(map); - if (spec.getOpStatus() == VALID) { - String file = spec.getAnnotatedPathString(DEPOT); - if (isNotBlank(file)) { - if (!filesSeen.contains(file)) { - filesSeen.add(file); - resultList.add(spec); - } - } - } else { - resultList.add(spec); - } - } - } - return resultList; - } + /** + * Instantiate a new AttributeDelegator, providing the server object that will be used to + * execute Perforce Helix attribute commands. + * + * @param server a concrete implementation of a Perforce Helix Server + */ + public AttributeDelegator(IOptionsServer server) { + super(server); + } + + @Override + public List unsetFileAttribute( + final List files, + @Nonnull final String attribute, + final SetFileAttributesOptions opts) throws P4JavaException { + + Validate.notNull(attribute); + + HashMap attributesToUnsetMap = new HashMap<>(); + attributesToUnsetMap.put(attribute, ""); + + return setFileAttributes(files, attributesToUnsetMap, opts); + } + + @Override + public List unsetFileAttributes( + final List files, + @Nonnull final List attributes, + final SetFileAttributesOptions opts) throws P4JavaException { + + Validate.notNull(attributes); + + HashMap attributesToUnsetMap = new HashMap<>(); + for (String attribute : attributes) { + attributesToUnsetMap.put(attribute, ""); + } + + return setFileAttributes(files, attributesToUnsetMap, opts); + } + + @Override + public List setFileAttributes( + final List files, + @Nonnull final Map attributes, + final SetFileAttributesOptions opts) throws P4JavaException { + + Validate.notNull(attributes); + + /* + * Note the rather odd parameter processing below, required due to the + * rather odd way attributes are passed to the server (or not) -- each + * name must have a -n flag attached, and each value a corresponding -v + * flag; it's unclear what happens when these don't match up, but never + * mind... in any case, after some experimentation, it seems safest to + * bunch all the names first, then the values. This may change with + * further experimentation. + */ + List args = new ArrayList<>(); + for (String name : attributes.keySet()) { + args.add("-n" + name); + } + + for (Map.Entry entry : attributes.entrySet()) { + if (isNotBlank(entry.getValue())) { + args.add("-v" + entry.getValue()); + } + } + + /* + * Note that this is the one command that doesn't adhere to the + * (admittedly loose) rules about multiple returns and tag names, etc, + * meaning that we anomalously return a list of result strings rather + * than file specs; the reason underlying this is that each attribute + * set causes a result row, meaning we may get multiple results back + * from the server for the same file, and several error messages, etc. + * -- all from the single request. This seems less than optimal to me... + */ + List> resultMaps = execMapCmdList( + ATTRIBUTE, + processParameters( + opts, + files, + args.toArray(new String[args.size()]), + true, + server), + null); + + return buildSetFileAttributesFileSpecsFromCommandResultMaps( + resultMaps, + rethrowFunction( + new FunctionWithException, IFileSpec>() { + @Override + public IFileSpec apply(Map map) throws P4JavaException { + return ResultListBuilder.handleFileReturn(map, server); + } + } + ) + ); + } + + @Override + public List setFileAttributes( + final List files, + @Nonnull final String attributeName, + @Nonnull final InputStream inStream, + final SetFileAttributesOptions opts) throws P4JavaException { + + Validate.notNull(inStream); + Validate.notBlank(attributeName, "Attribute name shouldn't blank"); + /* + * Note that we use the map argument here to pass in a single stream; + * this can be expanded later if the server introduces multiple streams + * for attributes (not likely for the attributes command, but other + * commands may do this in the distant future, and anyway, it's the + * thought that counts...). + */ + Map inputMap = new HashMap<>(); + inputMap.put(IOptionsServer.ATTRIBUTE_STREAM_MAP_KEY, inStream); + + List> resultMaps = execMapCmdList( + ATTRIBUTE, + processParameters( + opts, + files, + new String[]{"-i", "-n" + attributeName}, + true, + server), + inputMap); + + return buildSetFileAttributesFileSpecsFromCommandResultMaps( + resultMaps, + rethrowFunction( + new FunctionWithException, IFileSpec>() { + @Override + public IFileSpec apply(Map map) throws P4JavaException { + return ResultListBuilder.handleFileReturn(map, server); + } + } + ) + ); + } + + /** + * Inner utility class to convert a resultmaps list into attribute filespec objects. + * TODO: this doesn't belong in here, maybe filespecbuilder? + */ + private List buildSetFileAttributesFileSpecsFromCommandResultMaps( + @Nullable final List> resultMaps, + @Nonnull final Function, IFileSpec> handle) + throws RequestException { + + List resultList = new ArrayList<>(); + if (nonNull(resultMaps)) { + List filesSeen = new ArrayList<>(); + for (Map map : resultMaps) { + IFileSpec spec = handle.apply(map); + if (spec.getOpStatus() == VALID) { + String file = spec.getAnnotatedPathString(DEPOT); + if (isNotBlank(file)) { + if (!filesSeen.contains(file)) { + filesSeen.add(file); + resultList.add(spec); + } + } + } else { + resultList.add(spec); + } + } + } + return resultList; + } } \ No newline at end of file diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/BaseDelegator.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/BaseDelegator.java index 9933921..5e1fc7e 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/BaseDelegator.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/BaseDelegator.java @@ -9,10 +9,10 @@ import com.perforce.p4java.exception.AccessException; import com.perforce.p4java.exception.ConnectionException; import com.perforce.p4java.exception.RequestException; -import com.perforce.p4java.impl.generic.core.InputMapper; import com.perforce.p4java.impl.generic.core.file.FileSpec; import com.perforce.p4java.server.CmdSpec; import com.perforce.p4java.server.IOptionsServer; +import com.perforce.p4java.server.IServer; import org.apache.commons.lang3.Validate; import javax.annotation.Nonnull; @@ -29,166 +29,95 @@ * */ public abstract class BaseDelegator { - protected static int MAX_LIMIT_SUPPORTED_MIN_VERSION = 20061; - protected static int USER_RESTRICTIONS_SUPPORTED_MIN_VERSION = 20062; - protected static int QUERY_EXPRESSIONS_SUPPORTED_MIN_VERSION = 20082; - - /** The server object */ - - final IOptionsServer server; - - /** - * - * Basic constructor, taking a server object. - * - * @param server - * - an instance of the currently effective server implementaion - * - */ - - BaseDelegator(IOptionsServer server) { - this.server = server; - } - - /** - * - * Utility method for constructing an IFileSpec object from a key value pair - * map, a client - * - * and the current server. - * - * @param map - * The result map from an execcmd operation - * - * @param client - * - * @return An IFileSpec object - * - * @throws AccessException - * Insufficient privileges for the server - * - * @throws ConnectionException - * Cannot connect to the server - * - */ - - IFileSpec handleFileReturn(final Map map, final IClient client) - - throws AccessException, ConnectionException { - - if (map != null) { - - String errStr = server.handleFileErrorStr(map); - - if (isBlank(errStr)) { - - return new FileSpec(map, server, -1); - - } else { - - FileSpecOpStatus specOpStatus = FileSpecOpStatus.ERROR; - - if (server.isInfoMessage(map)) { - - specOpStatus = FileSpecOpStatus.INFO; - - } - - String codeStr = parseCode0ErrorString(map); - - return new FileSpec(specOpStatus, errStr, codeStr); - - } - - } - - return null; - - } - - /** - * - * Run the given command against the real server method. - * - * @param cmdSpec - * The command being run; e.g. VERIFY - * - * @param cmdArgs - * The parameters transformed into an array of arguments - * - * @param inMap - * Optional, used to provide input data to the server command; - * e.g. spec data - * - * @return A list of result map objects - * - * @throws ConnectionException - * When there is a problem connecting to the server - * - * @throws AccessException - * When privileges are insufficient to run the command - * - */ - List> execMapCmdList( - @Nonnull final CmdSpec cmdSpec, - String[] cmdArgs, - Map inMap) - throws ConnectionException, AccessException, RequestException { - - Validate.notNull(cmdSpec); - return server.execMapCmdList(cmdSpec.toString(), cmdArgs, inMap); - } - - /** - * - * Run the given streaming command against the real server method. - * - * @param cmdSpec - * The command being run; e.g. VERIFY - * - * @param cmdArgs - * The parameters transformed into an array of arguments - * - * @return the stream returned by the server command - * - * @throws ConnectionException - * When there is a problem connecting to the server - * - * @throws AccessException - * When privileges are insufficient to run the command - * - */ - InputStream execStreamCmd(final CmdSpec cmdSpec, String[] cmdArgs) - throws ConnectionException, RequestException, AccessException { - Validate.notNull(cmdSpec); - return server.execStreamCmd(cmdSpec.toString(), cmdArgs); - } - - void checkMinSupportedPerforceVersion(final String userName, final int maxLimit, - final String queryString, final String clientOrLabel) - throws RequestException, ConnectionException { - - int serverVersion = server.getServerVersion(); - - if (isNotBlank(userName)) { - throwRequestExceptionIfPerforceServerVersionOldThanExpected( - serverVersion >= USER_RESTRICTIONS_SUPPORTED_MIN_VERSION, - "user restrictions '%s' for %s lists are not supported by this version of the Perforce server", - userName, clientOrLabel); - } - - if (maxLimit > 0) { - throwRequestExceptionIfPerforceServerVersionOldThanExpected( - serverVersion >= MAX_LIMIT_SUPPORTED_MIN_VERSION, - "max limit '%s' for %s lists are not supported by this version of the Perforce server", - maxLimit, clientOrLabel); - } - - if (isNotBlank(queryString)) { - throwRequestExceptionIfPerforceServerVersionOldThanExpected( - serverVersion >= QUERY_EXPRESSIONS_SUPPORTED_MIN_VERSION, - "query expressions '%s' for %s lists are not supported by this version of the Perforce server", - queryString, clientOrLabel); - } - } + protected static int MAX_LIMIT_SUPPORTED_MIN_VERSION = 20061; + protected static int USER_RESTRICTIONS_SUPPORTED_MIN_VERSION = 20062; + protected static int QUERY_EXPRESSIONS_SUPPORTED_MIN_VERSION = 20082; + + /** + * The server object + */ + final IOptionsServer server; + + /** + * Basic constructor, taking a server object. + * + * @param server - an instance of the currently effective server implementaion + */ + BaseDelegator(IOptionsServer server) { + this.server = server; + } + + /** + * Utility method for constructing an IFileSpec object from a key value pair + * map, a client + *

+ * and the current server. + * + * @param map The result map from an execcmd operation + * @param client client + * @return An IFileSpec object + * @throws AccessException Insufficient privileges for the server + * @throws ConnectionException Cannot connect to the server + * @deprecated use @deprecated use {@link ResultListBuilder#handleFileReturn(Map, IServer)} instead + */ + @Deprecated + IFileSpec handleFileReturn(final Map map, final IClient client) throws AccessException, ConnectionException { + if (map != null) { + String errStr = server.handleFileErrorStr(map); + if (isBlank(errStr)) { + return new FileSpec(map, server, -1); + } else { + FileSpecOpStatus specOpStatus = FileSpecOpStatus.ERROR; + if (server.isInfoMessage(map)) { + specOpStatus = FileSpecOpStatus.INFO; + } + String codeStr = parseCode0ErrorString(map); + return new FileSpec(specOpStatus, errStr, codeStr); + } + } + return null; + } + + /** + * Run the given command against the real server method. + * + * @param cmdSpec The command being run; e.g. VERIFY + * @param cmdArgs The parameters transformed into an array of arguments + * @param inMap Optional, used to provide input data to the server command; + * e.g. spec data + * @return A list of result map objects + * @throws ConnectionException When there is a problem connecting to the server + * @throws AccessException When privileges are insufficient to run the command + */ + List> execMapCmdList(@Nonnull final CmdSpec cmdSpec, String[] cmdArgs, Map inMap) throws ConnectionException, AccessException, RequestException { + Validate.notNull(cmdSpec); + return server.execMapCmdList(cmdSpec.toString(), cmdArgs, inMap); + } + + /** + * Run the given streaming command against the real server method. + * + * @param cmdSpec The command being run; e.g. VERIFY + * @param cmdArgs The parameters transformed into an array of arguments + * @return the stream returned by the server command + * @throws ConnectionException When there is a problem connecting to the server + * @throws AccessException When privileges are insufficient to run the command + */ + InputStream execStreamCmd(final CmdSpec cmdSpec, String[] cmdArgs) throws ConnectionException, RequestException, AccessException { + Validate.notNull(cmdSpec); + return server.execStreamCmd(cmdSpec.toString(), cmdArgs); + } + + void checkMinSupportedPerforceVersion(final String userName, final int maxLimit, final String queryString, final String clientOrLabel) throws RequestException, ConnectionException { + int serverVersion = server.getServerVersion(); + if (isNotBlank(userName)) { + throwRequestExceptionIfPerforceServerVersionOldThanExpected(serverVersion >= USER_RESTRICTIONS_SUPPORTED_MIN_VERSION, "user restrictions '%s' for %s lists are not supported by this version of the Perforce server", userName, clientOrLabel); + } + if (maxLimit > 0) { + throwRequestExceptionIfPerforceServerVersionOldThanExpected(serverVersion >= MAX_LIMIT_SUPPORTED_MIN_VERSION, "max limit '%s' for %s lists are not supported by this version of the Perforce server", maxLimit, clientOrLabel); + } + if (isNotBlank(queryString)) { + throwRequestExceptionIfPerforceServerVersionOldThanExpected(serverVersion >= QUERY_EXPRESSIONS_SUPPORTED_MIN_VERSION, "query expressions '%s' for %s lists are not supported by this version of the Perforce server", queryString, clientOrLabel); + } + } } \ No newline at end of file diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/BranchDelegator.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/BranchDelegator.java index 390bc7a..c244e8b 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/BranchDelegator.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/BranchDelegator.java @@ -74,13 +74,8 @@ public IBranchSpec getBranchSpec(final String name, final GetBranchSpecOptions o return ResultListBuilder.buildNullableObjectFromNonInfoMessageCommandResultMaps( resultMaps, - new Function() { - @Override - public IBranchSpec apply(Map map) { - return new BranchSpec(map, server); - } - } - ); + (Function, IBranchSpec>) map -> new BranchSpec(map, server) + ); } @Override @@ -100,6 +95,7 @@ public String updateBranchSpec(@Nonnull final IBranchSpec branchSpec) } } + @Deprecated @Override public String deleteBranchSpec(final String branchSpecName, final boolean force) throws ConnectionException, RequestException, AccessException { diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/BranchesDelegator.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/BranchesDelegator.java index 48d1026..a4db65e 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/BranchesDelegator.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/BranchesDelegator.java @@ -44,12 +44,7 @@ public List getBranchSpecs(final GetBranchSpecsOptions opts) return ResultListBuilder.buildNonNullObjectListFromCommandResultMaps( resultMaps, - new Function() { - @Override - public IBranchSpecSummary apply(Map map) { - return new BranchSpecSummary(map, true); - } - }); + map -> new BranchSpecSummary(map, true)); } @Override diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/ChangeDelegator.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/ChangeDelegator.java index 73a730c..a834546 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/ChangeDelegator.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/ChangeDelegator.java @@ -108,13 +108,8 @@ public IChangelist getChangelist(final int id, final ChangelistOptions opts) return ResultListBuilder.buildNullableObjectFromNonInfoMessageCommandResultMaps( resultMaps, - new Function() { - @Override - public IChangelist apply(Map map) { - return new Changelist(map, server); - } - } - ); + (Function, IChangelist>) map -> new Changelist(map, server) + ); } } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/ChangesDelegator.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/ChangesDelegator.java index 0be60cc..3cb688f 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/ChangesDelegator.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/ChangesDelegator.java @@ -130,11 +130,6 @@ public List getChangelists( return ResultListBuilder.buildNonNullObjectListFromCommandResultMaps( resultMaps, - new Function() { - @Override - public IChangelistSummary apply(Map map) { - return new ChangelistSummary(map, true); - } - }); + map -> new ChangelistSummary(map, true)); } } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/CommitDelegator.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/CommitDelegator.java index e065123..4599f38 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/CommitDelegator.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/CommitDelegator.java @@ -55,16 +55,12 @@ public CommitDelegator(final IOptionsServer server) { @Override public ICommit getCommitObject(String sha) throws P4JavaException { - List> resultMaps = execMapCmdList( - GRAPH, - Parameters.processParameters( - null, null, new String[]{"cat-file", "commit", sha}, server), - null); + List> resultMaps = execMapCmdList(GRAPH, Parameters.processParameters(null, null, new String[]{"cat-file", "commit", sha}, server), null); List commits = parseCommitList(resultMaps); // should only return a single result - if(commits != null && !commits.isEmpty()) { + if (commits != null && !commits.isEmpty()) { return commits.get(0); } @@ -74,16 +70,12 @@ public ICommit getCommitObject(String sha) throws P4JavaException { @Override public ICommit getCommitObject(String sha, String repo) throws P4JavaException { - List> resultMaps = execMapCmdList( - GRAPH, - Parameters.processParameters( - null, null, new String[]{"cat-file", "-n", repo, "commit", sha}, server), - null); + List> resultMaps = execMapCmdList(GRAPH, Parameters.processParameters(null, null, new String[]{"cat-file", "-n", repo, "commit", sha}, server), null); List commits = parseCommitList(resultMaps); // should only return a single result - if(commits != null && !commits.isEmpty()) { + if (commits != null && !commits.isEmpty()) { return commits.get(0); } @@ -93,11 +85,7 @@ public ICommit getCommitObject(String sha, String repo) throws P4JavaException { @Override public InputStream getBlobObject(String repo, String sha) throws P4JavaException { - InputStream inputStream = execStreamCmd( - GRAPH, - Parameters.processParameters( - null, null, new String[]{"cat-file", "-n", repo, "blob", sha}, server) - ); + InputStream inputStream = execStreamCmd(GRAPH, Parameters.processParameters(null, null, new String[]{"cat-file", "-n", repo, "blob", sha}, server)); return inputStream; } @@ -105,11 +93,7 @@ public InputStream getBlobObject(String repo, String sha) throws P4JavaException @Override public IGraphObject getGraphObject(String sha) throws P4JavaException { - List> resultMaps = execMapCmdList( - CmdSpec.GRAPH, - Parameters.processParameters( - null, null, new String[]{"cat-file", "-t", sha}, server), - null); + List> resultMaps = execMapCmdList(CmdSpec.GRAPH, Parameters.processParameters(null, null, new String[]{"cat-file", "-t", sha}, server), null); if (!nonNull(resultMaps)) { return null; @@ -143,18 +127,17 @@ public IGraphObject getGraphObject(String sha) throws P4JavaException { } /** - * Returns a List encapsulating a commit logs which holds the + * Returns a {@code List} encapsulating a commit logs which holds the * data retrieved as part of the 'p4 graph log -n command' * * @param options Various options supported by the command - * @return List - * @throws P4JavaException + * @return list of commits + * @throws P4JavaException on error */ @Override public List getGraphCommitLogList(GraphCommitLogOptions options) throws P4JavaException { - List> resultMaps = execMapCmdList( - GRAPH, Parameters.processParameters(options, server), null); + List> resultMaps = execMapCmdList(GRAPH, Parameters.processParameters(options, server), null); if (!nonNull(resultMaps)) { return null; diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/ConfigureDelegator.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/ConfigureDelegator.java index a5d7d56..7fc246c 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/ConfigureDelegator.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/ConfigureDelegator.java @@ -115,11 +115,6 @@ public List showServerConfiguration(final String serve List> resultMaps = execMapCmdList(CONFIGURE, args, null); return ResultListBuilder.buildNonNullObjectListFromCommandResultMaps(resultMaps, - new Function() { - @Override - public ServerConfigurationValue apply(Map map) { - return new ServerConfigurationValue(map); - } - }); + map -> new ServerConfigurationValue(map)); } } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/CounterDelegator.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/CounterDelegator.java index 4168510..79f913d 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/CounterDelegator.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/CounterDelegator.java @@ -58,13 +58,8 @@ public String getCounter(final String counterName, final CounterOptions opts) return ResultListBuilder.buildNullableObjectFromNonInfoMessageCommandResultMaps( resultMaps, - new Function() { - @Override - public String apply(Map map) { - return parseString(map, VALUE); - } - } - ); + map -> parseString(map, VALUE) + ); } @Override @@ -96,13 +91,8 @@ public String setCounter(final String counterName, final String value, return ResultListBuilder.buildNullableObjectFromNonInfoMessageCommandResultMaps( resultMaps, - new Function() { - @Override - public String apply(Map map) { - return parseString(map, VALUE); - } - } - ); + map -> parseString(map, VALUE) + ); } @Override diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/CountersDelegator.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/CountersDelegator.java index 097d195..964409b 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/CountersDelegator.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/CountersDelegator.java @@ -59,6 +59,7 @@ public Map getCounters() } } + @Deprecated @Override public Map getCounters(final CounterOptions opts) throws P4JavaException { List> resultMaps = execMapCmdList( diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/DBSchemaDelegator.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/DBSchemaDelegator.java index 383e716..9f442f7 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/DBSchemaDelegator.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/DBSchemaDelegator.java @@ -46,11 +46,6 @@ public List getDbSchema(final List tableSpecs) throws P4JavaE List> resultMaps = execMapCmdList(DBSCHEMA, args, null); return ResultListBuilder.buildNonNullObjectListFromCommandResultMaps( resultMaps, - new Function() { - @Override - public IDbSchema apply(Map map) { - return new DbSchema(map); - } - }); + map -> new DbSchema(map)); } } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/DepotDelegator.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/DepotDelegator.java index 27ba3fd..3d3d8c8 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/DepotDelegator.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/DepotDelegator.java @@ -75,12 +75,7 @@ public IDepot getDepot(final String name) throws P4JavaException { null); return ResultListBuilder.buildNullableObjectFromNonInfoMessageCommandResultMaps( resultMaps, - new Function() { - @Override - public IDepot apply(Map map) { - return new Depot(map); - } - } - ); + (Function, IDepot>) map -> new Depot(map) + ); } } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/DepotsDelegator.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/DepotsDelegator.java index 7208842..77e9776 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/DepotsDelegator.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/DepotsDelegator.java @@ -1,6 +1,5 @@ package com.perforce.p4java.impl.mapbased.server.cmd; -import com.perforce.p4java.common.function.Function; import com.perforce.p4java.core.IDepot; import com.perforce.p4java.exception.AccessException; import com.perforce.p4java.exception.ConnectionException; @@ -24,46 +23,41 @@ */ public class DepotsDelegator extends BaseDelegator implements IDepotsDelegator { - /** - * Instantiates a new depots delegator. - * - * @param server the server - */ - public DepotsDelegator(final IOptionsServer server) { - super(server); - } - - /* (non-Javadoc) - * @see com.perforce.p4java.server.delegator.IDepotsDelegator#getDepots() - */ - @Override - public List getDepots() throws ConnectionException, RequestException, AccessException { - List metadataArray = new ArrayList<>(); - - List> resultMaps = execMapCmdList(DEPOTS, new String[0], null); - - if (nonNull(resultMaps)) { - for (Map map : resultMaps) { - if (!ResultMapParser.handleErrorStr(map)) { - metadataArray.add(new Depot(map)); - } - } - } - - return metadataArray; - } - - @Override - public List getDepots(GetDepotsOptions opts) throws P4JavaException { - - List> resultsMap = execMapCmdList(DEPOTS, processParameters(opts, server), null); - - return ResultListBuilder.buildNonNullObjectListFromCommandResultMaps(resultsMap, new Function() { - @Override - public IDepot apply(Map map) throws RequestException { - return new Depot(map); - } - }); - } + /** + * Instantiates a new depots delegator. + * + * @param server the server + */ + public DepotsDelegator(final IOptionsServer server) { + super(server); + } + + /* (non-Javadoc) + * @see com.perforce.p4java.server.delegator.IDepotsDelegator#getDepots() + */ + @Override + public List getDepots() throws ConnectionException, RequestException, AccessException { + List metadataArray = new ArrayList<>(); + + List> resultMaps = execMapCmdList(DEPOTS, new String[0], null); + + if (nonNull(resultMaps)) { + for (Map map : resultMaps) { + if (!ResultMapParser.handleErrorStr(map)) { + metadataArray.add(new Depot(map)); + } + } + } + + return metadataArray; + } + + @Override + public List getDepots(GetDepotsOptions opts) throws P4JavaException { + + List> resultsMap = execMapCmdList(DEPOTS, processParameters(opts, server), null); + + return ResultListBuilder.buildNonNullObjectListFromCommandResultMaps(resultsMap, map -> new Depot(map)); + } } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/Diff2Delegator.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/Diff2Delegator.java index ef362c5..8040c25 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/Diff2Delegator.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/Diff2Delegator.java @@ -54,12 +54,7 @@ public List getFileDiffs( null); return buildNonNullObjectListFromNonMessageCommandResultMaps( resultMaps, - new Function() { - @Override - public IFileDiff apply(Map map) { - return new FileDiff(map); - } - }); + map -> new FileDiff(map)); } @Override diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/DiskspaceDelegator.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/DiskspaceDelegator.java index 66833a7..3ee3065 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/DiskspaceDelegator.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/DiskspaceDelegator.java @@ -42,11 +42,6 @@ public List getDiskSpace(final List filesystems) throws P4Ja return buildNonNullObjectListFromCommandResultMaps( resultMaps, - new Function() { - @Override - public IDiskSpace apply(Map map) { - return new DiskSpace(map); - } - }); + map -> new DiskSpace(map)); } } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/DuplicateDelegator.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/DuplicateDelegator.java index 461b8b6..e069d0a 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/DuplicateDelegator.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/DuplicateDelegator.java @@ -48,14 +48,9 @@ public List duplicateRevisions( return buildNonNullObjectListFromCommandResultMaps( resultMaps, rethrowFunction( - new FunctionWithException() { - @Override - public IFileSpec apply(Map map) throws P4JavaException { - return ResultListBuilder.handleIntegrationFileReturn( - map, - server); - } - } - )); + map -> ResultListBuilder.handleIntegrationFileReturn( + map, + server) + )); } } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/ExportDelegator.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/ExportDelegator.java index 0c24f28..a96630a 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/ExportDelegator.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/ExportDelegator.java @@ -79,15 +79,12 @@ public List> getExportRecords(final ExportRecordsOptions opt return buildNonNullObjectListFromCommandResultMaps( resultMaps, - new Function>() { - @Override - public Map apply(Map map) { - if (map.containsKey(FUNCTION)) { - map.remove(FUNCTION); - } - return map; - } - }); + map -> { + if (map.containsKey(FUNCTION)) { + map.remove(FUNCTION); + } + return map; + }); } @Override diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/FixesDelegator.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/FixesDelegator.java index b851228..134c6e7 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/FixesDelegator.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/FixesDelegator.java @@ -68,12 +68,7 @@ public List getFixes(final List fileSpecs, final GetFixesOption processParameters(opts, fileSpecs, server), null); return ResultListBuilder.buildNonNullObjectListFromCommandResultMaps(resultMaps, - new Function() { - @Override - public IFix apply(Map map) { - return new Fix(map); - } - } - ); + map -> new Fix(map) + ); } } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/GraphReceivePackDelegator.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/GraphReceivePackDelegator.java index de16773..80ce33b 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/GraphReceivePackDelegator.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/GraphReceivePackDelegator.java @@ -34,13 +34,12 @@ public GraphReceivePackDelegator(final IOptionsServer server) { /** * Invokes the receive-pack command on the sever. * - * @param options - * @throws P4JavaException + * @param options options + * @throws P4JavaException on error */ @Override public void doGraphReceivePack(GraphReceivePackOptions options) throws P4JavaException { - List> resultMaps = execMapCmdList( - GRAPH, Parameters.processParameters(options, server), null); + List> resultMaps = execMapCmdList(GRAPH, Parameters.processParameters(options, server), null); if (nonNull(resultMaps)) { for (Map map : resultMaps) { diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/GraphRevListDelegator.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/GraphRevListDelegator.java index ee86013..543d763 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/GraphRevListDelegator.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/GraphRevListDelegator.java @@ -37,9 +37,9 @@ public GraphRevListDelegator(final IOptionsServer server) { * Returns a List encapsulating a RevListCommit which holds the * data retrieved as part of the 'p4 graph rev-list -n' * - * @param options - * @return - * @throws P4JavaException + * @param options options + * @return List of graph revision items + * @throws P4JavaException on error */ @Override public List getGraphRevList(GraphRevListOptions options) throws P4JavaException { diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/GroupDelegator.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/GroupDelegator.java index 8a698e1..24f8f3e 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/GroupDelegator.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/GroupDelegator.java @@ -27,105 +27,109 @@ */ public class GroupDelegator extends BaseDelegator implements IGroupDelegator { - /** - * Instantiate a new GroupDelegator for the given server implementation. - * - * @param server - * the server to delegate for - */ - public GroupDelegator(IOptionsServer server) { - super(server); - } - - @Override - public IUserGroup getUserGroup(@Nonnull final String name) - throws ConnectionException, RequestException, AccessException { - Validate.notBlank(name, "Group name shouldn't use null or empty"); - - List> resultMaps = execMapCmdList(GROUP, new String[] { "-o", name }, - null); - UserGroup ugImpl = null; - - if (nonNull(resultMaps)) { - Map firstResultMap = resultMaps.get(0); - if (nonNull(firstResultMap)) { - ResultMapParser.handleErrorStr(firstResultMap); - ugImpl = new UserGroup(firstResultMap); - } - } - - return ugImpl; - } - - @Override - public String deleteUserGroup(@Nonnull IUserGroup group, @Nullable UpdateUserGroupOptions opts) - throws P4JavaException { - - Validate.notNull(group); - Validate.notBlank(group.getName(), "Group name shouldn't a null or empty."); - - List> resultMaps = execMapCmdList(GROUP, Parameters - .processParameters(opts, null, new String[] { "-d", group.getName() }, server), null); - - return ResultMapParser.parseCommandResultMapAsString(resultMaps); - } - - @Override - public String createUserGroup(@Nonnull final IUserGroup group, - @Nullable final UpdateUserGroupOptions opts) throws P4JavaException { - return updateUserGroup(group, opts); - } - - @Override - public String updateUserGroup(@Nonnull final IUserGroup group, - @Nullable final UpdateUserGroupOptions opts) throws P4JavaException { - - Validate.notNull(group); - - List> resultMaps = execMapCmdList(GROUP, - Parameters.processParameters(opts, null, "-i", server), InputMapper.map(group)); - - return ResultMapParser.parseCommandResultMapAsString(resultMaps); - } - - /** - * Implemented on behalf of IServer for backwards compatibility. - * - */ - public String createUserGroup(@Nonnull final IUserGroup group) - throws ConnectionException, RequestException, AccessException { - Validate.notNull(group); - return updateUserGroup(group, false); - } - - /** - * Implemented on behalf of IServer for backwards compatibility. - * - */ - public String updateUserGroup(@Nonnull final IUserGroup group, final boolean updateIfOwner) - throws ConnectionException, RequestException, AccessException { - try { - return updateUserGroup(group, - new UpdateUserGroupOptions().setUpdateIfOwner(updateIfOwner)); - } catch (final ConnectionException | AccessException exc) { - throw exc; - } catch (P4JavaException exc) { - throw new RequestException(exc.getMessage(), exc); - } - } - - /** - * Implemented on behalf of IServer for backwards compatibility. - * - */ - public String deleteUserGroup(@Nonnull final IUserGroup group) - throws ConnectionException, RequestException, AccessException { - try { - return deleteUserGroup(group, new UpdateUserGroupOptions()); - } catch (final ConnectionException | AccessException exc) { - throw exc; - } catch (P4JavaException exc) { - throw new RequestException(exc.getMessage(), exc); - } - } + /** + * Instantiate a new GroupDelegator for the given server implementation. + * + * @param server the server to delegate for + */ + public GroupDelegator(IOptionsServer server) { + super(server); + } + + @Override + public IUserGroup getUserGroup(@Nonnull final String name) throws ConnectionException, RequestException, AccessException { + Validate.notBlank(name, "Group name shouldn't use null or empty"); + + List> resultMaps = execMapCmdList(GROUP, new String[]{"-o", name}, null); + UserGroup ugImpl = null; + + if (nonNull(resultMaps)) { + Map firstResultMap = resultMaps.get(0); + if (nonNull(firstResultMap)) { + ResultMapParser.handleErrorStr(firstResultMap); + ugImpl = new UserGroup(firstResultMap); + } + } + + return ugImpl; + } + + @Override + public String deleteUserGroup(@Nonnull IUserGroup group, @Nullable UpdateUserGroupOptions opts) throws P4JavaException { + + Validate.notNull(group); + Validate.notBlank(group.getName(), "Group name shouldn't a null or empty."); + + List> resultMaps = execMapCmdList(GROUP, Parameters.processParameters(opts, null, new String[]{"-d", group.getName()}, server), null); + + return ResultMapParser.parseCommandResultMapAsString(resultMaps); + } + + @Override + public String createUserGroup(@Nonnull final IUserGroup group, @Nullable final UpdateUserGroupOptions opts) throws P4JavaException { + return updateUserGroup(group, opts); + } + + @Override + public String updateUserGroup(@Nonnull final IUserGroup group, @Nullable final UpdateUserGroupOptions opts) throws P4JavaException { + + Validate.notNull(group); + + List> resultMaps = execMapCmdList(GROUP, Parameters.processParameters(opts, null, "-i", server), InputMapper.map(group)); + + return ResultMapParser.parseCommandResultMapAsString(resultMaps); + } + + /** + * Implemented on behalf of IServer for backwards compatibility. + * + * @param group group + * @return response + * @throws ConnectionException on error + * @throws RequestException on error + * @throws AccessException on error + */ + public String createUserGroup(@Nonnull final IUserGroup group) throws ConnectionException, RequestException, AccessException { + Validate.notNull(group); + return updateUserGroup(group, false); + } + + /** + * Implemented on behalf of IServer for backwards compatibility. + * + * @param group group + * @param updateIfOwner updateIfOwner + * @return response + * @throws ConnectionException on error + * @throws RequestException on error + * @throws AccessException on error + */ + public String updateUserGroup(@Nonnull final IUserGroup group, final boolean updateIfOwner) throws ConnectionException, RequestException, AccessException { + try { + return updateUserGroup(group, new UpdateUserGroupOptions().setUpdateIfOwner(updateIfOwner)); + } catch (final ConnectionException | AccessException exc) { + throw exc; + } catch (P4JavaException exc) { + throw new RequestException(exc.getMessage(), exc); + } + } + + /** + * Implemented on behalf of IServer for backwards compatibility. + * + * @param group group + * @return response + * @throws ConnectionException on error + * @throws RequestException on error + * @throws AccessException on error + */ + public String deleteUserGroup(@Nonnull final IUserGroup group) throws ConnectionException, RequestException, AccessException { + try { + return deleteUserGroup(group, new UpdateUserGroupOptions()); + } catch (final ConnectionException | AccessException exc) { + throw exc; + } catch (P4JavaException exc) { + throw new RequestException(exc.getMessage(), exc); + } + } } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/GroupsDelegator.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/GroupsDelegator.java index a964434..f1c0c3a 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/GroupsDelegator.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/GroupsDelegator.java @@ -121,7 +121,15 @@ public List getUserGroups(final String userOrGroupName, /** * Implemented on behalf of legacy clients. * - * @see com.perforce.p4java.server.IServer#getUserGroups(String, boolean, boolean, int) + * @param userOrGroupName userOrGroupName + * @param indirect indirect + * @param displayValues displayValues + * @param maxGroups maxGroups + * @see com.perforce.p4java.server.IServer#getUserGroups(String, boolean, boolean, int) + * @return list of groups + * @throws ConnectionException on error + * @throws RequestException on error + * @throws AccessException on error */ public List getUserGroups(final String userOrGroupName, final boolean indirect, final boolean displayValues, final int maxGroups) diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/InterchangesDelegator.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/InterchangesDelegator.java index 9eb9807..b9ed112 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/InterchangesDelegator.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/InterchangesDelegator.java @@ -132,7 +132,7 @@ public List processInterchangeMaps(final List> // which case we pick the files off as best we can and then // associate // them with the changelist constructed as above. - String errStr = server.handleFileErrorStr(map); + String errStr = ResultMapParser.handleFileErrorStr(map); if (isNotBlank(errStr)) { // What we're doing here is weeding out the "all // revision(s) diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/JobDelegator.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/JobDelegator.java index f5a67cf..9879976 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/JobDelegator.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/JobDelegator.java @@ -99,7 +99,6 @@ public String deleteJob(final String jobId) * @see com.perforce.p4java.server.delegator.IJobDelegator#getJob(java.lang. * String) */ - @SuppressWarnings("unchecked") @Override public IJob getJob(final String jobId) throws ConnectionException, RequestException, AccessException { @@ -111,13 +110,8 @@ public IJob getJob(final String jobId) return ResultListBuilder.buildNullableObjectFromNonInfoMessageCommandResultMaps( resultMaps, - new Function() { - @Override - public IJob apply(Map map) { - return new Job(server, map); - } - } - ); + (Function, IJob>) map -> new Job(server, map) + ); } /* diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/JobSpecDelegator.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/JobSpecDelegator.java index 8b4784f..b8304cb 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/JobSpecDelegator.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/JobSpecDelegator.java @@ -31,18 +31,12 @@ public JobSpecDelegator(final IOptionsServer server) { /* (non-Javadoc) * @see com.perforce.p4java.server.delegator.IJobSpecDelegator#getJobSpec() */ - @SuppressWarnings("unchecked") @Override public IJobSpec getJobSpec() throws ConnectionException, RequestException, AccessException { List> resultMaps = execMapCmdList(JOBSPEC, new String[] { "-o" }, null); return ResultListBuilder.buildNullableObjectFromNonInfoMessageCommandResultMaps( resultMaps, - new Function() { - @Override - public IJobSpec apply(Map map) { - return new JobSpec(map, server); - } - } - ); + (Function, IJobSpec>) map -> new JobSpec(map, server) + ); } } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/KeyDelegator.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/KeyDelegator.java index 5cdc63f..b35b01d 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/KeyDelegator.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/KeyDelegator.java @@ -57,12 +57,7 @@ public String setKey(final String keyName, final String value, final KeyOptions return parseValueFromResultMaps( resultMaps, - rethrowFunction(new FunctionWithException() { - @Override - public Boolean apply(Map map) throws P4JavaException { - return handleErrorStr(map); - } - }) + rethrowFunction(map -> handleErrorStr(map)) ); } @@ -73,18 +68,13 @@ public String getKey(final String keyName) throws P4JavaException { List> resultMaps = execMapCmdList(KEY, new String[]{keyName}, null); return parseValueFromResultMaps( resultMaps, - rethrowFunction(new FunctionWithException() { - @Override - public Boolean apply(Map map) throws P4JavaException { - return handleErrorStr(map); - } - }) + rethrowFunction(map -> handleErrorStr(map)) ); } private String parseValueFromResultMaps( final List> resultMaps, - final Function construct) throws RequestException { + final Function, Boolean> construct) throws RequestException { if (nonNull(resultMaps)) { for (Map map : resultMaps) { if (nonNull(map) && !construct.apply(map) && map.containsKey(VALUE)) { diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/LabelsDelegator.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/LabelsDelegator.java index 4b5f76b..f62c23a 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/LabelsDelegator.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/LabelsDelegator.java @@ -69,12 +69,7 @@ public List getLabels( return buildNonNullObjectListFromCommandResultMaps( resultMaps, - new Function() { - @Override - public ILabelSummary apply(Map map) { - return new LabelSummary(map); - } - } - ); + map -> new LabelSummary(map) + ); } } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/ListDelegator.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/ListDelegator.java index 5e9beaf..bfcd556 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/ListDelegator.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/ListDelegator.java @@ -37,14 +37,13 @@ public ListDelegator(final IOptionsServer server) { * * @param fileSpecs List of file paths to be labeled * @param options Options as required by the command p4 list - * @return - * @throws P4JavaException + * @return ListData + * @throws P4JavaException on error */ @Override public ListData getListData(List fileSpecs, ListOptions options) throws P4JavaException { - Map[] resultMap = server.execMapCmd(LIST.toString(), - Parameters.processParameters(options, fileSpecs, server), null); + Map[] resultMap = server.execMapCmd(LIST.toString(), Parameters.processParameters(options, fileSpecs, server), null); if (!nonNull(resultMap)) { return null; diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/MonitorDelegator.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/MonitorDelegator.java index f188971..46e77a7 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/MonitorDelegator.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/MonitorDelegator.java @@ -64,12 +64,7 @@ public List getServerProcesses(final GetServerProcessesOptions o return buildNonNullObjectListFromCommandResultMaps( resultMaps, - new Function() { - @Override - public IServerProcess apply(Map map) { - return new ServerProcess(map); - } - } - ); + map -> new ServerProcess(map) + ); } } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/MoveDelegator.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/MoveDelegator.java index 6bc337d..8a37465 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/MoveDelegator.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/MoveDelegator.java @@ -103,11 +103,7 @@ public List moveFile( null); return buildNonNullObjectListFromCommandResultMaps(resultMaps, - rethrowFunction(new FunctionWithException() { - public IFileSpec apply(Map map) throws P4JavaException { - return ResultListBuilder.handleFileReturn(map, server); - } - }) + rethrowFunction(map -> ResultListBuilder.handleFileReturn(map, server)) ); } } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/OpenedDelegator.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/OpenedDelegator.java index 50685c7..2fafd9a 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/OpenedDelegator.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/OpenedDelegator.java @@ -69,12 +69,7 @@ public List getOpenedFiles( return ResultListBuilder.buildNonNullObjectListFromCommandResultMaps( resultMaps, - rethrowFunction(new FunctionWithException() { - @Override - public IFileSpec apply(Map map) throws P4JavaException { - return ResultListBuilder.handleFileReturn(map, server); - } - }) + rethrowFunction(map -> ResultListBuilder.handleFileReturn(map, server)) ); } } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/PropertyDelegator.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/PropertyDelegator.java index 707efa6..cf90007 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/PropertyDelegator.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/PropertyDelegator.java @@ -74,13 +74,8 @@ public List getProperty(final GetPropertyOptions opts) throws P4JavaE return buildNonNullObjectListFromCommandResultMaps( resultMaps, - new Function() { - @Override - public IProperty apply(Map map) { - return new Property(map); - } - } - ); + map -> new Property(map) + ); } @Override diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/ProtectsDelegator.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/ProtectsDelegator.java index de4c25d..e242c60 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/ProtectsDelegator.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/ProtectsDelegator.java @@ -80,12 +80,7 @@ public List getProtectionEntries( final AtomicInteger order = new AtomicInteger(-1); return buildNonNullObjectListFromCommandResultMaps( resultMaps, - new Function() { - @Override - public IProtectionEntry apply(Map map) { - return new ProtectionEntry(map, order.incrementAndGet()); - } - } + map -> new ProtectionEntry(map, order.incrementAndGet()) ); } } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/ReposDelegator.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/ReposDelegator.java index c7e6e90..36f51ca 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/ReposDelegator.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/ReposDelegator.java @@ -50,7 +50,7 @@ public List getRepos() throws ConnectionException, RequestException, Acce * * @param options Repos filter options * @return a list of repos - * @throws P4JavaException + * @throws P4JavaException on error */ @Override public List getRepos(ReposOptions options) throws P4JavaException { @@ -64,9 +64,9 @@ public List getRepos(ReposOptions options) throws P4JavaException { * * @param client the name of the client workspace * @return a list of repos - * @throws ConnectionException - * @throws RequestException - * @throws AccessException + * @throws ConnectionException on error + * @throws RequestException on error + * @throws AccessException on error */ @Override public List getRepos(@Nonnull String client) throws ConnectionException, RequestException, AccessException { diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/ResultListBuilder.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/ResultListBuilder.java index c7a6d2b..da3a1ad 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/ResultListBuilder.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/ResultListBuilder.java @@ -28,132 +28,121 @@ import static org.apache.commons.lang3.StringUtils.isBlank; public class ResultListBuilder { - public static List buildNonNullObjectListFromCommandResultMaps( - final List> resultMaps, final Function construct) throws P4JavaException { - List objectList = new ArrayList<>(); - if (resultMaps != null) { - for (Map map : resultMaps) { - if (!ResultMapParser.handleErrorStr(map)) { - T object = construct.apply(map); - objectList.add(object); - } - } - } - return objectList; - } + public static List buildNonNullObjectListFromCommandResultMaps(final List> resultMaps, final Function, T> construct) throws P4JavaException { + List objectList = new ArrayList<>(); + if (resultMaps != null) { + for (Map map : resultMaps) { + if (!ResultMapParser.handleErrorStr(map)) { + T object = construct.apply(map); + objectList.add(object); + } + } + } + return objectList; + } - public static List buildNonNullObjectListFromNonMessageCommandResultMaps( - final List> resultMaps, final Function construct) throws P4JavaException { - List objectList = new ArrayList<>(); - if (resultMaps != null) { - for (Map map : resultMaps) { - if (!ResultMapParser.handleErrorStr(map) && isBlank(ResultMapParser.getErrorOrInfoStr(map))) { - T object = construct.apply(map); - objectList.add(object); - } - } - } - return objectList; - } + public static List buildNonNullObjectListFromNonMessageCommandResultMaps(final List> resultMaps, final Function, T> construct) throws P4JavaException { + List objectList = new ArrayList<>(); + if (resultMaps != null) { + for (Map map : resultMaps) { + if (!ResultMapParser.handleErrorStr(map) && isBlank(ResultMapParser.getErrorOrInfoStr(map))) { + T object = construct.apply(map); + objectList.add(object); + } + } + } + return objectList; + } - public static T buildNullableObjectFromNonInfoMessageCommandResultMaps( - final List> resultMaps, final Function construct) throws RequestException, AccessException { - T obj = null; - if (resultMaps != null) { - for (Map map : resultMaps) { - if (map != null) { - if (!ResultMapParser.handleErrorStr(map) && !ResultMapParser.isInfoMessage(map)) { - obj = construct.apply(map); - } - } - } - } - return obj; - } + public static T buildNullableObjectFromNonInfoMessageCommandResultMaps(final List> resultMaps, final Function, T> construct) throws RequestException, AccessException { + T obj = null; + if (resultMaps != null) { + for (Map map : resultMaps) { + if (map != null) { + if (!ResultMapParser.handleErrorStr(map) && !ResultMapParser.isInfoMessage(map)) { + obj = construct.apply(map); + } + } + } + } + return obj; + } - public static List buildNonNullExtendedFileSpecListFromCommandResultMaps( - final List> resultMaps, final IOptionsServer server) - throws RequestException, AccessException, ConnectionException { - List specList = new ArrayList<>(); - if (resultMaps != null) { - for (Map map : resultMaps) { - // We do this by hand for the statFiles case; this may be - // included in the generic handler later -- HR. - // Note: as of 10.1 or so, fstats on shelved files may return - // a "special" fstat info message (usually the last message) - // that - // contains only the description field of the associated - // changelist - // (see fstat -e documentation for this); therefore we carefully - // weed - // out any return map here that has no depot path and a "desc" - // field - // -- HR (see also job040680). - String errStr = ResultMapParser.handleFileErrorStr(map); - if (isBlank(errStr)) { - if (isContainsValidRevisionSpecificInformation(map)) { - specList.add(new ExtendedFileSpec(map, server)); - } - } else { - FileSpecOpStatus fileSpecOpStatus = ERROR; - if (ResultMapParser.isInfoMessage(map)) { - fileSpecOpStatus = INFO; - } - specList.add(new ExtendedFileSpec(fileSpecOpStatus, errStr)); - } - } - } - return specList; - } + public static List buildNonNullExtendedFileSpecListFromCommandResultMaps(final List> resultMaps, final IOptionsServer server) throws AccessException, ConnectionException { + List specList = new ArrayList<>(); + if (resultMaps != null) { + for (Map map : resultMaps) { + // We do this by hand for the statFiles case; this may be + // included in the generic handler later -- HR. + // Note: as of 10.1 or so, fstats on shelved files may return + // a "special" fstat info message (usually the last message) + // that + // contains only the description field of the associated + // changelist + // (see fstat -e documentation for this); therefore we carefully + // weed + // out any return map here that has no depot path and a "desc" + // field + // -- HR (see also job040680). + String errStr = ResultMapParser.handleFileErrorStr(map); + if (isBlank(errStr)) { + if (isContainsValidRevisionSpecificInformation(map)) { + specList.add(new ExtendedFileSpec(map, server)); + } + } else { + FileSpecOpStatus fileSpecOpStatus = ERROR; + if (ResultMapParser.isInfoMessage(map)) { + fileSpecOpStatus = INFO; + } + specList.add(new ExtendedFileSpec(fileSpecOpStatus, errStr)); + } + } + } + return specList; + } - public static IFileSpec handleIntegrationFileReturn( - final Map map, - final IServer server) throws AccessException, ConnectionException { + public static IFileSpec handleIntegrationFileReturn(final Map map, final IServer server) throws AccessException, ConnectionException { - return handleIntegrationFileReturn(map, false, server); - } + return handleIntegrationFileReturn(map, false, server); + } - public static IFileSpec handleIntegrationFileReturn(final Map map, - final boolean ignoreInfo, final IServer server) throws AccessException, ConnectionException { + public static IFileSpec handleIntegrationFileReturn(final Map map, final boolean ignoreInfo, final IServer server) throws AccessException, ConnectionException { - if (nonNull(map)) { - String errStr = ResultMapParser.handleFileErrorStr(map); - if (isBlank(errStr)) { - return new FileSpec(map, server, -1); - } else { - String codeStr = parseCode0ErrorString(map); - if (ResultMapParser.isInfoMessage(map)) { - if (ignoreInfo) { - return new FileSpec(map, server, -1); - } else { - return new FileSpec(FileSpecOpStatus.INFO, errStr, codeStr); - } - } else { - return new FileSpec(FileSpecOpStatus.ERROR, errStr, codeStr); - } - } - } - return null; - } + if (nonNull(map)) { + String errStr = ResultMapParser.handleFileErrorStr(map); + if (isBlank(errStr)) { + return new FileSpec(map, server, -1); + } else { + String codeStr = parseCode0ErrorString(map); + if (ResultMapParser.isInfoMessage(map)) { + if (ignoreInfo) { + return new FileSpec(map, server, -1); + } else { + return new FileSpec(FileSpecOpStatus.INFO, errStr, codeStr); + } + } else { + return new FileSpec(FileSpecOpStatus.ERROR, errStr, codeStr); + } + } + } + return null; + } - public static IFileSpec handleFileReturn( - final Map map, final IServer server) - throws AccessException, ConnectionException { + public static IFileSpec handleFileReturn(final Map map, final IServer server) throws AccessException, ConnectionException { + if (nonNull(map)) { + String errStr = ResultMapParser.handleFileErrorStr(map); + if (isBlank(errStr)) { + return new FileSpec(map, server, -1); + } else { + FileSpecOpStatus specOpStatus = FileSpecOpStatus.ERROR; + if (ResultMapParser.isInfoMessage(map)) { + specOpStatus = FileSpecOpStatus.INFO; + } - if (nonNull(map)) { - String errStr = ResultMapParser.handleFileErrorStr(map); - if (isBlank(errStr)) { - return new FileSpec(map, server, -1); - } else { - FileSpecOpStatus specOpStatus = FileSpecOpStatus.ERROR; - if (ResultMapParser.isInfoMessage(map)) { - specOpStatus = FileSpecOpStatus.INFO; - } - - String codeStr = parseCode0ErrorString(map); - return new FileSpec(specOpStatus, errStr, codeStr); - } - } - return null; - } + String codeStr = parseCode0ErrorString(map); + return new FileSpec(specOpStatus, errStr, codeStr); + } + } + return null; + } } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/ResultMapParser.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/ResultMapParser.java index a8292ca..f7784b7 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/ResultMapParser.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/ResultMapParser.java @@ -79,9 +79,7 @@ public abstract class ResultMapParser { /** * Array of access error messages. */ - private static final String[] ACCESS_ERR_MSGS = {CORE_AUTH_FAIL_STRING_1, - CORE_AUTH_FAIL_STRING_2, CORE_AUTH_FAIL_STRING_3, CORE_AUTH_FAIL_STRING_4, - AUTH_FAIL_STRING_1, AUTH_FAIL_STRING_2}; + private static final String[] ACCESS_ERR_MSGS = {CORE_AUTH_FAIL_STRING_1, CORE_AUTH_FAIL_STRING_2, CORE_AUTH_FAIL_STRING_3, CORE_AUTH_FAIL_STRING_4, AUTH_FAIL_STRING_1, AUTH_FAIL_STRING_2}; /** * Parses the command result map to return a String of info messages. The @@ -93,9 +91,7 @@ public abstract class ResultMapParser { * @throws AccessException the access exception * @throws RequestException the request exception */ - public static String parseCommandResultMapIfIsInfoMessageAsString( - @Nonnull final List> resultMaps) - throws AccessException, RequestException { + public static String parseCommandResultMapIfIsInfoMessageAsString(@Nonnull final List> resultMaps) throws AccessException, RequestException { StringBuilder retVal = new StringBuilder(INITIAL_STRING_BUILDER); if (nonNull(resultMaps)) { for (Map map : resultMaps) { @@ -140,8 +136,7 @@ public static boolean isWarningMessage(final Map map) { * @throws RequestException the request exception * @throws AccessException the access exception */ - public static boolean handleErrorStr(final Map map) - throws RequestException, AccessException { + public static boolean handleErrorStr(final Map map) throws RequestException, AccessException { String errStr = getErrorStr(map); if (isNotBlank(errStr)) { @@ -162,8 +157,7 @@ public static boolean handleErrorStr(final Map map) * @throws RequestException the request exception * @throws AccessException the access exception */ - public static boolean handleWarningStr(final Map map) - throws RequestException, AccessException { + public static boolean handleWarningStr(final Map map) throws RequestException, AccessException { String warnStr = getWarningStr(map); if (isNotBlank(warnStr)) { @@ -175,17 +169,14 @@ public static boolean handleWarningStr(final Map map) /** * RPC impl errors come across the wire as a map in the form usually like * this: - *

- *

+	 * 
{@code
 	 * fmt0=Access for user '%user%' has not been enabled by 'p4 protect'.,
 	 * func=client-Message, user=nouser, code0=822483067
-	 * 
- *

+ * }

* With tags being used for non-error payloads, we can just basically pick * up the presence of the code0 entry; if it's there, use fmt0 as the format * and the other args as appropriate... *

- *

* FIXME: work with multiple code/fmt sets... -- HR. * * @param map the map @@ -221,21 +212,16 @@ public static boolean isAuthFail(final String errStr) { * Gets the info message from the passed-in Perforce command results map. If * no info message found in the results map it returns null. *

- *

- *

* Note that the severity code is MessageSeverityCode.E_INFO. Therefore, * only message with severity code = MessageSeverityCode.E_INFO will be * returned. *

- *

* RPC impl errors come across the wire as a map in the form usually like * this: - *

- *

+	 * 
{@code
 	 * fmt0=Access for user '%user%' has not been enabled by 'p4 protect'.,
 	 * func=client-Message, user=nouser, code0=822483067
-	 * 
- *

+ * }

* Note that the code0 entry will be used to get the severity level; the * fmt0 entry contains the message. *

@@ -315,21 +301,16 @@ private static String getString(final Map map, final int minimum * command results map. If no info/warning/error/fatal message found in the * results map it returns null. *

- *

- *

* Note that the minimum severity code is MessageSeverityCode.E_INFO. - * Therefore, only message with severity code >= MessageSeverityCode.E_INFO + * Therefore, only message with severity code >= MessageSeverityCode.E_INFO * will be returned. *

- *

* RPC impl errors come across the wire as a map in the form usually like * this: - *

- *

+	 * 
{@code
 	 * fmt0=Access for user '%user%' has not been enabled by 'p4 protect'.,
 	 * func=client-Message, user=nouser, code0=822483067
-	 * 
- *

+ * }

* Note that the code0 entry will be used to get the severity level; the * fmt0 entry contains the message. *

@@ -348,8 +329,7 @@ public static String getErrorOrInfoStr(final Map map) { * @param map the map * @throws RequestException the request exception */ - public static void throwRequestExceptionIfErrorMessageFound(final Map map) - throws RequestException { + public static void throwRequestExceptionIfErrorMessageFound(final Map map) throws RequestException { String errStr = getErrorStr(map); if (isNotBlank(errStr)) { throw new RequestException(errStr, parseCode0ErrorString(map)); @@ -364,8 +344,7 @@ public static void throwRequestExceptionIfErrorMessageFound(final Map map) - throws RequestException, AccessException { + public static boolean handleErrorOrInfoStr(final Map map) throws RequestException, AccessException { String errStr = getErrorOrInfoStr(map); if (isNotBlank(errStr)) { @@ -386,9 +365,7 @@ public static boolean handleErrorOrInfoStr(final Map map) * @throws AccessException the access exception * @throws RequestException the request exception */ - public static String parseCommandResultMapAsString( - @Nonnull final List> resultMaps) - throws AccessException, RequestException { + public static String parseCommandResultMapAsString(@Nonnull final List> resultMaps) throws AccessException, RequestException { StringBuilder retVal = new StringBuilder(); if (nonNull(resultMaps)) { for (Map map : resultMaps) { @@ -414,8 +391,7 @@ public static String parseCommandResultMapAsString( * @param resultMaps the result maps * @return the list */ - public static List parseCommandResultMapAsFileSpecs(final int id, - final IServer server, final List> resultMaps) { + public static List parseCommandResultMapAsFileSpecs(final int id, final IServer server, final List> resultMaps) { List fileList = new ArrayList<>(); if (nonNull(resultMaps)) { @@ -442,8 +418,7 @@ public static List parseCommandResultMapAsFileSpecs(final int id, * @param resultMaps the result maps * @return the list */ - public static List parseCommandResultMapAsExtendedFileSpecs(final int id, - final IServer server, final List> resultMaps) { + public static List parseCommandResultMapAsExtendedFileSpecs(final int id, final IServer server, final List> resultMaps) { List fileList = new ArrayList<>(); @@ -521,8 +496,7 @@ public static List parseGraphCommandResultMapAsFileSpecs(final IServe * @throws ConnectionException the connection exception * @throws AccessException the access exception */ - public static String handleFileErrorStr(final Map map) - throws ConnectionException, AccessException { + public static String handleFileErrorStr(final Map map) throws ConnectionException, AccessException { String errStr = getErrorOrInfoStr(map); if (isNotBlank(errStr)) { if (isAuthFail(errStr)) { diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/SizesDelegator.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/SizesDelegator.java index ee36ab6..59439e9 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/SizesDelegator.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/SizesDelegator.java @@ -42,12 +42,7 @@ public List getFileSizes( return buildNonNullObjectListFromCommandResultMaps( resultMaps, - new Function() { - @Override - public IFileSize apply(Map map) { - return new FileSize(map); - } - } - ); + map -> new FileSize(map) + ); } } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/SpecDelegator.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/SpecDelegator.java index c4df8c2..291de07 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/SpecDelegator.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/SpecDelegator.java @@ -30,18 +30,12 @@ public SpecDelegator(final IOptionsServer server) { /* (non-Javadoc) * @see com.perforce.p4java.server.delegator.ISpecDelegator#getSpec(CustomSpec) */ - @SuppressWarnings("unchecked") @Override public Map getSpec(CustomSpec type) throws AccessException, RequestException, ConnectionException { List> resultMaps = execMapCmdList(SPEC, new String[]{"-o", type.toString()}, null); return ResultListBuilder.buildNullableObjectFromNonInfoMessageCommandResultMaps( resultMaps, - new Function() { - @Override - public Map apply(Map map) { - return map; - } - } + map -> map ); } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/StatDelegator.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/StatDelegator.java index 8b48cb8..6362b48 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/StatDelegator.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/StatDelegator.java @@ -37,12 +37,7 @@ public IStreamIntegrationStatus getStreamIntegrationStatus(final String stream, return ResultListBuilder.buildNullableObjectFromNonInfoMessageCommandResultMaps( resultMaps, - new Function() { - @Override - public IStreamIntegrationStatus apply(Map map) { - return new StreamIntegrationStatus(map); - } - } - ); + (Function, IStreamIntegrationStatus>) map -> new StreamIntegrationStatus(map) + ); } } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/StreamDelegator.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/StreamDelegator.java index 58d61db..dcc985a 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/StreamDelegator.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/StreamDelegator.java @@ -63,13 +63,8 @@ public IStream getStream( return buildNullableObjectFromNonInfoMessageCommandResultMaps( resultMaps, - new Function() { - @Override - public IStream apply(Map map) { - return new Stream(map, server); - } - } - ); + (Function, IStream>) map -> new Stream(map, server) + ); } @Override diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/TagDelegator.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/TagDelegator.java index a244656..16c416a 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/TagDelegator.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/TagDelegator.java @@ -79,12 +79,7 @@ public List tagFiles( return buildNonNullObjectListFromCommandResultMaps( resultMaps, - rethrowFunction(new FunctionWithException() { - @Override - public IFileSpec apply(Map map) throws P4JavaException { - return ResultListBuilder.handleFileReturn(map, server); - } - }) + rethrowFunction(map -> ResultListBuilder.handleFileReturn(map, server)) ); } } diff --git a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/UsersDelegator.java b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/UsersDelegator.java index f9b4c3b..cb9b082 100644 --- a/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/UsersDelegator.java +++ b/src/main/java/com/perforce/p4java/impl/mapbased/server/cmd/UsersDelegator.java @@ -50,13 +50,8 @@ public List getUsers( return buildNonNullObjectListFromCommandResultMaps( resultMaps, - new Function() { - @Override - public IUserSummary apply(Map map) { - return new UserSummary(map, true); - } - } - ); + map -> new UserSummary(map, true) + ); } @Override diff --git a/src/main/java/com/perforce/p4java/io/apple/AppleFile.java b/src/main/java/com/perforce/p4java/io/apple/AppleFile.java index f13ef86..d6549f6 100644 --- a/src/main/java/com/perforce/p4java/io/apple/AppleFile.java +++ b/src/main/java/com/perforce/p4java/io/apple/AppleFile.java @@ -11,109 +11,142 @@ * method to verify the Apple file, and figure out if it is an AppleSingle or * AppleDouble formatted file. *

- * * The AppleSingle format is a representation of Macintosh files as one * consecutive stream of bytes. AppleSingle combines the data fork, resource * fork and the related Finder meta-file information into a single file. *

- * * The AppleDouble format stores the data fork, resource fork as two separate * files. AppleDouble leaves the data fork in its original format, and the * resource fork and Finder information were combined into a second file. *

- * * Apple defined the magic number for the AppleSingle format as 0x00051600, and * the magic number for the AppleDouble format as 0x00051607. - * + * *


- * AppleSingle file header: 

- * 

+ * AppleSingle file header:

+ *

  * Field Length

  * ----- ------

- * Magic number ------- 4 bytes

+ * Magic number -------- 4 bytes

  * Version number ------ 4 bytes

  * Filler ------------- 16 bytes

- * Number of entries ----- 2 bytes

- * 

+ * Number of entries --- 2 bytes

+ *

  * Entry descriptor for each entry:

  * Entry ID ------ 4 bytes

  * Offset -------- 4 bytes

  * Length -------- 4 bytes

- * 

+ *

  * Apple reserved entry IDs:

- * 

- * Data Fork -------- 1 Data fork

- * Resource Fork ----- 2 Resource fork

- * Real Name -------- 3 File's name as created on home file system

- * Comment --------- 4 Standard Macintosh comment

- * Icon, B&W -------- 5 Standard Macintosh black and white icon

- * Icon, Color -------- 6 Macintosh color icon

- * File Dates Info ------8 File creation date, modification date, and so on

- * Finder Info -------- 9 Standard Macintosh Finder information

- * Macintosh File Info ---10 Macintosh file information, attributes, and so on

- * ProDOS File Info -----11 ProDOS file information, attributes, and so on

- * MS-DOS File Info ----12 MS-DOS file information, attributes, and so on

- * Short Name --------13 AFP short name

- * AFP File Info ------- 14 AFP file information, attributes, and so on

- * Directory ID --------15 AFP directory ID

+ *

+ * Data Fork -------------- 1 Data fork

+ * Resource Fork ---------- 2 Resource fork

+ * Real Name -------------- 3 File's name as created on home file system

+ * Comment ---------------- 4 Standard Macintosh comment

+ * Icon, B and W ---------- 5 Standard Macintosh black and white icon

+ * Icon, Color ------------ 6 Macintosh color icon

+ * File Dates Info -------- 8 File creation date, modification date, and so on

+ * Finder Info ------------ 9 Standard Macintosh Finder information

+ * Macintosh File Info --- 10 Macintosh file information, attributes, and so on

+ * ProDOS File Info ------ 11 ProDOS file information, attributes, and so on

+ * MS-DOS File Info ------ 12 MS-DOS file information, attributes, and so on

+ * Short Name ------------ 13 AFP short name

+ * AFP File Info --------- 14 AFP file information, attributes, and so on

+ * Directory ID ---------- 15 AFP directory ID

  * 
- * + *

* See RFC 1740 for reference: http://tools.ietf.org/html/rfc1740 */ public abstract class AppleFile { - /** The Apple file format: AppleSingle, AppleDouble, default to unknown. */ + /** + * The Apple file format: AppleSingle, AppleDouble, default to unknown. + */ protected FileFormat format = FileFormat.UNKNOWN; - /** The raw Apple file. */ + /** + * The raw Apple file. + */ protected AppleFileData fileData = AppleFileData.EMPTY_FILE_DATA; - /** Entry 1: Data fork. */ + /** + * Entry 1: Data fork. + */ protected AppleFileData dataFork = AppleFileData.EMPTY_FILE_DATA; - /** Entry 2: Resource fork. */ + /** + * Entry 2: Resource fork. + */ protected AppleFileData resourceFork = AppleFileData.EMPTY_FILE_DATA; - /** Entry 3: File's name as created on home file system. */ + /** + * Entry 3: File's name as created on home file system. + */ protected AppleFileData realName = AppleFileData.EMPTY_FILE_DATA; - /** Entry 4: Standard Macintosh comment. */ + /** + * Entry 4: Standard Macintosh comment. + */ protected AppleFileData comment = AppleFileData.EMPTY_FILE_DATA; - /** Entry 5: Standard Macintosh black and white icon. */ + /** + * Entry 5: Standard Macintosh black and white icon. + */ protected AppleFileData iconBW = AppleFileData.EMPTY_FILE_DATA; - /** Entry 6: Macintosh color icon. */ + /** + * Entry 6: Macintosh color icon. + */ protected AppleFileData iconColor = AppleFileData.EMPTY_FILE_DATA; - /** Entry 8: File creation date, modification date, and so on. */ + /** + * Entry 8: File creation date, modification date, and so on. + */ protected AppleFileData fileDatesInfo = AppleFileData.EMPTY_FILE_DATA; - /** The file dates info entry. */ + /** + * The file dates info entry. + */ protected FileDatesInfoEntry fileDatesInfoEntry = null; - /** Entry 9: Standard Macintosh Finder information. */ + /** + * Entry 9: Standard Macintosh Finder information. + */ protected AppleFileData finderInfo = AppleFileData.EMPTY_FILE_DATA; - /** Entry 10: Macintosh file information, attributes, and so on. */ + /** + * Entry 10: Macintosh file information, attributes, and so on. + */ protected AppleFileData macintoshInfo = AppleFileData.EMPTY_FILE_DATA; - /** Entry 11: ProDOS file information, attributes, and so on. */ + /** + * Entry 11: ProDOS file information, attributes, and so on. + */ protected AppleFileData proDOSFileInfo = AppleFileData.EMPTY_FILE_DATA; - /** Entry 12: MS-DOS file information, attributes, and so on. */ + /** + * Entry 12: MS-DOS file information, attributes, and so on. + */ protected AppleFileData msDOSFileInfo = AppleFileData.EMPTY_FILE_DATA; - /** Entry 13: AFP short name. */ + /** + * Entry 13: AFP short name. + */ protected AppleFileData shortName = AppleFileData.EMPTY_FILE_DATA; - /** Entry 14: AFP file information, attributes, and so on. */ + /** + * Entry 14: AFP file information, attributes, and so on. + */ protected AppleFileData afpFileInfo = AppleFileData.EMPTY_FILE_DATA; - /** Entry 15: AFP directory ID. */ + /** + * Entry 15: AFP directory ID. + */ protected AppleFileData directoryID = AppleFileData.EMPTY_FILE_DATA; - /** The num entries. */ + /** + * The num entries. + */ protected int numEntries = 0; /** @@ -121,16 +154,13 @@ public abstract class AppleFile { */ public enum FileFormat { - APPLE_SINGLE, - APPLE_DOUBLE, - UNKNOWN; + APPLE_SINGLE, APPLE_DOUBLE, UNKNOWN; /** * Return a suitable Apple file format as inferred from the passed-in * string. Otherwise return the UNKNOWN file format. - * - * @param fileFormat - * the file format + * + * @param fileFormat the file format * @return the FileFormat */ public static FileFormat fromString(String fileFormat) { @@ -141,29 +171,38 @@ public static FileFormat fromString(String fileFormat) { try { return FileFormat.valueOf(fileFormat.toUpperCase()); } catch (IllegalArgumentException iae) { - Log.error("Bad conversion attempt in FileFormat.fromString; string: " - + fileFormat + "; message: " + iae.getMessage()); + Log.error("Bad conversion attempt in FileFormat.fromString; string: " + fileFormat + "; message: " + iae.getMessage()); Log.exception(iae); return UNKNOWN; } } - }; + } + + ; /** * This class represents the file dates. */ public class FileDatesInfoEntry { - /** The create time. */ + /** + * The create time. + */ private int createTime = Integer.MIN_VALUE; - /** The modify time. */ + /** + * The modify time. + */ private int modifyTime = Integer.MIN_VALUE; - /** The backup time. */ + /** + * The backup time. + */ private int backupTime = Integer.MIN_VALUE; - /** The access time. */ + /** + * The access time. + */ private int accessTime = Integer.MIN_VALUE; /** @@ -175,7 +214,7 @@ public FileDatesInfoEntry() { /** * Gets the creates the time. - * + * * @return the creates the time */ public int getCreateTime() { @@ -184,9 +223,8 @@ public int getCreateTime() { /** * Sets the creates the time. - * - * @param createTime - * the new creates the time + * + * @param createTime the new creates the time */ public void setCreateTime(int createTime) { this.createTime = createTime; @@ -194,7 +232,7 @@ public void setCreateTime(int createTime) { /** * Gets the modify time. - * + * * @return the modify time */ public int getModifyTime() { @@ -203,9 +241,8 @@ public int getModifyTime() { /** * Sets the modify time. - * - * @param modifyTime - * the new modify time + * + * @param modifyTime the new modify time */ public void setModifyTime(int modifyTime) { this.modifyTime = modifyTime; @@ -213,7 +250,7 @@ public void setModifyTime(int modifyTime) { /** * Gets the backup time. - * + * * @return the backup time */ public int getBackupTime() { @@ -222,9 +259,8 @@ public int getBackupTime() { /** * Sets the backup time. - * - * @param backupTime - * the new backup time + * + * @param backupTime the new backup time */ public void setBackupTime(int backupTime) { this.backupTime = backupTime; @@ -232,7 +268,7 @@ public void setBackupTime(int backupTime) { /** * Gets the access time. - * + * * @return the access time */ public int getAccessTime() { @@ -241,9 +277,8 @@ public int getAccessTime() { /** * Sets the access time. - * - * @param accessTime - * the new access time + * + * @param accessTime the new access time */ public void setAccessTime(int accessTime) { this.accessTime = accessTime; @@ -252,9 +287,8 @@ public void setAccessTime(int accessTime) { /** * Sets the num entries. - * - * @param numEntries - * the new num entries + * + * @param numEntries the new num entries */ public void setNumEntries(int numEntries) { this.numEntries = numEntries; @@ -262,9 +296,8 @@ public void setNumEntries(int numEntries) { /** * Verify the validity of the Apple file. - * - * @throws FileDecoderException - * the file decoder exception + * + * @throws FileDecoderException the file decoder exception */ @SuppressWarnings("unused") protected void verify() throws FileDecoderException { @@ -358,8 +391,7 @@ protected void verify() throws FileDecoderException { entryLength <<= 8; entryLength |= data[(position++)] & 0xFF; entryLength &= 0x7FFFFFFF; - if ((entryOffset < contentPosition) - || (length < entryOffset + entryLength)) { + if ((entryOffset < contentPosition) || (length < entryOffset + entryLength)) { throw new FileDecoderException("Corrupt Apple file data."); } } @@ -368,61 +400,59 @@ protected void verify() throws FileDecoderException { /** * Extract file dates. * - * @param data the data + * @param data the data * @param offset the offset * @param length the length */ protected void extractFileDates(byte[] data, int offset, int length) { - if ((0 > offset) || (offset > data.length)) - throw new IndexOutOfBoundsException(); - if ((0 > length) || (length > data.length - offset)) - throw new IndexOutOfBoundsException(); - - int position = offset; - - int createTime = 0; - createTime |= data[(position++)] & 0xFF; - createTime <<= 8; - createTime |= data[(position++)] & 0xFF; - createTime <<= 8; - createTime |= data[(position++)] & 0xFF; - createTime <<= 8; - createTime |= data[(position++)] & 0xFF; - int modifyTime = 0; - modifyTime |= data[(position++)] & 0xFF; - modifyTime <<= 8; - modifyTime |= data[(position++)] & 0xFF; - modifyTime <<= 8; - modifyTime |= data[(position++)] & 0xFF; - modifyTime <<= 8; - modifyTime |= data[(position++)] & 0xFF; - int backupTime = 0; - backupTime |= data[(position++)] & 0xFF; - backupTime <<= 8; - backupTime |= data[(position++)] & 0xFF; - backupTime <<= 8; - backupTime |= data[(position++)] & 0xFF; - backupTime <<= 8; - backupTime |= data[(position++)] & 0xFF; - int accessTime = 0; - accessTime |= data[(position++)] & 0xFF; - accessTime <<= 8; - accessTime |= data[(position++)] & 0xFF; - accessTime <<= 8; - accessTime |= data[(position++)] & 0xFF; - accessTime <<= 8; - accessTime |= data[(position++)] & 0xFF; - - this.fileDatesInfoEntry = new FileDatesInfoEntry(); - fileDatesInfoEntry.setCreateTime(createTime); - fileDatesInfoEntry.setModifyTime(modifyTime); - fileDatesInfoEntry.setBackupTime(backupTime); - fileDatesInfoEntry.setAccessTime(accessTime); + if ((0 > offset) || (offset > data.length)) throw new IndexOutOfBoundsException(); + if ((0 > length) || (length > data.length - offset)) throw new IndexOutOfBoundsException(); + + int position = offset; + + int createTime = 0; + createTime |= data[(position++)] & 0xFF; + createTime <<= 8; + createTime |= data[(position++)] & 0xFF; + createTime <<= 8; + createTime |= data[(position++)] & 0xFF; + createTime <<= 8; + createTime |= data[(position++)] & 0xFF; + int modifyTime = 0; + modifyTime |= data[(position++)] & 0xFF; + modifyTime <<= 8; + modifyTime |= data[(position++)] & 0xFF; + modifyTime <<= 8; + modifyTime |= data[(position++)] & 0xFF; + modifyTime <<= 8; + modifyTime |= data[(position++)] & 0xFF; + int backupTime = 0; + backupTime |= data[(position++)] & 0xFF; + backupTime <<= 8; + backupTime |= data[(position++)] & 0xFF; + backupTime <<= 8; + backupTime |= data[(position++)] & 0xFF; + backupTime <<= 8; + backupTime |= data[(position++)] & 0xFF; + int accessTime = 0; + accessTime |= data[(position++)] & 0xFF; + accessTime <<= 8; + accessTime |= data[(position++)] & 0xFF; + accessTime <<= 8; + accessTime |= data[(position++)] & 0xFF; + accessTime <<= 8; + accessTime |= data[(position++)] & 0xFF; + + this.fileDatesInfoEntry = new FileDatesInfoEntry(); + fileDatesInfoEntry.setCreateTime(createTime); + fileDatesInfoEntry.setModifyTime(modifyTime); + fileDatesInfoEntry.setBackupTime(backupTime); + fileDatesInfoEntry.setAccessTime(accessTime); } /** * Gets the format. - * + * * @return the format */ public FileFormat getFormat() { @@ -431,9 +461,8 @@ public FileFormat getFormat() { /** * Sets the format. - * - * @param format - * the new format + * + * @param format the new format */ public void setFormat(FileFormat format) { this.format = format; @@ -441,7 +470,7 @@ public void setFormat(FileFormat format) { /** * Gets the file data. - * + * * @return the file data */ public AppleFileData getFileData() { @@ -450,9 +479,8 @@ public AppleFileData getFileData() { /** * Sets the file data. - * - * @param fileData - * the new file data + * + * @param fileData the new file data */ public void setFileData(AppleFileData fileData) { this.fileData = fileData; @@ -460,7 +488,7 @@ public void setFileData(AppleFileData fileData) { /** * Gets the data fork. - * + * * @return the data fork */ public AppleFileData getDataFork() { @@ -469,9 +497,8 @@ public AppleFileData getDataFork() { /** * Sets the data fork. - * - * @param dataFork - * the new data fork + * + * @param dataFork the new data fork */ public void setDataFork(AppleFileData dataFork) { this.dataFork = dataFork; @@ -479,7 +506,7 @@ public void setDataFork(AppleFileData dataFork) { /** * Gets the resource fork. - * + * * @return the resource fork */ public AppleFileData getResourceFork() { @@ -488,9 +515,8 @@ public AppleFileData getResourceFork() { /** * Sets the resource fork. - * - * @param resourceFork - * the new resource fork + * + * @param resourceFork the new resource fork */ public void setResourceFork(AppleFileData resourceFork) { this.resourceFork = resourceFork; @@ -498,7 +524,7 @@ public void setResourceFork(AppleFileData resourceFork) { /** * Gets the real name. - * + * * @return the real name */ public AppleFileData getRealName() { @@ -507,9 +533,8 @@ public AppleFileData getRealName() { /** * Sets the real name. - * - * @param realName - * the new real name + * + * @param realName the new real name */ public void setRealName(AppleFileData realName) { this.realName = realName; @@ -517,7 +542,7 @@ public void setRealName(AppleFileData realName) { /** * Gets the comment. - * + * * @return the comment */ public AppleFileData getComment() { @@ -526,9 +551,8 @@ public AppleFileData getComment() { /** * Sets the comment. - * - * @param comment - * the new comment + * + * @param comment the new comment */ public void setComment(AppleFileData comment) { this.comment = comment; @@ -536,7 +560,7 @@ public void setComment(AppleFileData comment) { /** * Gets the icon bw. - * + * * @return the icon bw */ public AppleFileData getIconBW() { @@ -545,9 +569,8 @@ public AppleFileData getIconBW() { /** * Sets the icon bw. - * - * @param iconBW - * the new icon bw + * + * @param iconBW the new icon bw */ public void setIconBW(AppleFileData iconBW) { this.iconBW = iconBW; @@ -555,7 +578,7 @@ public void setIconBW(AppleFileData iconBW) { /** * Gets the icon color. - * + * * @return the icon color */ public AppleFileData getIconColor() { @@ -564,9 +587,8 @@ public AppleFileData getIconColor() { /** * Sets the icon color. - * - * @param iconColor - * the new icon color + * + * @param iconColor the new icon color */ public void setIconColor(AppleFileData iconColor) { this.iconColor = iconColor; @@ -574,7 +596,7 @@ public void setIconColor(AppleFileData iconColor) { /** * Gets the file dates info. - * + * * @return the file dates info */ public AppleFileData getFileDatesInfo() { @@ -583,9 +605,8 @@ public AppleFileData getFileDatesInfo() { /** * Sets the file dates info. - * - * @param fileDatesInfo - * the new file dates info + * + * @param fileDatesInfo the new file dates info */ public void setFileDatesInfo(AppleFileData fileDatesInfo) { this.fileDatesInfo = fileDatesInfo; @@ -593,7 +614,7 @@ public void setFileDatesInfo(AppleFileData fileDatesInfo) { /** * Gets the finder info. - * + * * @return the finder info */ public AppleFileData getFinderInfo() { @@ -602,9 +623,8 @@ public AppleFileData getFinderInfo() { /** * Sets the finder info. - * - * @param finderInfo - * the new finder info + * + * @param finderInfo the new finder info */ public void setFinderInfo(AppleFileData finderInfo) { this.finderInfo = finderInfo; @@ -612,7 +632,7 @@ public void setFinderInfo(AppleFileData finderInfo) { /** * Gets the macintosh info. - * + * * @return the macintosh info */ public AppleFileData getMacintoshInfo() { @@ -621,9 +641,8 @@ public AppleFileData getMacintoshInfo() { /** * Sets the macintosh info. - * - * @param macintoshInfo - * the new macintosh info + * + * @param macintoshInfo the new macintosh info */ public void setMacintoshInfo(AppleFileData macintoshInfo) { this.macintoshInfo = macintoshInfo; @@ -631,7 +650,7 @@ public void setMacintoshInfo(AppleFileData macintoshInfo) { /** * Gets the pro dos file info. - * + * * @return the pro dos file info */ public AppleFileData getProDOSFileInfo() { @@ -640,9 +659,8 @@ public AppleFileData getProDOSFileInfo() { /** * Sets the pro dos file info. - * - * @param proDOSFileInfo - * the new pro dos file info + * + * @param proDOSFileInfo the new pro dos file info */ public void setProDOSFileInfo(AppleFileData proDOSFileInfo) { this.proDOSFileInfo = proDOSFileInfo; @@ -650,7 +668,7 @@ public void setProDOSFileInfo(AppleFileData proDOSFileInfo) { /** * Gets the ms dos file info. - * + * * @return the ms dos file info */ public AppleFileData getMsDOSFileInfo() { @@ -659,9 +677,8 @@ public AppleFileData getMsDOSFileInfo() { /** * Sets the ms dos file info. - * - * @param msDOSFileInfo - * the new ms dos file info + * + * @param msDOSFileInfo the new ms dos file info */ public void setMsDOSFileInfo(AppleFileData msDOSFileInfo) { this.msDOSFileInfo = msDOSFileInfo; @@ -669,7 +686,7 @@ public void setMsDOSFileInfo(AppleFileData msDOSFileInfo) { /** * Gets the short name. - * + * * @return the short name */ public AppleFileData getShortName() { @@ -678,9 +695,8 @@ public AppleFileData getShortName() { /** * Sets the short name. - * - * @param shortName - * the new short name + * + * @param shortName the new short name */ public void setShortName(AppleFileData shortName) { this.shortName = shortName; @@ -688,7 +704,7 @@ public void setShortName(AppleFileData shortName) { /** * Gets the afp file info. - * + * * @return the afp file info */ public AppleFileData getAfpFileInfo() { @@ -697,9 +713,8 @@ public AppleFileData getAfpFileInfo() { /** * Sets the afp file info. - * - * @param afpFileInfo - * the new afp file info + * + * @param afpFileInfo the new afp file info */ public void setAfpFileInfo(AppleFileData afpFileInfo) { this.afpFileInfo = afpFileInfo; @@ -707,7 +722,7 @@ public void setAfpFileInfo(AppleFileData afpFileInfo) { /** * Gets the directory id. - * + * * @return the directory id */ public AppleFileData getDirectoryID() { @@ -716,9 +731,8 @@ public AppleFileData getDirectoryID() { /** * Sets the directory id. - * - * @param directoryID - * the new directory id + * + * @param directoryID the new directory id */ public void setDirectoryID(AppleFileData directoryID) { this.directoryID = directoryID; @@ -726,7 +740,7 @@ public void setDirectoryID(AppleFileData directoryID) { /** * Gets the num entries. - * + * * @return the num entries */ public int getNumEntries() { diff --git a/src/main/java/com/perforce/p4java/io/apple/AppleFileEncoder.java b/src/main/java/com/perforce/p4java/io/apple/AppleFileEncoder.java index c0a0ecc..72f2061 100644 --- a/src/main/java/com/perforce/p4java/io/apple/AppleFileEncoder.java +++ b/src/main/java/com/perforce/p4java/io/apple/AppleFileEncoder.java @@ -9,7 +9,6 @@ * This class handles the combination of the data fork, resource fork and other * entries into an AppleSingle/Double file. *

- * * Note that if it is an AppleDouble, the data fork is a separate file external * to this file. */ @@ -17,8 +16,9 @@ public class AppleFileEncoder extends AppleFile { /** * Instantiates a new apple file decoder. - * - * @throws FileEncoderException + * + * @param fileFormat fileFormat + * @throws FileEncoderException on error */ public AppleFileEncoder(FileFormat fileFormat) throws FileEncoderException { if (fileFormat == null) { @@ -32,9 +32,8 @@ public AppleFileEncoder(FileFormat fileFormat) throws FileEncoderException { /** * Combine the data fork, resource fork and other entries into an * AppleSingle/Double file. - * - * @throws FileEncoderException - * the file encoder exception + * + * @throws FileEncoderException the file encoder exception */ @SuppressWarnings("unused") public void combine() throws FileEncoderException { diff --git a/src/main/java/com/perforce/p4java/mapapi/MapItem.java b/src/main/java/com/perforce/p4java/mapapi/MapItem.java index 91bda05..f457861 100644 --- a/src/main/java/com/perforce/p4java/mapapi/MapItem.java +++ b/src/main/java/com/perforce/p4java/mapapi/MapItem.java @@ -8,11 +8,11 @@ public class MapItem { - /* - * chain - linked list - * mapFlag - represent +map, or -map - * slot - precedence (higher is better) on the chain - */ + /* + * chain - linked list + * mapFlag - represent +map, or -map + * slot - precedence (higher is better) on the chain + */ public MapItem chain; public MapFlag mapFlag; @@ -53,8 +53,7 @@ public MapHalf half(MapTableT dir) { } public boolean isParent(MapItem other, MapTableT dir) { - return ths(dir).getFixedLen() == - ths(dir).getCommonLen(other.ths(dir)); + return ths(dir).getFixedLen() == ths(dir).getCommonLen(other.ths(dir)); } /** @@ -63,9 +62,14 @@ public boolean isParent(MapItem other, MapTableT dir) { * A MapItem holds two MapHalfs that constitute a single entry in * a MapTable. MapItem also implement fast searching for entries * for MapTable::Check() and MapTable::Translate(). + * + * @param c chain + * @param l left mapping + * @param r right mapping + * @param f map flags + * @param s slot */ - public MapItem(MapItem c, String l, - String r, MapFlag f, int s) { + public MapItem(MapItem c, String l, String r, MapFlag f, int s) { lhs().set(l); rhs().set(r); mapFlag = f; @@ -85,10 +89,15 @@ public MapItem(MapItem c, String l, * A MapItem holds two MapHalfs that constitute a single entry in * a MapTable. MapItem also implement fast searching for entries * for MapTable::Check() and MapTable::Translate(). + * + * @param c chain + * @param l left mapping + * @param r right mapping + * @param f map flags + * @param s slot + * @param caseMode case mode */ - public MapItem(MapItem c, String l, - String r, MapFlag f, int s, - int caseMode) { + public MapItem(MapItem c, String l, String r, MapFlag f, int s, int caseMode) { lhs().set(l); rhs().set(r); mapFlag = f; @@ -136,6 +145,8 @@ public int slot() { /** * MapItem::Reverse - reverse the chain, to swap precedence + * + * @return map item */ public MapItem reverse() { MapItem m = this; @@ -155,6 +166,9 @@ public MapItem reverse() { /** * MapItem::Move - moves an item up the chain + * + * @param slot slot position + * @return map item */ MapItem move(int slot) { MapItem m = this; @@ -164,11 +178,9 @@ MapItem move(int slot) { // This has no error state, but this is bad // We can't go below 0 and we can't go back up either - if (start <= slot) - return m; + if (start <= slot) return m; - if (slot < 0) - slot = 0; + if (slot < 0) slot = 0; MapItem n = m.chain; while (n != null) { @@ -192,43 +204,36 @@ MapItem move(int slot) { /** * MapItem::Tree - recursively construct a trinary sort tree */ - static MapItem tree( - ArrayList items, - int start, - int end, - MapTableT dir, - MapItem parent, - AtomicInteger depth) { + static MapItem tree(ArrayList items, int start, int end, MapTableT dir, MapItem parent, AtomicInteger depth) { /* No empties */ - if (items.size() == 0 || start == end) - return null; - - /* - * start li (middle) ri end - * - * (middle) is halfway between start and end. - * li is first item that is a parent of middle. - * ri is last item li is a parent of. - * - * We return - * - * *li - * / | \ - * / | \ - * / | \ - * / | \ - * start.li li+1.ri ri.end - */ + if (items.size() == 0 || start == end) return null; + + /* + * start li (middle) ri end + * + * (middle) is halfway between start and end. + * li is first item that is a parent of middle. + * ri is last item li is a parent of. + * + * We return + * + * *li + * / | \ + * / | \ + * / | \ + * / | \ + * start.li li+1.ri ri.end + */ int li = start; int ri = -1; - /* - * Quick check: the center tree often ends up in the - * shape of a linked list (due to identical entries). - * This is an optimization for that case. - */ + /* + * Quick check: the center tree often ends up in the + * shape of a linked list (due to identical entries). + * This is an optimization for that case. + */ if (start == end - 1 || items.get(start).isParent(items.get(end - 1), dir)) { ri = end; @@ -263,14 +268,11 @@ static MapItem tree( t.center = tree(items, ri + 1, end, dir, items.get(ri), depthBelow); - if (maxSlot < t.maxSlot) - maxSlot = t.maxSlot; + if (maxSlot < t.maxSlot) maxSlot = t.maxSlot; - if (maxSlotNoAnds < t.maxSlotNoAnds) - maxSlotNoAnds = t.maxSlotNoAnds; + if (maxSlotNoAnds < t.maxSlotNoAnds) maxSlotNoAnds = t.maxSlotNoAnds; - if (t.hasands) - hasands = true; + if (t.hasands) hasands = true; if (parent != null && (items.get(ri).mapFlag == MfAndmap || t.hasands)) { parent.whole(dir).hasands = true; @@ -324,11 +326,11 @@ static MapItem tree( return items.get(li); } else - /* - * Start in middle. - * Move li from start until we find first parent of ri. - * Move ri right until we find last child of li. - */ + /* + * Start in middle. + * Move li from start until we find first parent of ri. + * Move ri right until we find last child of li. + */ ri = start + (end - start) / 2; @@ -340,11 +342,11 @@ static MapItem tree( ++ri; } - /* - * Fill in the *li node, which we will return. - * - * left, right, center computed recursively. - */ + /* + * Fill in the *li node, which we will return. + * + * left, right, center computed recursively. + */ MapItem.MapWhole t = items.get(li).whole(dir); @@ -359,31 +361,27 @@ static MapItem tree( t.center = tree(items, li + 1, ri, dir, items.get(li), depthBelow); t.right = tree(items, ri, end, dir, items.get(li), depthBelow); - /* - * Current depth is 1 + what's below us, as long as one of - * our peers isn't deeper. - */ + /* + * Current depth is 1 + what's below us, as long as one of + * our peers isn't deeper. + */ - if (depth.get() < depthBelow.get() + 1) - depth.set(depthBelow.get() + 1); + if (depth.get() < depthBelow.get() + 1) depth.set(depthBelow.get() + 1); - /* - * Relationship to parent: - * parent's maxSlot includes our maxSlot. - * our initial substring overlap with our parent. - */ + /* + * Relationship to parent: + * parent's maxSlot includes our maxSlot. + * our initial substring overlap with our parent. + */ if (parent != null) { - if (parent.whole(dir).maxSlot < t.maxSlot) - parent.whole(dir).maxSlot = t.maxSlot; + if (parent.whole(dir).maxSlot < t.maxSlot) parent.whole(dir).maxSlot = t.maxSlot; - if (parent.whole(dir).maxSlotNoAnds < t.maxSlotNoAnds) - parent.whole(dir).maxSlotNoAnds = t.maxSlotNoAnds; + if (parent.whole(dir).maxSlotNoAnds < t.maxSlotNoAnds) parent.whole(dir).maxSlotNoAnds = t.maxSlotNoAnds; t.overlap = t.half.getCommonLen(parent.ths(dir)); - if (items.get(li).mapFlag == MfAndmap || t.hasands) - parent.whole(dir).hasands = true; + if (items.get(li).mapFlag == MfAndmap || t.hasands) parent.whole(dir).hasands = true; } return items.get(li); @@ -428,15 +426,15 @@ MapItem match(MapTableT dir, String from, MapItemArray ands) { ands = new MapItemArray(); } - /* Decend */ + /* Decend */ while (tree != null) { MapItem.MapWhole t = tree.whole(dir); - /* - * No better precendence below? Bail. - * Unless we're looking for andmaps - */ + /* + * No better precendence below? Bail. + * Unless we're looking for andmaps + */ if (best > t.maxSlot && // Have we already got the best? !t.hasands && // Are there andmaps down the tree? @@ -444,87 +442,72 @@ MapItem match(MapTableT dir, String from, MapItemArray ands) { bestnotands > t.maxSlotNoAnds) // We prefer a real mapping break; - /* - * Match with prev map greater than overlap? trim. - */ + /* + * Match with prev map greater than overlap? trim. + */ - if (coff > t.overlap) - coff = t.overlap; + if (coff > t.overlap) coff = t.overlap; - /* - * Match initial substring (by which the tree is ordered). - * Can skip match if same initial substring as previous map. - */ + /* + * Match initial substring (by which the tree is ordered). + * Can skip match if same initial substring as previous map. + */ int r = 0; - if (coff < t.half.getFixedLen()) - r = t.half.match1(from, coff); + if (coff < t.half.getFixedLen()) r = t.half.match1(from, coff); - /* - * Match? Higher precedence? Wildcard match? Save. - */ + /* + * Match? Higher precedence? Wildcard match? Save. + */ - if (r == 0 && - best < tree.slot && - t.half.match2(from, params)) { + if (r == 0 && best < tree.slot && t.half.match2(from, params)) { map = tree; best = map.slot; - if (ands != null) - ands.put(tree, null); - if (tree.flag() != MfAndmap) - bestnotands = tree.slot; + if (ands != null) ands.put(tree, null); + if (tree.flag() != MfAndmap) bestnotands = tree.slot; } - /* - * Not higher precedence? AndMap Array? Wildcard match? Save - */ + /* + * Not higher precedence? AndMap Array? Wildcard match? Save + */ - if (r == 0 && - ands != null && - map != tree && - best >= tree.slot && - t.half.match2(from, params)) { + if (r == 0 && ands != null && map != tree && best >= tree.slot && t.half.match2(from, params)) { ands.put(tree, null); - if (tree.flag() != MfAndmap) - bestnotands = tree.slot; + if (tree.flag() != MfAndmap) bestnotands = tree.slot; } - /* - * Follow to appropriate child. - */ + /* + * Follow to appropriate child. + */ if (r < 0) tree = t.left; else if (r > 0) tree = t.right; else tree = t.center; } - /* - * If we were dealing with & maps, we need to make sure we either: - * 1. return the highest precedence non-andmap mapping - * 2. return the highest precedence andmap mapping - */ + /* + * If we were dealing with & maps, we need to make sure we either: + * 1. return the highest precedence non-andmap mapping + * 2. return the highest precedence andmap mapping + */ if (map != null && ands != null) { MapItem m0 = null; int i = 0; - while ((m0 = ands.getItem(i++)) != null) - if (m0.flag() != MfAndmap) { - if (m0.mapFlag == MfUnmap) - break; // Take the best & mapping and break + while ((m0 = ands.getItem(i++)) != null) if (m0.flag() != MfAndmap) { + if (m0.mapFlag == MfUnmap) break; // Take the best & mapping and break - map = m0; // Take the best non-& mapping and break - break; - } else if (i == 1) - map = m0; // Take the best & mapping; keep going + map = m0; // Take the best non-& mapping and break + break; + } else if (i == 1) map = m0; // Take the best & mapping; keep going } - /* - * Best mapping an unmapping? That's no mapping. - */ + /* + * Best mapping an unmapping? That's no mapping. + */ - if (map == null || map.mapFlag == MfUnmap) - return null; + if (map == null || map.mapFlag == MfUnmap) return null; return map; } @@ -543,23 +526,17 @@ void dump(StringBuffer buf, MapTableT d, String name, int l) { } if (l == 0) { - if (buf == null) - System.out.print("MapTree\n"); - else - buf.append("MapTree\n"); + if (buf == null) System.out.print("MapTree\n"); + else buf.append("MapTree\n"); } if (whole(d).left != null) { whole(d).left.dump(buf, d, "<<<", l + 1); } - String out = String.format("%s%s %c%s <-> %s%s (maxslot %d (%d))\n", indent, name, - " -+$@& 123456789".charAt(mapFlag.code), ths(d).get(), ohs(d).get(), - whole(d).hasands ? " (has &)" : "", whole(d).maxSlot, whole(d).maxSlotNoAnds); - if (buf == null) - System.out.print(out); - else - buf.append(out); + String out = String.format("%s%s %c%s <-> %s%s (maxslot %d (%d))\n", indent, name, " -+$@& 123456789".charAt(mapFlag.code), ths(d).get(), ohs(d).get(), whole(d).hasands ? " (has &)" : "", whole(d).maxSlot, whole(d).maxSlotNoAnds); + if (buf == null) System.out.print(out); + else buf.append(out); if (whole(d).center != null) { whole(d).center.dump(buf, d, "===", l + 1); diff --git a/src/main/java/com/perforce/p4java/messages/PerforceMessages.java b/src/main/java/com/perforce/p4java/messages/PerforceMessages.java index df7e812..76c7f10 100644 --- a/src/main/java/com/perforce/p4java/messages/PerforceMessages.java +++ b/src/main/java/com/perforce/p4java/messages/PerforceMessages.java @@ -8,23 +8,28 @@ import java.util.ResourceBundle; /** - * Handles formatting Perforce messages. It provides locale (language & country) + * Handles formatting Perforce messages. It provides locale (language and country) * specific messages. The default locale is set during startup of the JVM based - * on the host environment.

- * + * on the host environment. + *

* Additionally, this class provides a convenient way to format messages with * parameters. */ public class PerforceMessages { - /** Default name of the Perforce message bundle properties file. */ - public static final String MESSAGE_BUNDLE = PerforceMessages.class - .getName(); + /** + * Default name of the Perforce message bundle properties file. + */ + public static final String MESSAGE_BUNDLE = PerforceMessages.class.getName(); - /** The locale. */ + /** + * The locale. + */ private Locale locale; - /** The messages. */ + /** + * The messages. + */ private ResourceBundle messages; /** @@ -38,11 +43,10 @@ public PerforceMessages() { /** * Instantiates a new perforce messages base on the passed-in message bundle * properties file package path name. - * - * @param propertiesFile - * the name (without the extension) of the properties file - * including the full package path name (i.e. - * com.perforce.p4java.messages.PerforceMessages) + * + * @param propertiesFile the name (without the extension) of the properties file + * including the full package path name (i.e. + * com.perforce.p4java.messages.PerforceMessages) */ public PerforceMessages(String propertiesFile) { this.messages = ResourceBundle.getBundle(propertiesFile); @@ -50,9 +54,8 @@ public PerforceMessages(String propertiesFile) { /** * Instantiates a new perforce messages. - * - * @param locale - * the locale + * + * @param locale the locale */ public PerforceMessages(Locale locale) { this.locale = locale; @@ -61,7 +64,7 @@ public PerforceMessages(Locale locale) { /** * Gets the locale. - * + * * @return the locale */ public Locale getLocale() { @@ -70,9 +73,8 @@ public Locale getLocale() { /** * Sets the locale. - * - * @param locale - * the new locale + * + * @param locale the new locale */ public void setLocale(Locale locale) { this.locale = locale; @@ -80,7 +82,7 @@ public void setLocale(Locale locale) { /** * Gets the messages. - * + * * @return the messages */ public ResourceBundle getMessages() { @@ -89,9 +91,8 @@ public ResourceBundle getMessages() { /** * Sets the messages. - * - * @param messages - * the new messages + * + * @param messages the new messages */ public void setMessages(ResourceBundle messages) { this.messages = messages; @@ -99,9 +100,8 @@ public void setMessages(ResourceBundle messages) { /** * Gets the message. - * - * @param key - * the key + * + * @param key the key * @return the message */ public String getMessage(String key) { @@ -110,11 +110,9 @@ public String getMessage(String key) { /** * Gets the message. - * - * @param key - * the key - * @param params - * the params + * + * @param key the key + * @param params the params * @return the message */ public String getMessage(String key, Object[] params) { @@ -123,11 +121,9 @@ public String getMessage(String key, Object[] params) { /** * Format a message with parameters. - * - * @param message - * the message - * @param params - * the params + * + * @param message the message + * @param params the params * @return the string * @see MessageFormat */ diff --git a/src/main/java/com/perforce/p4java/option/Options.java b/src/main/java/com/perforce/p4java/option/Options.java index 42a923e..cb399ce 100644 --- a/src/main/java/com/perforce/p4java/option/Options.java +++ b/src/main/java/com/perforce/p4java/option/Options.java @@ -73,7 +73,7 @@ public Options() { * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

* * The intention here is to provide a way to bypass the various @@ -110,7 +110,7 @@ public Options(String... options) { * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

* * The intention here is to provide a way to bypass the various diff --git a/src/main/java/com/perforce/p4java/option/UsageOptions.java b/src/main/java/com/perforce/p4java/option/UsageOptions.java index 8ec02dc..90bc028 100644 --- a/src/main/java/com/perforce/p4java/option/UsageOptions.java +++ b/src/main/java/com/perforce/p4java/option/UsageOptions.java @@ -1,24 +1,24 @@ /** - * + * */ package com.perforce.p4java.option; -import java.util.Properties; - import com.perforce.p4java.PropertyDefs; import com.perforce.p4java.exception.NullPointerError; import com.perforce.p4java.exception.P4JavaError; +import java.util.Properties; + /** * Global server usage options class.

- * + * * Intended to implement some of the options described in * the main Perforce p4 usage and p4 undoc documentation on * a per-IOptionsServer object basis, and also implements some of * the broader environment settings (such as the client name used * by the P4Java server implementation when no client has been * associated with the server).

- * + * * The UsageOptions object associated with a server is read and used * for a small number of usage values (currently programName, programVersion, * unsetUserName, and unsetClientName) each time a command is issued to the @@ -28,12 +28,12 @@ * UsageOption objects shared between multiple servers are sensitive to such * changes, and that changes that occur when a server is processing command * requests may cause unexpected results.

- * + * * A UsageOption object is associated with a server instance when * the server is issued by the server factory; this can be the default * object or one passed-in to the server factory specifically for that * server.

- * + * * Note that the UsageOptions class should be used with some * care as the possible side effects of setting some of the * usage parameters to the wrong value can lead to unexpected or @@ -41,13 +41,13 @@ */ public class UsageOptions { - + /** * The name of the system property used to determine the JVM's current * working directory. */ public static final String WORKING_DIRECTORY_PROPNAME = "user.dir"; - + /** * Properties object used to get default field values from. Note that * these properties are potentially accessed for each command, so any @@ -55,36 +55,36 @@ public class UsageOptions { * object is used. */ protected Properties props = null; - + /** * If not null, will be used to identify the P4Java application's * program name to the Perforce server. */ protected String programName = null; - + /** * If not null, will be used to identify the P4Java application's * program version to the Perforce server. */ protected String programVersion = null; - + /** * If not null, this specifies the Perforce server's idea of each command's * working directory for the associated server object. Corresponds to * the p4 -d usage option.

- * + * * This affects all commands on the associated server from this point on, * and the passed-in path should be both absolute and valid, otherwise * strange errors may appear from the server. If workingDirectory is null, * the Java VM's actual current working directory at the time this object * is constructed is used instead (which is almost always a safe option unless * you're using Perforce alt roots).

- * + * * Note: no checking is done at any time for correctness (or otherwise) * of the workingDirectory option. */ protected String workingDirectory = null; - + /** * If not null, specifies the host name used by the server's commands. * Set to null by the default constructor. Corresponds to the p4 -H @@ -94,7 +94,7 @@ public class UsageOptions { * associated server. */ protected String hostName = null; - + /** * If not null, use this field to tell the server which language to * use in text messages it sends back to the client. Corresponds to @@ -102,30 +102,31 @@ public class UsageOptions { * the default constructor. */ protected String textLanguage = null; - + /** * What will be sent to the Perforce server with each command as the user * name if no user name has been explicitly set for servers associated with * this UsageOption. */ protected String unsetUserName = null; - + /** * If set, this will be used as the name of the client when no * client has actually been explicitly set for the associated server(s). */ protected String unsetClientName = null; - + /** * Default working directory from the JVM to fall back to if not working * directory is set on the usage options */ protected String defaultWorkingDirectory = null; - + /** * Default constructor. Sets props field then calls setFieldDefaults * to set appropriate field default values; otherwise does nothing. + * @param props properties */ public UsageOptions(Properties props) { if (props == null) { @@ -140,10 +141,18 @@ public UsageOptions(Properties props) { * Explicit value constructor. After setting any values explicitly, * calls setFieldDefaults() to tidy up any still-null fields that shouldn't * be null. + * @param props properties + * @param programName program name + * @param programVersion program version + * @param workingDirectory working directory + * @param hostName host name + * @param textLanguage language + * @param unsetUserName user name + * @param noClientName client name */ public UsageOptions(Properties props, String programName, String programVersion, - String workingDirectory, String hostName, String textLanguage, - String unsetUserName, String noClientName) { + String workingDirectory, String hostName, String textLanguage, + String unsetUserName, String noClientName) { if (props == null) { this.props = new Properties(); } else { @@ -158,26 +167,28 @@ public UsageOptions(Properties props, String programName, String programVersion, this.unsetClientName = noClientName; setFieldDefaults(getProps()); } - + /** * Set any non-null default values when the object * is constructed. Basically, this means running down the fields * and if a field is null and it's not a field that should have a null * default value, calling the corresponding getXXXXDefault method.

- * + * * Fields set here: workingDirectory. + * @param props properties */ protected void setFieldDefaults(Properties props) { this.defaultWorkingDirectory = getWorkingDirectoryDefault(props); } - + /** * Get a suitable default value for the programName field. * This version tries to find a suitable value in the passed-in * properties with the key PropertyDefs.PROG_NAME_KEY_SHORTFORM, then * with the key PropertyDefs.PROG_NAME_KEY; if that comes up null, * it uses the value of PropertyDefs.PROG_NAME_DEFAULT. - * + * + * @param props properties * @return non-null default programName value. */ protected String getProgramNameDefault(Properties props) { @@ -188,14 +199,15 @@ protected String getProgramNameDefault(Properties props) { props.getProperty(PropertyDefs.PROG_NAME_KEY, PropertyDefs.PROG_NAME_DEFAULT)); } - + /** * Get a suitable default value for the programVersion field. * This version tries to find a suitable value in the passed-in * properties with the key PropertyDefs.PROG_VERSION_KEY_SHORTFORM, then * with the key PropertyDefs.PROG_VERSION_KEY; if that comes up null, * it uses the value of PropertyDefs.PROG_VERSION_DEFAULT. - * + * + * @param props properties * @return non-null default programVersion value. */ protected String getProgramVersionDefault(Properties props) { @@ -206,12 +218,13 @@ protected String getProgramVersionDefault(Properties props) { props.getProperty(PropertyDefs.PROG_VERSION_KEY, PropertyDefs.PROG_VERSION_DEFAULT)); } - + /** * Get a suitable default value for the workingDirectory field. This * is taken from the JVM's system properties using the WORKING_DIRECTORY_PROPNAME * system properties key (which is normally user.dir). - * + * + * @param props properties * @return non-null working directory. */ protected String getWorkingDirectoryDefault(Properties props) { @@ -221,15 +234,16 @@ protected String getWorkingDirectoryDefault(Properties props) { throw new P4JavaError( "Unable to retrieve current working directory from JVM system properties"); } - + return cwd; } - + /** * Get a suitable default value for the unsetUserName field. This version * returns the value of the property associated with the PropertyDefs.USER_UNSET_NAME_KEY * if it exists, or PropertyDefs.USER_UNSET_NAME_DEFAULT if not. * + * @param props properties * @return non-null default unsetUserName value. */ protected String getUnsetUserNameDefault(Properties props) { @@ -239,12 +253,13 @@ protected String getUnsetUserNameDefault(Properties props) { return this.props.getProperty(PropertyDefs.USER_UNSET_NAME_KEY, PropertyDefs.USER_UNSET_NAME_DEFAULT); } - + /** * Get a suitable default value for the unsetClientName field. This version * returns the value of the property associated with the PropertyDefs.CLIENT_UNSET_NAME_KEY * if it exists, or PropertyDefs.CLIENT_UNSET_NAME_DEFAULT if not. * + * @param props properties * @return non-null default unsetClientName value. */ protected String getUnsetClientNameDefault(Properties props) { @@ -262,6 +277,7 @@ protected String getUnsetClientNameDefault(Properties props) { * for a value with the key PropertyDefs.PROG_NAME_KEY_SHORTFORM, then * with the key PropertyDefs.PROG_NAME_KEY; if that comes up null, * it returns the value of PropertyDefs.PROG_NAME_DEFAULT. + * @return program name */ public String getProgramName() { if (this.programName != null) { @@ -287,6 +303,7 @@ public UsageOptions setProgramName(String programName) { * for a value with the key PropertyDefs.PROG_VERSION_KEY_SHORTFORM, then * with the key PropertyDefs.PROG_VERSION_KEY; if that comes up null, * it returns the value of PropertyDefs.PROG_VERSION_DEFAULT. + * @return program version */ public String getProgramVersion() { if (this.programVersion != null) { @@ -300,6 +317,10 @@ public String getProgramVersion() { PropertyDefs.PROG_VERSION_DEFAULT)); } + /** + * @param programVersion program version + * @return usage options + */ public UsageOptions setProgramVersion(String programVersion) { this.programVersion = programVersion; return this; @@ -310,17 +331,25 @@ public UsageOptions setProgramVersion(String programVersion) { * set explicitly using the setter method or implicitly when the object is * constructed using the JVM's working directory as reflected in the * System properties. + * @return working directory */ public String getWorkingDirectory() { return workingDirectory != null ? workingDirectory : defaultWorkingDirectory; } + /** + * @param workingDirectory working directory + * @return usage options + */ public UsageOptions setWorkingDirectory(String workingDirectory) { this.workingDirectory = workingDirectory; return this; } + /** + * @return host name + */ public String getHostName() { return hostName; } @@ -328,25 +357,41 @@ public String getHostName() { /** * Set the host name. Calling this method has no effect at all after * any associated server object is created. + * @param hostName host name + * @return usage options */ public UsageOptions setHostName(String hostName) { this.hostName = hostName; return this; } + /** + * @return language + */ public String getTextLanguage() { return textLanguage; } + /** + * @param textLanguage language + * @return usage options + */ public UsageOptions setTextLanguage(String textLanguage) { this.textLanguage = textLanguage; return this; } + /** + * @return properties + */ public Properties getProps() { return props; } + /** + * @param props properties + * @return usage options + */ public UsageOptions setProps(Properties props) { this.props = props; return this; @@ -358,6 +403,7 @@ public UsageOptions setProps(Properties props) { * if so, it's returned; otherwise the associated properties are searched * for a value with the key PropertyDefs.CLIENT_UNSET_NAME_KEY; if that comes * up null, it returns the value of PropertyDefs.CLIENT_UNSET_NAME_DEFAULT. + * @return client name */ public String getUnsetClientName() { if (this.unsetClientName != null) { @@ -367,9 +413,13 @@ public String getUnsetClientName() { throw new NullPointerError("Null properties in UsageOptions"); } return props.getProperty(PropertyDefs.CLIENT_UNSET_NAME_KEY, - PropertyDefs.CLIENT_UNSET_NAME_DEFAULT); + PropertyDefs.CLIENT_UNSET_NAME_DEFAULT); } + /** + * @param unsetClientName client name + * @return usage options + */ public UsageOptions setUnsetClientName(String unsetClientName) { this.unsetClientName = unsetClientName; return this; @@ -381,6 +431,7 @@ public UsageOptions setUnsetClientName(String unsetClientName) { * if so, it's returned; otherwise the associated properties are searched * for a value with the key PropertyDefs.USER_UNSET_NAME_KEY; if that comes * up null, it returns the value of PropertyDefs.USER_UNSET_NAME_DEFAULT. + * @return user name */ public String getUnsetUserName() { if (this.unsetUserName != null) { @@ -390,9 +441,13 @@ public String getUnsetUserName() { throw new NullPointerError("Null properties in UsageOptions"); } return props.getProperty(PropertyDefs.USER_UNSET_NAME_KEY, - PropertyDefs.USER_UNSET_NAME_DEFAULT); + PropertyDefs.USER_UNSET_NAME_DEFAULT); } + /** + * @param unsetUserName user name + * @return usage options + */ public UsageOptions setUnsetUserName(String unsetUserName) { this.unsetUserName = unsetUserName; return this; diff --git a/src/main/java/com/perforce/p4java/option/changelist/SubmitOptions.java b/src/main/java/com/perforce/p4java/option/changelist/SubmitOptions.java index 2425752..1dee25d 100644 --- a/src/main/java/com/perforce/p4java/option/changelist/SubmitOptions.java +++ b/src/main/java/com/perforce/p4java/option/changelist/SubmitOptions.java @@ -1,43 +1,43 @@ /** - * + * */ package com.perforce.p4java.option.changelist; -import java.util.ArrayList; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.ArrayList; +import java.util.List; + /** * Options class for the IChangelist.submit method. */ public class SubmitOptions extends Options { - + /** * Options: -r, -s */ public static final String OPTIONS_SPECS = "b:r b:s"; - + /** * If true, submitted files will remain open (on the client's * default changelist) after the submit has completed. * Corresponds to the -r flag. */ protected boolean reOpen = false; - + /** * If not null, should contain a list of job IDs for jobs that will have * their status changed to fixed or "jobStatus", below. No corresponding * flag.

- * + * * This list will override any jobs already in the changelist's local * job list (usually the result of being fixed elsewhere and picked up * during a refresh of the changelist). */ protected List jobIds = null; - + /** * If not null, should contain a string to which * the jobs in the jobIds list (or local jobs list) will be set on a successful submit; if @@ -56,19 +56,20 @@ public SubmitOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public SubmitOptions(String... options) { @@ -77,9 +78,12 @@ public SubmitOptions(String... options) { /** * Explicit value constructor. + * @param reOpen true/false + * @param jobIds jobID + * @param jobStatus status */ public SubmitOptions(boolean reOpen, List jobIds, - String jobStatus) { + String jobStatus) { super(); this.reOpen = reOpen; this.jobIds = jobIds; @@ -90,14 +94,14 @@ public SubmitOptions(boolean reOpen, List jobIds, * Note that the implementation of the various options here is less straightforward * than for typical server-based Options classes due to the lack of one-to-one correspondence * between options and flags and the need for strict option ordering. - * + * * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { this.optionList = new ArrayList(); this.optionList.addAll(this.processFields(OPTIONS_SPECS, - this.isReOpen(), - this.getJobStatus() == null? false : true)); + this.isReOpen(), + this.getJobStatus() == null ? false : true)); return this.optionList; } diff --git a/src/main/java/com/perforce/p4java/option/client/AddFilesOptions.java b/src/main/java/com/perforce/p4java/option/client/AddFilesOptions.java index f57467c..1cfc68f 100644 --- a/src/main/java/com/perforce/p4java/option/client/AddFilesOptions.java +++ b/src/main/java/com/perforce/p4java/option/client/AddFilesOptions.java @@ -1,32 +1,32 @@ /** - * + * */ package com.perforce.p4java.option.client; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * IClient addFiles method Options definitions. - * - * @see com.perforce.p4java.client.IClient#addFiles(java.util.List, com.perforce.p4java.option.client.AddFilesOptions) + * + * @see com.perforce.p4java.client.IClient#addFiles(java.util.List, com.perforce.p4java.option.client.AddFilesOptions) */ public class AddFilesOptions extends Options { - + /** * Options: -n, -c[changelist], -t[filetype], -f, -I, -Q[charset] */ public static final String OPTIONS_SPECS = "b:n i:c:gtz s:t b:f b:I s:Q"; - + /** * If true, don't actually do the add, just return the files that * would have been opened for addition. */ protected boolean noUpdate = false; - + /** * If positive, the opened files are put into the pending * changelist identified by changelistId (this changelist must have been @@ -34,13 +34,13 @@ public class AddFilesOptions extends Options { * file is opened in the 'default' (unnumbered) changelist. */ protected int changelistId = 0; - + /** * If non-null, the files are added as that filetype. * See 'p4 help filetypes' to attempt to make any sense of Perforce file types. */ protected String fileType = null; - + /** * If true, filenames that contain wildcards are permitted. * See the main Perforce documentation for file adding for details. @@ -51,12 +51,12 @@ public class AddFilesOptions extends Options { * If true, informs the client that it should not perform any ignore checking. */ protected boolean noIgnoreChecking = false; - + /** * If non-null, the files are added using that charset; corresponds to the * undoc '-Q' flag. Please see the 'Versioned character set' section of the * 'p4 help undoc' command for more info.

- * + * * Note that you must set the server.filecharset configurable to 1 in an * unicode Perforce server in order to version the charset of individual * unicode files along with the filetype. @@ -73,19 +73,20 @@ public AddFilesOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public AddFilesOptions(String... options) { @@ -94,9 +95,13 @@ public AddFilesOptions(String... options) { /** * Explicit-value constructor. + * + * @param noUpdate noUpdate + * @param changelistId changelistId + * @param fileType fileType + * @param useWildcards useWildcards */ - public AddFilesOptions(boolean noUpdate, int changelistId, String fileType, - boolean useWildcards) { + public AddFilesOptions(boolean noUpdate, int changelistId, String fileType, boolean useWildcards) { super(); this.noUpdate = noUpdate; this.changelistId = changelistId; @@ -106,9 +111,14 @@ public AddFilesOptions(boolean noUpdate, int changelistId, String fileType, /** * Explicit-value constructor. + * + * @param noUpdate noUpdate + * @param changelistId changelistId + * @param fileType fileType + * @param useWildcards useWildcards + * @param noIgnoreChecking noIgnoreChecking */ - public AddFilesOptions(boolean noUpdate, int changelistId, String fileType, - boolean useWildcards, boolean noIgnoreChecking) { + public AddFilesOptions(boolean noUpdate, int changelistId, String fileType, boolean useWildcards, boolean noIgnoreChecking) { super(); this.noUpdate = noUpdate; this.changelistId = changelistId; @@ -121,13 +131,7 @@ public AddFilesOptions(boolean noUpdate, int changelistId, String fileType, * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.noUpdate, - this.changelistId, - this.fileType, - this.useWildcards, - this.noIgnoreChecking, - this.charset); + this.optionList = this.processFields(OPTIONS_SPECS, this.noUpdate, this.changelistId, this.fileType, this.useWildcards, this.noIgnoreChecking, this.charset); return this.optionList; } @@ -170,7 +174,7 @@ public AddFilesOptions setUseWildcards(boolean useWildcards) { public boolean isNoIgnoreChecking() { return noIgnoreChecking; } - + public AddFilesOptions setNoIgnoreChecking(boolean noIgnoreChecking) { this.noIgnoreChecking = noIgnoreChecking; return this; diff --git a/src/main/java/com/perforce/p4java/option/client/CopyFilesOptions.java b/src/main/java/com/perforce/p4java/option/client/CopyFilesOptions.java index a21bcd2..a47aeb4 100644 --- a/src/main/java/com/perforce/p4java/option/client/CopyFilesOptions.java +++ b/src/main/java/com/perforce/p4java/option/client/CopyFilesOptions.java @@ -3,13 +3,13 @@ */ package com.perforce.p4java.option.client; -import java.util.List; - import com.perforce.p4java.core.IChangelist; import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for the IClient copyFiles method. * @@ -17,329 +17,348 @@ */ public class CopyFilesOptions extends Options { - /** - * Options: -c[changelist], -f, -n, -q, -v, -b[branch], -S[stream], -P[parentStream], -F, -r, -s - */ - public static final String OPTIONS_SPECS = "i:c:cl b:f b:n b:q b:v i:m:gtz s:b s:S s:P b:F b:r b:s"; - - /** - * If positive, use the changelistId given instead of - * the default changelist. Corresponds to the -c option. - */ - protected int changelistId = IChangelist.UNKNOWN; - - /** - * If true, force the creation of extra revisions in order to - * explicitly record that files have been copied. - * Corresponds to -f flag. - */ - protected boolean force = false; - - /** If true, don't actually do the copy. Corresponds to -n flag. */ - protected boolean noUpdate = false; - - /** - * If true, suppresses normal output messages. Messages regarding - * errors or exceptional conditions are not suppressed. - * Corresponds to -q flag. - */ - protected boolean quiet = false; - - /** - * If true, don't do syncing or modifying of client files. - * Corresponds to -v flag. - */ - protected boolean noClientSyncOrMod = false; - - /** - * If true, this is a 'bidirectional' copy. Corresponds - * to -s flag. - */ - protected boolean bidirectional = false; - - /** - * Reverse the mappings in the branch view, with the - * target files and source files exchanging place. - * Corresponds to the -r flag. - */ - protected boolean reverseMapping = false; - - /** - * If positive, copy only the first maxFiles files. - * Corresponds to -m flag. - */ - protected int maxFiles = 0; - - /** - * If non-null, use a user-defined branch view. The source is the left - * side of the branch view and the target is the right side. With -r, - * the direction is reversed. Corresponds to -b flag. - */ - protected String branch = null; - - /** - * If non-null, use this stream's branch view. The source is the stream - * itself, and the target is the stream's parent. With -r, the direction - * is reversed. -P can be used to specify a parent stream other than the - * stream's actual parent. Note that to submit copied stream files, the - * current client must be dedicated to the target stream. - * Corresponds to -S flag. - */ - protected String stream = null; - - /** - * If non-null, specify a parent stream other than the stream's actual - * parent. Corresponds to -P flag. - */ - protected String parentStream = null; - - /** - * If true, used with -S to force copying even though the stream does - * not expect a copy to occur in the direction indicated. Normally - * 'p4 copy' enforces the expected flow of change dictated by the - * stream's spec. The 'p4 istat' command summarizes a stream's expected - * flow of change. Corresponds to -F flag. - */ - protected boolean forceStreamCopy = false; - - /** - * Default constructor. - */ - public CopyFilesOptions() { - super(); - } - - /** - * Strings-based constructor; see 'p4 help [command]' for possible options. - *

- * - * WARNING: you should not pass more than one option or argument in each - * string parameter. Each option or argument should be passed-in as its own - * separate string parameter, without any spaces between the option and the - * option value (if any). - *

- * - * NOTE: setting options this way always bypasses the internal options - * values, and getter methods against the individual values corresponding to - * the strings passed in to this constructor will not normally reflect the - * string's setting. Do not use this constructor unless you know what you're - * doing and / or you do not also use the field getters and setters. - * - * @see com.perforce.p4java.option.Options#Options(java.lang.String...) - */ - public CopyFilesOptions(String... options) { - super(options); - } - - /** - * Explicit-value constructor. - */ - public CopyFilesOptions(int changelistId, boolean noUpdate, - boolean noClientSyncOrMod) { - super(); - this.changelistId = changelistId; - this.noUpdate = noUpdate; - this.noClientSyncOrMod = noClientSyncOrMod; - } - - /** - * Explicit-value constructor. - */ - public CopyFilesOptions(int changelistId, boolean noUpdate, - boolean noClientSyncOrMod, boolean bidirectional) { - super(); - this.changelistId = changelistId; - this.noUpdate = noUpdate; - this.noClientSyncOrMod = noClientSyncOrMod; - this.bidirectional = bidirectional; - } - - /** - * Explicit-value constructor. - */ - public CopyFilesOptions(int changelistId, boolean noUpdate, - boolean noClientSyncOrMod, boolean bidirectional, boolean reverseMapping) { - super(); - this.changelistId = changelistId; - this.noUpdate = noUpdate; - this.noClientSyncOrMod = noClientSyncOrMod; - this.bidirectional = bidirectional; - this.reverseMapping = reverseMapping; - } - - /** - * Explicit-value constructor. - */ - public CopyFilesOptions(int changelistId, boolean noUpdate, - boolean noClientSyncOrMod, boolean bidirectional, boolean reverseMapping, - int maxFiles) { - super(); - this.changelistId = changelistId; - this.noUpdate = noUpdate; - this.noClientSyncOrMod = noClientSyncOrMod; - this.bidirectional = bidirectional; - this.reverseMapping = reverseMapping; - this.maxFiles = maxFiles; - } - - /** - * Explicit-value constructor for use with a branch. - */ - public CopyFilesOptions(int changelistId, boolean noUpdate, - boolean noClientSyncOrMod, int maxFiles, String branch, - boolean reverseMapping, boolean bidirectional) { - super(); - this.changelistId = changelistId; - this.noUpdate = noUpdate; - this.noClientSyncOrMod = noClientSyncOrMod; - this.maxFiles = maxFiles; - this.branch = branch; - this.reverseMapping = reverseMapping; - this.bidirectional = bidirectional; - } - - /** - * Explicit-value constructor for use with a stream. - */ - public CopyFilesOptions(int changelistId, boolean noUpdate, - boolean noClientSyncOrMod, int maxFiles, - String stream, String parentStream, - boolean forceStreamCopy, boolean reverseMapping) { - super(); - this.changelistId = changelistId; - this.noUpdate = noUpdate; - this.noClientSyncOrMod = noClientSyncOrMod; - this.maxFiles = maxFiles; - this.stream = stream; - this.parentStream = parentStream; - this.forceStreamCopy = forceStreamCopy; - this.reverseMapping = reverseMapping; - } - - /** - * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) - */ - public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.getChangelistId(), - this.isForce(), - this.isNoUpdate(), - this.isQuiet(), - this.isNoClientSyncOrMod(), - this.getMaxFiles(), - this.getBranch(), - this.getStream(), - this.getParentStream(), - this.isForceStreamCopy(), - this.isReverseMapping(), - this.isBidirectional()); - return this.optionList; - } - - public int getChangelistId() { - return changelistId; - } - - public CopyFilesOptions setChangelistId(int changelistId) { - this.changelistId = changelistId; - return this; - } - - public boolean isForce() { - return force; - } - - public CopyFilesOptions setForce(boolean force) { - this.force = force; - return this; - } - public boolean isNoUpdate() { - return noUpdate; - } - - public CopyFilesOptions setNoUpdate(boolean noUpdate) { - this.noUpdate = noUpdate; - return this; - } - - public boolean isQuiet() { - return quiet; - } - - public CopyFilesOptions setQuiet(boolean quiet) { - this.quiet = quiet; - return this; - } - - public boolean isNoClientSyncOrMod() { - return noClientSyncOrMod; - } - - public CopyFilesOptions setNoClientSyncOrMod(boolean noClientSyncOrMod) { - this.noClientSyncOrMod = noClientSyncOrMod; - return this; - } - - public boolean isBidirectional() { - return bidirectional; - } - - public CopyFilesOptions setBidirectional(boolean bidirectional) { - this.bidirectional = bidirectional; - return this; - } - - public boolean isReverseMapping() { - return reverseMapping; - } - - public CopyFilesOptions setReverseMapping(boolean reverseMapping) { - this.reverseMapping = reverseMapping; - return this; - } - - public int getMaxFiles() { - return maxFiles; - } - - public CopyFilesOptions setMaxFiles(int maxFiles) { - this.maxFiles = maxFiles; - return this; - } - - public String getBranch() { - return branch; - } - - public CopyFilesOptions setBranch(String branch) { - this.branch = branch; - return this; - } - - public String getStream() { - return stream; - } - - public CopyFilesOptions setStream(String stream) { - this.stream = stream; - return this; - } - - public String getParentStream() { - return parentStream; - } - - public CopyFilesOptions setParentStream(String parentStream) { - this.parentStream = parentStream; - return this; - } - - public boolean isForceStreamCopy() { - return forceStreamCopy; - } - - public CopyFilesOptions setForceStreamCopy(boolean forceStreamCopy) { - this.forceStreamCopy = forceStreamCopy; - return this; - } + /** + * Options: -c[changelist], -f, -n, -q, -v, -b[branch], -S[stream], -P[parentStream], -F, -r, -s + */ + public static final String OPTIONS_SPECS = "i:c:cl b:f b:n b:q b:v i:m:gtz s:b s:S s:P b:F b:r b:s"; + + /** + * If positive, use the changelistId given instead of + * the default changelist. Corresponds to the -c option. + */ + protected int changelistId = IChangelist.UNKNOWN; + + /** + * If true, force the creation of extra revisions in order to + * explicitly record that files have been copied. + * Corresponds to -f flag. + */ + protected boolean force = false; + + /** If true, don't actually do the copy. Corresponds to -n flag. */ + protected boolean noUpdate = false; + + /** + * If true, suppresses normal output messages. Messages regarding + * errors or exceptional conditions are not suppressed. + * Corresponds to -q flag. + */ + protected boolean quiet = false; + + /** + * If true, don't do syncing or modifying of client files. + * Corresponds to -v flag. + */ + protected boolean noClientSyncOrMod = false; + + /** + * If true, this is a 'bidirectional' copy. Corresponds + * to -s flag. + */ + protected boolean bidirectional = false; + + /** + * Reverse the mappings in the branch view, with the + * target files and source files exchanging place. + * Corresponds to the -r flag. + */ + protected boolean reverseMapping = false; + + /** + * If positive, copy only the first maxFiles files. + * Corresponds to -m flag. + */ + protected int maxFiles = 0; + + /** + * If non-null, use a user-defined branch view. The source is the left + * side of the branch view and the target is the right side. With -r, + * the direction is reversed. Corresponds to -b flag. + */ + protected String branch = null; + + /** + * If non-null, use this stream's branch view. The source is the stream + * itself, and the target is the stream's parent. With -r, the direction + * is reversed. -P can be used to specify a parent stream other than the + * stream's actual parent. Note that to submit copied stream files, the + * current client must be dedicated to the target stream. + * Corresponds to -S flag. + */ + protected String stream = null; + + /** + * If non-null, specify a parent stream other than the stream's actual + * parent. Corresponds to -P flag. + */ + protected String parentStream = null; + + /** + * If true, used with -S to force copying even though the stream does + * not expect a copy to occur in the direction indicated. Normally + * 'p4 copy' enforces the expected flow of change dictated by the + * stream's spec. The 'p4 istat' command summarizes a stream's expected + * flow of change. Corresponds to -F flag. + */ + protected boolean forceStreamCopy = false; + + /** + * Default constructor. + */ + public CopyFilesOptions() { + super(); + } + + /** + * Strings-based constructor; see 'p4 help [command]' for possible options. + *

+ * + * WARNING: you should not pass more than one option or argument in each + * string parameter. Each option or argument should be passed-in as its own + * separate string parameter, without any spaces between the option and the + * option value (if any). + *

+ * + * NOTE: setting options this way always bypasses the internal options + * values, and getter methods against the individual values corresponding to + * the strings passed in to this constructor will not normally reflect the + * string's setting. Do not use this constructor unless you know what you're + * doing and / or you do not also use the field getters and setters. + * + * @param options options + * @see com.perforce.p4java.option.Options#Options(java.lang.String...) + */ + public CopyFilesOptions(String... options) { + super(options); + } + + /** + * Explicit-value constructor. + * + * @param changelistId changelistId + * @param noUpdate noUpdate + * @param noClientSyncOrMod noClientSyncOrMod + */ + public CopyFilesOptions(int changelistId, boolean noUpdate, boolean noClientSyncOrMod) { + super(); + this.changelistId = changelistId; + this.noUpdate = noUpdate; + this.noClientSyncOrMod = noClientSyncOrMod; + } + + /** + * Explicit-value constructor. + * + * @param changelistId changelistId + * @param noUpdate noUpdate + * @param noClientSyncOrMod noClientSyncOrMod + * @param bidirectional bidirectional + */ + public CopyFilesOptions(int changelistId, boolean noUpdate, boolean noClientSyncOrMod, boolean bidirectional) { + super(); + this.changelistId = changelistId; + this.noUpdate = noUpdate; + this.noClientSyncOrMod = noClientSyncOrMod; + this.bidirectional = bidirectional; + } + + /** + * Explicit-value constructor. + * + * @param changelistId changelistId + * @param noUpdate noUpdate + * @param noClientSyncOrMod noClientSyncOrMod + * @param bidirectional bidirectional + * @param reverseMapping reverseMapping + */ + public CopyFilesOptions(int changelistId, boolean noUpdate, boolean noClientSyncOrMod, boolean bidirectional, boolean reverseMapping) { + super(); + this.changelistId = changelistId; + this.noUpdate = noUpdate; + this.noClientSyncOrMod = noClientSyncOrMod; + this.bidirectional = bidirectional; + this.reverseMapping = reverseMapping; + } + + /** + * Explicit-value constructor. + * + * @param changelistId changelistId + * @param noUpdate noUpdate + * @param noClientSyncOrMod noClientSyncOrMod + * @param bidirectional bidirectional + * @param reverseMapping reverseMapping + * @param maxFiles maxFiles + */ + public CopyFilesOptions(int changelistId, boolean noUpdate, boolean noClientSyncOrMod, boolean bidirectional, boolean reverseMapping, int maxFiles) { + super(); + this.changelistId = changelistId; + this.noUpdate = noUpdate; + this.noClientSyncOrMod = noClientSyncOrMod; + this.bidirectional = bidirectional; + this.reverseMapping = reverseMapping; + this.maxFiles = maxFiles; + } + + /** + * Explicit-value constructor for use with a branch. + * + * @param changelistId changelistId + * @param noUpdate noUpdate + * @param noClientSyncOrMod noClientSyncOrMod + * @param maxFiles maxFiles + * @param branch branch + * @param reverseMapping reverseMapping + * @param bidirectional bidirectional + */ + public CopyFilesOptions(int changelistId, boolean noUpdate, boolean noClientSyncOrMod, int maxFiles, String branch, boolean reverseMapping, boolean bidirectional) { + super(); + this.changelistId = changelistId; + this.noUpdate = noUpdate; + this.noClientSyncOrMod = noClientSyncOrMod; + this.maxFiles = maxFiles; + this.branch = branch; + this.reverseMapping = reverseMapping; + this.bidirectional = bidirectional; + } + + /** + * Explicit-value constructor for use with a stream. + * + * @param changelistId changelistId + * @param noUpdate noUpdate + * @param noClientSyncOrMod noClientSyncOrMod + * @param maxFiles maxFiles + * @param stream stream + * @param parentStream parentStream + * @param forceStreamCopy forceStreamCopy + * @param reverseMapping reverseMapping + */ + public CopyFilesOptions(int changelistId, boolean noUpdate, boolean noClientSyncOrMod, int maxFiles, String stream, String parentStream, boolean forceStreamCopy, boolean reverseMapping) { + super(); + this.changelistId = changelistId; + this.noUpdate = noUpdate; + this.noClientSyncOrMod = noClientSyncOrMod; + this.maxFiles = maxFiles; + this.stream = stream; + this.parentStream = parentStream; + this.forceStreamCopy = forceStreamCopy; + this.reverseMapping = reverseMapping; + } + + /** + * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) + */ + public List processOptions(IServer server) throws OptionsException { + this.optionList = this.processFields(OPTIONS_SPECS, this.getChangelistId(), this.isForce(), this.isNoUpdate(), this.isQuiet(), this.isNoClientSyncOrMod(), this.getMaxFiles(), this.getBranch(), this.getStream(), this.getParentStream(), this.isForceStreamCopy(), this.isReverseMapping(), this.isBidirectional()); + return this.optionList; + } + + public int getChangelistId() { + return changelistId; + } + + public CopyFilesOptions setChangelistId(int changelistId) { + this.changelistId = changelistId; + return this; + } + + public boolean isForce() { + return force; + } + + public CopyFilesOptions setForce(boolean force) { + this.force = force; + return this; + } + + public boolean isNoUpdate() { + return noUpdate; + } + + public CopyFilesOptions setNoUpdate(boolean noUpdate) { + this.noUpdate = noUpdate; + return this; + } + + public boolean isQuiet() { + return quiet; + } + + public CopyFilesOptions setQuiet(boolean quiet) { + this.quiet = quiet; + return this; + } + + public boolean isNoClientSyncOrMod() { + return noClientSyncOrMod; + } + + public CopyFilesOptions setNoClientSyncOrMod(boolean noClientSyncOrMod) { + this.noClientSyncOrMod = noClientSyncOrMod; + return this; + } + + public boolean isBidirectional() { + return bidirectional; + } + + public CopyFilesOptions setBidirectional(boolean bidirectional) { + this.bidirectional = bidirectional; + return this; + } + + public boolean isReverseMapping() { + return reverseMapping; + } + + public CopyFilesOptions setReverseMapping(boolean reverseMapping) { + this.reverseMapping = reverseMapping; + return this; + } + + public int getMaxFiles() { + return maxFiles; + } + + public CopyFilesOptions setMaxFiles(int maxFiles) { + this.maxFiles = maxFiles; + return this; + } + + public String getBranch() { + return branch; + } + + public CopyFilesOptions setBranch(String branch) { + this.branch = branch; + return this; + } + + public String getStream() { + return stream; + } + + public CopyFilesOptions setStream(String stream) { + this.stream = stream; + return this; + } + + public String getParentStream() { + return parentStream; + } + + public CopyFilesOptions setParentStream(String parentStream) { + this.parentStream = parentStream; + return this; + } + + public boolean isForceStreamCopy() { + return forceStreamCopy; + } + + public CopyFilesOptions setForceStreamCopy(boolean forceStreamCopy) { + this.forceStreamCopy = forceStreamCopy; + return this; + } } diff --git a/src/main/java/com/perforce/p4java/option/client/DeleteFilesOptions.java b/src/main/java/com/perforce/p4java/option/client/DeleteFilesOptions.java index 99d92a7..9391ffb 100644 --- a/src/main/java/com/perforce/p4java/option/client/DeleteFilesOptions.java +++ b/src/main/java/com/perforce/p4java/option/client/DeleteFilesOptions.java @@ -3,13 +3,13 @@ */ package com.perforce.p4java.option.client; -import java.util.List; - import com.perforce.p4java.core.IChangelist; import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options-based method options for IClient deleteFiles method(s). * @@ -17,140 +17,144 @@ */ public class DeleteFilesOptions extends Options { - /** - * Options: -c[changelist], -n, -v, -k - */ - public static final String OPTIONS_SPECS = "i:c:clz b:n b:v b:k"; - - /** - * If positive, the deleted files are put into the pending - * changelist identified by changelistId (this changelist must have been - * previously created for this to succeed). If zero or negative, the - * file is opened in the 'default' (unnumbered) changelist. - * Corresponds to the -c flag. - */ - protected int changelistId = IChangelist.DEFAULT; - - /** - * If true, don't actually do the deletes, just return the files that - * would have been opened for deletion. Corresponds to the -n flag. - */ - protected boolean noUpdate = false; - - /** - * If true, delete files that are not synced into the client workspace. - * Corresponds to the -v flag. - */ - protected boolean deleteNonSyncedFiles = false; - - /** - * If true, bypass deleting files on the client workspace. The -k flag - * performs the delete on the server without modifying client files. Use - * with caution, as an incorrect delete can cause discrepancies between - * the state of the client and the corresponding server metadata. - * Corresponds to the -k flag. - */ - protected boolean bypassClientDelete = false; - - /** - * Default constructor. - */ - public DeleteFilesOptions() { - super(); - } - - /** - * Strings-based constructor; see 'p4 help [command]' for possible options. - *

- * - * WARNING: you should not pass more than one option or argument in each - * string parameter. Each option or argument should be passed-in as its own - * separate string parameter, without any spaces between the option and the - * option value (if any). - *

- * - * NOTE: setting options this way always bypasses the internal options - * values, and getter methods against the individual values corresponding to - * the strings passed in to this constructor will not normally reflect the - * string's setting. Do not use this constructor unless you know what you're - * doing and / or you do not also use the field getters and setters. - * - * @see com.perforce.p4java.option.Options#Options(java.lang.String...) - */ - public DeleteFilesOptions(String... options) { - super(options); - } - - - /** - * Explicit-value constructor. - */ - public DeleteFilesOptions(int changelistId, boolean noUpdate, - boolean deleteNonSyncedFiles) { - super(); - this.changelistId = changelistId; - this.noUpdate = noUpdate; - this.deleteNonSyncedFiles = deleteNonSyncedFiles; - } - - /** - * Explicit-value constructor. - */ - public DeleteFilesOptions(int changelistId, boolean noUpdate, - boolean deleteNonSyncedFiles, boolean bypassClientDelete) { - super(); - this.changelistId = changelistId; - this.noUpdate = noUpdate; - this.deleteNonSyncedFiles = deleteNonSyncedFiles; - this.bypassClientDelete = bypassClientDelete; - } - - /** - * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) - */ - public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.changelistId, - this.noUpdate, - this.deleteNonSyncedFiles, - this.bypassClientDelete); - - return this.optionList; - } - - public int getChangelistId() { - return changelistId; - } - - public DeleteFilesOptions setChangelistId(int changelistId) { - this.changelistId = changelistId; - return this; - } - - public boolean isNoUpdate() { - return noUpdate; - } - - public DeleteFilesOptions setNoUpdate(boolean noUpdate) { - this.noUpdate = noUpdate; - return this; - } - - public boolean isDeleteNonSyncedFiles() { - return deleteNonSyncedFiles; - } - - public DeleteFilesOptions setDeleteNonSyncedFiles(boolean deleteNonSyncedFiles) { - this.deleteNonSyncedFiles = deleteNonSyncedFiles; - return this; - } - - public boolean isBypassClientDelete() { - return bypassClientDelete; - } - - public DeleteFilesOptions setBypassClientDelete(boolean bypassClientDelete) { - this.bypassClientDelete = bypassClientDelete; - return this; - } + /** + * Options: -c[changelist], -n, -v, -k + */ + public static final String OPTIONS_SPECS = "i:c:clz b:n b:v b:k"; + + /** + * If positive, the deleted files are put into the pending + * changelist identified by changelistId (this changelist must have been + * previously created for this to succeed). If zero or negative, the + * file is opened in the 'default' (unnumbered) changelist. + * Corresponds to the -c flag. + */ + protected int changelistId = IChangelist.DEFAULT; + + /** + * If true, don't actually do the deletes, just return the files that + * would have been opened for deletion. Corresponds to the -n flag. + */ + protected boolean noUpdate = false; + + /** + * If true, delete files that are not synced into the client workspace. + * Corresponds to the -v flag. + */ + protected boolean deleteNonSyncedFiles = false; + + /** + * If true, bypass deleting files on the client workspace. The -k flag + * performs the delete on the server without modifying client files. Use + * with caution, as an incorrect delete can cause discrepancies between + * the state of the client and the corresponding server metadata. + * Corresponds to the -k flag. + */ + protected boolean bypassClientDelete = false; + + /** + * Default constructor. + */ + public DeleteFilesOptions() { + super(); + } + + /** + * Strings-based constructor; see 'p4 help [command]' for possible options. + *

+ * + * WARNING: you should not pass more than one option or argument in each + * string parameter. Each option or argument should be passed-in as its own + * separate string parameter, without any spaces between the option and the + * option value (if any). + *

+ * + * NOTE: setting options this way always bypasses the internal options + * values, and getter methods against the individual values corresponding to + * the strings passed in to this constructor will not normally reflect the + * string's setting. Do not use this constructor unless you know what you're + * doing and / or you do not also use the field getters and setters. + * + * @param options options + * @see com.perforce.p4java.option.Options#Options(java.lang.String...) + */ + public DeleteFilesOptions(String... options) { + super(options); + } + + + /** + * Explicit-value constructor. + * + * @param changelistId changelistId + * @param noUpdate noUpdate + * @param deleteNonSyncedFiles deleteNonSyncedFiles + */ + public DeleteFilesOptions(int changelistId, boolean noUpdate, boolean deleteNonSyncedFiles) { + super(); + this.changelistId = changelistId; + this.noUpdate = noUpdate; + this.deleteNonSyncedFiles = deleteNonSyncedFiles; + } + + /** + * Explicit-value constructor. + * + * @param changelistId changelistId + * @param noUpdate noUpdate + * @param deleteNonSyncedFiles deleteNonSyncedFiles + * @param bypassClientDelete bypassClientDelete + */ + public DeleteFilesOptions(int changelistId, boolean noUpdate, boolean deleteNonSyncedFiles, boolean bypassClientDelete) { + super(); + this.changelistId = changelistId; + this.noUpdate = noUpdate; + this.deleteNonSyncedFiles = deleteNonSyncedFiles; + this.bypassClientDelete = bypassClientDelete; + } + + /** + * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) + */ + public List processOptions(IServer server) throws OptionsException { + this.optionList = this.processFields(OPTIONS_SPECS, this.changelistId, this.noUpdate, this.deleteNonSyncedFiles, this.bypassClientDelete); + + return this.optionList; + } + + public int getChangelistId() { + return changelistId; + } + + public DeleteFilesOptions setChangelistId(int changelistId) { + this.changelistId = changelistId; + return this; + } + + public boolean isNoUpdate() { + return noUpdate; + } + + public DeleteFilesOptions setNoUpdate(boolean noUpdate) { + this.noUpdate = noUpdate; + return this; + } + + public boolean isDeleteNonSyncedFiles() { + return deleteNonSyncedFiles; + } + + public DeleteFilesOptions setDeleteNonSyncedFiles(boolean deleteNonSyncedFiles) { + this.deleteNonSyncedFiles = deleteNonSyncedFiles; + return this; + } + + public boolean isBypassClientDelete() { + return bypassClientDelete; + } + + public DeleteFilesOptions setBypassClientDelete(boolean bypassClientDelete) { + this.bypassClientDelete = bypassClientDelete; + return this; + } } diff --git a/src/main/java/com/perforce/p4java/option/client/EditFilesOptions.java b/src/main/java/com/perforce/p4java/option/client/EditFilesOptions.java index f9fb9f8..d171a5b 100644 --- a/src/main/java/com/perforce/p4java/option/client/EditFilesOptions.java +++ b/src/main/java/com/perforce/p4java/option/client/EditFilesOptions.java @@ -1,37 +1,37 @@ /** - * + * */ package com.perforce.p4java.option.client; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options subclass for use with IClient editFiles method(s). - * + * * @see com.perforce.p4java.client.IClient#editFiles(java.util.List, com.perforce.p4java.option.client.EditFilesOptions) */ public class EditFilesOptions extends Options { - + /** * Options: -n, -k, -c[changelist], -t[filetype], -Q[charset] */ public static final String OPTIONS_SPECS = "b:n b:k i:c:gtz s:t s:Q b:So"; - + /** * If true, don't actually do the edit, just return the files that * would have been opened for edit. Corresponds to the -n flag. */ protected boolean noUpdate = false; - + /** * If true, bypass updating the client. Corresponds to the -k flag. */ protected boolean bypassClientUpdate = false; - + /** * If positive, the opened files are put into the pending * changelist identified by changelistId (this changelist must have been @@ -40,7 +40,7 @@ public class EditFilesOptions extends Options { * Corresponds to the -c flag. */ protected int changelistId = 0; - + /** * If non-null, the files are added as that filetype. See 'p4 help filetypes' * to attempt to make any sense of Perforce file types. @@ -52,7 +52,7 @@ public class EditFilesOptions extends Options { * If non-null, the files are edited using that charset; corresponds to the * undoc '-Q' flag. Please see the 'Versioned character set' section of the * 'p4 help undoc' command for more info.

- * + * * Note that you must set the server.filecharset configurable to 1 in an * unicode Perforce server in order to version the charset of individual * unicode files along with the filetype. @@ -75,19 +75,20 @@ public EditFilesOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public EditFilesOptions(String... options) { @@ -96,9 +97,13 @@ public EditFilesOptions(String... options) { /** * Explicit-value constructor. + * + * @param noUpdate noUpdate + * @param bypassClientUpdate bypassClientUpdate + * @param changelistId changelistId + * @param fileType fileType */ - public EditFilesOptions(boolean noUpdate, boolean bypassClientUpdate, - int changelistId, String fileType) { + public EditFilesOptions(boolean noUpdate, boolean bypassClientUpdate, int changelistId, String fileType) { super(); this.noUpdate = noUpdate; this.bypassClientUpdate = bypassClientUpdate; @@ -110,13 +115,7 @@ public EditFilesOptions(boolean noUpdate, boolean bypassClientUpdate, * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.noUpdate, - this.bypassClientUpdate, - this.changelistId, - this.fileType, - this.charset, - this.editStreamSpec); + this.optionList = this.processFields(OPTIONS_SPECS, this.noUpdate, this.bypassClientUpdate, this.changelistId, this.fileType, this.charset, this.editStreamSpec); return this.optionList; } diff --git a/src/main/java/com/perforce/p4java/option/client/GetDiffFilesOptions.java b/src/main/java/com/perforce/p4java/option/client/GetDiffFilesOptions.java index 75e5488..2a7a6ab 100644 --- a/src/main/java/com/perforce/p4java/option/client/GetDiffFilesOptions.java +++ b/src/main/java/com/perforce/p4java/option/client/GetDiffFilesOptions.java @@ -1,66 +1,66 @@ /** - * + * */ package com.perforce.p4java.option.client; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options subclass for the IClient.getDiffFiles method. - * + * * @see com.perforce.p4java.client.IClient#getDiffFiles(java.util.List, com.perforce.p4java.option.client.GetDiffFilesOptions) */ public class GetDiffFilesOptions extends Options { - + /** * Options: -m[max], -t, -s[x] */ public static final String OPTIONS_SPECS = "i:m:gtz b:t b:sa b:sb b:sd b:se b:sl b:sr"; - + /** * If non-zero, return only this many results. Corresponds to -m flag. */ protected int maxFiles = 0; - + /** * If true, diff non-text files. Corresponds to -t flag. */ protected boolean diffNonTextFiles = false; - + /** * If true, report opened files that are different from the revision in the depot, * or missing. Corresponds to -sa. */ protected boolean openedDifferentMissing = false; - + /** * If true, report files that are opened for integrate. Corresponds to -sb flag. */ protected boolean openedForIntegrate = false; - + /** * If true, report unopened files that are missing on the client. Corresponds * to -sd. */ protected boolean unopenedMissing = false; - + /** * If true, report unopened files that are different from the revision * in the depot. Corresponds to -se flag. */ protected boolean unopenedDifferent = false; - + /** * If true, report every unopened file, along with the status of * 'same, 'diff', or 'missing' as compared to its * revision in the depot. Corresponds to -sl. */ protected boolean unopenedWithStatus = false; - + /** * If true, report opened files that are the same as the revision in the depot. * Corresponds to -sr. @@ -77,19 +77,20 @@ public GetDiffFilesOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public GetDiffFilesOptions(String... options) { @@ -98,11 +99,17 @@ public GetDiffFilesOptions(String... options) { /** * Explicit-value constructor. + * + * @param maxFiles maxFiles + * @param diffNonTextFiles diffNonTextFiles + * @param openedDifferentMissing openedDifferentMissing + * @param openedForIntegrate openedForIntegrate + * @param unopenedMissing unopenedMissing + * @param unopenedDifferent unopenedDifferent + * @param unopenedWithStatus unopenedWithStatus + * @param openedSame openedSame */ - public GetDiffFilesOptions(int maxFiles, boolean diffNonTextFiles, - boolean openedDifferentMissing, boolean openedForIntegrate, - boolean unopenedMissing, boolean unopenedDifferent, - boolean unopenedWithStatus, boolean openedSame) { + public GetDiffFilesOptions(int maxFiles, boolean diffNonTextFiles, boolean openedDifferentMissing, boolean openedForIntegrate, boolean unopenedMissing, boolean unopenedDifferent, boolean unopenedWithStatus, boolean openedSame) { super(); this.maxFiles = maxFiles; this.diffNonTextFiles = diffNonTextFiles; @@ -118,17 +125,8 @@ public GetDiffFilesOptions(int maxFiles, boolean diffNonTextFiles, * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.getMaxFiles(), - this.isDiffNonTextFiles(), - this.isOpenedDifferentMissing(), - this.isOpenedForIntegrate(), - this.isUnopenedMissing(), - this.isUnopenedDifferent(), - this.isUnopenedWithStatus(), - this.isOpenedSame() - ); - + this.optionList = this.processFields(OPTIONS_SPECS, this.getMaxFiles(), this.isDiffNonTextFiles(), this.isOpenedDifferentMissing(), this.isOpenedForIntegrate(), this.isUnopenedMissing(), this.isUnopenedDifferent(), this.isUnopenedWithStatus(), this.isOpenedSame()); + return this.optionList; } diff --git a/src/main/java/com/perforce/p4java/option/client/IntegrateFilesOptions.java b/src/main/java/com/perforce/p4java/option/client/IntegrateFilesOptions.java index 445c0a7..bcbe4b6 100644 --- a/src/main/java/com/perforce/p4java/option/client/IntegrateFilesOptions.java +++ b/src/main/java/com/perforce/p4java/option/client/IntegrateFilesOptions.java @@ -12,12 +12,12 @@ import java.util.List; /** - * Options for the IClient.integrateFiles method.

+ * Options for the IClient.integrateFiles method. *

* Note that this implementation extends the normal default * options processing with its own method(s) due to the complexity * of the various -D and -R flag options; note also the somewhat odd - * relationship with the previous IntegrationOptions class.

+ * relationship with the previous IntegrationOptions class. *

* Note also that the current implementation makes no attempt * to validate the sanity or otherwise of the various options and @@ -206,12 +206,10 @@ public IntegrateFilesOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- *

* WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). - *

+ * option value (if any). *

* NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to @@ -219,6 +217,7 @@ public IntegrateFilesOptions() { * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public IntegrateFilesOptions(String... options) { @@ -227,16 +226,24 @@ public IntegrateFilesOptions(String... options) { /** * Explicit-value constructor. - */ - public IntegrateFilesOptions(int changelistId, - boolean bidirectionalInteg, - boolean integrateAroundDeletedRevs, - boolean rebranchSourceAfterDelete, boolean deleteTargetAfterDelete, - boolean integrateAllAfterReAdd, boolean forceIntegration, - boolean useHaveRev, boolean doBaselessMerge, - boolean displayBaseDetails, boolean showActionsOnly, - boolean reverseMapping, boolean propagateType, - boolean dontCopyToClient, int maxFiles) { + * + * @param changelistId changelistId + * @param bidirectionalInteg bidirectionalInteg + * @param integrateAroundDeletedRevs integrateAroundDeletedRevs + * @param rebranchSourceAfterDelete rebranchSourceAfterDelete + * @param deleteTargetAfterDelete deleteTargetAfterDelete + * @param integrateAllAfterReAdd integrateAllAfterReAdd + * @param forceIntegration forceIntegration + * @param useHaveRev useHaveRev + * @param doBaselessMerge doBaselessMerge + * @param displayBaseDetails displayBaseDetails + * @param showActionsOnly showActionsOnly + * @param reverseMapping reverseMapping + * @param propagateType propagateType + * @param dontCopyToClient dontCopyToClient + * @param maxFiles maxFiles + */ + public IntegrateFilesOptions(int changelistId, boolean bidirectionalInteg, boolean integrateAroundDeletedRevs, boolean rebranchSourceAfterDelete, boolean deleteTargetAfterDelete, boolean integrateAllAfterReAdd, boolean forceIntegration, boolean useHaveRev, boolean doBaselessMerge, boolean displayBaseDetails, boolean showActionsOnly, boolean reverseMapping, boolean propagateType, boolean dontCopyToClient, int maxFiles) { super(); this.changelistId = changelistId; this.bidirectionalInteg = bidirectionalInteg; @@ -257,18 +264,27 @@ public IntegrateFilesOptions(int changelistId, /** * Explicit-value constructor. - */ - public IntegrateFilesOptions(int changelistId, - boolean bidirectionalInteg, - boolean integrateAroundDeletedRevs, - boolean rebranchSourceAfterDelete, boolean deleteTargetAfterDelete, - boolean integrateAllAfterReAdd, - boolean branchResolves, boolean deleteResolves, - boolean skipIntegratedRevs, boolean forceIntegration, - boolean useHaveRev, boolean doBaselessMerge, - boolean displayBaseDetails, boolean showActionsOnly, - boolean reverseMapping, boolean propagateType, - boolean dontCopyToClient, int maxFiles) { + * + * @param changelistId changelistId + * @param bidirectionalInteg bidirectionalInteg + * @param integrateAroundDeletedRevs integrateAroundDeletedRevs + * @param rebranchSourceAfterDelete rebranchSourceAfterDelete + * @param deleteTargetAfterDelete deleteTargetAfterDelete + * @param integrateAllAfterReAdd integrateAllAfterReAdd + * @param branchResolves branchResolves + * @param deleteResolves deleteResolves + * @param skipIntegratedRevs skipIntegratedRevs + * @param forceIntegration forceIntegration + * @param useHaveRev useHaveRev + * @param doBaselessMerge doBaselessMerge + * @param displayBaseDetails displayBaseDetails + * @param showActionsOnly showActionsOnly + * @param reverseMapping reverseMapping + * @param propagateType propagateType + * @param dontCopyToClient dontCopyToClient + * @param maxFiles maxFiles + */ + public IntegrateFilesOptions(int changelistId, boolean bidirectionalInteg, boolean integrateAroundDeletedRevs, boolean rebranchSourceAfterDelete, boolean deleteTargetAfterDelete, boolean integrateAllAfterReAdd, boolean branchResolves, boolean deleteResolves, boolean skipIntegratedRevs, boolean forceIntegration, boolean useHaveRev, boolean doBaselessMerge, boolean displayBaseDetails, boolean showActionsOnly, boolean reverseMapping, boolean propagateType, boolean dontCopyToClient, int maxFiles) { super(); this.changelistId = changelistId; this.bidirectionalInteg = bidirectionalInteg; @@ -292,18 +308,28 @@ public IntegrateFilesOptions(int changelistId, /** * Explicit-value constructor for use with a branch. - */ - public IntegrateFilesOptions(int changelistId, - boolean integrateAroundDeletedRevs, - boolean rebranchSourceAfterDelete, boolean deleteTargetAfterDelete, - boolean integrateAllAfterReAdd, - boolean branchResolves, boolean deleteResolves, - boolean skipIntegratedRevs, boolean forceIntegration, - boolean useHaveRev, boolean doBaselessMerge, - boolean displayBaseDetails, boolean showActionsOnly, - boolean propagateType, boolean dontCopyToClient, - int maxFiles, String branch, - boolean reverseMapping, boolean bidirectionalInteg) { + * + * @param changelistId changelistId + * @param integrateAroundDeletedRevs integrateAroundDeletedRevs + * @param rebranchSourceAfterDelete rebranchSourceAfterDelete + * @param deleteTargetAfterDelete deleteTargetAfterDelete + * @param integrateAllAfterReAdd integrateAllAfterReAdd + * @param branchResolves branchResolves + * @param deleteResolves deleteResolves + * @param skipIntegratedRevs skipIntegratedRevs + * @param forceIntegration forceIntegration + * @param useHaveRev useHaveRev + * @param doBaselessMerge doBaselessMerge + * @param displayBaseDetails displayBaseDetails + * @param showActionsOnly showActionsOnly + * @param propagateType propagateType + * @param dontCopyToClient dontCopyToClient + * @param maxFiles maxFiles + * @param branch branch + * @param reverseMapping reverseMapping + * @param bidirectionalInteg bidirectionalInteg + */ + public IntegrateFilesOptions(int changelistId, boolean integrateAroundDeletedRevs, boolean rebranchSourceAfterDelete, boolean deleteTargetAfterDelete, boolean integrateAllAfterReAdd, boolean branchResolves, boolean deleteResolves, boolean skipIntegratedRevs, boolean forceIntegration, boolean useHaveRev, boolean doBaselessMerge, boolean displayBaseDetails, boolean showActionsOnly, boolean propagateType, boolean dontCopyToClient, int maxFiles, String branch, boolean reverseMapping, boolean bidirectionalInteg) { super(); this.changelistId = changelistId; this.integrateAroundDeletedRevs = integrateAroundDeletedRevs; @@ -328,18 +354,28 @@ public IntegrateFilesOptions(int changelistId, /** * Explicit-value constructor for use with a stream. - */ - public IntegrateFilesOptions(int changelistId, - boolean integrateAroundDeletedRevs, - boolean rebranchSourceAfterDelete, boolean deleteTargetAfterDelete, - boolean integrateAllAfterReAdd, - boolean branchResolves, boolean deleteResolves, - boolean skipIntegratedRevs, boolean forceIntegration, - boolean useHaveRev, boolean doBaselessMerge, - boolean displayBaseDetails, boolean showActionsOnly, - boolean propagateType, boolean dontCopyToClient, - int maxFiles, String stream, - String parentStream, boolean reverseMapping) { + * + * @param changelistId changelistId + * @param integrateAroundDeletedRevs integrateAroundDeletedRevs + * @param rebranchSourceAfterDelete rebranchSourceAfterDelete + * @param deleteTargetAfterDelete deleteTargetAfterDelete + * @param integrateAllAfterReAdd integrateAllAfterReAdd + * @param branchResolves branchResolves + * @param deleteResolves deleteResolves + * @param skipIntegratedRevs skipIntegratedRevs + * @param forceIntegration forceIntegration + * @param useHaveRev useHaveRev + * @param doBaselessMerge doBaselessMerge + * @param displayBaseDetails displayBaseDetails + * @param showActionsOnly showActionsOnly + * @param propagateType propagateType + * @param dontCopyToClient dontCopyToClient + * @param maxFiles maxFiles + * @param stream stream + * @param parentStream parentStream + * @param reverseMapping reverseMapping + */ + public IntegrateFilesOptions(int changelistId, boolean integrateAroundDeletedRevs, boolean rebranchSourceAfterDelete, boolean deleteTargetAfterDelete, boolean integrateAllAfterReAdd, boolean branchResolves, boolean deleteResolves, boolean skipIntegratedRevs, boolean forceIntegration, boolean useHaveRev, boolean doBaselessMerge, boolean displayBaseDetails, boolean showActionsOnly, boolean propagateType, boolean dontCopyToClient, int maxFiles, String stream, String parentStream, boolean reverseMapping) { super(); this.changelistId = changelistId; this.integrateAroundDeletedRevs = integrateAroundDeletedRevs; @@ -366,32 +402,7 @@ public IntegrateFilesOptions(int changelistId, * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.getChangelistId(), - this.isIntegrateAroundDeletedRevs(), - this.isIntegrateAllAfterReAdd(), - this.isDeleteTargetAfterDelete(), - this.isRebranchSourceAfterDelete(), - this.isBranchResolves(), - this.isDeleteResolves(), - this.isSkipIntegratedRevs(), - this.isForceIntegration(), - this.isUseHaveRev(), - this.isDoBaselessMerge(), - this.isDisplayBaseDetails(), - this.isShowActionsOnly(), - this.isPropagateType(), - this.isQuiet(), - this.isDontCopyToClient(), - this.getMaxFiles(), - this.getBranch(), - this.getStream(), - this.getParentStream(), - this.isReverseMapping(), - this.isBidirectionalInteg(), - this.isShowBaseRevision(), - this.isShowScheduledResolve(), - this.isInteg2()); + this.optionList = this.processFields(OPTIONS_SPECS, this.getChangelistId(), this.isIntegrateAroundDeletedRevs(), this.isIntegrateAllAfterReAdd(), this.isDeleteTargetAfterDelete(), this.isRebranchSourceAfterDelete(), this.isBranchResolves(), this.isDeleteResolves(), this.isSkipIntegratedRevs(), this.isForceIntegration(), this.isUseHaveRev(), this.isDoBaselessMerge(), this.isDisplayBaseDetails(), this.isShowActionsOnly(), this.isPropagateType(), this.isQuiet(), this.isDontCopyToClient(), this.getMaxFiles(), this.getBranch(), this.getStream(), this.getParentStream(), this.isReverseMapping(), this.isBidirectionalInteg(), this.isShowBaseRevision(), this.isShowScheduledResolve(), this.isInteg2()); combineGroupOptions("-R"); combineGroupOptions("-O"); diff --git a/src/main/java/com/perforce/p4java/option/client/LabelSyncOptions.java b/src/main/java/com/perforce/p4java/option/client/LabelSyncOptions.java index 9fe67ff..a6a3253 100644 --- a/src/main/java/com/perforce/p4java/option/client/LabelSyncOptions.java +++ b/src/main/java/com/perforce/p4java/option/client/LabelSyncOptions.java @@ -1,33 +1,33 @@ /** - * + * */ package com.perforce.p4java.option.client; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Label sync options subclass for use with IClient.labelSync. - * + * * @see com.perforce.p4java.client.IClient#labelSync(java.util.List, java.lang.String, com.perforce.p4java.option.client.LabelSyncOptions) */ public class LabelSyncOptions extends Options { - + /** * Options: -n, -a, -d */ public static final String OPTIONS_SPECS = "b:n b:a b:d"; - + /** If true, don't actually do the update (c.f. the p4 -n flag) */ protected boolean noUpdate = false; - + /** If true, add the files in fileSpecs to the label * (c.f. the p4 -a flag) */ protected boolean addFiles = false; - + /** If true, delete the files in fileSpecs from the label * (c.f. the p4 -d flag) */ protected boolean deleteFiles = false; @@ -42,27 +42,32 @@ public LabelSyncOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public LabelSyncOptions(String... options) { super(options); } - + /** * Explicit-value constructor. + * + * @param noUpdate noUpdate + * @param addFiles addFiles + * @param deleteFiles deleteFiles */ public LabelSyncOptions(boolean noUpdate, boolean addFiles, boolean deleteFiles) { super(); @@ -75,10 +80,7 @@ public LabelSyncOptions(boolean noUpdate, boolean addFiles, boolean deleteFiles) * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.noUpdate, - this.addFiles, - this.deleteFiles); + this.optionList = this.processFields(OPTIONS_SPECS, this.noUpdate, this.addFiles, this.deleteFiles); return this.optionList; } diff --git a/src/main/java/com/perforce/p4java/option/client/LockFilesOptions.java b/src/main/java/com/perforce/p4java/option/client/LockFilesOptions.java index a5a44ad..e3bb6fb 100644 --- a/src/main/java/com/perforce/p4java/option/client/LockFilesOptions.java +++ b/src/main/java/com/perforce/p4java/option/client/LockFilesOptions.java @@ -1,27 +1,27 @@ /** - * + * */ package com.perforce.p4java.option.client; -import java.util.List; - import com.perforce.p4java.core.IChangelist; import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options subclass for IClient.lockFiles. - * + * * @see com.perforce.p4java.client.IClient#lockFiles(java.util.List, com.perforce.p4java.option.client.LockFilesOptions) */ public class LockFilesOptions extends Options { - + /** * Options: -c[changelist] */ public static final String OPTIONS_SPECS = "i:c:cl"; - + /** * If positive, use the changelistId given instead of * the default changelist. Corresponds to the -c option. @@ -38,19 +38,20 @@ public LockFilesOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public LockFilesOptions(String... options) { @@ -59,6 +60,8 @@ public LockFilesOptions(String... options) { /** * Explicit-value constructor. + * + * @param changelistId changelistId */ public LockFilesOptions(int changelistId) { super(); @@ -69,9 +72,7 @@ public LockFilesOptions(int changelistId) { * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.getChangelistId() - ); + this.optionList = this.processFields(OPTIONS_SPECS, this.getChangelistId()); return this.optionList; } diff --git a/src/main/java/com/perforce/p4java/option/client/MergeFilesOptions.java b/src/main/java/com/perforce/p4java/option/client/MergeFilesOptions.java index 034ce4e..2f9ebb9 100644 --- a/src/main/java/com/perforce/p4java/option/client/MergeFilesOptions.java +++ b/src/main/java/com/perforce/p4java/option/client/MergeFilesOptions.java @@ -3,14 +3,14 @@ */ package com.perforce.p4java.option.client; -import java.util.List; - import com.perforce.p4java.core.IChangelist; import com.perforce.p4java.core.file.IFileSpec; import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options for the IClient.mergeFiles method.

* @@ -22,247 +22,249 @@ */ public class MergeFilesOptions extends Options { - /** - * Options: -c[changelist], -n, -q, -m[max], -b[branch], -S[stream], -P[parentStream], -F, -r, -s - */ - public static final String OPTIONS_SPECS = "i:c:clz b:n b:q i:m:gtz s:b s:S s:P b:F b:r b:s"; - - /** - * If positive, the integrated files are opened in the numbered - * pending changelist instead of the default changelist. - */ - protected int changelistId = IChangelist.UNKNOWN; - - /** - * Cause the branch view to work bidirectionally, where the scope of - * the command is limited to integrations whose 'from' files match - * fromFile[revRange]. Corresponds to the -s flag, with the fromFile - * arg being specified in the main method fromFile parameter. - */ - protected boolean bidirectionalMerge = false; - - /** - * Display what integrations would be necessary but don't - * actually do them. Corresponds to the -n flag. - */ - protected boolean showActionsOnly = false; - - /** - * If true, suppresses normal output messages. Messages regarding - * errors or exceptional conditions are not suppressed. - * Corresponds to -q flag. - */ - protected boolean quiet = false; - - /** - * Reverse the mappings in the branch view, with the - * target files and source files exchanging place. - * Corresponds to the -r flag. - */ - protected boolean reverseMapping = false; - - /** - * If positive, integrate only the first maxFiles files. - * Corresponds to -m flag. - */ - protected int maxFiles = 0; - - /** - * If non-null, use a user-defined branch view. The source is the left - * side of the branch view and the target is the right side. With -r, - * the direction is reversed. Corresponds to -b flag. - */ - protected String branch = null; - - /** - * If not null, makes 'p4 integrate' use a stream's branch view. The - * source is the stream itself, and the target is the stream's parent. - * With -r, the direction is reversed. -P can be used to specify a - * parent stream other than the stream's actual parent. Note that to - * submit integrated stream files, the current client must be dedicated - * to the target stream. Corresponds to -S flag. - */ - protected String stream = null; - - /** - * If non-null, specify a parent stream other than the stream's actual - * parent. Corresponds to -P flag. - */ - protected String parentStream = null; - - /** - * If true, force merging even though the stream does not expect a merge - * to occur in the direction indicated. Normally 'p4 merge' enforces the - * expected flow of change dictated by the stream's spec. The 'p4 istat' - * command summarizes a stream's expected flow of change. - */ - protected boolean forceStreamMerge = false; - - /** - * Default constructor. - */ - public MergeFilesOptions() { - super(); - } - - /** - * Strings-based constructor; see 'p4 help [command]' for possible options. - *

- * - * WARNING: you should not pass more than one option or argument in each - * string parameter. Each option or argument should be passed-in as its own - * separate string parameter, without any spaces between the option and the - * option value (if any). - *

- * - * NOTE: setting options this way always bypasses the internal options - * values, and getter methods against the individual values corresponding to - * the strings passed in to this constructor will not normally reflect the - * string's setting. Do not use this constructor unless you know what you're - * doing and / or you do not also use the field getters and setters. - * - * @see com.perforce.p4java.option.Options#Options(java.lang.String...) - */ - public MergeFilesOptions(String... options) { - super(options); - } - - /** - * Explicit-value constructor for use with a branch. - */ - public MergeFilesOptions(int changelistId, boolean showActionsOnly, - int maxFiles, String branch, - boolean reverseMapping, boolean bidirectionalInteg) { - super(); - this.changelistId = changelistId; - this.showActionsOnly = showActionsOnly; - this.maxFiles = maxFiles; - this.branch = branch; - this.reverseMapping = reverseMapping; - this.bidirectionalMerge = bidirectionalInteg; - } - - /** - * Explicit-value constructor for use with a stream. - */ - public MergeFilesOptions(int changelistId, boolean showActionsOnly, - int maxFiles, String stream, String parentStream, - boolean forceStreamMerge, boolean reverseMapping) { - super(); - this.changelistId = changelistId; - this.showActionsOnly = showActionsOnly; - this.maxFiles = maxFiles; - this.stream = stream; - this.parentStream = parentStream; - this.forceStreamMerge = forceStreamMerge; - this.reverseMapping = reverseMapping; - } - - /** - * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) - */ - public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.getChangelistId(), - this.isShowActionsOnly(), - this.isQuiet(), - this.getMaxFiles(), - this.getBranch(), - this.getStream(), - this.getParentStream(), - this.isForceStreamMerge(), - this.isReverseMapping(), - this.isBidirectionalInteg()); - return this.optionList; - } - - public int getChangelistId() { - return changelistId; - } - - public MergeFilesOptions setChangelistId(int changelistId) { - this.changelistId = changelistId; - return this; - } - - public boolean isShowActionsOnly() { - return showActionsOnly; - } - - public MergeFilesOptions setShowActionsOnly(boolean showActionsOnly) { - this.showActionsOnly = showActionsOnly; - return this; - } - - public boolean isQuiet() { - return quiet; - } - - public MergeFilesOptions setQuiet(boolean quiet) { - this.quiet = quiet; - return this; - } - - public boolean isReverseMapping() { - return reverseMapping; - } - - public MergeFilesOptions setReverseMapping(boolean reverseMapping) { - this.reverseMapping = reverseMapping; - return this; - } - - public boolean isBidirectionalInteg() { - return bidirectionalMerge; - } - - public MergeFilesOptions setBidirectionalInteg(boolean bidirectionalInteg) { - this.bidirectionalMerge = bidirectionalInteg; - return this; - } - - public int getMaxFiles() { - return maxFiles; - } - - public MergeFilesOptions setMaxFiles(int maxFiles) { - this.maxFiles = maxFiles; - return this; - } - - public String getBranch() { - return branch; - } - - public MergeFilesOptions setBranch(String branch) { - this.branch = branch; - return this; - } - - public String getStream() { - return stream; - } - - public MergeFilesOptions setStream(String stream) { - this.stream = stream; - return this; - } - - public String getParentStream() { - return parentStream; - } - - public MergeFilesOptions setParentStream(String parentStream) { - this.parentStream = parentStream; - return this; - } - - public boolean isForceStreamMerge() { - return forceStreamMerge; - } - - public MergeFilesOptions setForceStreamMerge(boolean forceStreamMerge) { - this.forceStreamMerge = forceStreamMerge; - return this; - } + /** + * Options: -c[changelist], -n, -q, -m[max], -b[branch], -S[stream], -P[parentStream], -F, -r, -s + */ + public static final String OPTIONS_SPECS = "i:c:clz b:n b:q i:m:gtz s:b s:S s:P b:F b:r b:s"; + + /** + * If positive, the integrated files are opened in the numbered + * pending changelist instead of the default changelist. + */ + protected int changelistId = IChangelist.UNKNOWN; + + /** + * Cause the branch view to work bidirectionally, where the scope of + * the command is limited to integrations whose 'from' files match + * fromFile[revRange]. Corresponds to the -s flag, with the fromFile + * arg being specified in the main method fromFile parameter. + */ + protected boolean bidirectionalMerge = false; + + /** + * Display what integrations would be necessary but don't + * actually do them. Corresponds to the -n flag. + */ + protected boolean showActionsOnly = false; + + /** + * If true, suppresses normal output messages. Messages regarding + * errors or exceptional conditions are not suppressed. + * Corresponds to -q flag. + */ + protected boolean quiet = false; + + /** + * Reverse the mappings in the branch view, with the + * target files and source files exchanging place. + * Corresponds to the -r flag. + */ + protected boolean reverseMapping = false; + + /** + * If positive, integrate only the first maxFiles files. + * Corresponds to -m flag. + */ + protected int maxFiles = 0; + + /** + * If non-null, use a user-defined branch view. The source is the left + * side of the branch view and the target is the right side. With -r, + * the direction is reversed. Corresponds to -b flag. + */ + protected String branch = null; + + /** + * If not null, makes 'p4 integrate' use a stream's branch view. The + * source is the stream itself, and the target is the stream's parent. + * With -r, the direction is reversed. -P can be used to specify a + * parent stream other than the stream's actual parent. Note that to + * submit integrated stream files, the current client must be dedicated + * to the target stream. Corresponds to -S flag. + */ + protected String stream = null; + + /** + * If non-null, specify a parent stream other than the stream's actual + * parent. Corresponds to -P flag. + */ + protected String parentStream = null; + + /** + * If true, force merging even though the stream does not expect a merge + * to occur in the direction indicated. Normally 'p4 merge' enforces the + * expected flow of change dictated by the stream's spec. The 'p4 istat' + * command summarizes a stream's expected flow of change. + */ + protected boolean forceStreamMerge = false; + + /** + * Default constructor. + */ + public MergeFilesOptions() { + super(); + } + + /** + * Strings-based constructor; see 'p4 help [command]' for possible options. + *

+ * + * WARNING: you should not pass more than one option or argument in each + * string parameter. Each option or argument should be passed-in as its own + * separate string parameter, without any spaces between the option and the + * option value (if any). + *

+ * + * NOTE: setting options this way always bypasses the internal options + * values, and getter methods against the individual values corresponding to + * the strings passed in to this constructor will not normally reflect the + * string's setting. Do not use this constructor unless you know what you're + * doing and / or you do not also use the field getters and setters. + * + * @param options options + * @see com.perforce.p4java.option.Options#Options(java.lang.String...) + */ + public MergeFilesOptions(String... options) { + super(options); + } + + /** + * Explicit-value constructor for use with a branch. + * + * @param changelistId changelistId + * @param showActionsOnly showActionsOnly + * @param maxFiles maxFiles + * @param branch branch + * @param reverseMapping reverseMapping + * @param bidirectionalInteg bidirectionalInteg + */ + public MergeFilesOptions(int changelistId, boolean showActionsOnly, int maxFiles, String branch, boolean reverseMapping, boolean bidirectionalInteg) { + super(); + this.changelistId = changelistId; + this.showActionsOnly = showActionsOnly; + this.maxFiles = maxFiles; + this.branch = branch; + this.reverseMapping = reverseMapping; + this.bidirectionalMerge = bidirectionalInteg; + } + + /** + * Explicit-value constructor for use with a stream. + * + * @param changelistId changelistId + * @param showActionsOnly showActionsOnly + * @param maxFiles maxFiles + * @param stream stream + * @param parentStream parentStream + * @param forceStreamMerge forceStreamMerge + * @param reverseMapping reverseMapping + */ + public MergeFilesOptions(int changelistId, boolean showActionsOnly, int maxFiles, String stream, String parentStream, boolean forceStreamMerge, boolean reverseMapping) { + super(); + this.changelistId = changelistId; + this.showActionsOnly = showActionsOnly; + this.maxFiles = maxFiles; + this.stream = stream; + this.parentStream = parentStream; + this.forceStreamMerge = forceStreamMerge; + this.reverseMapping = reverseMapping; + } + + /** + * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) + */ + public List processOptions(IServer server) throws OptionsException { + this.optionList = this.processFields(OPTIONS_SPECS, this.getChangelistId(), this.isShowActionsOnly(), this.isQuiet(), this.getMaxFiles(), this.getBranch(), this.getStream(), this.getParentStream(), this.isForceStreamMerge(), this.isReverseMapping(), this.isBidirectionalInteg()); + return this.optionList; + } + + public int getChangelistId() { + return changelistId; + } + + public MergeFilesOptions setChangelistId(int changelistId) { + this.changelistId = changelistId; + return this; + } + + public boolean isShowActionsOnly() { + return showActionsOnly; + } + + public MergeFilesOptions setShowActionsOnly(boolean showActionsOnly) { + this.showActionsOnly = showActionsOnly; + return this; + } + + public boolean isQuiet() { + return quiet; + } + + public MergeFilesOptions setQuiet(boolean quiet) { + this.quiet = quiet; + return this; + } + + public boolean isReverseMapping() { + return reverseMapping; + } + + public MergeFilesOptions setReverseMapping(boolean reverseMapping) { + this.reverseMapping = reverseMapping; + return this; + } + + public boolean isBidirectionalInteg() { + return bidirectionalMerge; + } + + public MergeFilesOptions setBidirectionalInteg(boolean bidirectionalInteg) { + this.bidirectionalMerge = bidirectionalInteg; + return this; + } + + public int getMaxFiles() { + return maxFiles; + } + + public MergeFilesOptions setMaxFiles(int maxFiles) { + this.maxFiles = maxFiles; + return this; + } + + public String getBranch() { + return branch; + } + + public MergeFilesOptions setBranch(String branch) { + this.branch = branch; + return this; + } + + public String getStream() { + return stream; + } + + public MergeFilesOptions setStream(String stream) { + this.stream = stream; + return this; + } + + public String getParentStream() { + return parentStream; + } + + public MergeFilesOptions setParentStream(String parentStream) { + this.parentStream = parentStream; + return this; + } + + public boolean isForceStreamMerge() { + return forceStreamMerge; + } + + public MergeFilesOptions setForceStreamMerge(boolean forceStreamMerge) { + this.forceStreamMerge = forceStreamMerge; + return this; + } } diff --git a/src/main/java/com/perforce/p4java/option/client/PopulateFilesOptions.java b/src/main/java/com/perforce/p4java/option/client/PopulateFilesOptions.java index b195327..9f2b946 100644 --- a/src/main/java/com/perforce/p4java/option/client/PopulateFilesOptions.java +++ b/src/main/java/com/perforce/p4java/option/client/PopulateFilesOptions.java @@ -128,7 +128,7 @@ public PopulateFilesOptions() { * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

* * NOTE: setting options this way always bypasses the internal options diff --git a/src/main/java/com/perforce/p4java/option/client/ReconcileFilesOptions.java b/src/main/java/com/perforce/p4java/option/client/ReconcileFilesOptions.java index 9624168..22c57c9 100644 --- a/src/main/java/com/perforce/p4java/option/client/ReconcileFilesOptions.java +++ b/src/main/java/com/perforce/p4java/option/client/ReconcileFilesOptions.java @@ -1,33 +1,33 @@ /** - * + * */ package com.perforce.p4java.option.client; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * IClient reconcileFiles method Options definitions. - * + * * @see com.perforce.p4java.client.IClient#addFiles(List, AddFilesOptions) */ public class ReconcileFilesOptions extends Options { - + /** * Options: -n, -c[changelist], -e, -a, -f, -I, -d, -l, -m, -t, -w */ public static final String OPTIONS_SPECS = "b:n i:c:gtz b:e b:a b:f b:I b:d b:l b:m b:t b:w"; - + /** * If true, don't actually do the add, just return the files that * would have been opened for addition. * Corresponds to the '-n' flag. */ protected boolean noUpdate = false; - + /** * If positive, the opened files are put into the pending * changelist identified by changelistId (this changelist must have been @@ -36,14 +36,14 @@ public class ReconcileFilesOptions extends Options { * Corresponds to the '-c changelist#' flag. */ protected int changelistId = 0; - + /** * If true, allows the user to reconcile files that have been modified * outside of Perforce. The reconcile command will open these files for edit. * Corresponds to the '-e' flag. */ protected boolean outsideEdit = false; - + /** * If true, allows the user to reconcile files that are in the user's * directory that are not under Perforce source control. These files are @@ -64,7 +64,7 @@ public class ReconcileFilesOptions extends Options { * Corresponds to the '-I' flag */ protected boolean noIgnoreChecking = false; - + /** * If true, allows the user to reconcile files that have been removed from * the user's directory but are still in the depot. These files will be @@ -115,19 +115,20 @@ public ReconcileFilesOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public ReconcileFilesOptions(String... options) { @@ -136,10 +137,17 @@ public ReconcileFilesOptions(String... options) { /** * Explicit-value constructor. + * + * @param noUpdate noUpdate + * @param changelistId changelistId + * @param outsideEdit outsideEdit + * @param outsideAdd outsideAdd + * @param useWildcards useWildcards + * @param noIgnoreChecking noIgnoreChecking + * @param removed removed + * @param localSyntax localSyntax */ - public ReconcileFilesOptions(boolean noUpdate, int changelistId, boolean outsideEdit, - boolean outsideAdd, boolean useWildcards, boolean noIgnoreChecking, boolean removed, - boolean localSyntax) { + public ReconcileFilesOptions(boolean noUpdate, int changelistId, boolean outsideEdit, boolean outsideAdd, boolean useWildcards, boolean noIgnoreChecking, boolean removed, boolean localSyntax) { super(); this.noUpdate = noUpdate; this.changelistId = changelistId; @@ -155,18 +163,7 @@ public ReconcileFilesOptions(boolean noUpdate, int changelistId, boolean outside * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.noUpdate, - this.changelistId, - this.outsideEdit, - this.outsideAdd, - this.useWildcards, - this.noIgnoreChecking, - this.removed, - this.localSyntax, - this.checkModTime, - this.fileType, - this.updateWorkspace); + this.optionList = this.processFields(OPTIONS_SPECS, this.noUpdate, this.changelistId, this.outsideEdit, this.outsideAdd, this.useWildcards, this.noIgnoreChecking, this.removed, this.localSyntax, this.checkModTime, this.fileType, this.updateWorkspace); return this.optionList; } @@ -218,7 +215,7 @@ public ReconcileFilesOptions setUseWildcards(boolean useWildcards) { public boolean isNoIgnoreChecking() { return noIgnoreChecking; } - + public ReconcileFilesOptions setNoIgnoreChecking(boolean noIgnoreChecking) { this.noIgnoreChecking = noIgnoreChecking; return this; @@ -227,7 +224,7 @@ public ReconcileFilesOptions setNoIgnoreChecking(boolean noIgnoreChecking) { public boolean isRemoved() { return removed; } - + public ReconcileFilesOptions setRemoved(boolean removed) { this.removed = removed; return this; @@ -236,7 +233,7 @@ public ReconcileFilesOptions setRemoved(boolean removed) { public boolean isLocalSyntax() { return localSyntax; } - + public ReconcileFilesOptions setLocalSyntax(boolean localSyntax) { this.localSyntax = localSyntax; return this; @@ -245,13 +242,15 @@ public ReconcileFilesOptions setLocalSyntax(boolean localSyntax) { public boolean isCheckModTime() { return checkModTime; } - + public ReconcileFilesOptions setCheckModTime(boolean checkModTime) { this.checkModTime = checkModTime; return this; } - public boolean isFileType() { return fileType; } + public boolean isFileType() { + return fileType; + } public ReconcileFilesOptions setFileType(boolean fileType) { this.fileType = fileType; @@ -261,7 +260,7 @@ public ReconcileFilesOptions setFileType(boolean fileType) { public boolean isUpdateWorkspace() { return updateWorkspace; } - + public ReconcileFilesOptions setUpdateWorkspace(boolean updateWorkspace) { this.updateWorkspace = updateWorkspace; return this; diff --git a/src/main/java/com/perforce/p4java/option/client/ReopenFilesOptions.java b/src/main/java/com/perforce/p4java/option/client/ReopenFilesOptions.java index 15598ec..da3a51a 100644 --- a/src/main/java/com/perforce/p4java/option/client/ReopenFilesOptions.java +++ b/src/main/java/com/perforce/p4java/option/client/ReopenFilesOptions.java @@ -1,32 +1,32 @@ /** - * + * */ package com.perforce.p4java.option.client; -import java.util.List; - import com.perforce.p4java.core.IChangelist; import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options-based method options for IClient reopenFiles method(s).

- * + * * Recognized options (depending non server version, etc.): * -c changelist# -t filetype */ public class ReopenFilesOptions extends Options { - + /** * Options: -c[changelist], -t[filetype], -Q[charset] */ public static final String OPTIONS_SPECS = "i:c:cl s:t s:Q"; - + /** The changelist to be reopened to; if non-negative, specifies which changelist * to reopen onto */ protected int changelistId = IChangelist.DEFAULT; - + /** If not null, the file is reopened as the given filetype. */ protected String fileType = null; @@ -34,7 +34,7 @@ public class ReopenFilesOptions extends Options { * If non-null, the files are reopened using that charset; corresponds to the * undoc '-Q' flag. Please see the 'Versioned character set' section of the * 'p4 help undoc' command for more info.

- * + * * Note that you must set the server.filecharset configurable to 1 in an * unicode Perforce server in order to version the charset of individual * unicode files along with the filetype. @@ -51,19 +51,20 @@ public ReopenFilesOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public ReopenFilesOptions(String... options) { @@ -72,6 +73,9 @@ public ReopenFilesOptions(String... options) { /** * Explicit-value constructor. + * + * @param changeListId changeListId + * @param fileType fileType */ public ReopenFilesOptions(int changeListId, String fileType) { super(); @@ -84,9 +88,9 @@ public ReopenFilesOptions(int changeListId, String fileType) { */ public List processOptions(IServer server) throws OptionsException { this.optionList = this.processFields(OPTIONS_SPECS, - this.changelistId, - this.fileType, - this.charset); + this.changelistId, + this.fileType, + this.charset); return this.optionList; } diff --git a/src/main/java/com/perforce/p4java/option/client/ResolveFilesAutoOptions.java b/src/main/java/com/perforce/p4java/option/client/ResolveFilesAutoOptions.java index 0f254ea..20548c6 100644 --- a/src/main/java/com/perforce/p4java/option/client/ResolveFilesAutoOptions.java +++ b/src/main/java/com/perforce/p4java/option/client/ResolveFilesAutoOptions.java @@ -13,7 +13,7 @@ /** * Options class for IClient.resolveFilesAuto.

- * + * * Note that absolutely no sanity checking is performed in the current default * implementation for clashing options, etc. * @@ -21,97 +21,97 @@ */ public class ResolveFilesAutoOptions extends Options { - /** - * Options: -n, -s, -af, -at, -ay, -as, -Aa, -Ab, -Ac, -Ad, -Am, -At, -c[changelist], -t, -db, -dw, -dl, -o, -So - */ - public static final String OPTIONS_SPECS = "b:n b:s b:af b:as b:at b:ay b:Aa b:Ab b:Ac b:Ad b:Am b:At i:c:cl b:t b:db b:dw b:dl b:o b:So"; - - /** If true, only do "safe" resolves, as documented for the p4 "-as" option. */ - protected boolean safeMerge = false; - - /** - * If true, automatically accept "their" changes, as documented for the p4 - * "-at" option. - */ - protected boolean acceptTheirs = false; - - /** - * If true, automatically accept "your" changes, as documented for the p4 - * "-ay" option. - */ - protected boolean acceptYours = false; - - /** - * If true, don't do the actual resolve, just return the actions that would - * have been performed for the resolve. Corresponds to the '-n' option. - */ - protected boolean showActionsOnly = false; - - /** - * If true, skip this file. Corresponds to the '-s' option. - */ - protected boolean skipFile = false; - - /** - * Forces auto-mode resolve to accept the merged file even if there are - * conflicts. Corresponds to the -af option. - */ - protected boolean forceResolve = false; - - - /** Resolve file attribute changes. Corresponds to the '-Aa' option. */ - protected boolean resolveFileAttributeChanges = false; - - /** Resolve file branching. Corresponds to the '-Ab' option. */ - protected boolean resolveFileBranching = false; - - /** Resolve file content changes. Corresponds to the '-Ac' option. */ - protected boolean resolveFileContentChanges = false; - - /** Resolve file deletions. Corresponds to the '-Ad' option. */ - protected boolean resolveFileDeletions = false; - - /** Resolve moved and renamed files. Corresponds to the '-Am' option. */ - protected boolean resolveMovedFiles = false; - - /** Resolve filetype changes. Corresponds to the '-At' option. */ - protected boolean resolveFiletypeChanges = false; - - /** - * Limits 'p4 resolve' to the files in changelist#. Corresponds to - * '-c changelist#'. - */ - protected int changelistId = IChangelist.UNKNOWN; - - /** - * If true, forces 'p4 resolve' to attempt a textual merge, even for files - * with non-text (binary) types. Corresponds to the '-t' option. - */ - protected boolean forceTextualMerge = false; - - /** - * If true, ignores whitespace-only changes (for instance, a tab replaced by - * eight spaces). Corresponds to the '-db' option. - */ - protected boolean ignoreWhitespaceChanges = false; - - /** - * If true, ignores whitespace altogether (for instance, deletion of tabs or - * other whitespace). Corresponds to the '-dw' option. - */ - protected boolean ignoreWhitespace = false; - - /** - * If true, ignores differences in line-ending convention. Corresponds to - * the '-dl' option. - */ - protected boolean ignoreLineEndings = false; - - /** - * If true, show the base file name and revision to be used during the merge. - * Corresponds to the '-o' option. - */ - protected boolean showBase = false; + /** + * Options: -n, -s, -af, -at, -ay, -as, -Aa, -Ab, -Ac, -Ad, -Am, -At, -c[changelist], -t, -db, -dw, -dl, -o, -So + */ + public static final String OPTIONS_SPECS = "b:n b:s b:af b:as b:at b:ay b:Aa b:Ab b:Ac b:Ad b:Am b:At i:c:cl b:t b:db b:dw b:dl b:o b:So"; + + /** If true, only do "safe" resolves, as documented for the p4 "-as" option. */ + protected boolean safeMerge = false; + + /** + * If true, automatically accept "their" changes, as documented for the p4 + * "-at" option. + */ + protected boolean acceptTheirs = false; + + /** + * If true, automatically accept "your" changes, as documented for the p4 + * "-ay" option. + */ + protected boolean acceptYours = false; + + /** + * If true, don't do the actual resolve, just return the actions that would + * have been performed for the resolve. Corresponds to the '-n' option. + */ + protected boolean showActionsOnly = false; + + /** + * If true, skip this file. Corresponds to the '-s' option. + */ + protected boolean skipFile = false; + + /** + * Forces auto-mode resolve to accept the merged file even if there are + * conflicts. Corresponds to the -af option. + */ + protected boolean forceResolve = false; + + + /** Resolve file attribute changes. Corresponds to the '-Aa' option. */ + protected boolean resolveFileAttributeChanges = false; + + /** Resolve file branching. Corresponds to the '-Ab' option. */ + protected boolean resolveFileBranching = false; + + /** Resolve file content changes. Corresponds to the '-Ac' option. */ + protected boolean resolveFileContentChanges = false; + + /** Resolve file deletions. Corresponds to the '-Ad' option. */ + protected boolean resolveFileDeletions = false; + + /** Resolve moved and renamed files. Corresponds to the '-Am' option. */ + protected boolean resolveMovedFiles = false; + + /** Resolve filetype changes. Corresponds to the '-At' option. */ + protected boolean resolveFiletypeChanges = false; + + /** + * Limits 'p4 resolve' to the files in changelist#. Corresponds to + * '-c changelist#'. + */ + protected int changelistId = IChangelist.UNKNOWN; + + /** + * If true, forces 'p4 resolve' to attempt a textual merge, even for files + * with non-text (binary) types. Corresponds to the '-t' option. + */ + protected boolean forceTextualMerge = false; + + /** + * If true, ignores whitespace-only changes (for instance, a tab replaced by + * eight spaces). Corresponds to the '-db' option. + */ + protected boolean ignoreWhitespaceChanges = false; + + /** + * If true, ignores whitespace altogether (for instance, deletion of tabs or + * other whitespace). Corresponds to the '-dw' option. + */ + protected boolean ignoreWhitespace = false; + + /** + * If true, ignores differences in line-ending convention. Corresponds to + * the '-dl' option. + */ + protected boolean ignoreLineEndings = false; + + /** + * If true, show the base file name and revision to be used during the merge. + * Corresponds to the '-o' option. + */ + protected boolean showBase = false; /** * If true, resolves changes that have been submitted to the @@ -119,326 +119,327 @@ public class ResolveFilesAutoOptions extends Options { * stream spec until newer changes have been resolved. */ protected boolean resolveStreamSpec = false; - - /** - * Default constructor. - */ - public ResolveFilesAutoOptions() { - super(); - } + + /** + * Default constructor. + */ + public ResolveFilesAutoOptions() { + super(); + } /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ - public ResolveFilesAutoOptions(String... options) { - super(options); - } - - /** - * Explicit-value constructor. - */ - public ResolveFilesAutoOptions(boolean showActionsOnly, boolean safeMerge, - boolean acceptTheirs, boolean acceptYours, boolean forceResolve) { - super(); - this.showActionsOnly = showActionsOnly; - this.safeMerge = safeMerge; - this.acceptTheirs = acceptTheirs; - this.acceptYours = acceptYours; - this.forceResolve = forceResolve; - } - - /** - * Explicit-value constructor. - */ - public ResolveFilesAutoOptions(boolean showActionsOnly, boolean safeMerge, - boolean acceptTheirs, boolean acceptYours, boolean forceResolve, - boolean resolveFileBranching, boolean resolveFileContentChanges, - boolean resolveFileDeletions, boolean resolveMovedFiles, - boolean resolveFiletypeChanges, int changelistId) { - super(); - this.showActionsOnly = showActionsOnly; - this.safeMerge = safeMerge; - this.acceptTheirs = acceptTheirs; - this.acceptYours = acceptYours; - this.forceResolve = forceResolve; - this.resolveFileBranching = resolveFileBranching; - this.resolveFileContentChanges = resolveFileContentChanges; - this.resolveFileDeletions = resolveFileDeletions; - this.resolveMovedFiles = resolveMovedFiles; - this.resolveFiletypeChanges = resolveFiletypeChanges; - this.changelistId = changelistId; - } - - /** - * Explicit-value constructor. - */ - public ResolveFilesAutoOptions(boolean showActionsOnly, boolean safeMerge, - boolean acceptTheirs, boolean acceptYours, boolean forceResolve, - boolean resolveFileBranching, boolean resolveFileContentChanges, - boolean resolveFileDeletions, boolean resolveMovedFiles, - boolean resolveFiletypeChanges, int changelistId, - boolean forceTextualMerge, boolean ignoreWhitespaceChanges, - boolean ignoreWhitespace, boolean ignoreLineEndings) { - super(); - this.showActionsOnly = showActionsOnly; - this.safeMerge = safeMerge; - this.acceptTheirs = acceptTheirs; - this.acceptYours = acceptYours; - this.forceResolve = forceResolve; - this.resolveFileBranching = resolveFileBranching; - this.resolveFileContentChanges = resolveFileContentChanges; - this.resolveFileDeletions = resolveFileDeletions; - this.resolveMovedFiles = resolveMovedFiles; - this.resolveFiletypeChanges = resolveFiletypeChanges; - this.changelistId = changelistId; - this.forceTextualMerge = forceTextualMerge; - this.ignoreWhitespaceChanges = ignoreWhitespaceChanges; - this.ignoreWhitespace = ignoreWhitespace; - this.ignoreLineEndings = ignoreLineEndings; - } - - /** - * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) - */ - public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.isShowActionsOnly(), this.isSkipFile(), - this.isForceResolve(), - this.isSafeMerge(), this.isAcceptTheirs(), - this.isAcceptYours(), - this.isResolveFileAttributeChanges(), - this.isResolveFileBranching(), - this.isResolveFileContentChanges(), - this.isResolveFileDeletions(), this.isResolveMovedFiles(), - this.isResolveFiletypeChanges(), this.getChangelistId(), - this.isForceTextualMerge(), this.isIgnoreWhitespaceChanges(), - this.isIgnoreWhitespace(), this.isIgnoreLineEndings(), - this.isShowBase(), - this.isResolveStreamSpec()); - - // Combine the -A flags, if more than one is set - StringBuilder sb = new StringBuilder(); - if (this.optionList != null) { - // Use an iterator for safe removal of elements in a collection - for (Iterator it = this.optionList.iterator(); it.hasNext();) { - String s = it.next(); - if (s.startsWith("-A")) { - if (s.length() == 3) { - char c = s.charAt(2); - sb.append(c); - } - it.remove(); - } - } - } - if (sb != null && sb.length() > 0) { - optionList.add("-A" + sb.toString()); - } - - return this.optionList; - } - - public boolean isSafeMerge() { - return safeMerge; - } - - public ResolveFilesAutoOptions setSafeMerge(boolean safeMerge) { - this.safeMerge = safeMerge; - return this; - } - - public boolean isAcceptTheirs() { - return acceptTheirs; - } - - public ResolveFilesAutoOptions setAcceptTheirs(boolean acceptTheirs) { - this.acceptTheirs = acceptTheirs; - return this; - } - - public boolean isAcceptYours() { - return acceptYours; - } - - public ResolveFilesAutoOptions setAcceptYours(boolean acceptYours) { - this.acceptYours = acceptYours; - return this; - } - - public boolean isShowActionsOnly() { - return showActionsOnly; - } - - public ResolveFilesAutoOptions setShowActionsOnly(boolean showActionsOnly) { - this.showActionsOnly = showActionsOnly; - return this; - } - - public boolean isSkipFile() { - return skipFile; - } - - public ResolveFilesAutoOptions setSkipFile(boolean skipFile) { - this.skipFile = skipFile; - return this; - } - - public boolean isForceResolve() { - return forceResolve; - } + public ResolveFilesAutoOptions(String... options) { + super(options); + } + + /** + * Explicit-value constructor. + * + * @param showActionsOnly showActionsOnly + * @param safeMerge safeMerge + * @param acceptTheirs acceptTheirs + * @param acceptYours acceptYours + * @param forceResolve forceResolve + */ + public ResolveFilesAutoOptions(boolean showActionsOnly, boolean safeMerge, boolean acceptTheirs, boolean acceptYours, boolean forceResolve) { + super(); + this.showActionsOnly = showActionsOnly; + this.safeMerge = safeMerge; + this.acceptTheirs = acceptTheirs; + this.acceptYours = acceptYours; + this.forceResolve = forceResolve; + } + + /** + * Explicit-value constructor. + * + * @param showActionsOnly showActionsOnly + * @param safeMerge safeMerge + * @param acceptTheirs acceptTheirs + * @param acceptYours acceptYours + * @param forceResolve forceResolve + * @param resolveFileBranching resolveFileBranching + * @param resolveFileContentChanges resolveFileContentChanges + * @param resolveFileDeletions resolveFileDeletions + * @param resolveMovedFiles resolveMovedFiles + * @param resolveFiletypeChanges resolveFiletypeChanges + * @param changelistId changelistId + */ + public ResolveFilesAutoOptions(boolean showActionsOnly, boolean safeMerge, boolean acceptTheirs, boolean acceptYours, boolean forceResolve, boolean resolveFileBranching, boolean resolveFileContentChanges, boolean resolveFileDeletions, boolean resolveMovedFiles, boolean resolveFiletypeChanges, int changelistId) { + super(); + this.showActionsOnly = showActionsOnly; + this.safeMerge = safeMerge; + this.acceptTheirs = acceptTheirs; + this.acceptYours = acceptYours; + this.forceResolve = forceResolve; + this.resolveFileBranching = resolveFileBranching; + this.resolveFileContentChanges = resolveFileContentChanges; + this.resolveFileDeletions = resolveFileDeletions; + this.resolveMovedFiles = resolveMovedFiles; + this.resolveFiletypeChanges = resolveFiletypeChanges; + this.changelistId = changelistId; + } + + /** + * Explicit-value constructor. + * + * @param showActionsOnly showActionsOnly + * @param safeMerge safeMerge + * @param acceptTheirs acceptTheirs + * @param acceptYours acceptYours + * @param forceResolve forceResolve + * @param resolveFileBranching resolveFileBranching + * @param resolveFileContentChanges resolveFileContentChanges + * @param resolveFileDeletions resolveFileDeletions + * @param resolveMovedFiles resolveMovedFiles + * @param resolveFiletypeChanges resolveFiletypeChanges + * @param changelistId changelistId + * @param forceTextualMerge forceTextualMerge + * @param ignoreWhitespaceChanges ignoreWhitespaceChanges + * @param ignoreWhitespace ignoreWhitespace + * @param ignoreLineEndings ignoreLineEndings + */ + public ResolveFilesAutoOptions(boolean showActionsOnly, boolean safeMerge, boolean acceptTheirs, boolean acceptYours, boolean forceResolve, boolean resolveFileBranching, boolean resolveFileContentChanges, boolean resolveFileDeletions, boolean resolveMovedFiles, boolean resolveFiletypeChanges, int changelistId, boolean forceTextualMerge, boolean ignoreWhitespaceChanges, boolean ignoreWhitespace, boolean ignoreLineEndings) { + super(); + this.showActionsOnly = showActionsOnly; + this.safeMerge = safeMerge; + this.acceptTheirs = acceptTheirs; + this.acceptYours = acceptYours; + this.forceResolve = forceResolve; + this.resolveFileBranching = resolveFileBranching; + this.resolveFileContentChanges = resolveFileContentChanges; + this.resolveFileDeletions = resolveFileDeletions; + this.resolveMovedFiles = resolveMovedFiles; + this.resolveFiletypeChanges = resolveFiletypeChanges; + this.changelistId = changelistId; + this.forceTextualMerge = forceTextualMerge; + this.ignoreWhitespaceChanges = ignoreWhitespaceChanges; + this.ignoreWhitespace = ignoreWhitespace; + this.ignoreLineEndings = ignoreLineEndings; + } + + /** + * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) + */ + public List processOptions(IServer server) throws OptionsException { + this.optionList = this.processFields(OPTIONS_SPECS, this.isShowActionsOnly(), this.isSkipFile(), this.isForceResolve(), this.isSafeMerge(), this.isAcceptTheirs(), this.isAcceptYours(), this.isResolveFileAttributeChanges(), this.isResolveFileBranching(), this.isResolveFileContentChanges(), this.isResolveFileDeletions(), this.isResolveMovedFiles(), this.isResolveFiletypeChanges(), this.getChangelistId(), this.isForceTextualMerge(), this.isIgnoreWhitespaceChanges(), this.isIgnoreWhitespace(), this.isIgnoreLineEndings(), this.isShowBase(), this.isResolveStreamSpec()); + + // Combine the -A flags, if more than one is set + StringBuilder sb = new StringBuilder(); + if (this.optionList != null) { + // Use an iterator for safe removal of elements in a collection + for (Iterator it = this.optionList.iterator(); it.hasNext(); ) { + String s = it.next(); + if (s.startsWith("-A")) { + if (s.length() == 3) { + char c = s.charAt(2); + sb.append(c); + } + it.remove(); + } + } + } + if (sb != null && sb.length() > 0) { + optionList.add("-A" + sb.toString()); + } + + return this.optionList; + } + + public boolean isSafeMerge() { + return safeMerge; + } + + public ResolveFilesAutoOptions setSafeMerge(boolean safeMerge) { + this.safeMerge = safeMerge; + return this; + } + + public boolean isAcceptTheirs() { + return acceptTheirs; + } + + public ResolveFilesAutoOptions setAcceptTheirs(boolean acceptTheirs) { + this.acceptTheirs = acceptTheirs; + return this; + } + + public boolean isAcceptYours() { + return acceptYours; + } + + public ResolveFilesAutoOptions setAcceptYours(boolean acceptYours) { + this.acceptYours = acceptYours; + return this; + } + + public boolean isShowActionsOnly() { + return showActionsOnly; + } + + public ResolveFilesAutoOptions setShowActionsOnly(boolean showActionsOnly) { + this.showActionsOnly = showActionsOnly; + return this; + } + + public boolean isSkipFile() { + return skipFile; + } + + public ResolveFilesAutoOptions setSkipFile(boolean skipFile) { + this.skipFile = skipFile; + return this; + } + + public boolean isForceResolve() { + return forceResolve; + } public boolean isResolveStreamSpec() { return resolveStreamSpec; } - public ResolveFilesAutoOptions setForceResolve(boolean forceResolve) { - this.forceResolve = forceResolve; - return this; - } - - public boolean isResolveFileBranching() { - return resolveFileBranching; - } - - public ResolveFilesAutoOptions setResolveFileBranching( - boolean resolveFileBranching) { - this.resolveFileBranching = resolveFileBranching; - return this; - } - - public boolean isResolveFileContentChanges() { - return resolveFileContentChanges; - } - - public ResolveFilesAutoOptions setResolveFileContentChanges( - boolean resolveFileContentChanges) { - this.resolveFileContentChanges = resolveFileContentChanges; - return this; - } - - public boolean isResolveFileDeletions() { - return resolveFileDeletions; - } - - public ResolveFilesAutoOptions setResolveFileDeletions( - boolean resolveFileDeletions) { - this.resolveFileDeletions = resolveFileDeletions; - return this; - } - - public boolean isResolveMovedFiles() { - return resolveMovedFiles; - } - - public ResolveFilesAutoOptions setResolveMovedFiles( - boolean resolveMovedFiles) { - this.resolveMovedFiles = resolveMovedFiles; - return this; - } - - public boolean isResolveFiletypeChanges() { - return resolveFiletypeChanges; - } - - public ResolveFilesAutoOptions setResolveFiletypeChanges( - boolean resolveFiletypeChanges) { - this.resolveFiletypeChanges = resolveFiletypeChanges; - return this; - } - - public boolean isResolveFileAttributeChanges() { - return resolveFileAttributeChanges; - } - - public ResolveFilesAutoOptions setResolveFileAttributeChanges( - boolean resolveFileAttributeChanges) { - this.resolveFileAttributeChanges = resolveFileAttributeChanges; - return this; - } - public ResolveFilesAutoOptions setResolveResolveType(String type, boolean enable) { - if (type.equals("attributes")) - return setResolveFileAttributeChanges(enable); - if (type.equals("branch")) - return setResolveFileBranching(enable); - if (type.equals("content")) - return setResolveFileContentChanges(enable); - if (type.equals("delete")) - return setResolveFileDeletions(enable); - if (type.equals("filetype")) - return setResolveFiletypeChanges(enable); - if (type.equals("move")) - return setResolveMovedFiles(enable); - // unknown resolve type; could throw but maybe better to just ignore it - return this; - } - public int getChangelistId() { - return changelistId; - } - - public ResolveFilesAutoOptions setChangelistId(int changelistId) { - this.changelistId = changelistId; - return this; - } - - public boolean isForceTextualMerge() { - return forceTextualMerge; - } - - public ResolveFilesAutoOptions setForceTextualMerge(boolean forceTextualMerge) { - this.forceTextualMerge = forceTextualMerge; - return this; - } - - public boolean isIgnoreWhitespaceChanges() { - return ignoreWhitespaceChanges; - } - - public ResolveFilesAutoOptions setIgnoreWhitespaceChanges(boolean ignoreWhitespaceChanges) { - this.ignoreWhitespaceChanges = ignoreWhitespaceChanges; - return this; - } - - public boolean isIgnoreWhitespace() { - return ignoreWhitespace; - } - - public ResolveFilesAutoOptions setIgnoreWhitespace(boolean ignoreWhitespace) { - this.ignoreWhitespace = ignoreWhitespace; - return this; - } - - public boolean isIgnoreLineEndings() { - return ignoreLineEndings; - } - - public ResolveFilesAutoOptions setIgnoreLineEndings(boolean ignoreLineEndings) { - this.ignoreLineEndings = ignoreLineEndings; - return this; - } - - public boolean isShowBase() { - return showBase; - } - - public ResolveFilesAutoOptions setShowBase(boolean showBase) { - this.showBase = showBase; - return this; - } + public ResolveFilesAutoOptions setForceResolve(boolean forceResolve) { + this.forceResolve = forceResolve; + return this; + } + + public boolean isResolveFileBranching() { + return resolveFileBranching; + } + + public ResolveFilesAutoOptions setResolveFileBranching(boolean resolveFileBranching) { + this.resolveFileBranching = resolveFileBranching; + return this; + } + + public boolean isResolveFileContentChanges() { + return resolveFileContentChanges; + } + + public ResolveFilesAutoOptions setResolveFileContentChanges(boolean resolveFileContentChanges) { + this.resolveFileContentChanges = resolveFileContentChanges; + return this; + } + + public boolean isResolveFileDeletions() { + return resolveFileDeletions; + } + + public ResolveFilesAutoOptions setResolveFileDeletions(boolean resolveFileDeletions) { + this.resolveFileDeletions = resolveFileDeletions; + return this; + } + + public boolean isResolveMovedFiles() { + return resolveMovedFiles; + } + + public ResolveFilesAutoOptions setResolveMovedFiles(boolean resolveMovedFiles) { + this.resolveMovedFiles = resolveMovedFiles; + return this; + } + + public boolean isResolveFiletypeChanges() { + return resolveFiletypeChanges; + } + + public ResolveFilesAutoOptions setResolveFiletypeChanges(boolean resolveFiletypeChanges) { + this.resolveFiletypeChanges = resolveFiletypeChanges; + return this; + } + + public boolean isResolveFileAttributeChanges() { + return resolveFileAttributeChanges; + } + + public ResolveFilesAutoOptions setResolveFileAttributeChanges(boolean resolveFileAttributeChanges) { + this.resolveFileAttributeChanges = resolveFileAttributeChanges; + return this; + } + + public ResolveFilesAutoOptions setResolveResolveType(String type, boolean enable) { + if (type.equals("attributes")) return setResolveFileAttributeChanges(enable); + if (type.equals("branch")) return setResolveFileBranching(enable); + if (type.equals("content")) return setResolveFileContentChanges(enable); + if (type.equals("delete")) return setResolveFileDeletions(enable); + if (type.equals("filetype")) return setResolveFiletypeChanges(enable); + if (type.equals("move")) return setResolveMovedFiles(enable); + // unknown resolve type; could throw but maybe better to just ignore it + return this; + } + + public int getChangelistId() { + return changelistId; + } + + public ResolveFilesAutoOptions setChangelistId(int changelistId) { + this.changelistId = changelistId; + return this; + } + + public boolean isForceTextualMerge() { + return forceTextualMerge; + } + + public ResolveFilesAutoOptions setForceTextualMerge(boolean forceTextualMerge) { + this.forceTextualMerge = forceTextualMerge; + return this; + } + + public boolean isIgnoreWhitespaceChanges() { + return ignoreWhitespaceChanges; + } + + public ResolveFilesAutoOptions setIgnoreWhitespaceChanges(boolean ignoreWhitespaceChanges) { + this.ignoreWhitespaceChanges = ignoreWhitespaceChanges; + return this; + } + + public boolean isIgnoreWhitespace() { + return ignoreWhitespace; + } + + public ResolveFilesAutoOptions setIgnoreWhitespace(boolean ignoreWhitespace) { + this.ignoreWhitespace = ignoreWhitespace; + return this; + } + + public boolean isIgnoreLineEndings() { + return ignoreLineEndings; + } + + public ResolveFilesAutoOptions setIgnoreLineEndings(boolean ignoreLineEndings) { + this.ignoreLineEndings = ignoreLineEndings; + return this; + } + + public boolean isShowBase() { + return showBase; + } + + public ResolveFilesAutoOptions setShowBase(boolean showBase) { + this.showBase = showBase; + return this; + } public ResolveFilesAutoOptions setResolveStreamSpec(boolean resolveStreamSpec) { this.resolveStreamSpec = resolveStreamSpec; diff --git a/src/main/java/com/perforce/p4java/option/client/ResolvedFilesOptions.java b/src/main/java/com/perforce/p4java/option/client/ResolvedFilesOptions.java index 2fa8a01..fcf8a4e 100644 --- a/src/main/java/com/perforce/p4java/option/client/ResolvedFilesOptions.java +++ b/src/main/java/com/perforce/p4java/option/client/ResolvedFilesOptions.java @@ -1,17 +1,17 @@ /** - * + * */ package com.perforce.p4java.option.client; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for the IClient.resolvedFiles method. - * + * * @see com.perforce.p4java.client.IClient#resolvedFiles(java.util.List, com.perforce.p4java.option.client.ResolvedFilesOptions) */ public class ResolvedFilesOptions extends Options { @@ -20,13 +20,13 @@ public class ResolvedFilesOptions extends Options { * Options: -o */ public static final String OPTIONS_SPECS = "b:o"; - + /** * If true, report the revision used as the base during the resolve. * Corresponds to the -o flag. */ protected boolean showBaseRevision = false; - + /** * Default constructor. */ @@ -37,19 +37,20 @@ public ResolvedFilesOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public ResolvedFilesOptions(String... options) { @@ -58,6 +59,8 @@ public ResolvedFilesOptions(String... options) { /** * Explicit-value constructor. + * + * @param showBaseRevision showBaseRevision */ public ResolvedFilesOptions(boolean showBaseRevision) { super(); @@ -69,8 +72,8 @@ public ResolvedFilesOptions(boolean showBaseRevision) { */ public List processOptions(IServer server) throws OptionsException { this.optionList = this.processFields(OPTIONS_SPECS, - this.isShowBaseRevision() - ); + this.isShowBaseRevision() + ); return this.optionList; } diff --git a/src/main/java/com/perforce/p4java/option/client/RevertFilesOptions.java b/src/main/java/com/perforce/p4java/option/client/RevertFilesOptions.java index 7c8bc22..d041b91 100644 --- a/src/main/java/com/perforce/p4java/option/client/RevertFilesOptions.java +++ b/src/main/java/com/perforce/p4java/option/client/RevertFilesOptions.java @@ -80,7 +80,7 @@ public RevertFilesOptions() { * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

* * NOTE: setting options this way always bypasses the internal options @@ -89,6 +89,7 @@ public RevertFilesOptions() { * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public RevertFilesOptions(String... options) { @@ -97,9 +98,13 @@ public RevertFilesOptions(String... options) { /** * Explicit-value constructor. + * + * @param noUpdate noUpdate + * @param changeListId changeListId + * @param revertOnlyUnchanged revertOnlyUnchanged + * @param noClientRefresh noClientRefresh */ - public RevertFilesOptions(boolean noUpdate, int changeListId, - boolean revertOnlyUnchanged, boolean noClientRefresh) { + public RevertFilesOptions(boolean noUpdate, int changeListId, boolean revertOnlyUnchanged, boolean noClientRefresh) { super(); this.noUpdate = noUpdate; this.changelistId = changeListId; @@ -111,14 +116,7 @@ public RevertFilesOptions(boolean noUpdate, int changeListId, * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.noUpdate, - this.changelistId, - this.revertOnlyUnchanged, - this.noClientRefresh, - this.wipeAddFiles, - this.revertStreamSpec, - this.revertFileList); + this.optionList = this.processFields(OPTIONS_SPECS, this.noUpdate, this.changelistId, this.revertOnlyUnchanged, this.noClientRefresh, this.wipeAddFiles, this.revertStreamSpec, this.revertFileList); return this.optionList; } diff --git a/src/main/java/com/perforce/p4java/option/client/ShelveFilesOptions.java b/src/main/java/com/perforce/p4java/option/client/ShelveFilesOptions.java index 0dd1e40..790d7a7 100644 --- a/src/main/java/com/perforce/p4java/option/client/ShelveFilesOptions.java +++ b/src/main/java/com/perforce/p4java/option/client/ShelveFilesOptions.java @@ -1,11 +1,11 @@ package com.perforce.p4java.option.client; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for the IClient.shelveFiles method and associated * convenience methods. @@ -15,123 +15,122 @@ */ public class ShelveFilesOptions extends Options { - /** - * Options: -f, -r, -d, -p - */ - public static final String OPTIONS_SPECS = "b:f b:r b:d b:p"; - - /** - * If true, force the shelve operation; corresponds to the -f flag - */ - protected boolean forceShelve = false; - - /** - * If true, allow the incoming files to replace the shelved files; - * corresponds to the -r flag. - */ - protected boolean replaceFiles = false; - - /** - * If true, promotes a shelved change from an edge server to a commit - * server where it can be accessed by other edge servers participating - * in the distributed configuration. - * corresponds to the -p flag. - */ - protected boolean promotesShelvedChangeIfDistributedConfigured = false; - - /** - * If true, delete incoming files from the shelf; corresponds to the -d flag. - */ - protected boolean deleteFiles = false; - - /** - * Default constructor.. - */ - public ShelveFilesOptions() { - super(); - } - - /** - * Strings-based constructor; see 'p4 help [command]' for possible options. - *

- * - * WARNING: you should not pass more than one option or argument in each - * string parameter. Each option or argument should be passed-in as its own - * separate string parameter, without any spaces between the option and the - * option value (if any). - *

- * - * NOTE: setting options this way always bypasses the internal options - * values, and getter methods against the individual values corresponding to - * the strings passed in to this constructor will not normally reflect the - * string's setting. Do not use this constructor unless you know what you're - * doing and / or you do not also use the field getters and setters. - * - * @see com.perforce.p4java.option.Options#Options(java.lang.String...) - */ - public ShelveFilesOptions(String... options) { - super(options); - } - - /** - * Explicit-value constructor. - */ - public ShelveFilesOptions(final boolean forceShelve, - final boolean replaceFiles, - final boolean deleteFiles, - final boolean promotesShelvedChangeIfDistributedConfigured) { - super(); - this.forceShelve = forceShelve; - this.replaceFiles = replaceFiles; - this.deleteFiles = deleteFiles; - this.promotesShelvedChangeIfDistributedConfigured = promotesShelvedChangeIfDistributedConfigured; - } - - /** - * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) - */ - public List processOptions(IServer server) throws OptionsException { - optionList = processFields(OPTIONS_SPECS, - isForceShelve(), - isReplaceFiles(), - isDeleteFiles(), - isPromotesShelvedChangeIfDistributedConfigured()); - return optionList; - } - - public boolean isForceShelve() { - return forceShelve; - } - - public ShelveFilesOptions setForceShelve(boolean forceShelve) { - this.forceShelve = forceShelve; - return this; - } - - public boolean isReplaceFiles() { - return replaceFiles; - } - - public ShelveFilesOptions setReplaceFiles(boolean replaceFiles) { - this.replaceFiles = replaceFiles; - return this; - } - - public boolean isPromotesShelvedChangeIfDistributedConfigured() { - return promotesShelvedChangeIfDistributedConfigured; - } - - public ShelveFilesOptions setPromotesShelvedChangeIfDistributedConfigured(boolean promotesShelvedChangeIfDistributedConfigured) { - this.promotesShelvedChangeIfDistributedConfigured = promotesShelvedChangeIfDistributedConfigured; - return this; - } - - public boolean isDeleteFiles() { - return deleteFiles; - } - - public ShelveFilesOptions setDeleteFiles(boolean deleteFiles) { - this.deleteFiles = deleteFiles; - return this; - } + /** + * Options: -f, -r, -d, -p + */ + public static final String OPTIONS_SPECS = "b:f b:r b:d b:p"; + + /** + * If true, force the shelve operation; corresponds to the -f flag + */ + protected boolean forceShelve = false; + + /** + * If true, allow the incoming files to replace the shelved files; + * corresponds to the -r flag. + */ + protected boolean replaceFiles = false; + + /** + * If true, promotes a shelved change from an edge server to a commit + * server where it can be accessed by other edge servers participating + * in the distributed configuration. + * corresponds to the -p flag. + */ + protected boolean promotesShelvedChangeIfDistributedConfigured = false; + + /** + * If true, delete incoming files from the shelf; corresponds to the -d flag. + */ + protected boolean deleteFiles = false; + + /** + * Default constructor.. + */ + public ShelveFilesOptions() { + super(); + } + + /** + * Strings-based constructor; see 'p4 help [command]' for possible options. + *

+ * + * WARNING: you should not pass more than one option or argument in each + * string parameter. Each option or argument should be passed-in as its own + * separate string parameter, without any spaces between the option and the + * option value (if any). + *

+ * + * NOTE: setting options this way always bypasses the internal options + * values, and getter methods against the individual values corresponding to + * the strings passed in to this constructor will not normally reflect the + * string's setting. Do not use this constructor unless you know what you're + * doing and / or you do not also use the field getters and setters. + * + * @param options options + * @see com.perforce.p4java.option.Options#Options(java.lang.String...) + */ + public ShelveFilesOptions(String... options) { + super(options); + } + + /** + * Explicit-value constructor. + * + * @param forceShelve forceShelve + * @param replaceFiles replaceFiles + * @param deleteFiles deleteFiles + * @param promotesShelvedChangeIfDistributedConfigured promotesShelvedChangeIfDistributedConfigured + */ + public ShelveFilesOptions(final boolean forceShelve, final boolean replaceFiles, final boolean deleteFiles, final boolean promotesShelvedChangeIfDistributedConfigured) { + super(); + this.forceShelve = forceShelve; + this.replaceFiles = replaceFiles; + this.deleteFiles = deleteFiles; + this.promotesShelvedChangeIfDistributedConfigured = promotesShelvedChangeIfDistributedConfigured; + } + + /** + * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) + */ + public List processOptions(IServer server) throws OptionsException { + optionList = processFields(OPTIONS_SPECS, isForceShelve(), isReplaceFiles(), isDeleteFiles(), isPromotesShelvedChangeIfDistributedConfigured()); + return optionList; + } + + public boolean isForceShelve() { + return forceShelve; + } + + public ShelveFilesOptions setForceShelve(boolean forceShelve) { + this.forceShelve = forceShelve; + return this; + } + + public boolean isReplaceFiles() { + return replaceFiles; + } + + public ShelveFilesOptions setReplaceFiles(boolean replaceFiles) { + this.replaceFiles = replaceFiles; + return this; + } + + public boolean isPromotesShelvedChangeIfDistributedConfigured() { + return promotesShelvedChangeIfDistributedConfigured; + } + + public ShelveFilesOptions setPromotesShelvedChangeIfDistributedConfigured(boolean promotesShelvedChangeIfDistributedConfigured) { + this.promotesShelvedChangeIfDistributedConfigured = promotesShelvedChangeIfDistributedConfigured; + return this; + } + + public boolean isDeleteFiles() { + return deleteFiles; + } + + public ShelveFilesOptions setDeleteFiles(boolean deleteFiles) { + this.deleteFiles = deleteFiles; + return this; + } } diff --git a/src/main/java/com/perforce/p4java/option/client/SyncOptions.java b/src/main/java/com/perforce/p4java/option/client/SyncOptions.java index 124564f..fb2f1b0 100644 --- a/src/main/java/com/perforce/p4java/option/client/SyncOptions.java +++ b/src/main/java/com/perforce/p4java/option/client/SyncOptions.java @@ -3,168 +3,171 @@ */ package com.perforce.p4java.option.client; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Simple default options object for IClient.sync. */ public class SyncOptions extends Options { - /** - * Options: -f, -n, -k, -p, -q, -s - */ - public static final String OPTIONS_SPECS = "b:f b:n b:k b:p b:q b:s"; - - /** If true, force the update (corresponds to p4 -f flag) */ - protected boolean forceUpdate = false; // -f - - /** If true, don't actually do the update (corresponds to p4 -n flag) */ - protected boolean noUpdate = false; // -n - - /** If true, bypass the client (corresponds to p4 -k flag) */ - protected boolean clientBypass = false; // -k - - /** If true, bypass the server (corresponds to p4 -p flag) */ - protected boolean serverBypass = false; // -p - - /** - * If true, suppresses normal output messages. Messages regarding - * errors or exceptional conditions are not suppressed. - * (corresponds to p4 -q flag) - */ - protected boolean quiet = false; // -q - - /** - * If true, do a safety check before sending content to the client - * workspace (corresponds to p4 -s flag) - */ - protected boolean safetyCheck = false; // -s - - /** - * Default constructor. - */ - public SyncOptions() { - super(); - } - - /** - * Strings-based constructor; see 'p4 help [command]' for possible options. - *

- * - * WARNING: you should not pass more than one option or argument in each - * string parameter. Each option or argument should be passed-in as its own - * separate string parameter, without any spaces between the option and the - * option value (if any). - *

- * - * NOTE: setting options this way always bypasses the internal options - * values, and getter methods against the individual values corresponding to - * the strings passed in to this constructor will not normally reflect the - * string's setting. Do not use this constructor unless you know what you're - * doing and / or you do not also use the field getters and setters. - * - * @see com.perforce.p4java.option.Options#Options(java.lang.String...) - */ - public SyncOptions(String... options) { - super(options); - } - - /** - * Explicit value constructor. - */ - public SyncOptions(boolean forceUpdate, boolean noUpdate, - boolean clientBypass, boolean serverBypass) { - super(); - this.forceUpdate = forceUpdate; - this.noUpdate = noUpdate; - this.clientBypass = clientBypass; - this.serverBypass = serverBypass; - } - - /** - * Explicit value constructor. - */ - public SyncOptions(boolean forceUpdate, boolean noUpdate, - boolean clientBypass, boolean serverBypass, - boolean safetyCheck) { - super(); - this.forceUpdate = forceUpdate; - this.noUpdate = noUpdate; - this.clientBypass = clientBypass; - this.serverBypass = serverBypass; - this.safetyCheck = safetyCheck; - } - - /** - * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) - */ - @Override - public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.forceUpdate, - this.noUpdate, - this.clientBypass, - this.serverBypass, - this.quiet, - this.safetyCheck); - return this.optionList; - } - - public boolean isForceUpdate() { - return forceUpdate; - } - - public SyncOptions setForceUpdate(boolean forceUpdate) { - this.forceUpdate = forceUpdate; - return this; - } - - public boolean isNoUpdate() { - return noUpdate; - } - - public SyncOptions setNoUpdate(boolean noUpdate) { - this.noUpdate = noUpdate; - return this; - } - - public boolean isClientBypass() { - return clientBypass; - } - - public SyncOptions setClientBypass(boolean clientBypass) { - this.clientBypass = clientBypass; - return this; - } - - public boolean isServerBypass() { - return serverBypass; - } - - public SyncOptions setServerBypass(boolean serverBypass) { - this.serverBypass = serverBypass; - return this; - } - - public boolean isQuiet() { - return quiet; - } - - public SyncOptions setQuiet(boolean quiet) { - this.quiet = quiet; - return this; - } - - public boolean isSafetyCheck() { - return safetyCheck; - } - - public SyncOptions setSafetyCheck(boolean safetyCheck) { - this.safetyCheck = safetyCheck; - return this; - } + /** + * Options: -f, -n, -k, -p, -q, -s + */ + public static final String OPTIONS_SPECS = "b:f b:n b:k b:p b:q b:s"; + + /** If true, force the update (corresponds to p4 -f flag) */ + protected boolean forceUpdate = false; // -f + + /** If true, don't actually do the update (corresponds to p4 -n flag) */ + protected boolean noUpdate = false; // -n + + /** If true, bypass the client (corresponds to p4 -k flag) */ + protected boolean clientBypass = false; // -k + + /** If true, bypass the server (corresponds to p4 -p flag) */ + protected boolean serverBypass = false; // -p + + /** + * If true, suppresses normal output messages. Messages regarding + * errors or exceptional conditions are not suppressed. + * (corresponds to p4 -q flag) + */ + protected boolean quiet = false; // -q + + /** + * If true, do a safety check before sending content to the client + * workspace (corresponds to p4 -s flag) + */ + protected boolean safetyCheck = false; // -s + + /** + * Default constructor. + */ + public SyncOptions() { + super(); + } + + /** + * Strings-based constructor; see 'p4 help [command]' for possible options. + *

+ * + * WARNING: you should not pass more than one option or argument in each + * string parameter. Each option or argument should be passed-in as its own + * separate string parameter, without any spaces between the option and the + * option value (if any). + *

+ * + * NOTE: setting options this way always bypasses the internal options + * values, and getter methods against the individual values corresponding to + * the strings passed in to this constructor will not normally reflect the + * string's setting. Do not use this constructor unless you know what you're + * doing and / or you do not also use the field getters and setters. + * + * @param options options + * @see com.perforce.p4java.option.Options#Options(java.lang.String...) + */ + public SyncOptions(String... options) { + super(options); + } + + /** + * Explicit value constructor. + * + * @param forceUpdate forceUpdate + * @param noUpdate noUpdate + * @param clientBypass clientBypass + * @param serverBypass serverBypass + */ + public SyncOptions(boolean forceUpdate, boolean noUpdate, boolean clientBypass, boolean serverBypass) { + super(); + this.forceUpdate = forceUpdate; + this.noUpdate = noUpdate; + this.clientBypass = clientBypass; + this.serverBypass = serverBypass; + } + + /** + * Explicit value constructor. + * + * @param forceUpdate forceUpdate + * @param noUpdate noUpdate + * @param clientBypass clientBypass + * @param serverBypass serverBypass + * @param safetyCheck safetyCheck + */ + public SyncOptions(boolean forceUpdate, boolean noUpdate, boolean clientBypass, boolean serverBypass, boolean safetyCheck) { + super(); + this.forceUpdate = forceUpdate; + this.noUpdate = noUpdate; + this.clientBypass = clientBypass; + this.serverBypass = serverBypass; + this.safetyCheck = safetyCheck; + } + + /** + * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) + */ + @Override + public List processOptions(IServer server) throws OptionsException { + this.optionList = this.processFields(OPTIONS_SPECS, this.forceUpdate, this.noUpdate, this.clientBypass, this.serverBypass, this.quiet, this.safetyCheck); + return this.optionList; + } + + public boolean isForceUpdate() { + return forceUpdate; + } + + public SyncOptions setForceUpdate(boolean forceUpdate) { + this.forceUpdate = forceUpdate; + return this; + } + + public boolean isNoUpdate() { + return noUpdate; + } + + public SyncOptions setNoUpdate(boolean noUpdate) { + this.noUpdate = noUpdate; + return this; + } + + public boolean isClientBypass() { + return clientBypass; + } + + public SyncOptions setClientBypass(boolean clientBypass) { + this.clientBypass = clientBypass; + return this; + } + + public boolean isServerBypass() { + return serverBypass; + } + + public SyncOptions setServerBypass(boolean serverBypass) { + this.serverBypass = serverBypass; + return this; + } + + public boolean isQuiet() { + return quiet; + } + + public SyncOptions setQuiet(boolean quiet) { + this.quiet = quiet; + return this; + } + + public boolean isSafetyCheck() { + return safetyCheck; + } + + public SyncOptions setSafetyCheck(boolean safetyCheck) { + this.safetyCheck = safetyCheck; + return this; + } } diff --git a/src/main/java/com/perforce/p4java/option/client/UndoFilesOptions.java b/src/main/java/com/perforce/p4java/option/client/UndoFilesOptions.java index b2e3b25..4c6a6d7 100644 --- a/src/main/java/com/perforce/p4java/option/client/UndoFilesOptions.java +++ b/src/main/java/com/perforce/p4java/option/client/UndoFilesOptions.java @@ -9,89 +9,91 @@ public class UndoFilesOptions extends Options { - /** - * Options: -c[changelist], -n - */ - public static final String OPTIONS_SPECS = "i:c:clz b:n"; + /** + * Options: -c[changelist], -n + */ + public static final String OPTIONS_SPECS = "i:c:clz b:n"; - /** - * If not IChangelist.UNKNOWN, the files are opened in the numbered - * pending changelist instead of the 'default' changelist. - * Corresponds to the -c flag. - */ - protected int changelistId = IChangelist.UNKNOWN; + /** + * If not IChangelist.UNKNOWN, the files are opened in the numbered + * pending changelist instead of the 'default' changelist. + * Corresponds to the -c flag. + */ + protected int changelistId = IChangelist.UNKNOWN; - /** - * If true, don't actually perform the undo, just return what would - * happen if the undo was performed. Corresponds to the -n flag. - */ - protected boolean listOnly = false; + /** + * If true, don't actually perform the undo, just return what would + * happen if the undo was performed. Corresponds to the -n flag. + */ + protected boolean listOnly = false; - /** - * Default constructor. - */ - public UndoFilesOptions() { - super(); - } + /** + * Default constructor. + */ + public UndoFilesOptions() { + super(); + } - /** - * Strings-based constructor; see 'p4 help [command]' for possible options. - *

- * - * WARNING: you should not pass more than one option or argument in each - * string parameter. Each option or argument should be passed-in as its own - * separate string parameter, without any spaces between the option and the - * option value (if any). - *

- * - * NOTE: setting options this way always bypasses the internal options - * values, and getter methods against the individual values corresponding to - * the strings passed in to this constructor will not normally reflect the - * string's setting. Do not use this constructor unless you know what you're - * doing and / or you do not also use the field getters and setters. - * - * @see com.perforce.p4java.option.Options#Options(java.lang.String...) - */ - public UndoFilesOptions(String... options) { - super(options); - } + /** + * Strings-based constructor; see 'p4 help [command]' for possible options. + *

+ * + * WARNING: you should not pass more than one option or argument in each + * string parameter. Each option or argument should be passed-in as its own + * separate string parameter, without any spaces between the option and the + * option value (if any). + *

+ * + * NOTE: setting options this way always bypasses the internal options + * values, and getter methods against the individual values corresponding to + * the strings passed in to this constructor will not normally reflect the + * string's setting. Do not use this constructor unless you know what you're + * doing and / or you do not also use the field getters and setters. + * + * @param options options + * @see com.perforce.p4java.option.Options#Options(java.lang.String...) + */ + public UndoFilesOptions(String... options) { + super(options); + } - /** - * Explicit-value constructor. - */ - public UndoFilesOptions(boolean listOnly, int changelistId) { - super(); - this.listOnly = listOnly; - this.changelistId = changelistId; - } + /** + * Explicit-value constructor. + * + * @param listOnly listOnly + * @param changelistId changelistId + */ + public UndoFilesOptions(boolean listOnly, int changelistId) { + super(); + this.listOnly = listOnly; + this.changelistId = changelistId; + } - /** - * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) - */ - @Override - public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.getChangelistId(), - this.isListOnly()); - return this.optionList; - } + /** + * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) + */ + @Override + public List processOptions(IServer server) throws OptionsException { + this.optionList = this.processFields(OPTIONS_SPECS, this.getChangelistId(), this.isListOnly()); + return this.optionList; + } - public int getChangelistId() { - return changelistId; - } + public int getChangelistId() { + return changelistId; + } - public UndoFilesOptions setChangelistId(int changelistId) { - this.changelistId = changelistId; - return this; - } + public UndoFilesOptions setChangelistId(int changelistId) { + this.changelistId = changelistId; + return this; + } - public boolean isListOnly() { - return listOnly; - } + public boolean isListOnly() { + return listOnly; + } - public UndoFilesOptions setListOnly(boolean listOnly) { - this.listOnly = listOnly; - return this; - } + public UndoFilesOptions setListOnly(boolean listOnly) { + this.listOnly = listOnly; + return this; + } } diff --git a/src/main/java/com/perforce/p4java/option/client/UnlockFilesOptions.java b/src/main/java/com/perforce/p4java/option/client/UnlockFilesOptions.java index 5b33d84..b7e97f8 100644 --- a/src/main/java/com/perforce/p4java/option/client/UnlockFilesOptions.java +++ b/src/main/java/com/perforce/p4java/option/client/UnlockFilesOptions.java @@ -1,33 +1,33 @@ /** - * + * */ package com.perforce.p4java.option.client; -import java.util.List; - import com.perforce.p4java.core.IChangelist; import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for IClient.unlockFiles. - * + * * @see com.perforce.p4java.client.IClient#unlockFiles(java.util.List, com.perforce.p4java.option.client.UnlockFilesOptions) */ public class UnlockFilesOptions extends Options { - + /** * Options: -c[changelist], -f */ public static final String OPTIONS_SPECS = "i:c:cl b:f"; - + /** * If positive, use the changelistId given instead of * the default changelist. Corresponds to the -c option. */ protected int changelistId = IChangelist.UNKNOWN; - + /** * If true, enables you to unlock files in changelists owned by other users. * Corresponds to the -f option. @@ -44,19 +44,20 @@ public UnlockFilesOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public UnlockFilesOptions(String... options) { @@ -65,6 +66,9 @@ public UnlockFilesOptions(String... options) { /** * Explicit-value constructor. + * + * @param changelistId changelistId + * @param forceUnlock forceUnlock */ public UnlockFilesOptions(int changelistId, boolean forceUnlock) { super(); @@ -76,10 +80,7 @@ public UnlockFilesOptions(int changelistId, boolean forceUnlock) { * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.getChangelistId(), - this.isForceUnlock() - ); + this.optionList = this.processFields(OPTIONS_SPECS, this.getChangelistId(), this.isForceUnlock()); return this.optionList; } diff --git a/src/main/java/com/perforce/p4java/option/client/UnshelveFilesOptions.java b/src/main/java/com/perforce/p4java/option/client/UnshelveFilesOptions.java index 024a6e8..6e5391e 100644 --- a/src/main/java/com/perforce/p4java/option/client/UnshelveFilesOptions.java +++ b/src/main/java/com/perforce/p4java/option/client/UnshelveFilesOptions.java @@ -1,18 +1,18 @@ /** - * + * */ package com.perforce.p4java.option.client; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for the IClient.unshelveFiles method and associated * convenience methods. - * + * * @see com.perforce.p4java.client.IClient#unshelveFiles(java.util.List, int, int, com.perforce.p4java.option.client.UnshelveFilesOptions) */ public class UnshelveFilesOptions extends Options { @@ -21,15 +21,15 @@ public class UnshelveFilesOptions extends Options { * Options: -f, -n */ public static final String OPTIONS_SPECS = "b:f b:n"; - + /** If true, force the unshelve operation; corresponds to the -f flag */ protected boolean forceUnshelve = false; - + /** If true, preview what would be unshelved without actually changing * any files or metadata; corresponds to the -n flag. * */ protected boolean preview = false; - + /** * Default constructor. */ @@ -40,19 +40,20 @@ public UnshelveFilesOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public UnshelveFilesOptions(String... options) { @@ -61,6 +62,9 @@ public UnshelveFilesOptions(String... options) { /** * Explicit-value constructor. + * + * @param forceUnshelve forceUnshelve + * @param preview preview */ public UnshelveFilesOptions(boolean forceUnshelve, boolean preview) { super(); @@ -73,8 +77,8 @@ public UnshelveFilesOptions(boolean forceUnshelve, boolean preview) { */ public List processOptions(IServer server) throws OptionsException { this.optionList = this.processFields(OPTIONS_SPECS, - this.isForceUnshelve(), - this.isPreview()); + this.isForceUnshelve(), + this.isPreview()); return this.optionList; } diff --git a/src/main/java/com/perforce/p4java/option/server/ChangelistOptions.java b/src/main/java/com/perforce/p4java/option/server/ChangelistOptions.java index f5f6452..2a5261a 100644 --- a/src/main/java/com/perforce/p4java/option/server/ChangelistOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/ChangelistOptions.java @@ -74,7 +74,7 @@ public ChangelistOptions() { * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

* * NOTE: setting options this way always bypasses the internal options @@ -83,6 +83,7 @@ public ChangelistOptions() { * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public ChangelistOptions(String... options) { diff --git a/src/main/java/com/perforce/p4java/option/server/CounterOptions.java b/src/main/java/com/perforce/p4java/option/server/CounterOptions.java index b87d336..30973e6 100644 --- a/src/main/java/com/perforce/p4java/option/server/CounterOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/CounterOptions.java @@ -1,24 +1,24 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for IOptionsServer's setCounter method. */ public class CounterOptions extends Options { - + /** * Options: -u, -f, -d, -i */ public static final String OPTIONS_SPECS = "b:u b:f b:d b:i"; - + protected boolean undocCounter = false; /** @@ -26,17 +26,17 @@ public class CounterOptions extends Options { * in 'p4 help counter'. Corresponds to the -f flag. */ protected boolean perforceCounter = false; - + /** * If true, delete the counter. Corresponds to the -d flag. */ protected boolean delete = false; - + /** * If true, increment the counter and return the new value. This option is * used instead of a value argument and can only be used with numeric key * values. Corresponds to the -i flag.

- * + * * Note: will work only with 10.1 or later servers. */ protected boolean incrementCounter = false; @@ -51,45 +51,45 @@ public CounterOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public CounterOptions(String... options) { super(options); } - + /** * Explicit value constructor. + * + * @param perforceCounter counter + * @param delete delete option + * @param incrementCounter increment option */ - public CounterOptions(boolean perforceCounter, boolean delete, - boolean incrementCounter) { + public CounterOptions(boolean perforceCounter, boolean delete, boolean incrementCounter) { super(); this.perforceCounter = perforceCounter; this.delete = delete; this.incrementCounter = incrementCounter; } - + /** * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.isUndocCounter(), - this.isPerforceCounter(), - this.isDelete(), - this.isIncrementCounter()); + this.optionList = this.processFields(OPTIONS_SPECS, this.isUndocCounter(), this.isPerforceCounter(), this.isDelete(), this.isIncrementCounter()); return this.optionList; } diff --git a/src/main/java/com/perforce/p4java/option/server/DeleteBranchSpecOptions.java b/src/main/java/com/perforce/p4java/option/server/DeleteBranchSpecOptions.java index 23387bf..c26b703 100644 --- a/src/main/java/com/perforce/p4java/option/server/DeleteBranchSpecOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/DeleteBranchSpecOptions.java @@ -1,26 +1,26 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for IOptionsServer.deleteBranchSpec methods. - * + * * @see com.perforce.p4java.server.IOptionsServer#deleteBranchSpec(java.lang.String, com.perforce.p4java.option.server.DeleteBranchSpecOptions) */ public class DeleteBranchSpecOptions extends Options { - + /** * Options: -f */ public static final String OPTIONS_SPECS = "b:f"; - + /** * If true, forces the deletion of any branch; normally branches * can only be deleted by their owner. Corresponds to -f flag. @@ -37,19 +37,20 @@ public DeleteBranchSpecOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public DeleteBranchSpecOptions(String... options) { @@ -58,6 +59,8 @@ public DeleteBranchSpecOptions(String... options) { /** * Explicit-value constructor. + * + * @param force force option */ public DeleteBranchSpecOptions(boolean force) { super(); diff --git a/src/main/java/com/perforce/p4java/option/server/DeleteClientOptions.java b/src/main/java/com/perforce/p4java/option/server/DeleteClientOptions.java index 9ef3471..85a5ecd 100644 --- a/src/main/java/com/perforce/p4java/option/server/DeleteClientOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/DeleteClientOptions.java @@ -1,26 +1,26 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options object for the IOptionsServer deleteClient method. - * + * * @see com.perforce.p4java.server.IOptionsServer#deleteClient(java.lang.String, com.perforce.p4java.option.server.DeleteClientOptions) */ public class DeleteClientOptions extends Options { - + /** * Options: -f */ public static final String OPTIONS_SPECS = "b:f"; - + /** If true, tell the server to attempt to force the delete regardless of * the consequences; corresponds to the -f flag. */ @@ -36,19 +36,20 @@ public DeleteClientOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public DeleteClientOptions(String... options) { @@ -57,8 +58,9 @@ public DeleteClientOptions(String... options) { /** * Explicit value constructor. + * + * @param force force option */ - public DeleteClientOptions(boolean force) { super(); this.force = force; diff --git a/src/main/java/com/perforce/p4java/option/server/DeleteLabelOptions.java b/src/main/java/com/perforce/p4java/option/server/DeleteLabelOptions.java index 239ba97..8df30ec 100644 --- a/src/main/java/com/perforce/p4java/option/server/DeleteLabelOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/DeleteLabelOptions.java @@ -1,26 +1,26 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for the server's deleteLabel method. - * + * * @see com.perforce.p4java.server.IOptionsServer#deleteLabel(java.lang.String, com.perforce.p4java.option.server.DeleteLabelOptions) */ public class DeleteLabelOptions extends Options { - + /** * Options: -f */ public static final String OPTIONS_SPECS = "b:f"; - + protected boolean force = false; /** @@ -33,19 +33,20 @@ public DeleteLabelOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public DeleteLabelOptions(String... options) { @@ -54,6 +55,7 @@ public DeleteLabelOptions(String... options) { /** * Explicit-value constructor. + * @param force force option */ public DeleteLabelOptions(boolean force) { super(); diff --git a/src/main/java/com/perforce/p4java/option/server/DescribeOptions.java b/src/main/java/com/perforce/p4java/option/server/DescribeOptions.java index 7075e7d..f25de67 100644 --- a/src/main/java/com/perforce/p4java/option/server/DescribeOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/DescribeOptions.java @@ -3,20 +3,20 @@ */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.core.file.DiffType; import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.exception.P4JavaError; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for the different options that can be specified when running a * describe on a changelist */ public class DescribeOptions extends Options { - + /** * Options: */ @@ -35,19 +35,20 @@ public DescribeOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public DescribeOptions(String... options) { @@ -56,8 +57,8 @@ public DescribeOptions(String... options) { /** * Create a changelist describe options - * - * @param type + * + * @param type diff type */ public DescribeOptions(DiffType type) { this(type, false); @@ -65,9 +66,9 @@ public DescribeOptions(DiffType type) { /** * Create a changelist describe options - * - * @param type - * @param outputShelvedDiffs + * + * @param type diff type + * @param outputShelvedDiffs shelved diffs option */ public DescribeOptions(DiffType type, boolean outputShelvedDiffs) { this.type = type; @@ -82,8 +83,8 @@ public DiffType getType() { } /** - * @param type - * the type to set + * @param type the type to set + * @return DescribeOptions class */ public DescribeOptions setType(DiffType type) { this.type = type; @@ -98,8 +99,8 @@ public boolean isOutputShelvedDiffs() { } /** - * @param showShelvedDiffs - * the showShelvedDiffs to set + * @param showShelvedDiffs the showShelvedDiffs to set + * @return DescribeOptions class */ public DescribeOptions setOutputShelvedDiffs(boolean showShelvedDiffs) { this.outputShelvedDiffs = showShelvedDiffs; diff --git a/src/main/java/com/perforce/p4java/option/server/DuplicateRevisionsOptions.java b/src/main/java/com/perforce/p4java/option/server/DuplicateRevisionsOptions.java index 7c39489..4cbf22b 100644 --- a/src/main/java/com/perforce/p4java/option/server/DuplicateRevisionsOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/DuplicateRevisionsOptions.java @@ -3,12 +3,12 @@ */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for the IOptionsServer duplicateRevisions method. * @@ -16,83 +16,86 @@ */ public class DuplicateRevisionsOptions extends Options { - /** - * Options: -n, -q - */ - public static final String OPTIONS_SPECS = "b:n b:q"; + /** + * Options: -n, -q + */ + public static final String OPTIONS_SPECS = "b:n b:q"; - /** If true, don't actually do the duplicate. Corresponds to -n flag. */ - protected boolean noUpdate = false; + /** If true, don't actually do the duplicate. Corresponds to -n flag. */ + protected boolean noUpdate = false; - /** - * If true, suppresses the warning about target revisions already - * existing. Corresponds to -q flag. - */ - protected boolean suppressWarning = false; + /** + * If true, suppresses the warning about target revisions already + * existing. Corresponds to -q flag. + */ + protected boolean suppressWarning = false; - /** - * Default constructor. - */ - public DuplicateRevisionsOptions() { - super(); - } + /** + * Default constructor. + */ + public DuplicateRevisionsOptions() { + super(); + } - /** - * Strings-based constructor; see 'p4 help [command]' for possible options. - *

- * - * WARNING: you should not pass more than one option or argument in each - * string parameter. Each option or argument should be passed-in as its own - * separate string parameter, without any spaces between the option and the - * option value (if any). - *

- * - * NOTE: setting options this way always bypasses the internal options - * values, and getter methods against the individual values corresponding to - * the strings passed in to this constructor will not normally reflect the - * string's setting. Do not use this constructor unless you know what you're - * doing and / or you do not also use the field getters and setters. - * - * @see com.perforce.p4java.option.Options#Options(java.lang.String...) - */ - public DuplicateRevisionsOptions(String... options) { - super(options); - } + /** + * Strings-based constructor; see 'p4 help [command]' for possible options. + *

+ * + * WARNING: you should not pass more than one option or argument in each + * string parameter. Each option or argument should be passed-in as its own + * separate string parameter, without any spaces between the option and the + * option value (if any). + *

+ * + * NOTE: setting options this way always bypasses the internal options + * values, and getter methods against the individual values corresponding to + * the strings passed in to this constructor will not normally reflect the + * string's setting. Do not use this constructor unless you know what you're + * doing and / or you do not also use the field getters and setters. + * + * @param options options + * @see com.perforce.p4java.option.Options#Options(java.lang.String...) + */ + public DuplicateRevisionsOptions(String... options) { + super(options); + } - /** - * Explicit-value constructor. - */ - public DuplicateRevisionsOptions(boolean noUpdate, boolean suppressWarning) { - super(); - this.noUpdate = noUpdate; - this.suppressWarning = suppressWarning; - } + /** + * Explicit-value constructor. + * @param noUpdate no update option + * @param suppressWarning suppress warnings option + */ + public DuplicateRevisionsOptions(boolean noUpdate, boolean suppressWarning) { + super(); + this.noUpdate = noUpdate; + this.suppressWarning = suppressWarning; + } - /** - * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) - */ - public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.isNoUpdate(), - this.isSuppressWarning()); - return this.optionList; - } + /** + * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) + */ + public List processOptions(IServer server) throws OptionsException { + this.optionList = this.processFields(OPTIONS_SPECS, + this.isNoUpdate(), + this.isSuppressWarning()); + return this.optionList; + } - public boolean isNoUpdate() { - return noUpdate; - } + public boolean isNoUpdate() { + return noUpdate; + } - public DuplicateRevisionsOptions setNoUpdate(boolean noUpdate) { - this.noUpdate = noUpdate; - return this; - } + public DuplicateRevisionsOptions setNoUpdate(boolean noUpdate) { + this.noUpdate = noUpdate; + return this; + } - public boolean isSuppressWarning() { - return suppressWarning; - } + public boolean isSuppressWarning() { + return suppressWarning; + } - public DuplicateRevisionsOptions setSuppressWarning(boolean suppressWarning) { - this.suppressWarning = suppressWarning; - return this; - } + public DuplicateRevisionsOptions setSuppressWarning(boolean suppressWarning) { + this.suppressWarning = suppressWarning; + return this; + } } diff --git a/src/main/java/com/perforce/p4java/option/server/ExportRecordsOptions.java b/src/main/java/com/perforce/p4java/option/server/ExportRecordsOptions.java index 0729f25..df72b6f 100644 --- a/src/main/java/com/perforce/p4java/option/server/ExportRecordsOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/ExportRecordsOptions.java @@ -3,38 +3,38 @@ */ package com.perforce.p4java.option.server; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.CmdSpec; import com.perforce.p4java.server.IServer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + /** * Options class for IOptionsServer.getExportRecords method. Please see the * relevant Perforce admin help for details of the meaning and usage of the * options defined here -- this method is not intended for general use. Note - * also some special-casing in the options processing for this class.

- * + * also some special-casing in the options processing for this class. + *

* The 'skip*' options are specific to P4Java only; they are not Perforce * command options. These options are for field handling rules in the lower * layers of P4Java. The field rules are for identifying the fields that should * skip charset translation of their values; leaving their values as bytes - * instead of converting them to strings.

- * + * instead of converting them to strings. + *

* These 'skip*' options (if any) are placed into the command 'input map' and - * carried downstream to the lower layer of P4Java for field rule processing.

- * + * carried downstream to the lower layer of P4Java for field rule processing. + *

* If you choose to use the IOptionsServer.execStreamingMapCommand method, you * would place those 'skip*' options manually into an 'input map' and pass the * map to the execStreamingMapCommand method. Use 'startField' and 'stopField' * as map keys for the 'field range' rule; and use 'fieldPattern' as map key for - * the 'field pattern' rule. See examples (code snippets) below.

- * - *

+ * the 'field pattern' rule. See examples (code snippets) below.
+ *
+ * 
{@code
  * HashMap inMap = new HashMap();
  * Map skipParams = new HashMap();
  * skipParams.put("startField", "op");
@@ -42,25 +42,26 @@
  * inMap.put(CmdSpec.EXPORT.toString(), skipParams);
  * server.execStreamingMapCommand("export", new String[] { "-l100000",
  *               "-j155", "-Ftable=db.traits" }, inMap, handler, key);
- * 
- * 
+ * }
+ * + *
{@code
  * HashMap inMap = new HashMap();
  * Map skipParams = new HashMap();
  * skipParams.put("fieldPattern", "^[A-Z]{2}\\w+");
  * inMap.put(CmdSpec.EXPORT.toString(), skipParams);
  * server.execStreamingMapCommand("export", new String[] { "-l100000",
  *               "-j155", "-Ftable=db.traits" }, inMap, handler, key);
- * 
- * + * }
+ *

* Currently, there are two implemented field rules for skipping charset * translations. Only one rule can be activated at once. To turn on the rules * you would set the 'skipDataConversion' option to true. Note that the rule - * creation will be processed in the order listed below.

- * + * creation will be processed in the order listed below. + *

* The 'field pattern' rule defines a regex pattern matching the fields to be * skipped. To use this rule you would need to set the 'skipFieldPattern' - * option.

- * + * option. + *

* The 'field range' rule defines a range of fields to be skipped, with a start * field (inclusive) and a stop field (non-inclusive). To use this rule you * would set the 'skipStartField' and 'skipStopField' options. @@ -75,8 +76,8 @@ public class ExportRecordsOptions extends Options { /** * If true, specifies a journal number and optional offset position (journal * number/offset) from which to start exporting. Corresponds to the '-j - * token' flag.

- * + * token' flag. + *

* If false, specifies a checkpoint number and optional offset position * (checkpoint number#offset) from which to start exporting. Corresponds to * the '-c token' flag. @@ -91,8 +92,8 @@ public class ExportRecordsOptions extends Options { /** * If positive, specifies a journal or checkpoint number. Corresponds to the - * 'token' part of the '-j token' and '-c token' flags.

- * + * 'token' part of the '-j token' and '-c token' flags. + *

* The '-j token' flag specifies a journal number and optional position (in * the form: journal number/offset) from which to start exporting. The -c * token flag specifies a checkpoint number and optional position (in the @@ -115,7 +116,7 @@ public class ExportRecordsOptions extends Options { /** * If non-null, specifies a file name prefix to match the one used with 'p4d - * -jc '. Corresponds to the '-J' flag. + * -jc prefix'. Corresponds to the '-J' flag. */ protected String journalPrefix = null; @@ -130,7 +131,6 @@ public class ExportRecordsOptions extends Options { * level logic to skip the charset conversion of data fields; leave the * values as bytes. *

- * * Note: by default the field values affected will be between the start * field "op" (non inclusive) and the end field "func" (non inclusive). */ @@ -141,7 +141,6 @@ public class ExportRecordsOptions extends Options { * (inclusive) marking the beginning of a series of fields which the field * values (bytes) will not be converted to strings. *

- * * Note: don't change this unless you know what you're doing. */ protected String skipStartField = "op"; @@ -151,7 +150,6 @@ public class ExportRecordsOptions extends Options { * (non-inclusive) marking the end of a series of fields which the field * values (bytes) will not be converted to strings. *

- * * Note: don't change this unless you know what you're doing. */ protected String skipStopField = "func"; @@ -160,7 +158,6 @@ public class ExportRecordsOptions extends Options { * The regex pattern for matching fields which the field values (bytes) will * not be converted to strings. *

- * * Note: don't set this value unless you know what you're doing. */ protected String skipFieldPattern = null; @@ -175,19 +172,20 @@ public ExportRecordsOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public ExportRecordsOptions(String... options) { @@ -196,25 +194,16 @@ public ExportRecordsOptions(String... options) { /** * Explicit-value constructor. - * - * @param useJournal - * the use journal - * @param maxRecs - * the max recs - * @param sourceNum - * the source num - * @param offset - * the offset - * @param format - * the format - * @param journalPrefix - * the journal prefix - * @param filter - * the filter - */ - public ExportRecordsOptions(boolean useJournal, long maxRecs, - int sourceNum, long offset, boolean format, String journalPrefix, - String filter) { + * + * @param useJournal the use journal + * @param maxRecs the max recs + * @param sourceNum the source num + * @param offset the offset + * @param format the format + * @param journalPrefix the journal prefix + * @param filter the filter + */ + public ExportRecordsOptions(boolean useJournal, long maxRecs, int sourceNum, long offset, boolean format, String journalPrefix, String filter) { super(); this.useJournal = useJournal; this.maxRecs = maxRecs; @@ -227,28 +216,21 @@ public ExportRecordsOptions(boolean useJournal, long maxRecs, /** * Process options. - * - * @param server - * the server + * + * @param server the server * @return the list - * @throws OptionsException - * the options exception + * @throws OptionsException the options exception * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { List args = new ArrayList(); - if (maxRecs > 0) - args.add("-l" + maxRecs); + if (maxRecs > 0) args.add("-l" + maxRecs); if (sourceNum >= 0) - args.add((useJournal ? "-j" : "-c") + sourceNum - + (offset >= 0 ? (useJournal ? "/" : "#") + offset : "")); - if (journalPrefix != null) - args.add("-J" + journalPrefix); - if (format) - args.add("-f"); - if (filter != null) - args.add("-F" + filter); + args.add((useJournal ? "-j" : "-c") + sourceNum + (offset >= 0 ? (useJournal ? "/" : "#") + offset : "")); + if (journalPrefix != null) args.add("-J" + journalPrefix); + if (format) args.add("-f"); + if (filter != null) args.add("-F" + filter); return args; } @@ -256,19 +238,18 @@ public List processOptions(IServer server) throws OptionsException { /** * Process the field rules and return an input map for field handling rules * in the deeper layers of P4Java. - * + * * @return map of field handling rules */ public Map processFieldRules() { HashMap inMap = new HashMap(); - + if (isSkipDataConversion()) { Map skipParams = new HashMap(); if (getSkipFieldPattern() != null) { skipParams.put("fieldPattern", getSkipFieldPattern()); - } else if (getSkipStartField() != null - && getSkipStopField() != null) { + } else if (getSkipStartField() != null && getSkipStopField() != null) { skipParams.put("startField", getSkipStartField()); skipParams.put("stopField", getSkipStopField()); } @@ -277,10 +258,10 @@ && getSkipStopField() != null) { return inMap; } - + /** * Checks if is use journal. - * + * * @return true, if is use journal */ public boolean isUseJournal() { @@ -289,9 +270,8 @@ public boolean isUseJournal() { /** * Sets the use journal (true/false). - * - * @param useJournal - * the use journal (true/false) + * + * @param useJournal the use journal (true/false) * @return the export records options */ public ExportRecordsOptions setUseJournal(boolean useJournal) { @@ -301,7 +281,7 @@ public ExportRecordsOptions setUseJournal(boolean useJournal) { /** * Gets the maximum lines to be exported. - * + * * @return the maximum lines */ public long getMaxRecs() { @@ -310,9 +290,8 @@ public long getMaxRecs() { /** * Sets the maximum lines to be exported. - * - * @param maxRecs - * the maximum lines + * + * @param maxRecs the maximum lines * @return the export records options */ public ExportRecordsOptions setMaxRecs(long maxRecs) { @@ -322,7 +301,7 @@ public ExportRecordsOptions setMaxRecs(long maxRecs) { /** * Gets the journal or checkpoint number. - * + * * @return the journal or checkpoint number */ public int getSourceNum() { @@ -331,9 +310,8 @@ public int getSourceNum() { /** * Sets the journal or checkpoint number. - * - * @param sourceNum - * the journal or checkpoint number + * + * @param sourceNum the journal or checkpoint number * @return the export records options */ public ExportRecordsOptions setSourceNum(int sourceNum) { @@ -343,7 +321,7 @@ public ExportRecordsOptions setSourceNum(int sourceNum) { /** * Gets the journal or checkpoint offset. - * + * * @return the journal or checkpoint offset */ public long getOffset() { @@ -352,9 +330,8 @@ public long getOffset() { /** * Sets the journal or checkpoint offset. - * - * @param offset - * the journal or checkpoint offset + * + * @param offset the journal or checkpoint offset * @return the export records options */ public ExportRecordsOptions setOffset(long offset) { @@ -364,7 +341,7 @@ public ExportRecordsOptions setOffset(long offset) { /** * Checks if is format. - * + * * @return true, if is format */ public boolean isFormat() { @@ -373,9 +350,8 @@ public boolean isFormat() { /** * Sets the format (true/false). - * - * @param format - * the format (true/false) + * + * @param format the format (true/false) * @return the export records options */ public ExportRecordsOptions setFormat(boolean format) { @@ -385,7 +361,7 @@ public ExportRecordsOptions setFormat(boolean format) { /** * Gets the journal prefix. - * + * * @return the journal prefix */ public String getJournalPrefix() { @@ -394,9 +370,8 @@ public String getJournalPrefix() { /** * Sets the journal prefix. - * - * @param journalPrefix - * the journal prefix + * + * @param journalPrefix the journal prefix * @return the export records options */ public ExportRecordsOptions setJournalPrefix(String journalPrefix) { @@ -406,7 +381,7 @@ public ExportRecordsOptions setJournalPrefix(String journalPrefix) { /** * Gets the filter. - * + * * @return the filter */ public String getFilter() { @@ -415,9 +390,8 @@ public String getFilter() { /** * Sets the filter. - * - * @param filter - * the filter + * + * @param filter the filter * @return the export records options */ public ExportRecordsOptions setFilter(String filter) { @@ -427,7 +401,7 @@ public ExportRecordsOptions setFilter(String filter) { /** * Checks if is skip data conversion. - * + * * @return true, if is skip data conversion */ public boolean isSkipDataConversion() { @@ -436,9 +410,8 @@ public boolean isSkipDataConversion() { /** * Sets the skip data conversion. - * - * @param skipDataConversion - * the skip data conversion (true/false) + * + * @param skipDataConversion the skip data conversion (true/false) * @return the export records options */ public ExportRecordsOptions setSkipDataConversion(boolean skipDataConversion) { @@ -448,7 +421,7 @@ public ExportRecordsOptions setSkipDataConversion(boolean skipDataConversion) { /** * Gets the skip start field. - * + * * @return the skip start field */ public String getSkipStartField() { @@ -457,9 +430,8 @@ public String getSkipStartField() { /** * Sets the skip start field. - * - * @param skipStartField - * the skip start field + * + * @param skipStartField the skip start field * @return the export records options */ public ExportRecordsOptions setSkipStartField(String skipStartField) { @@ -469,7 +441,7 @@ public ExportRecordsOptions setSkipStartField(String skipStartField) { /** * Gets the skip stop field. - * + * * @return the skip stop field */ public String getSkipStopField() { @@ -478,9 +450,8 @@ public String getSkipStopField() { /** * Sets the skip stop field. - * - * @param skipStopField - * the skip stop field + * + * @param skipStopField the skip stop field * @return the export records options */ public ExportRecordsOptions setSkipStopField(String skipStopField) { @@ -490,7 +461,7 @@ public ExportRecordsOptions setSkipStopField(String skipStopField) { /** * Gets the skip field pattern. - * + * * @return the skip field pattern */ public String getSkipFieldPattern() { @@ -499,9 +470,8 @@ public String getSkipFieldPattern() { /** * Sets the skip field pattern. - * - * @param skipFieldPattern - * the skip field pattern + * + * @param skipFieldPattern the skip field pattern * @return the export records options */ public ExportRecordsOptions setSkipFieldPattern(String skipFieldPattern) { diff --git a/src/main/java/com/perforce/p4java/option/server/FixJobsOptions.java b/src/main/java/com/perforce/p4java/option/server/FixJobsOptions.java index ee29ec8..7db8421 100644 --- a/src/main/java/com/perforce/p4java/option/server/FixJobsOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/FixJobsOptions.java @@ -1,30 +1,30 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for the IOptionsServer fixJobs method. */ public class FixJobsOptions extends Options { - + /** * Options: -s[status], -d */ public static final String OPTIONS_SPECS = "s:s b:d"; - + /** * If not null, use this as the new status rather than "closed". * Corresponds to the -s flag. */ protected String status = null; - + /** * If true, delete the specified fixes. Corresponds * to the -d flag. @@ -41,19 +41,20 @@ public FixJobsOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public FixJobsOptions(String... options) { @@ -62,6 +63,8 @@ public FixJobsOptions(String... options) { /** * Explicit-value constructor. + * @param status status + * @param delete delete option */ public FixJobsOptions(String status, boolean delete) { super(); @@ -73,9 +76,7 @@ public FixJobsOptions(String status, boolean delete) { * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.getStatus(), - this.isDelete()); + this.optionList = this.processFields(OPTIONS_SPECS, this.getStatus(), this.isDelete()); return this.optionList; } diff --git a/src/main/java/com/perforce/p4java/option/server/GetBranchSpecOptions.java b/src/main/java/com/perforce/p4java/option/server/GetBranchSpecOptions.java index 6412122..631a72c 100644 --- a/src/main/java/com/perforce/p4java/option/server/GetBranchSpecOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/GetBranchSpecOptions.java @@ -1,26 +1,26 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for IOptionsServer.getBranchSpec method. - * + * * @see com.perforce.p4java.server.IOptionsServer#getBranchSpec(java.lang.String, com.perforce.p4java.option.server.GetBranchSpecOptions) */ public class GetBranchSpecOptions extends Options { - - /** - * Options: -S[stream], -P[parentStream] - */ + + /** + * Options: -S[stream], -P[parentStream] + */ public static final String OPTIONS_SPECS = "s:S s:P"; - + /** * If not null, the -S stream flag will expose the internally generated * mapping. The stream's path in a stream depot, of the form //depotname/streamname. @@ -33,7 +33,7 @@ public class GetBranchSpecOptions extends Options { * depot, of the form //depotname/streamname. */ protected String parentStream = null; - + /** * Default constructor. */ @@ -44,19 +44,20 @@ public GetBranchSpecOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public GetBranchSpecOptions(String... options) { @@ -65,6 +66,8 @@ public GetBranchSpecOptions(String... options) { /** * Explicit value constructor. + * @param stream stream + * @param parentStream parent stream */ public GetBranchSpecOptions(String stream, String parentStream) { super(); @@ -76,10 +79,10 @@ public GetBranchSpecOptions(String stream, String parentStream) { * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.getStream(), - this.getParentStream()); - return this.optionList; + this.optionList = this.processFields(OPTIONS_SPECS, + this.getStream(), + this.getParentStream()); + return this.optionList; } public String getStream() { diff --git a/src/main/java/com/perforce/p4java/option/server/GetBranchSpecsOptions.java b/src/main/java/com/perforce/p4java/option/server/GetBranchSpecsOptions.java index f44f806..3692770 100644 --- a/src/main/java/com/perforce/p4java/option/server/GetBranchSpecsOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/GetBranchSpecsOptions.java @@ -3,12 +3,12 @@ */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for IOptionsServer.getBranchSpecs method. * @@ -16,158 +16,166 @@ */ public class GetBranchSpecsOptions extends Options { - /** - * Options: -u[user], -e[nameFilter], -E[nameFilter], -m[max], -t - */ - public static final String OPTIONS_SPECS = "s:u s:e s:E i:m:gtz b:t"; - - /** - * If non-null, limit qualifying branches to those owned by the named user. - * Corresponds to -uname flag. - */ - protected String userName = null; - - /** - * If non-null, limits output to branches whose name matches - * the nameFilter pattern. Corresponds to -enameFilter flag - */ - protected String nameFilter = null; - - /** - * If non-null, limits output to branches whose name matches (case-insensitive) - * the nameFilter pattern. Corresponds to -EnameFilter flag - */ - protected String caseInsensitiveNameFilter = null; - - /** - * If greater than zero, limit output to the first maxResults - * number of branches. Corresponds to -m flag. - */ - protected int maxResults = 0; - - /** - * If true, displays the time as well as the date. Corresponds to -t flag. - */ - protected boolean showTime = false; - - /** - * Default constructor; sets all fields to null, zero, or false. - */ - public GetBranchSpecsOptions() { - super(); - } - - /** - * Strings-based constructor; see 'p4 help [command]' for possible options. - *

- * - * WARNING: you should not pass more than one option or argument in each - * string parameter. Each option or argument should be passed-in as its own - * separate string parameter, without any spaces between the option and the - * option value (if any). - *

- * - * NOTE: setting options this way always bypasses the internal options - * values, and getter methods against the individual values corresponding to - * the strings passed in to this constructor will not normally reflect the - * string's setting. Do not use this constructor unless you know what you're - * doing and / or you do not also use the field getters and setters. - * - * @see com.perforce.p4java.option.Options#Options(java.lang.String...) - */ - public GetBranchSpecsOptions(String... options) { - super(options); - } - - /** - * Explicit-value constructor. - */ - public GetBranchSpecsOptions(String userName, String nameFilter, - int maxResults) { - super(); - this.userName = userName; - this.nameFilter = nameFilter; - this.maxResults = maxResults; - } - - /** - * Explicit-value constructor. - */ - public GetBranchSpecsOptions(String userName, String nameFilter, - int maxResults, boolean showTime) { - super(); - this.userName = userName; - this.nameFilter = nameFilter; - this.maxResults = maxResults; - this.showTime = showTime; - } - - /** - * Explicit-value constructor. - */ - public GetBranchSpecsOptions(boolean showTime, String userName, String caseInsensitiveNameFilter, int maxResults) { - super(); - this.showTime = showTime; - this.userName = userName; - this.caseInsensitiveNameFilter = caseInsensitiveNameFilter; - this.maxResults = maxResults; - } - - /** - * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) - */ - public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.getUserName(), - this.getNameFilter(), - this.getCaseInsensitiveNameFilter(), - this.getMaxResults(), - this.isShowTime()); - return this.optionList; - } - - public String getUserName() { - return userName; - } - - public GetBranchSpecsOptions setUserName(String userName) { - this.userName = userName; - return this; - } - - public String getNameFilter() { - return nameFilter; - } - - public GetBranchSpecsOptions setNameFilter(String nameFilter) { - this.nameFilter = nameFilter; - return this; - } - - public String getCaseInsensitiveNameFilter() { - return caseInsensitiveNameFilter; - } - - public GetBranchSpecsOptions setCaseInsensitiveNameFilter(String caseInsensitiveNameFilter) { - this.caseInsensitiveNameFilter = caseInsensitiveNameFilter; - return this; - } - - public int getMaxResults() { - return maxResults; - } - - public GetBranchSpecsOptions setMaxResults(int maxResults) { - this.maxResults = maxResults; - return this; - } - - public boolean isShowTime() { - return showTime; - } - - public GetBranchSpecsOptions setShowTime(boolean showTime) { - this.showTime = showTime; - return this; - } + /** + * Options: -u[user], -e[nameFilter], -E[nameFilter], -m[max], -t + */ + public static final String OPTIONS_SPECS = "s:u s:e s:E i:m:gtz b:t"; + + /** + * If non-null, limit qualifying branches to those owned by the named user. + * Corresponds to -uname flag. + */ + protected String userName = null; + + /** + * If non-null, limits output to branches whose name matches + * the nameFilter pattern. Corresponds to -enameFilter flag + */ + protected String nameFilter = null; + + /** + * If non-null, limits output to branches whose name matches (case-insensitive) + * the nameFilter pattern. Corresponds to -EnameFilter flag + */ + protected String caseInsensitiveNameFilter = null; + + /** + * If greater than zero, limit output to the first maxResults + * number of branches. Corresponds to -m flag. + */ + protected int maxResults = 0; + + /** + * If true, displays the time as well as the date. Corresponds to -t flag. + */ + protected boolean showTime = false; + + /** + * Default constructor; sets all fields to null, zero, or false. + */ + public GetBranchSpecsOptions() { + super(); + } + + /** + * Strings-based constructor; see 'p4 help [command]' for possible options. + *

+ * + * WARNING: you should not pass more than one option or argument in each + * string parameter. Each option or argument should be passed-in as its own + * separate string parameter, without any spaces between the option and the + * option value (if any). + *

+ * + * NOTE: setting options this way always bypasses the internal options + * values, and getter methods against the individual values corresponding to + * the strings passed in to this constructor will not normally reflect the + * string's setting. Do not use this constructor unless you know what you're + * doing and / or you do not also use the field getters and setters. + * + * @param options options + * @see com.perforce.p4java.option.Options#Options(java.lang.String...) + */ + public GetBranchSpecsOptions(String... options) { + super(options); + } + + /** + * Explicit-value constructor. + * + * @param userName userName + * @param nameFilter nameFilter + * @param maxResults maxResults + */ + public GetBranchSpecsOptions(String userName, String nameFilter, int maxResults) { + super(); + this.userName = userName; + this.nameFilter = nameFilter; + this.maxResults = maxResults; + } + + /** + * Explicit-value constructor. + * + * @param userName userName + * @param nameFilter nameFilter + * @param maxResults maxResults + * @param showTime showTime + */ + public GetBranchSpecsOptions(String userName, String nameFilter, int maxResults, boolean showTime) { + super(); + this.userName = userName; + this.nameFilter = nameFilter; + this.maxResults = maxResults; + this.showTime = showTime; + } + + /** + * Explicit-value constructor. + * + * @param showTime showTime + * @param userName userName + * @param caseInsensitiveNameFilter caseInsensitiveNameFilter + * @param maxResults maxResults + */ + public GetBranchSpecsOptions(boolean showTime, String userName, String caseInsensitiveNameFilter, int maxResults) { + super(); + this.showTime = showTime; + this.userName = userName; + this.caseInsensitiveNameFilter = caseInsensitiveNameFilter; + this.maxResults = maxResults; + } + + /** + * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) + */ + public List processOptions(IServer server) throws OptionsException { + this.optionList = this.processFields(OPTIONS_SPECS, this.getUserName(), this.getNameFilter(), this.getCaseInsensitiveNameFilter(), this.getMaxResults(), this.isShowTime()); + return this.optionList; + } + + public String getUserName() { + return userName; + } + + public GetBranchSpecsOptions setUserName(String userName) { + this.userName = userName; + return this; + } + + public String getNameFilter() { + return nameFilter; + } + + public GetBranchSpecsOptions setNameFilter(String nameFilter) { + this.nameFilter = nameFilter; + return this; + } + + public String getCaseInsensitiveNameFilter() { + return caseInsensitiveNameFilter; + } + + public GetBranchSpecsOptions setCaseInsensitiveNameFilter(String caseInsensitiveNameFilter) { + this.caseInsensitiveNameFilter = caseInsensitiveNameFilter; + return this; + } + + public int getMaxResults() { + return maxResults; + } + + public GetBranchSpecsOptions setMaxResults(int maxResults) { + this.maxResults = maxResults; + return this; + } + + public boolean isShowTime() { + return showTime; + } + + public GetBranchSpecsOptions setShowTime(boolean showTime) { + this.showTime = showTime; + return this; + } } diff --git a/src/main/java/com/perforce/p4java/option/server/GetChangelistDiffsOptions.java b/src/main/java/com/perforce/p4java/option/server/GetChangelistDiffsOptions.java index cbed318..9e690c5 100644 --- a/src/main/java/com/perforce/p4java/option/server/GetChangelistDiffsOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/GetChangelistDiffsOptions.java @@ -1,55 +1,55 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for IOptionsServer.getChangelistDiffs method(s). - * + * * @see com.perforce.p4java.server.IOptionsServer#getChangelistDiffs(int, com.perforce.p4java.option.server.GetChangelistDiffsOptions) */ public class GetChangelistDiffsOptions extends Options implements DiffsOptions { - + /** * Options: "-S", "-dn", "-dc[n]", "-ds", "-du[n]" "-db", "-dw", "-dl" */ public static final String OPTIONS_SPECS = "b:S b:dn i:dc:dcn b:ds i:du:dcn b:db b:dw b:dl"; - + /** If true, output diffs of shelved files for the changelist */ protected boolean outputShelvedDiffs = false; - + /** If true, use RCS diff; corresponds to -dn. */ protected boolean rcsDiffs = false; - + /** * If positive, specifies the number of context diff lines; * if zero, lets server pick context number; if negative, * no options are generated. Corresponds to -dc[n], with -dc - * generated for diffContext == 0, -dcn for diffContext > 0, + * generated for diffContext == 0, -dcn for diffContext > 0, * where "n" is of course the value of diffContext. */ protected int diffContext = -1; - + /** If true, perform summary diff; corresponds to -ds. */ protected boolean summaryDiff = false; - + /** If true, do a unified diff; corresponds to -du[n] with -du - * generated for unifiedDiff == 0, -dun for unifiedDiff > 0, + * generated for unifiedDiff == 0, -dun for unifiedDiff > 0, * where "n" is of course the value of unifiedDiff. */ protected int unifiedDiff = -1; - + /** If true, ignore whitespace changes; corresponds to -db. */ protected boolean ignoreWhitespaceChanges = false; - + /** If true, ignore whitespace; corresponds to -dw. */ protected boolean ignoreWhitespace = false; - + /** If true, ignore line endings; corresponds to -dl. */ protected boolean ignoreLineEndings = false; @@ -63,19 +63,20 @@ public GetChangelistDiffsOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public GetChangelistDiffsOptions(String... options) { @@ -84,11 +85,17 @@ public GetChangelistDiffsOptions(String... options) { /** * Explicit-value constructor. + * + * @param outputShelvedDiffs outputShelvedDiffs + * @param rcsDiffs rcsDiffs + * @param diffContext diffContext + * @param summaryDiff summaryDiff + * @param unifiedDiff unifiedDiff + * @param ignoreWhitespaceChanges ignoreWhitespaceChanges + * @param ignoreWhitespace ignoreWhitespace + * @param ignoreLineEndings ignoreLineEndings */ - public GetChangelistDiffsOptions(boolean outputShelvedDiffs, - boolean rcsDiffs, int diffContext, boolean summaryDiff, - int unifiedDiff, boolean ignoreWhitespaceChanges, - boolean ignoreWhitespace, boolean ignoreLineEndings) { + public GetChangelistDiffsOptions(boolean outputShelvedDiffs, boolean rcsDiffs, int diffContext, boolean summaryDiff, int unifiedDiff, boolean ignoreWhitespaceChanges, boolean ignoreWhitespace, boolean ignoreLineEndings) { super(); this.outputShelvedDiffs = outputShelvedDiffs; this.rcsDiffs = rcsDiffs; @@ -100,20 +107,12 @@ public GetChangelistDiffsOptions(boolean outputShelvedDiffs, this.ignoreLineEndings = ignoreLineEndings; } - /** + /** * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.isOutputShelvedDiffs(), - this.isRcsDiffs(), - this.getDiffContext(), - this.isSummaryDiff(), - this.isUnifiedDiff(), - this.isIgnoreWhitespaceChanges(), - this.isIgnoreWhitespace(), - this.isIgnoreLineEndings()); - + this.optionList = this.processFields(OPTIONS_SPECS, this.isOutputShelvedDiffs(), this.isRcsDiffs(), this.getDiffContext(), this.isSummaryDiff(), this.isUnifiedDiff(), this.isIgnoreWhitespaceChanges(), this.isIgnoreWhitespace(), this.isIgnoreLineEndings()); + return this.optionList; } diff --git a/src/main/java/com/perforce/p4java/option/server/GetChangelistsOptions.java b/src/main/java/com/perforce/p4java/option/server/GetChangelistsOptions.java index 2280021..67e4935 100644 --- a/src/main/java/com/perforce/p4java/option/server/GetChangelistsOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/GetChangelistsOptions.java @@ -1,77 +1,77 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.core.IChangelist.Type; import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for IOptionsServer getChangelists method(s). - * + * * @see com.perforce.p4java.server.IOptionsServer#getChangelists(java.util.List, com.perforce.p4java.option.server.GetChangelistsOptions) */ public class GetChangelistsOptions extends Options { - + /** * Options: -i, -l, -c[client], -m[max], -s[status], -u[user], -f, -L */ public static final String OPTIONS_SPECS = "b:i b:l s:c i:m:gtz s:s s:u b:f b:L"; - + /** * If positive, restrict the list to the maxMostRecent most recent changelists. * Corresponds to -mmax. */ protected int maxMostRecent = 0; - + /** * If non-null, restrict the results to changelists associated * with the given client. Corresponds to -cclient flag. */ protected String clientName = null; - + /** * If non-null, restrict the results to changelists associated * with the given user name. Corresponds to -uuser flag. */ protected String userName = null; - + /** * If true, also include any changelists integrated into the - * specified files (if any). Corresponds to -i flag. + * specified files (if any). Corresponds to -i flag. */ protected boolean includeIntegrated = false; - + /** * If not null, restrict output to pending, shelved or * submitted changelists. Corresponds to -sstatus flag. */ protected Type type = null; - + /** * If true, produce a non-truncated long version of the description. * Corresponds to the -l flag. */ protected boolean longDesc = false; - + /** * If true, enables admins to see restricted changes. * Corresponds to -f flag. */ protected boolean viewRestricted = false; - + /** * If true, truncate the changelist descriptions to 250 * characters if longer; corresponds to -L. - * + * * @since 2011.1 */ protected boolean truncateDescriptions = false; - + /** * Default constructor. */ @@ -82,19 +82,20 @@ public GetChangelistsOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public GetChangelistsOptions(String... options) { @@ -103,10 +104,15 @@ public GetChangelistsOptions(String... options) { /** * Explicit-value constructor. + * + * @param maxMostRecent maxMostRecent + * @param clientName clientName + * @param userName userName + * @param includeIntegrated includeIntegrated + * @param type type + * @param longDesc longDesc */ - public GetChangelistsOptions(int maxMostRecent, String clientName, - String userName, boolean includeIntegrated, Type type, - boolean longDesc) { + public GetChangelistsOptions(int maxMostRecent, String clientName, String userName, boolean includeIntegrated, Type type, boolean longDesc) { super(); this.maxMostRecent = maxMostRecent; this.clientName = clientName; @@ -115,13 +121,19 @@ public GetChangelistsOptions(int maxMostRecent, String clientName, this.type = type; this.longDesc = longDesc; } - + /** * Explicit-value constructor. + * + * @param maxMostRecent maxMostRecent + * @param clientName clientName + * @param userName userName + * @param includeIntegrated includeIntegrated + * @param type type + * @param longDesc longDesc + * @param viewRestricted viewRestricted */ - public GetChangelistsOptions(int maxMostRecent, String clientName, - String userName, boolean includeIntegrated, Type type, - boolean longDesc, boolean viewRestricted) { + public GetChangelistsOptions(int maxMostRecent, String clientName, String userName, boolean includeIntegrated, Type type, boolean longDesc, boolean viewRestricted) { super(); this.maxMostRecent = maxMostRecent; this.clientName = clientName; @@ -131,16 +143,21 @@ public GetChangelistsOptions(int maxMostRecent, String clientName, this.longDesc = longDesc; this.viewRestricted = viewRestricted; } - + /** * Explicit-value constructor. - * + * + * @param maxMostRecent maxMostRecent + * @param clientName clientName + * @param userName userName + * @param includeIntegrated includeIntegrated + * @param type type + * @param longDesc longDesc + * @param viewRestricted viewRestricted + * @param truncateDescriptions truncateDescriptions * @since 2011.1 */ - public GetChangelistsOptions(int maxMostRecent, String clientName, - String userName, boolean includeIntegrated, Type type, - boolean longDesc, boolean viewRestricted, - boolean truncateDescriptions) { + public GetChangelistsOptions(int maxMostRecent, String clientName, String userName, boolean includeIntegrated, Type type, boolean longDesc, boolean viewRestricted, boolean truncateDescriptions) { super(); this.maxMostRecent = maxMostRecent; this.clientName = clientName; @@ -156,15 +173,7 @@ public GetChangelistsOptions(int maxMostRecent, String clientName, * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.includeIntegrated, - this.isLongDesc(), - this.getClientName(), - this.getMaxMostRecent(), - (this.getType() == null ? null : this.getType().toString()), - this.getUserName(), - this.isViewRestricted(), - this.isTruncateDescriptions()); + this.optionList = this.processFields(OPTIONS_SPECS, this.includeIntegrated, this.isLongDesc(), this.getClientName(), this.getMaxMostRecent(), (this.getType() == null ? null : this.getType().toString()), this.getUserName(), this.isViewRestricted(), this.isTruncateDescriptions()); return this.optionList; } @@ -233,13 +242,16 @@ public GetChangelistsOptions setViewRestricted(boolean viewRestricted) { /** * @since 2011.1 + * @return true if description is truncated */ public boolean isTruncateDescriptions() { return truncateDescriptions; } /** + * @param truncateDescriptions truncate option * @since 2011.1 + * @return GetChangelistsOptions class */ public GetChangelistsOptions setTruncateDescriptions(boolean truncateDescriptions) { this.truncateDescriptions = truncateDescriptions; diff --git a/src/main/java/com/perforce/p4java/option/server/GetClientTemplateOptions.java b/src/main/java/com/perforce/p4java/option/server/GetClientTemplateOptions.java index 57d79ee..71611e8 100644 --- a/src/main/java/com/perforce/p4java/option/server/GetClientTemplateOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/GetClientTemplateOptions.java @@ -1,22 +1,22 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.core.IChangelist; import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for IOptionsServer.getClientTemplate method. - * + * * @see com.perforce.p4java.server.IOptionsServer#getClientTemplate(java.lang.String, com.perforce.p4java.option.server.GetClientTemplateOptions) */ public class GetClientTemplateOptions extends Options { - + /** * Options: -S[stream], -c[changelist] */ @@ -29,13 +29,13 @@ public class GetClientTemplateOptions extends Options { * path in a stream depot, of the form //depotname/streamname. */ protected String stream = null; - + /** * If positive, it yields the client spec that would have been created for * the stream at the moment the change was recorded. */ protected int changelistId = IChangelist.DEFAULT; - + /** * If true, return a client even if it exists. Note that this option is not * processed; this option is used solely post-command-issuance in Server @@ -52,19 +52,20 @@ public GetClientTemplateOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public GetClientTemplateOptions(String... options) { @@ -73,6 +74,7 @@ public GetClientTemplateOptions(String... options) { /** * Explicit value constructor. + * @param allowExistent allowExistent */ public GetClientTemplateOptions(boolean allowExistent) { super(); @@ -83,9 +85,7 @@ public GetClientTemplateOptions(boolean allowExistent) { * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.getStream(), - this.getChangelistId()); + this.optionList = this.processFields(OPTIONS_SPECS, this.getStream(), this.getChangelistId()); return this.optionList; } @@ -106,7 +106,7 @@ public GetClientTemplateOptions setChangelistId(int changelistId) { this.changelistId = changelistId; return this; } - + public boolean isAllowExistent() { return allowExistent; } diff --git a/src/main/java/com/perforce/p4java/option/server/GetClientsOptions.java b/src/main/java/com/perforce/p4java/option/server/GetClientsOptions.java index 04a2be0..189f3cf 100644 --- a/src/main/java/com/perforce/p4java/option/server/GetClientsOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/GetClientsOptions.java @@ -3,12 +3,12 @@ */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for the server's getClients method. * @@ -16,202 +16,217 @@ */ public class GetClientsOptions extends Options { - /** - * Options: -m[max], -u[user], -e[nameFilter], -E[nameFilter], -t, -S[stream] - *

- * Options: -U - */ - public static final String OPTIONS_SPECS = "i:m:gtz s:u s:e s:E b:t s:S b:U"; - - /** - * If non-null, limit qualifying clients to those owned by the named user. - * Corresponds to -uname flag. - */ - protected String userName = null; - - /** - * If non-null, limits output to clients whose name matches - * the nameFilter pattern. Corresponds to -enameFilter flag - */ - protected String nameFilter = null; - - /** - * If non-null, limits output to clients whose name matches (case-insensitive) - * the nameFilter pattern. Corresponds to -EnameFilter flag - */ - protected String caseInsensitiveNameFilter = null; - - /** - * If greater than zero, limit output to the first maxResults - * number of clients. Corresponds to -m flag. - */ - protected int maxResults = 0; - - /** - * If true, displays the time as well as the date. Corresponds to -t flag. - */ - protected boolean showTime = false; - - /** - * If non-null, limits output to the client workspaces dedicated to the - * stream. Corresponds to the "-S stream" flag. - */ - protected String stream = null; - - /** - * If true, lists unloaded clients. Corresponds to -U flag. - */ - protected boolean unloaded = false; - - /** - * Default constructor. - */ - public GetClientsOptions() { - super(); - } - - /** - * Strings-based constructor; see 'p4 help [command]' for possible options. - *

- * - * WARNING: you should not pass more than one option or argument in each - * string parameter. Each option or argument should be passed-in as its own - * separate string parameter, without any spaces between the option and the - * option value (if any). - *

- * - * NOTE: setting options this way always bypasses the internal options - * values, and getter methods against the individual values corresponding to - * the strings passed in to this constructor will not normally reflect the - * string's setting. Do not use this constructor unless you know what you're - * doing and / or you do not also use the field getters and setters. - * - * @see com.perforce.p4java.option.Options#Options(java.lang.String...) - */ - public GetClientsOptions(String... options) { - super(options); - } - - /** - * Explicit-value constructor. - */ - public GetClientsOptions(int maxResults, String userName, String nameFilter) { - super(); - this.maxResults = maxResults; - this.userName = userName; - this.nameFilter = nameFilter; - } - - /** - * Explicit-value constructor. - */ - public GetClientsOptions(int maxResults, String userName, String nameFilter, boolean showTime) { - super(); - this.maxResults = maxResults; - this.userName = userName; - this.nameFilter = nameFilter; - this.showTime = showTime; - } - - /** - * Explicit-value constructor. - */ - public GetClientsOptions(int maxResults, String userName, String nameFilter, boolean showTime, String stream) { - super(); - this.maxResults = maxResults; - this.userName = userName; - this.nameFilter = nameFilter; - this.showTime = showTime; - this.stream = stream; - } - - /** - * Explicit-value constructor. - */ - public GetClientsOptions(boolean showTime, String userName, String caseInsensitiveNameFilter, int maxResults, String stream) { - super(); - this.showTime = showTime; - this.userName = userName; - this.caseInsensitiveNameFilter = caseInsensitiveNameFilter; - this.maxResults = maxResults; - this.stream = stream; - } - - /** - * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) - */ - public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.getMaxResults(), - this.getUserName(), - this.getNameFilter(), - this.getCaseInsensitiveNameFilter(), - this.isShowTime(), - this.getStream(), - this.isUnloaded()); - return this.optionList; - } - - public int getMaxResults() { - return maxResults; - } - - public GetClientsOptions setMaxResults(int maxResults) { - this.maxResults = maxResults; - return this; - } - - public String getUserName() { - return userName; - } - - public GetClientsOptions setUserName(String userName) { - this.userName = userName; - return this; - } - - public String getNameFilter() { - return nameFilter; - } - - public GetClientsOptions setNameFilter(String nameFilter) { - this.nameFilter = nameFilter; - return this; - } - - public String getCaseInsensitiveNameFilter() { - return caseInsensitiveNameFilter; - } - - public GetClientsOptions setCaseInsensitiveNameFilter(String caseInsensitiveNameFilter) { - this.caseInsensitiveNameFilter = caseInsensitiveNameFilter; - return this; - } - - public boolean isShowTime() { - return showTime; - } - - public GetClientsOptions setShowTime(boolean showTime) { - this.showTime = showTime; - return this; - } - - public String getStream() { - return stream; - } - - public GetClientsOptions setStream(String stream) { - this.stream = stream; - return this; - } - - public boolean isUnloaded() { - return unloaded; - } - - public GetClientsOptions setUnloaded(boolean unloaded) { - this.unloaded = unloaded; - return this; - } + /** + * Options: -m[max], -u[user], -e[nameFilter], -E[nameFilter], -t, -S[stream] + *

+ * Options: -U + */ + public static final String OPTIONS_SPECS = "i:m:gtz s:u s:e s:E b:t s:S b:U"; + + /** + * If non-null, limit qualifying clients to those owned by the named user. + * Corresponds to -uname flag. + */ + protected String userName = null; + + /** + * If non-null, limits output to clients whose name matches + * the nameFilter pattern. Corresponds to -enameFilter flag + */ + protected String nameFilter = null; + + /** + * If non-null, limits output to clients whose name matches (case-insensitive) + * the nameFilter pattern. Corresponds to -EnameFilter flag + */ + protected String caseInsensitiveNameFilter = null; + + /** + * If greater than zero, limit output to the first maxResults + * number of clients. Corresponds to -m flag. + */ + protected int maxResults = 0; + + /** + * If true, displays the time as well as the date. Corresponds to -t flag. + */ + protected boolean showTime = false; + + /** + * If non-null, limits output to the client workspaces dedicated to the + * stream. Corresponds to the "-S stream" flag. + */ + protected String stream = null; + + /** + * If true, lists unloaded clients. Corresponds to -U flag. + */ + protected boolean unloaded = false; + + /** + * Default constructor. + */ + public GetClientsOptions() { + super(); + } + + /** + * Strings-based constructor; see 'p4 help [command]' for possible options. + *

+ * + * WARNING: you should not pass more than one option or argument in each + * string parameter. Each option or argument should be passed-in as its own + * separate string parameter, without any spaces between the option and the + * option value (if any). + *

+ * + * NOTE: setting options this way always bypasses the internal options + * values, and getter methods against the individual values corresponding to + * the strings passed in to this constructor will not normally reflect the + * string's setting. Do not use this constructor unless you know what you're + * doing and / or you do not also use the field getters and setters. + * + * @param options options + * @see com.perforce.p4java.option.Options#Options(java.lang.String...) + */ + public GetClientsOptions(String... options) { + super(options); + } + + /** + * Explicit-value constructor. + * + * @param maxResults maxResults + * @param userName userName + * @param nameFilter nameFilter + */ + public GetClientsOptions(int maxResults, String userName, String nameFilter) { + super(); + this.maxResults = maxResults; + this.userName = userName; + this.nameFilter = nameFilter; + } + + /** + * Explicit-value constructor. + * + * @param maxResults maxResults + * @param userName userName + * @param nameFilter nameFilter + * @param showTime showTime + */ + public GetClientsOptions(int maxResults, String userName, String nameFilter, boolean showTime) { + super(); + this.maxResults = maxResults; + this.userName = userName; + this.nameFilter = nameFilter; + this.showTime = showTime; + } + + /** + * Explicit-value constructor. + * + * @param maxResults maxResults + * @param userName userName + * @param nameFilter nameFilter + * @param showTime showTime + * @param stream stream + */ + public GetClientsOptions(int maxResults, String userName, String nameFilter, boolean showTime, String stream) { + super(); + this.maxResults = maxResults; + this.userName = userName; + this.nameFilter = nameFilter; + this.showTime = showTime; + this.stream = stream; + } + + /** + * Explicit-value constructor. + * + * @param showTime showTime + * @param userName userName + * @param caseInsensitiveNameFilter caseInsensitiveNameFilter + * @param maxResults maxResults + * @param stream stream + */ + public GetClientsOptions(boolean showTime, String userName, String caseInsensitiveNameFilter, int maxResults, String stream) { + super(); + this.showTime = showTime; + this.userName = userName; + this.caseInsensitiveNameFilter = caseInsensitiveNameFilter; + this.maxResults = maxResults; + this.stream = stream; + } + + /** + * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) + */ + public List processOptions(IServer server) throws OptionsException { + this.optionList = this.processFields(OPTIONS_SPECS, this.getMaxResults(), this.getUserName(), this.getNameFilter(), this.getCaseInsensitiveNameFilter(), this.isShowTime(), this.getStream(), this.isUnloaded()); + return this.optionList; + } + + public int getMaxResults() { + return maxResults; + } + + public GetClientsOptions setMaxResults(int maxResults) { + this.maxResults = maxResults; + return this; + } + + public String getUserName() { + return userName; + } + + public GetClientsOptions setUserName(String userName) { + this.userName = userName; + return this; + } + + public String getNameFilter() { + return nameFilter; + } + + public GetClientsOptions setNameFilter(String nameFilter) { + this.nameFilter = nameFilter; + return this; + } + + public String getCaseInsensitiveNameFilter() { + return caseInsensitiveNameFilter; + } + + public GetClientsOptions setCaseInsensitiveNameFilter(String caseInsensitiveNameFilter) { + this.caseInsensitiveNameFilter = caseInsensitiveNameFilter; + return this; + } + + public boolean isShowTime() { + return showTime; + } + + public GetClientsOptions setShowTime(boolean showTime) { + this.showTime = showTime; + return this; + } + + public String getStream() { + return stream; + } + + public GetClientsOptions setStream(String stream) { + this.stream = stream; + return this; + } + + public boolean isUnloaded() { + return unloaded; + } + + public GetClientsOptions setUnloaded(boolean unloaded) { + this.unloaded = unloaded; + return this; + } } diff --git a/src/main/java/com/perforce/p4java/option/server/GetCountersOptions.java b/src/main/java/com/perforce/p4java/option/server/GetCountersOptions.java index 8991c28..7c3242f 100644 --- a/src/main/java/com/perforce/p4java/option/server/GetCountersOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/GetCountersOptions.java @@ -1,47 +1,47 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for the IOptionsServer's getCounters method. */ public class GetCountersOptions extends Options { - - /** - * Options: -u, -e[nameFilter] ..., -m[max] - */ - public static final String OPTIONS_SPECS = "b:u s:e s[]:e i:m:gtz"; - - + + /** + * Options: -u, -e[nameFilter] ..., -m[max] + */ + public static final String OPTIONS_SPECS = "b:u s:e s[]:e i:m:gtz"; + + protected boolean undocCounter = false; - /** - * If non-null, limits output to counters whose name matches - * the nameFilter pattern. Corresponds to '-e nameFilter' flag - */ - protected String nameFilter = null; - - /** - * If non-null, limits output to counters whose name matches - * any of the nameFilter patterns. Corresponds to the multiple - * '-u -e nameFilter -e nameFilter ...' flags. - */ - protected String[] nameFilters = null; - - /** - * If greater than zero, limit output to the first maxResults - * number of counters. Corresponds to '-m max' flag. - */ - protected int maxResults = 0; - - /** + /** + * If non-null, limits output to counters whose name matches + * the nameFilter pattern. Corresponds to '-e nameFilter' flag + */ + protected String nameFilter = null; + + /** + * If non-null, limits output to counters whose name matches + * any of the nameFilter patterns. Corresponds to the multiple + * '-u -e nameFilter -e nameFilter ...' flags. + */ + protected String[] nameFilters = null; + + /** + * If greater than zero, limit output to the first maxResults + * number of counters. Corresponds to '-m max' flag. + */ + protected int maxResults = 0; + + /** * Default constructor. */ public GetCountersOptions() { @@ -51,45 +51,45 @@ public GetCountersOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public GetCountersOptions(String... options) { super(options); } - + /** * Explicit value constructor. + * + * @param undocCounter undocCounter + * @param nameFilter nameFilter + * @param maxResults maxResults */ - public GetCountersOptions(boolean undocCounter, String nameFilter, - int maxResults) { + public GetCountersOptions(boolean undocCounter, String nameFilter, int maxResults) { super(); this.undocCounter = undocCounter; this.nameFilter = nameFilter; this.maxResults = maxResults; } - + /** * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.isUndocCounter(), - this.getNameFilter(), - this.getNameFilters(), - this.getMaxResults()); + this.optionList = this.processFields(OPTIONS_SPECS, this.isUndocCounter(), this.getNameFilter(), this.getNameFilters(), this.getMaxResults()); return this.optionList; } diff --git a/src/main/java/com/perforce/p4java/option/server/GetDepotFilesOptions.java b/src/main/java/com/perforce/p4java/option/server/GetDepotFilesOptions.java index 4f306ed..c60e06e 100644 --- a/src/main/java/com/perforce/p4java/option/server/GetDepotFilesOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/GetDepotFilesOptions.java @@ -1,14 +1,14 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Simple options for the IOptionsServer.getDepotFiles method. */ @@ -18,43 +18,44 @@ public class GetDepotFilesOptions extends Options { * Options: -a, -m[max] */ public static final String OPTIONS_SPECS = "b:a i:m:gtz"; - + /** * If positive, return maxResults or fewer files; note: this is * an UNDOC feature and may not be supported on all servers. * Corresponds to the undoc -m flag. */ protected int maxResults = 0; - + /** * If true, display all revisions within the specific range, rather * than just the highest revision in the range. Corresponds to -a. */ protected boolean allRevs = false; - + /** * Default constructor; */ public GetDepotFilesOptions() { super(); } - + /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public GetDepotFilesOptions(String... options) { @@ -63,7 +64,7 @@ public GetDepotFilesOptions(String... options) { /** * Explicit value constructor. - * + * * @param allRevs the value for this object's allRevs field. */ public GetDepotFilesOptions(boolean allRevs) { @@ -72,6 +73,9 @@ public GetDepotFilesOptions(boolean allRevs) { /** * Explicit-value constructor. + * + * @param maxResults maxResults + * @param allRevs allRevs */ public GetDepotFilesOptions(int maxResults, boolean allRevs) { super(); @@ -83,15 +87,14 @@ public GetDepotFilesOptions(int maxResults, boolean allRevs) { * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.allRevs, - this.getMaxResults()); + this.optionList = this.processFields(OPTIONS_SPECS, this.allRevs, this.getMaxResults()); return this.optionList; } public boolean isAllRevs() { return allRevs; } + public GetDepotFilesOptions setAllRevs(boolean allRevs) { this.allRevs = allRevs; return this; diff --git a/src/main/java/com/perforce/p4java/option/server/GetDepotsOptions.java b/src/main/java/com/perforce/p4java/option/server/GetDepotsOptions.java index de6557c..88bfb2a 100644 --- a/src/main/java/com/perforce/p4java/option/server/GetDepotsOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/GetDepotsOptions.java @@ -44,7 +44,7 @@ public GetDepotsOptions() { * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

* * NOTE: setting options this way always bypasses the internal options @@ -53,6 +53,7 @@ public GetDepotsOptions() { * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public GetDepotsOptions(String... options) { @@ -67,12 +68,10 @@ public GetDepotsOptions(String... options) { this.type = type; this.nameFilter = nameFilter; }*/ + @Override public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.getType() == null ? null : this.getType().toString().toLowerCase(), - this.nameFilter, - this.caseInsensitiveNameFilter); + this.optionList = this.processFields(OPTIONS_SPECS, this.getType() == null ? null : this.getType().toString().toLowerCase(), this.nameFilter, this.caseInsensitiveNameFilter); return this.optionList; } diff --git a/src/main/java/com/perforce/p4java/option/server/GetDirectoriesOptions.java b/src/main/java/com/perforce/p4java/option/server/GetDirectoriesOptions.java index e572e0d..ccf6de6 100644 --- a/src/main/java/com/perforce/p4java/option/server/GetDirectoriesOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/GetDirectoriesOptions.java @@ -1,51 +1,51 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for IOptionsServer getDirectories method. - * + * * @see com.perforce.p4java.server.IOptionsServer#getDirectories(java.util.List, com.perforce.p4java.option.server.GetDirectoriesOptions) */ public class GetDirectoriesOptions extends Options { - + /** * Options: -C, -D, -H, -S[stream] */ public static final String OPTIONS_SPECS = "b:C b:D b:H s:S"; - + /** * If true, limit the returns to directories that are mapped in * the current Perforce client workspace. Corresponds to -C. */ protected boolean clientOnly = false; - + /** * If true, includes directories with only deleted files. * Corresponds to -D. */ protected boolean deletedOnly = false; - + /** * If true, lists directories of files on the 'have' list. * Corresponds to -H. */ protected boolean haveListOnly = false; - /** - * If non-null, limits output to depot directories mapped in a stream's - * client view. Corresponds to the "-S stream" flag. - */ - protected String stream = null; + /** + * If non-null, limits output to depot directories mapped in a stream's + * client view. Corresponds to the "-S stream" flag. + */ + protected String stream = null; - /** + /** * Default constructor -- sets all fields to false. */ public GetDirectoriesOptions() { @@ -55,19 +55,20 @@ public GetDirectoriesOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public GetDirectoriesOptions(String... options) { @@ -76,9 +77,12 @@ public GetDirectoriesOptions(String... options) { /** * Explicit-value constructor. + * + * @param clientOnly clientOnly + * @param deletedOnly deletedOnly + * @param haveListOnly haveListOnly */ - public GetDirectoriesOptions(boolean clientOnly, boolean deletedOnly, - boolean haveListOnly) { + public GetDirectoriesOptions(boolean clientOnly, boolean deletedOnly, boolean haveListOnly) { super(); this.clientOnly = clientOnly; this.deletedOnly = deletedOnly; @@ -87,9 +91,13 @@ public GetDirectoriesOptions(boolean clientOnly, boolean deletedOnly, /** * Explicit-value constructor. + * + * @param clientOnly clientOnly + * @param deletedOnly deletedOnly + * @param haveListOnly haveListOnly + * @param stream stream */ - public GetDirectoriesOptions(boolean clientOnly, boolean deletedOnly, - boolean haveListOnly, String stream) { + public GetDirectoriesOptions(boolean clientOnly, boolean deletedOnly, boolean haveListOnly, String stream) { super(); this.clientOnly = clientOnly; this.deletedOnly = deletedOnly; @@ -101,11 +109,7 @@ public GetDirectoriesOptions(boolean clientOnly, boolean deletedOnly, * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.isClientOnly(), - this.isDeletedOnly(), - this.isHaveListOnly(), - this.getStream()); + this.optionList = this.processFields(OPTIONS_SPECS, this.isClientOnly(), this.isDeletedOnly(), this.isHaveListOnly(), this.getStream()); return this.optionList; } @@ -137,11 +141,11 @@ public GetDirectoriesOptions setHaveListOnly(boolean haveListOnly) { } public String getStream() { - return stream; + return stream; } public GetDirectoriesOptions setStream(String stream) { - this.stream = stream; - return this; + this.stream = stream; + return this; } } diff --git a/src/main/java/com/perforce/p4java/option/server/GetExtendedFilesOptions.java b/src/main/java/com/perforce/p4java/option/server/GetExtendedFilesOptions.java index a84f49e..b359f70 100644 --- a/src/main/java/com/perforce/p4java/option/server/GetExtendedFilesOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/GetExtendedFilesOptions.java @@ -1,10 +1,8 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.core.IChangelist; import com.perforce.p4java.core.file.FileStatAncilliaryOptions; import com.perforce.p4java.core.file.FileStatOutputOptions; @@ -12,94 +10,98 @@ import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for the IOptionsServer getExtendedFiles (a.k.a. "fstat") method.

- * + * * The various options are too complex to be described in a few sentences here, and * the various option arguments reflect this complexity. Note also that several options * below (e.g. the "-F" equivalent) may only be available for later-model servers; * use of these with earlier servers will typically cause RequestExceptions from the * server (at least). Note further that no attempt is made with the default implementation * here to sanity check the complex set of options for consistency.

- * + * * Please consult the main p4 documentation for detailed options * semantics and option / server compatibility details. - * + * * @see com.perforce.p4java.server.IOptionsServer#getExtendedFiles(java.util.List, com.perforce.p4java.option.server.GetExtendedFilesOptions) */ public class GetExtendedFilesOptions extends Options { - + /** * Options: -F[filter], -m[max], -r, -c, -e[changelist], -O[x], -R[x], -S[x], -A[pattern] *

- * + * * NOTE: the -O[x] and -R[x] options are not processed using the OPTIONS_SPEC string. */ public static final String OPTIONS_SPECS = "s:F i:m:gtz b:r i:c:cl i:e:cl b:St b:Sd b:Sr b:Sh b:Ss s:A"; - + /** -F */ protected String filterString = null; - + /** -m */ protected int maxResults = 0; - + /** -r */ protected boolean reverseSort = false; - + /** -c */ protected int sinceChangelist = IChangelist.UNKNOWN; - + /** -e */ protected int affectedByChangelist = IChangelist.UNKNOWN; - + /** -St */ protected boolean sortByFiletype = false; - + /** -Sd */ protected boolean sortByDate = false; - + /** -Sr */ protected boolean sortByHeadRev = false; - + /** -Sh */ protected boolean sortByHaveRev = false; - + /** -Ss */ protected boolean sortByFileSize = false; - + /** -Rx options */ protected FileStatOutputOptions outputOptions = null; - + /** -Ox options */ protected FileStatAncilliaryOptions ancilliaryOptions = null; - + /** * fstat -A pattern (unsupported -- see 'p4 undoc' fstat entry). */ protected String attributePattern = null; - + /** * Default constructor. */ public GetExtendedFilesOptions() { - super(); } + super(); + } /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public GetExtendedFilesOptions(String... options) { @@ -108,13 +110,21 @@ public GetExtendedFilesOptions(String... options) { /** * Explicit-value constructor (release 2010.1). + * + * @param filterString filterString + * @param maxResults maxResults + * @param reverseSort reverseSort + * @param sinceChangelist sinceChangelist + * @param affectedByChangelist affectedByChangelist + * @param sortByFiletype sortByFiletype + * @param sortByDate sortByDate + * @param sortByHeadRev sortByHeadRev + * @param sortByHaveRev sortByHaveRev + * @param sortByFileSize sortByFileSize + * @param outputOptions outputOptions + * @param ancilliaryOptions ancilliaryOptions */ - public GetExtendedFilesOptions(String filterString, int maxResults, - boolean reverseSort, int sinceChangelist, int affectedByChangelist, - boolean sortByFiletype, boolean sortByDate, boolean sortByHeadRev, - boolean sortByHaveRev, boolean sortByFileSize, - FileStatOutputOptions outputOptions, - FileStatAncilliaryOptions ancilliaryOptions) { + public GetExtendedFilesOptions(String filterString, int maxResults, boolean reverseSort, int sinceChangelist, int affectedByChangelist, boolean sortByFiletype, boolean sortByDate, boolean sortByHeadRev, boolean sortByHaveRev, boolean sortByFileSize, FileStatOutputOptions outputOptions, FileStatAncilliaryOptions ancilliaryOptions) { super(); this.filterString = filterString; this.maxResults = maxResults; @@ -129,19 +139,26 @@ public GetExtendedFilesOptions(String filterString, int maxResults, this.outputOptions = outputOptions; this.ancilliaryOptions = ancilliaryOptions; } - + /** * Explicit-value constructor. - * + * + * @param filterString filterString + * @param maxResults maxResults + * @param reverseSort reverseSort + * @param sinceChangelist sinceChangelist + * @param affectedByChangelist affectedByChangelist + * @param sortByFiletype sortByFiletype + * @param sortByDate sortByDate + * @param sortByHeadRev sortByHeadRev + * @param sortByHaveRev sortByHaveRev + * @param sortByFileSize sortByFileSize + * @param outputOptions outputOptions + * @param ancilliaryOptions ancilliaryOptions + * @param attributePattern attributePattern * @since 2011.1 */ - - public GetExtendedFilesOptions(String filterString, int maxResults, - boolean reverseSort, int sinceChangelist, int affectedByChangelist, - boolean sortByFiletype, boolean sortByDate, boolean sortByHeadRev, - boolean sortByHaveRev, boolean sortByFileSize, - FileStatOutputOptions outputOptions, - FileStatAncilliaryOptions ancilliaryOptions, String attributePattern) { + public GetExtendedFilesOptions(String filterString, int maxResults, boolean reverseSort, int sinceChangelist, int affectedByChangelist, boolean sortByFiletype, boolean sortByDate, boolean sortByHeadRev, boolean sortByHaveRev, boolean sortByFileSize, FileStatOutputOptions outputOptions, FileStatAncilliaryOptions ancilliaryOptions, String attributePattern) { super(); this.filterString = filterString; this.maxResults = maxResults; @@ -162,18 +179,7 @@ public GetExtendedFilesOptions(String filterString, int maxResults, * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.getFilterString(), - this.getMaxResults(), - this.isReverseSort(), - this.getSinceChangelist(), - this.getAffectedByChangelist(), - this.isSortByFiletype(), - this.isSortByDate(), - this.isSortByHeadRev(), - this.isSortByHaveRev(), - this.isSortByFileSize(), - this.getAttributePattern()); + this.optionList = this.processFields(OPTIONS_SPECS, this.getFilterString(), this.getMaxResults(), this.isReverseSort(), this.getSinceChangelist(), this.getAffectedByChangelist(), this.isSortByFiletype(), this.isSortByDate(), this.isSortByHeadRev(), this.isSortByHaveRev(), this.isSortByFileSize(), this.getAttributePattern()); if (this.getOutputOptions() != null) { List strs = this.getOutputOptions().toStrings(); if ((strs != null) && (strs.size() > 0)) { diff --git a/src/main/java/com/perforce/p4java/option/server/GetFileAnnotationsOptions.java b/src/main/java/com/perforce/p4java/option/server/GetFileAnnotationsOptions.java index 2e6c74f..103def0 100644 --- a/src/main/java/com/perforce/p4java/option/server/GetFileAnnotationsOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/GetFileAnnotationsOptions.java @@ -1,69 +1,69 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.core.file.DiffType; import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for IOptionsServer getFileAnnotations method.

- * + * * Note that this class can take both DiffType args and the string * versions (-dw, etc.); mixing them up carelessly probably isn't a * good idea. - * + * * @see com.perforce.p4java.server.IOptionsServer#getFileAnnotations(java.util.List, com.perforce.p4java.option.server.GetFileAnnotationsOptions) */ public class GetFileAnnotationsOptions extends Options { - + /** * Options: -a, -c, -i, -db, -dw, -dl, -I, -q, -t */ public static final String OPTIONS_SPECS = "b:a b:c b:i b:db b:dw b:dl b:I b:q b:t"; - + /** * If true, include both deleted files and lines no longer present * at the head revision; corresponds to the -a flag. */ protected boolean allResults = false; - + /** * If true, annotate with change numbers rather than revision numbers * with each line; correspond to the -c flag. */ protected boolean useChangeNumbers = false; - + /** * If true, follow branches; corresponds to the -f flag. */ protected boolean followBranches = false; - + /** * If non-null, use the DiffType value to determine whitespace * options. */ protected DiffType wsOpts = null; - + /** * If true, ignore whitespace changes; corresponds to -db. */ protected boolean ignoreWhitespaceChanges = false; - + /** * If true, ignore whitespace; corresponds to -dw. */ protected boolean ignoreWhitespace = false; - + /** * If true, ignore line endisngs; corresponds to -dl. */ protected boolean ignoreLineEndings = false; - + /** * If true, follows all integrations into the file; * corresponds to -I. @@ -92,19 +92,20 @@ public GetFileAnnotationsOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public GetFileAnnotationsOptions(String... options) { @@ -113,9 +114,13 @@ public GetFileAnnotationsOptions(String... options) { /** * Explicit value constructor. + * + * @param allResults allResults + * @param useChangeNumbers useChangeNumbers + * @param followBranches followBranches + * @param wsOpts wsOpts */ - public GetFileAnnotationsOptions(boolean allResults, - boolean useChangeNumbers, boolean followBranches, DiffType wsOpts) { + public GetFileAnnotationsOptions(boolean allResults, boolean useChangeNumbers, boolean followBranches, DiffType wsOpts) { super(); this.allResults = allResults; this.useChangeNumbers = useChangeNumbers; @@ -125,11 +130,15 @@ public GetFileAnnotationsOptions(boolean allResults, /** * Explicit value constructor. + * + * @param allResults allResults + * @param useChangeNumbers useChangeNumbers + * @param followBranches followBranches + * @param ignoreWhitespaceChanges ignoreWhitespaceChanges + * @param ignoreWhitespace ignoreWhitespace + * @param ignoreLineEndings ignoreLineEndings */ - public GetFileAnnotationsOptions(boolean allResults, - boolean useChangeNumbers, boolean followBranches, - boolean ignoreWhitespaceChanges, boolean ignoreWhitespace, - boolean ignoreLineEndings) { + public GetFileAnnotationsOptions(boolean allResults, boolean useChangeNumbers, boolean followBranches, boolean ignoreWhitespaceChanges, boolean ignoreWhitespace, boolean ignoreLineEndings) { super(); this.allResults = allResults; this.useChangeNumbers = useChangeNumbers; @@ -138,14 +147,19 @@ public GetFileAnnotationsOptions(boolean allResults, this.ignoreWhitespace = ignoreWhitespace; this.ignoreLineEndings = ignoreLineEndings; } - + /** * Explicit value constructor. + * + * @param allResults allResults + * @param useChangeNumbers useChangeNumbers + * @param followBranches followBranches + * @param ignoreWhitespaceChanges ignoreWhitespaceChanges + * @param ignoreWhitespace ignoreWhitespace + * @param ignoreLineEndings ignoreLineEndings + * @param followAllIntegrations followAllIntegrations */ - public GetFileAnnotationsOptions(boolean allResults, - boolean useChangeNumbers, boolean followBranches, - boolean ignoreWhitespaceChanges, boolean ignoreWhitespace, - boolean ignoreLineEndings, boolean followAllIntegrations) { + public GetFileAnnotationsOptions(boolean allResults, boolean useChangeNumbers, boolean followBranches, boolean ignoreWhitespaceChanges, boolean ignoreWhitespace, boolean ignoreLineEndings, boolean followAllIntegrations) { super(); this.allResults = allResults; this.useChangeNumbers = useChangeNumbers; @@ -159,7 +173,7 @@ public GetFileAnnotationsOptions(boolean allResults, /** * If the wsOpts field is non-null, those values will override * the corresponding explicit boolean fields. - * + * * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { @@ -178,16 +192,7 @@ public List processOptions(IServer server) throws OptionsException { break; } } - this.optionList = this.processFields(OPTIONS_SPECS, - this.isAllResults(), - this.isUseChangeNumbers(), - this.isFollowBranches(), - this.isIgnoreWhitespaceChanges(), - this.isIgnoreWhitespace(), - this.isIgnoreLineEndings(), - this.isFollowAllIntegrations(), - this.isSuppressHeader(), - this.isShowBinaryContent()); + this.optionList = this.processFields(OPTIONS_SPECS, this.isAllResults(), this.isUseChangeNumbers(), this.isFollowBranches(), this.isIgnoreWhitespaceChanges(), this.isIgnoreWhitespace(), this.isIgnoreLineEndings(), this.isFollowAllIntegrations(), this.isSuppressHeader(), this.isShowBinaryContent()); return this.optionList; } diff --git a/src/main/java/com/perforce/p4java/option/server/GetFileContentsOptions.java b/src/main/java/com/perforce/p4java/option/server/GetFileContentsOptions.java index 5af4d92..c95c252 100644 --- a/src/main/java/com/perforce/p4java/option/server/GetFileContentsOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/GetFileContentsOptions.java @@ -1,32 +1,32 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for the IOptionsServer.getFileContents method. - * + * * @see com.perforce.p4java.server.IOptionsServer#getFileContents(java.util.List, com.perforce.p4java.option.server.GetFileContentsOptions) */ public class GetFileContentsOptions extends Options { - + /** * Options: -a, -q */ public static final String OPTIONS_SPECS = "b:a b:q"; - + /** * If true, get the contents of all revisions within the specific range, rather * than just the highest revision in the range. Corresponds to -a. - */ + */ protected boolean allrevs = false; - + /** * If true, suppress the initial line that displays the file name and revision. * Corresponds to -q. @@ -38,13 +38,13 @@ public class GetFileContentsOptions extends Options { * (Parameters.processParameters(...)). By default the filespecs passed to * IOptionsServer.getFileContents() would get revisions appended to them * during parameter processing.

- * + * * Note that this is not a standard option for this command. It is merely a * convenience flag to tell the parameter processor not to include revisions * with the filespecs. */ protected boolean dontAnnotateFiles = false; - + /** * Default constructor -- sets all fields to false. */ @@ -55,19 +55,20 @@ public GetFileContentsOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public GetFileContentsOptions(String... options) { @@ -76,6 +77,9 @@ public GetFileContentsOptions(String... options) { /** * Explicit-value constructor. + * + * @param allrevs allrevs + * @param noHeaderLine noHeaderLine */ public GetFileContentsOptions(boolean allrevs, boolean noHeaderLine) { super(); @@ -87,9 +91,7 @@ public GetFileContentsOptions(boolean allrevs, boolean noHeaderLine) { * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.isAllrevs(), - this.isNoHeaderLine()); + this.optionList = this.processFields(OPTIONS_SPECS, this.isAllrevs(), this.isNoHeaderLine()); return this.optionList; } diff --git a/src/main/java/com/perforce/p4java/option/server/GetFileDiffsOptions.java b/src/main/java/com/perforce/p4java/option/server/GetFileDiffsOptions.java index 14e02ab..5649fb0 100644 --- a/src/main/java/com/perforce/p4java/option/server/GetFileDiffsOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/GetFileDiffsOptions.java @@ -1,14 +1,14 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for the IOptionsServer getFileDiffs methods. */ @@ -18,7 +18,7 @@ public class GetFileDiffsOptions extends Options implements DiffsOptions 0, + * generated for diffContext == 0, -dcn for diffContext > 0, * where "n" is of course the value of diffContext. */ protected int diffContext = -1; - + /** If true, perform summary diff; corresponds to -ds. */ protected boolean summaryDiff = false; - + /** If true, do a unified diff; corresponds to -du[n] with -du - * generated for unifiedDiff == 0, -dun for unifiedDiff > 0, + * generated for unifiedDiff == 0, -dun for unifiedDiff > 0, * where "n" is of course the value of unifiedDiff. */ protected int unifiedDiff = -1; - + /** If true, ignore whitespace changes; corresponds to -db. */ protected boolean ignoreWhitespaceChanges = false; - + /** If true, ignore whitespace; corresponds to -dw. */ protected boolean ignoreWhitespace = false; - + /** If true, ignore line endings; corresponds to -dl. */ protected boolean ignoreLineEndings = false; - - /** - * If not null, makes 'p4 diff2' use a stream's branch view. The source is - * the stream itself, and the target is the stream's parent. The '-P' flag - * can be used to specify a parent stream other than the stream's actual - * parent. - */ - protected String stream = null; - - /** - * If non-null, specify a parent stream other than the stream's actual - * parent. Corresponds to -P flag. - */ - protected String parentStream = null; + + /** + * If not null, makes 'p4 diff2' use a stream's branch view. The source is + * the stream itself, and the target is the stream's parent. The '-P' flag + * can be used to specify a parent stream other than the stream's actual + * parent. + */ + protected String stream = null; + + /** + * If non-null, specify a parent stream other than the stream's actual + * parent. Corresponds to -P flag. + */ + protected String parentStream = null; /** * Default constructor. @@ -98,19 +98,20 @@ public GetFileDiffsOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public GetFileDiffsOptions(String... options) { @@ -119,12 +120,19 @@ public GetFileDiffsOptions(String... options) { /** * Explicit-value constructor. + * + * @param quiet quiet + * @param includeNonTextDiffs includeNonTextDiffs + * @param gnuDiffs gnuDiffs + * @param rcsDiffs rcsDiffs + * @param diffContext diffContext + * @param summaryDiff summaryDiff + * @param unifiedDiff unifiedDiff + * @param ignoreWhitespaceChanges ignoreWhitespaceChanges + * @param ignoreWhitespace ignoreWhitespace + * @param ignoreLineEndings ignoreLineEndings */ - public GetFileDiffsOptions(boolean quiet, boolean includeNonTextDiffs, - boolean gnuDiffs, boolean rcsDiffs, - int diffContext, boolean summaryDiff, int unifiedDiff, - boolean ignoreWhitespaceChanges, boolean ignoreWhitespace, - boolean ignoreLineEndings) { + public GetFileDiffsOptions(boolean quiet, boolean includeNonTextDiffs, boolean gnuDiffs, boolean rcsDiffs, int diffContext, boolean summaryDiff, int unifiedDiff, boolean ignoreWhitespaceChanges, boolean ignoreWhitespace, boolean ignoreLineEndings) { super(); this.quiet = quiet; this.includeNonTextDiffs = includeNonTextDiffs; @@ -140,12 +148,21 @@ public GetFileDiffsOptions(boolean quiet, boolean includeNonTextDiffs, /** * Explicit-value constructor. + * + * @param quiet quiet + * @param includeNonTextDiffs includeNonTextDiffs + * @param gnuDiffs gnuDiffs + * @param rcsDiffs rcsDiffs + * @param diffContext diffContext + * @param summaryDiff summaryDiff + * @param unifiedDiff unifiedDiff + * @param ignoreWhitespaceChanges ignoreWhitespaceChanges + * @param ignoreWhitespace ignoreWhitespace + * @param ignoreLineEndings ignoreLineEndings + * @param stream stream + * @param parentStream parentStream */ - public GetFileDiffsOptions(boolean quiet, boolean includeNonTextDiffs, - boolean gnuDiffs, boolean rcsDiffs, - int diffContext, boolean summaryDiff, int unifiedDiff, - boolean ignoreWhitespaceChanges, boolean ignoreWhitespace, - boolean ignoreLineEndings, String stream, String parentStream) { + public GetFileDiffsOptions(boolean quiet, boolean includeNonTextDiffs, boolean gnuDiffs, boolean rcsDiffs, int diffContext, boolean summaryDiff, int unifiedDiff, boolean ignoreWhitespaceChanges, boolean ignoreWhitespace, boolean ignoreLineEndings, String stream, String parentStream) { super(); this.quiet = quiet; this.includeNonTextDiffs = includeNonTextDiffs; @@ -165,20 +182,7 @@ public GetFileDiffsOptions(boolean quiet, boolean includeNonTextDiffs, * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.isOutputDifferFilesOnly(), - this.isQuiet(), - this.isIncludeNonTextDiffs(), - this.isGnuDiffs(), - this.isRcsDiffs(), - this.getDiffContext(), - this.isSummaryDiff(), - this.isUnifiedDiff(), - this.isIgnoreWhitespaceChanges(), - this.isIgnoreWhitespace(), - this.isIgnoreLineEndings(), - this.getStream(), - this.getParentStream()); + this.optionList = this.processFields(OPTIONS_SPECS, this.isOutputDifferFilesOnly(), this.isQuiet(), this.isIncludeNonTextDiffs(), this.isGnuDiffs(), this.isRcsDiffs(), this.getDiffContext(), this.isSummaryDiff(), this.isUnifiedDiff(), this.isIgnoreWhitespaceChanges(), this.isIgnoreWhitespace(), this.isIgnoreLineEndings(), this.getStream(), this.getParentStream()); return this.optionList; } @@ -282,21 +286,21 @@ public GetFileDiffsOptions setIgnoreLineEndings(boolean ignoreLineEndings) { return this; } - public String getStream() { - return stream; - } + public String getStream() { + return stream; + } - public GetFileDiffsOptions setStream(String stream) { - this.stream = stream; - return this; + public GetFileDiffsOptions setStream(String stream) { + this.stream = stream; + return this; } public String getParentStream() { - return parentStream; + return parentStream; } public GetFileDiffsOptions setParentStream(String parentStream) { - this.parentStream = parentStream; - return this; + this.parentStream = parentStream; + return this; } } diff --git a/src/main/java/com/perforce/p4java/option/server/GetFileSizesOptions.java b/src/main/java/com/perforce/p4java/option/server/GetFileSizesOptions.java index e8aea25..bdc72bd 100644 --- a/src/main/java/com/perforce/p4java/option/server/GetFileSizesOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/GetFileSizesOptions.java @@ -1,21 +1,21 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** - * Options class for IOptionsServer.getFileSizes method.

- * + * Options class for IOptionsServer.getFileSizes method. + * * @see com.perforce.p4java.server.IOptionsServer#getFileSizes(java.util.List, com.perforce.p4java.option.server.GetFileSizesOptions) */ public class GetFileSizesOptions extends Options { - + /** *

 	 * Options:
@@ -25,19 +25,19 @@ public class GetFileSizesOptions extends Options {
 	 * 
*/ public static final String OPTIONS_SPECS = "b:a b:S b:A b:U b:s b:z l:b:gtz i:m:gtz"; - + /** * If true, lists all revisions within the specific range, rather than just * the highest revision in the range. Corresponds to the -a flag. */ protected boolean allRevisions = false; - + /** * If true, list size information for shelved files only. With this option, * revision specifications are not permitted. Corresponds to the -S flag. */ protected boolean shelvedFiles = false; - + /** * If true, list files in archive depots (see 'p4 help archive'). * Corresponds to the -A flag. @@ -68,7 +68,7 @@ public class GetFileSizesOptions extends Options { * blocksize. Corresponds to the -b flag. */ protected long blockSize = 0; - + /** * If positive, limits sizes to the first 'max' number of files. Corresponds * to the -m flag. @@ -84,19 +84,20 @@ public GetFileSizesOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public GetFileSizesOptions(String... options) { @@ -107,15 +108,7 @@ public GetFileSizesOptions(String... options) { * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.isAllRevisions(), - this.isShelvedFiles(), - this.isArchivedFiles(), - this.isUnloadedFiles(), - this.isSumFileSizes(), - this.isOmitLazyCopies(), - this.getBlockSize(), - this.getMaxFiles()); + this.optionList = this.processFields(OPTIONS_SPECS, this.isAllRevisions(), this.isShelvedFiles(), this.isArchivedFiles(), this.isUnloadedFiles(), this.isSumFileSizes(), this.isOmitLazyCopies(), this.getBlockSize(), this.getMaxFiles()); return this.optionList; } diff --git a/src/main/java/com/perforce/p4java/option/server/GetFixesOptions.java b/src/main/java/com/perforce/p4java/option/server/GetFixesOptions.java index e033eeb..7b84c8f 100644 --- a/src/main/java/com/perforce/p4java/option/server/GetFixesOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/GetFixesOptions.java @@ -1,15 +1,15 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.core.IChangelist; import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options subclass for the IServer.getFixList method. */ @@ -20,31 +20,31 @@ public class GetFixesOptions extends Options { * Options: c[changelist], -j[job], -i, m[max] */ public static final String OPTIONS_SPECS = "i:c:cl s:j b:i i:m:gtz"; - + /** * If non-negative, only fixes from the numbered changelist are listed. * Corresponds to -c. */ protected int changelistId = IChangelist.UNKNOWN; - + /** * If non-null, only fixes for the named job are listed. * Corresponds to -j. */ protected String jobId = null; - + /** * If true, include any fixes made by changelists integrated * into the specified files. Corresponds to -i. */ protected boolean includeIntegrations = false; - + /** * If positive, restrict the list to the first maxFixes fixes. * Corresponds to -m. */ protected int maxFixes = 0; - + /** * Default constructor. */ @@ -55,19 +55,20 @@ public GetFixesOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public GetFixesOptions(String... options) { @@ -76,33 +77,33 @@ public GetFixesOptions(String... options) { /** * Explicit-value constructor. + * + * @param changelistId changelistId + * @param jobId jobId + * @param includeIntegrations includeIntegrations + * @param maxFixes maxFixes */ - public GetFixesOptions(int changelistId, String jobId, - boolean includeIntegrations, int maxFixes) { + public GetFixesOptions(int changelistId, String jobId, boolean includeIntegrations, int maxFixes) { super(); this.changelistId = changelistId; this.jobId = jobId; this.includeIntegrations = includeIntegrations; this.maxFixes = maxFixes; } - + /** * IServer.getFixList-specific options processing. Uses the generic Options.processFields * method to process options according to the static OPTIONS_SPECS field; will bypass * processing if this.optionList is non-null; will set this.optionList if processing * succeeds. - * + * * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ - + @Override public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.changelistId, - this.jobId, - this.includeIntegrations, - this.maxFixes); - + this.optionList = this.processFields(OPTIONS_SPECS, this.changelistId, this.jobId, this.includeIntegrations, this.maxFixes); + return this.optionList; } diff --git a/src/main/java/com/perforce/p4java/option/server/GetInterchangesOptions.java b/src/main/java/com/perforce/p4java/option/server/GetInterchangesOptions.java index f76cb22..2491f90 100644 --- a/src/main/java/com/perforce/p4java/option/server/GetInterchangesOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/GetInterchangesOptions.java @@ -1,15 +1,15 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.core.IChangelist; import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for the IOptionsServer getInterchanges methods. Serves * for both getInterchanges method signatures, but not all options @@ -17,41 +17,41 @@ * documentation. */ public class GetInterchangesOptions extends Options { - + /** * Options: -f, -l, -C[changelist], -b[branch], -S[stream], -P[parentStream], -r, -s *

- * + * * NOTE: not all options will be recognized by the specific version of the * getInterchanges method being called. */ public static final String OPTIONS_SPECS = "b:f b:l i:C:gtz s:b s:S s:P b:r b:s"; - + /** * If true, show the individual files that would require integration. * Corresponds to -f flag. */ protected boolean showFiles = false; - + /** * If true, produce long output with the full text of the * changelist descriptions. Corresponds to -l flag. */ protected boolean longDesc = false; - + /** * If greater than zero, only consider integration history from changelists * at or below the given number. Corresponds to the undoc -C flag. */ protected int maxChangelistId = IChangelist.UNKNOWN; - + /** * If true, reverse the mappings in the branch view, with the * target files and source files exchanging place. Correspsonds * to the -r flag. */ protected boolean reverseMapping = false; - + /** * If true, causes the branch view to work * bidirectionally, where the scope of the command is limited to @@ -60,30 +60,30 @@ public class GetInterchangesOptions extends Options { */ protected boolean biDirectional = false; - /** - * If non-null, use a user-defined branch view. The source is the left - * side of the branch view and the target is the right side. With -r, - * the direction is reversed. Corresponds to -b flag. - */ - protected String branch = null; - - /** - * If not null, makes 'p4 interchanges' use a stream's branch view. The - * source is the stream itself, and the target is the stream's parent. - * With -r, the direction is reversed. -P can be used to specify a - * parent stream other than the stream's actual parent. Note that to - * submit integrated stream files, the current client must be dedicated - * to the target stream. Corresponds to -S flag. - */ - protected String stream = null; - - /** - * If non-null, specify a parent stream other than the stream's actual - * parent. Corresponds to -P flag. - */ - protected String parentStream = null; - - /** + /** + * If non-null, use a user-defined branch view. The source is the left + * side of the branch view and the target is the right side. With -r, + * the direction is reversed. Corresponds to -b flag. + */ + protected String branch = null; + + /** + * If not null, makes 'p4 interchanges' use a stream's branch view. The + * source is the stream itself, and the target is the stream's parent. + * With -r, the direction is reversed. -P can be used to specify a + * parent stream other than the stream's actual parent. Note that to + * submit integrated stream files, the current client must be dedicated + * to the target stream. Corresponds to -S flag. + */ + protected String stream = null; + + /** + * If non-null, specify a parent stream other than the stream's actual + * parent. Corresponds to -P flag. + */ + protected String parentStream = null; + + /** * Default constructor. */ public GetInterchangesOptions() { @@ -92,19 +92,20 @@ public GetInterchangesOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public GetInterchangesOptions(String... options) { @@ -113,9 +114,14 @@ public GetInterchangesOptions(String... options) { /** * Explicit-value constructor. + * + * @param showFiles showFiles + * @param longDesc longDesc + * @param maxChangelistId maxChangelistId + * @param reverseMapping reverseMapping + * @param biDirectional biDirectional */ - public GetInterchangesOptions(boolean showFiles, boolean longDesc, - int maxChangelistId, boolean reverseMapping, boolean biDirectional) { + public GetInterchangesOptions(boolean showFiles, boolean longDesc, int maxChangelistId, boolean reverseMapping, boolean biDirectional) { super(); this.showFiles = showFiles; this.longDesc = longDesc; @@ -124,12 +130,17 @@ public GetInterchangesOptions(boolean showFiles, boolean longDesc, this.biDirectional = biDirectional; } - /** - * Explicit-value constructor for use with a branch. - */ - public GetInterchangesOptions(boolean showFiles, boolean longDesc, - int maxChangelistId, String branch, boolean reverseMapping, - boolean biDirectional) { + /** + * Explicit-value constructor for use with a branch. + * + * @param showFiles showFiles + * @param longDesc longDesc + * @param maxChangelistId maxChangelistId + * @param branch branch + * @param reverseMapping reverseMapping + * @param biDirectional biDirectional + */ + public GetInterchangesOptions(boolean showFiles, boolean longDesc, int maxChangelistId, String branch, boolean reverseMapping, boolean biDirectional) { super(); this.showFiles = showFiles; this.longDesc = longDesc; @@ -140,11 +151,17 @@ public GetInterchangesOptions(boolean showFiles, boolean longDesc, } /** - * Explicit-value constructor for use with a stream. - */ - public GetInterchangesOptions(boolean showFiles, boolean longDesc, - int maxChangelistId, String stream, String parentStream, - boolean reverseMapping, boolean biDirectional) { + * Explicit-value constructor for use with a stream. + * + * @param showFiles showFiles + * @param longDesc longDesc + * @param maxChangelistId maxChangelistId + * @param stream stream + * @param parentStream parentStream + * @param reverseMapping reverseMapping + * @param biDirectional biDirectional + */ + public GetInterchangesOptions(boolean showFiles, boolean longDesc, int maxChangelistId, String stream, String parentStream, boolean reverseMapping, boolean biDirectional) { super(); this.showFiles = showFiles; this.longDesc = longDesc; @@ -159,15 +176,7 @@ public GetInterchangesOptions(boolean showFiles, boolean longDesc, * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.isShowFiles(), - this.isLongDesc(), - this.getMaxChangelistId(), - this.getBranch(), - this.getStream(), - this.getParentStream(), - this.isReverseMapping(), - this.isBiDirectional()); + this.optionList = this.processFields(OPTIONS_SPECS, this.isShowFiles(), this.isLongDesc(), this.getMaxChangelistId(), this.getBranch(), this.getStream(), this.getParentStream(), this.isReverseMapping(), this.isBiDirectional()); return optionList; } @@ -216,28 +225,28 @@ public GetInterchangesOptions setBiDirectional(boolean biDirectional) { return this; } - public String getBranch() { - return branch; - } + public String getBranch() { + return branch; + } - public GetInterchangesOptions setBranch(String branch) { - this.branch = branch; - return this; - } + public GetInterchangesOptions setBranch(String branch) { + this.branch = branch; + return this; + } public String getStream() { return stream; } - + public GetInterchangesOptions setStream(String stream) { this.stream = stream; return this; } - + public String getParentStream() { return parentStream; } - + public GetInterchangesOptions setParentStream(String parentStream) { this.parentStream = parentStream; return this; diff --git a/src/main/java/com/perforce/p4java/option/server/GetJobsOptions.java b/src/main/java/com/perforce/p4java/option/server/GetJobsOptions.java index ca9fa10..10dcbcb 100644 --- a/src/main/java/com/perforce/p4java/option/server/GetJobsOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/GetJobsOptions.java @@ -1,50 +1,50 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for the IOptionsServer getJobs method. */ public class GetJobsOptions extends Options { - + /** * Options: -e[jobview], -i, -l, -m[max], -r */ public static final String OPTIONS_SPECS = "s:e b:i b:l i:m:gtz b:r"; - + /** * If greater than zero, limit the output to the first maxJobs jobs. * Corresponds to the -m flag. */ protected int maxJobs = 0; - + /** * If true, return full descriptions, otherwise show * only a subset (typically the first 128 characters, but * this is not guaranteed). Corresponds to the -l flag. */ protected boolean longDescriptions = false; - + /** * If true, reverse the normal sort order. * Corresponds to the -r flag. */ protected boolean reverseOrder = false; - + /** * If true, include any fixes made by changelists * integrated into the specified files. Corresponds to * the -i flag. */ protected boolean includeIntegrated = false; - + /** * If not null, this should be a string in format detailed by "p4 help jobview" * used to restrict jobs to those satisfying the job view expression. @@ -62,19 +62,20 @@ public GetJobsOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public GetJobsOptions(String... options) { @@ -83,9 +84,14 @@ public GetJobsOptions(String... options) { /** * Explicit-value constructor. + * + * @param maxJobs maxJobs + * @param longDescriptions longDescriptions + * @param reverseOrder reverseOrder + * @param includeIntegrated includeIntegrated + * @param jobView jobView */ - public GetJobsOptions(int maxJobs, boolean longDescriptions, - boolean reverseOrder, boolean includeIntegrated, String jobView) { + public GetJobsOptions(int maxJobs, boolean longDescriptions, boolean reverseOrder, boolean includeIntegrated, String jobView) { super(); this.maxJobs = maxJobs; this.longDescriptions = longDescriptions; @@ -98,12 +104,7 @@ public GetJobsOptions(int maxJobs, boolean longDescriptions, * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.getJobView(), - this.isIncludeIntegrated(), - this.isLongDescriptions(), - this.getMaxJobs(), - this.isReverseOrder()); + this.optionList = this.processFields(OPTIONS_SPECS, this.getJobView(), this.isIncludeIntegrated(), this.isLongDescriptions(), this.getMaxJobs(), this.isReverseOrder()); return this.optionList; } diff --git a/src/main/java/com/perforce/p4java/option/server/GetKeysOptions.java b/src/main/java/com/perforce/p4java/option/server/GetKeysOptions.java index b880c63..cfaea37 100644 --- a/src/main/java/com/perforce/p4java/option/server/GetKeysOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/GetKeysOptions.java @@ -1,47 +1,47 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for the IOptionsServer's getKeys method. */ public class GetKeysOptions extends Options { - - /** - * Options: -u, -e[nameFilter] ..., -m[max] - */ - public static final String OPTIONS_SPECS = "b:u s:e s[]:e i:m:gtz"; - - + + /** + * Options: -u, -e[nameFilter] ..., -m[max] + */ + public static final String OPTIONS_SPECS = "b:u s:e s[]:e i:m:gtz"; + + protected boolean undocKey = false; - /** - * If non-null, limits output to keys whose name matches - * the nameFilter pattern. Corresponds to '-e nameFilter' flag - */ - protected String nameFilter = null; - - /** - * If non-null, limits output to keys whose name matches - * any of the nameFilter patterns. Corresponds to the multiple - * '-u -e nameFilter -e nameFilter -e nameFilter ...' flags. - */ - protected String[] nameFilters = null; - - /** - * If greater than zero, limit output to the first maxResults - * number of keys. Corresponds to '-m max' flag. - */ - protected int maxResults = 0; - - /** + /** + * If non-null, limits output to keys whose name matches + * the nameFilter pattern. Corresponds to '-e nameFilter' flag + */ + protected String nameFilter = null; + + /** + * If non-null, limits output to keys whose name matches + * any of the nameFilter patterns. Corresponds to the multiple + * '-u -e nameFilter -e nameFilter -e nameFilter ...' flags. + */ + protected String[] nameFilters = null; + + /** + * If greater than zero, limit output to the first maxResults + * number of keys. Corresponds to '-m max' flag. + */ + protected int maxResults = 0; + + /** * Default constructor. */ public GetKeysOptions() { @@ -51,45 +51,45 @@ public GetKeysOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public GetKeysOptions(String... options) { super(options); } - + /** * Explicit value constructor. + * + * @param undocKey undocKey + * @param nameFilter nameFilter + * @param maxResults maxResults */ - public GetKeysOptions(boolean undocKey, String nameFilter, - int maxResults) { + public GetKeysOptions(boolean undocKey, String nameFilter, int maxResults) { super(); this.undocKey = undocKey; this.nameFilter = nameFilter; this.maxResults = maxResults; } - + /** * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.isUndocKey(), - this.getNameFilter(), - this.getNameFilters(), - this.getMaxResults()); + this.optionList = this.processFields(OPTIONS_SPECS, this.isUndocKey(), this.getNameFilter(), this.getNameFilters(), this.getMaxResults()); return this.optionList; } @@ -120,7 +120,7 @@ public GetKeysOptions setNameFilters(String[] nameFilters) { this.nameFilters = nameFilters; return this; } - + public int getMaxResults() { return maxResults; } diff --git a/src/main/java/com/perforce/p4java/option/server/GetLabelsOptions.java b/src/main/java/com/perforce/p4java/option/server/GetLabelsOptions.java index 5ef8f65..3c16e01 100644 --- a/src/main/java/com/perforce/p4java/option/server/GetLabelsOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/GetLabelsOptions.java @@ -3,12 +3,12 @@ */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for the server's getLabels method. * @@ -16,173 +16,182 @@ */ public class GetLabelsOptions extends Options { - /** - * Options: -m[max], -u[user], -e[nameFilter], -E[nameFilter], -t - *

- * Options: -U - */ - public static final String OPTIONS_SPECS = "i:m:gtz s:u s:e s:E b:t b:U"; - - /** - * If non-null, limit qualifying labels to those owned by the named user. - * Corresponds to -uname flag. - */ - protected String userName = null; - - /** - * If non-null, limits output to labels whose name matches - * the nameFilter pattern. Corresponds to -enameFilter flag - */ - protected String nameFilter = null; - - /** - * If non-null, limits output to labels whose name matches (case-insensitive) - * the nameFilter pattern. Corresponds to -EnameFilter flag - */ - protected String caseInsensitiveNameFilter = null; - - /** - * If greater than zero, limit output to the first maxResults - * number of labels. Corresponds to -m flag. - */ - protected int maxResults = 0; - - /** - * If true, displays the time as well as the date. Corresponds to -t flag. - */ - protected boolean showTime = false; - - /** - * If true, lists unloaded labels. Corresponds to -U flag. - */ - protected boolean unloaded = false; - - /** - * Default constructor; sets all fields to null, zero, or false. - */ - public GetLabelsOptions() { - super(); - } - - /** - * Strings-based constructor; see 'p4 help [command]' for possible options. - *

- * - * WARNING: you should not pass more than one option or argument in each - * string parameter. Each option or argument should be passed-in as its own - * separate string parameter, without any spaces between the option and the - * option value (if any). - *

- * - * NOTE: setting options this way always bypasses the internal options - * values, and getter methods against the individual values corresponding to - * the strings passed in to this constructor will not normally reflect the - * string's setting. Do not use this constructor unless you know what you're - * doing and / or you do not also use the field getters and setters. - * - * @see com.perforce.p4java.option.Options#Options(java.lang.String...) - */ - public GetLabelsOptions(String... options) { - super(options); - } - - /** - * Explicit-value constructor. - */ - public GetLabelsOptions(int maxResults, String userName, String nameFilter) { - super(); - this.maxResults = maxResults; - this.userName = userName; - this.nameFilter = nameFilter; - } - - /** - * Explicit-value constructor. - */ - public GetLabelsOptions(int maxResults, String userName, String nameFilter, boolean showTime) { - super(); - this.maxResults = maxResults; - this.userName = userName; - this.nameFilter = nameFilter; - this.showTime = showTime; - } - - /** - * Explicit-value constructor. - */ - public GetLabelsOptions(boolean showTime, String userName, String caseInsensitiveNameFilter, int maxResults) { - super(); - this.showTime = showTime; - this.userName = userName; - this.caseInsensitiveNameFilter = caseInsensitiveNameFilter; - this.maxResults = maxResults; - } - - /** - * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) - */ - public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.getMaxResults(), - this.getUserName(), - this.getNameFilter(), - this.getCaseInsensitiveNameFilter(), - this.isShowTime(), - this.isUnloaded()); - return this.optionList; - } - - public int getMaxResults() { - return maxResults; - } - - public GetLabelsOptions setMaxResults(int maxResults) { - this.maxResults = maxResults; - return this; - } - - public String getUserName() { - return userName; - } - - public GetLabelsOptions setUserName(String userName) { - this.userName = userName; - return this; - } - - public String getNameFilter() { - return nameFilter; - } - - public GetLabelsOptions setNameFilter(String nameFilter) { - this.nameFilter = nameFilter; - return this; - } - - public String getCaseInsensitiveNameFilter() { - return caseInsensitiveNameFilter; - } - - public GetLabelsOptions setCaseInsensitiveNameFilter(String caseInsensitiveNameFilter) { - this.caseInsensitiveNameFilter = caseInsensitiveNameFilter; - return this; - } - - public boolean isShowTime() { - return showTime; - } - - public GetLabelsOptions setShowTime(boolean showTime) { - this.showTime = showTime; - return this; - } - - public boolean isUnloaded() { - return unloaded; - } - - public GetLabelsOptions setUnloaded(boolean unloaded) { - this.unloaded = unloaded; - return this; - } + /** + * Options: -m[max], -u[user], -e[nameFilter], -E[nameFilter], -t + *

+ * Options: -U + */ + public static final String OPTIONS_SPECS = "i:m:gtz s:u s:e s:E b:t b:U"; + + /** + * If non-null, limit qualifying labels to those owned by the named user. + * Corresponds to -uname flag. + */ + protected String userName = null; + + /** + * If non-null, limits output to labels whose name matches + * the nameFilter pattern. Corresponds to -enameFilter flag + */ + protected String nameFilter = null; + + /** + * If non-null, limits output to labels whose name matches (case-insensitive) + * the nameFilter pattern. Corresponds to -EnameFilter flag + */ + protected String caseInsensitiveNameFilter = null; + + /** + * If greater than zero, limit output to the first maxResults + * number of labels. Corresponds to -m flag. + */ + protected int maxResults = 0; + + /** + * If true, displays the time as well as the date. Corresponds to -t flag. + */ + protected boolean showTime = false; + + /** + * If true, lists unloaded labels. Corresponds to -U flag. + */ + protected boolean unloaded = false; + + /** + * Default constructor; sets all fields to null, zero, or false. + */ + public GetLabelsOptions() { + super(); + } + + /** + * Strings-based constructor; see 'p4 help [command]' for possible options. + *

+ * + * WARNING: you should not pass more than one option or argument in each + * string parameter. Each option or argument should be passed-in as its own + * separate string parameter, without any spaces between the option and the + * option value (if any). + *

+ * + * NOTE: setting options this way always bypasses the internal options + * values, and getter methods against the individual values corresponding to + * the strings passed in to this constructor will not normally reflect the + * string's setting. Do not use this constructor unless you know what you're + * doing and / or you do not also use the field getters and setters. + * + * @param options options + * @see com.perforce.p4java.option.Options#Options(java.lang.String...) + */ + public GetLabelsOptions(String... options) { + super(options); + } + + /** + * Explicit-value constructor. + * + * @param maxResults maxResults + * @param userName userName + * @param nameFilter nameFilter + */ + public GetLabelsOptions(int maxResults, String userName, String nameFilter) { + super(); + this.maxResults = maxResults; + this.userName = userName; + this.nameFilter = nameFilter; + } + + /** + * Explicit-value constructor. + * + * @param maxResults maxResults + * @param userName userName + * @param nameFilter nameFilter + * @param showTime showTime + */ + public GetLabelsOptions(int maxResults, String userName, String nameFilter, boolean showTime) { + super(); + this.maxResults = maxResults; + this.userName = userName; + this.nameFilter = nameFilter; + this.showTime = showTime; + } + + /** + * Explicit-value constructor. + * + * @param showTime showTime + * @param userName userName + * @param caseInsensitiveNameFilter caseInsensitiveNameFilter + * @param maxResults maxResults + */ + public GetLabelsOptions(boolean showTime, String userName, String caseInsensitiveNameFilter, int maxResults) { + super(); + this.showTime = showTime; + this.userName = userName; + this.caseInsensitiveNameFilter = caseInsensitiveNameFilter; + this.maxResults = maxResults; + } + + /** + * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) + */ + public List processOptions(IServer server) throws OptionsException { + this.optionList = this.processFields(OPTIONS_SPECS, this.getMaxResults(), this.getUserName(), this.getNameFilter(), this.getCaseInsensitiveNameFilter(), this.isShowTime(), this.isUnloaded()); + return this.optionList; + } + + public int getMaxResults() { + return maxResults; + } + + public GetLabelsOptions setMaxResults(int maxResults) { + this.maxResults = maxResults; + return this; + } + + public String getUserName() { + return userName; + } + + public GetLabelsOptions setUserName(String userName) { + this.userName = userName; + return this; + } + + public String getNameFilter() { + return nameFilter; + } + + public GetLabelsOptions setNameFilter(String nameFilter) { + this.nameFilter = nameFilter; + return this; + } + + public String getCaseInsensitiveNameFilter() { + return caseInsensitiveNameFilter; + } + + public GetLabelsOptions setCaseInsensitiveNameFilter(String caseInsensitiveNameFilter) { + this.caseInsensitiveNameFilter = caseInsensitiveNameFilter; + return this; + } + + public boolean isShowTime() { + return showTime; + } + + public GetLabelsOptions setShowTime(boolean showTime) { + this.showTime = showTime; + return this; + } + + public boolean isUnloaded() { + return unloaded; + } + + public GetLabelsOptions setUnloaded(boolean unloaded) { + this.unloaded = unloaded; + return this; + } } diff --git a/src/main/java/com/perforce/p4java/option/server/GetPropertyOptions.java b/src/main/java/com/perforce/p4java/option/server/GetPropertyOptions.java index b3a2fdd..ad58f6d 100644 --- a/src/main/java/com/perforce/p4java/option/server/GetPropertyOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/GetPropertyOptions.java @@ -1,24 +1,24 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for IOptionsServer's getPropertyValues methods. */ public class GetPropertyOptions extends Options { - + /** * Options: [-A] [-n name [-s sequence] [-u user | -g group]] [-F filter -T taglist -m max] */ public static final String OPTIONS_SPECS = "b:A s:n i:s:gtz s:u s:g s:F s:T i:m:gtz"; - + /** * If true, specifies that properties for all users and groups should be * listed. This option requires the user to have 'admin' access granted by @@ -31,7 +31,7 @@ public class GetPropertyOptions extends Options { * Corresponds to the -n flag. */ protected String name = null; - + /** * If greater than zero, use this as the sequence number of this property. * If the sequence is not specified, it defaults to 1. @@ -51,28 +51,28 @@ public class GetPropertyOptions extends Options { */ protected String group = null; - /** - * If non-null, limits output to properties matching the filter pattern. - * The filter is composed of an exact field name and a field value pattern. - * (i.e. -F"name=test-property*"). This option can only be used with tagged - * format (ztag). Corresponds to '-F' flag. - */ - protected String filter = null; - - /** - * If non-null, limit the fields that are returned to the tagged format - * output fields. Separate multiple tagged format output fields with commas - * (i.e. -T"name,sequence,value,time"). This option can only be used with - * tagged format (-ztag). Corresponds to '-T' flag. - */ - protected String fields = null; - + /** + * If non-null, limits output to properties matching the filter pattern. + * The filter is composed of an exact field name and a field value pattern. + * (i.e. -F"name=test-property*"). This option can only be used with tagged + * format (ztag). Corresponds to '-F' flag. + */ + protected String filter = null; + + /** + * If non-null, limit the fields that are returned to the tagged format + * output fields. Separate multiple tagged format output fields with commas + * (i.e. -T"name,sequence,value,time"). This option can only be used with + * tagged format (-ztag). Corresponds to '-T' flag. + */ + protected String fields = null; + /** * If greater than zero, limits output to the first 'max' number of * properties. Corresponds to -m flag. */ protected int max = 0; - + /** * Default constructor. */ @@ -83,31 +83,39 @@ public GetPropertyOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public GetPropertyOptions(String... options) { super(options); } - + /** * Explicit value constructor. + * + * @param listAll listAll + * @param name name + * @param sequence sequence + * @param user user + * @param group group + * @param filter filter + * @param fields fields + * @param max max */ - public GetPropertyOptions(boolean listAll, String name, - int sequence, String user, String group, String filter, - String fields, int max) { + public GetPropertyOptions(boolean listAll, String name, int sequence, String user, String group, String filter, String fields, int max) { super(); this.listAll = listAll; this.name = name; @@ -118,20 +126,12 @@ public GetPropertyOptions(boolean listAll, String name, this.fields = fields; this.max = max; } - + /** * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.isListAll(), - this.getName(), - this.getSequence(), - this.getUser(), - this.getGroup(), - this.getFilter(), - this.getFields(), - this.getMax()); + this.optionList = this.processFields(OPTIONS_SPECS, this.isListAll(), this.getName(), this.getSequence(), this.getUser(), this.getGroup(), this.getFilter(), this.getFields(), this.getMax()); return this.optionList; } diff --git a/src/main/java/com/perforce/p4java/option/server/GetProtectionEntriesOptions.java b/src/main/java/com/perforce/p4java/option/server/GetProtectionEntriesOptions.java index eb50583..71e12bb 100644 --- a/src/main/java/com/perforce/p4java/option/server/GetProtectionEntriesOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/GetProtectionEntriesOptions.java @@ -1,36 +1,36 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options subclass for the IOptionsServer.getProtectionEntries method. - * + * * @see com.perforce.p4java.server.IOptionsServer#getProtectionEntries(List, GetProtectionEntriesOptions) */ public class GetProtectionEntriesOptions extends Options { - + /** * Options: -a, -g[group], -u[user], -h[host] */ public static final String OPTIONS_SPECS = "b:a s:g s:u s:h"; - + /** If true,protection lines for all users are displayed; corresponds to the -a flag. */ protected boolean allUsers = false; - + /** If not null, only those protection lines that apply to the given host (IP address) * are displayed; corresponds to the -h flag. */ protected String hostName = null; - + /** If not null, protection lines for the named user are displayed; -u flag */ protected String userName = null; - + /** If not null, protection lines for the named group are displayed; -g flag */ protected String groupName = null; @@ -44,19 +44,20 @@ public GetProtectionEntriesOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public GetProtectionEntriesOptions(String... options) { @@ -65,9 +66,13 @@ public GetProtectionEntriesOptions(String... options) { /** * Explicit-value constructor. + * + * @param allUsers allUsers + * @param hostName hostName + * @param userName userName + * @param groupName groupName */ - public GetProtectionEntriesOptions(boolean allUsers, String hostName, - String userName, String groupName) { + public GetProtectionEntriesOptions(boolean allUsers, String hostName, String userName, String groupName) { super(); this.allUsers = allUsers; this.hostName = hostName; @@ -79,11 +84,7 @@ public GetProtectionEntriesOptions(boolean allUsers, String hostName, * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.isAllUsers(), - this.getGroupName(), - this.getUserName(), - this.getHostName()); + this.optionList = this.processFields(OPTIONS_SPECS, this.isAllUsers(), this.getGroupName(), this.getUserName(), this.getHostName()); return this.optionList; } diff --git a/src/main/java/com/perforce/p4java/option/server/GetReviewChangelistsOptions.java b/src/main/java/com/perforce/p4java/option/server/GetReviewChangelistsOptions.java index 6e57327..c284177 100644 --- a/src/main/java/com/perforce/p4java/option/server/GetReviewChangelistsOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/GetReviewChangelistsOptions.java @@ -3,25 +3,25 @@ */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.core.IChangelist; import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for the IOptionsServer.getReviewChangelists method. - * + * * @see com.perforce.p4java.server.IOptionsServer#getReviewChangelists(com.perforce.p4java.option.server.GetReviewChangelistsOptions) */ public class GetReviewChangelistsOptions extends Options { - + /** * Options: -c[changelist], -t[counter] */ public static final String OPTIONS_SPECS = "i:c:clz s:t"; - + /** * If greater than zero, lists changelists that have not been reviewed * before, equal or above the specified changelist#. @@ -31,15 +31,15 @@ public class GetReviewChangelistsOptions extends Options { /** * If not null, lists changelists that have not been reviewed before, above - * the specified counter's changelist#.

- * + * the specified counter's changelist#. + *

* Note, if both the 'changelistId' and 'counter' options are specified, the * 'p4 review' sets the counter to that changelist# and produces no output. * This functionality has been superceded by the 'p4 counter' command. * Corresponds to -t counter. */ protected String counter = null; - + /** * Default constructor. */ @@ -50,19 +50,20 @@ public GetReviewChangelistsOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public GetReviewChangelistsOptions(String... options) { @@ -71,6 +72,9 @@ public GetReviewChangelistsOptions(String... options) { /** * Explicit-value constructor. + * + * @param changelistId changelistId + * @param counter counter */ public GetReviewChangelistsOptions(int changelistId, String counter) { super(); diff --git a/src/main/java/com/perforce/p4java/option/server/GetReviewsOptions.java b/src/main/java/com/perforce/p4java/option/server/GetReviewsOptions.java index 04a650a..9e51fa8 100644 --- a/src/main/java/com/perforce/p4java/option/server/GetReviewsOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/GetReviewsOptions.java @@ -1,27 +1,27 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.core.IChangelist; import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for the IOptionsServer.getReviews method. - * + * * @see com.perforce.p4java.server.IOptionsServer#getReviews(java.util.List, com.perforce.p4java.option.server.GetReviewsOptions) */ public class GetReviewsOptions extends Options { - + /** * Options: -c[changelist] */ public static final String OPTIONS_SPECS = "i:c:cl"; - + /** * If non-negative, use the value of changelistId for * the changelist; use IChangelist.DEFAULT for the default changelist. @@ -39,19 +39,20 @@ public GetReviewsOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public GetReviewsOptions(String... options) { @@ -60,6 +61,8 @@ public GetReviewsOptions(String... options) { /** * Explicit-value constructor. + * + * @param changelistId changelistId */ public GetReviewsOptions(int changelistId) { super(); @@ -70,8 +73,7 @@ public GetReviewsOptions(int changelistId) { * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.getChangelistId()); + this.optionList = this.processFields(OPTIONS_SPECS, this.getChangelistId()); return this.optionList; } diff --git a/src/main/java/com/perforce/p4java/option/server/GetRevisionHistoryOptions.java b/src/main/java/com/perforce/p4java/option/server/GetRevisionHistoryOptions.java index 89e7d9a..c6c58e2 100644 --- a/src/main/java/com/perforce/p4java/option/server/GetRevisionHistoryOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/GetRevisionHistoryOptions.java @@ -1,71 +1,71 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.core.IChangelist; import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for IOptionsServer.getRevisionHistory method.

- * + * * Note that behavior is undefined if both longOutput and truncatedLongOutput are true. * If both are false, a short form of the description (prepared by the server) is returned. - * + * * @see com.perforce.p4java.server.IOptionsServer#getRevisionHistory(java.util.List, com.perforce.p4java.option.server.GetRevisionHistoryOptions) */ public class GetRevisionHistoryOptions extends Options { - + /** * Options: -c[changelist], -m[max], -h, -i, -l, -L, -s */ public static final String OPTIONS_SPECS = "i:c:clz i:m:gtz b:h b:i b:l b:L b:s"; - + /** * If positive, displays only files submitted at the given changelist number. * Corresponds to -c#. */ protected int changelistId = IChangelist.UNKNOWN; - + /** * If positive, displays at most 'maxRevs' revisions per file of * the file[rev] argument specified. Corresponds to -m. */ protected int maxRevs = 0; - + /** * If true, display file content history instead of file name history. * Corresponds to -h. */ protected boolean contentHistory = false; - + /** * If true, causes inherited file history to be displayed as well. * Corresponds to -i. */ protected boolean includeInherited = false; - + /** * If true, produces long output with the full text of the * changelist descriptions. Corresponds to -l. */ protected boolean longOutput = false; - + /** * If true, produces long output with the full text of the * changelist descriptions truncated to 250 characters. * Corresponds to -L. */ protected boolean truncatedLongOutput = false; - + /** * If true, omit non-contributory integrations; * corresponds to -s. - * + * * @since 2011.1 */ protected boolean omitNonContributaryIntegrations = false; @@ -79,19 +79,20 @@ public GetRevisionHistoryOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public GetRevisionHistoryOptions(String... options) { @@ -100,10 +101,15 @@ public GetRevisionHistoryOptions(String... options) { /** * Explicit-value constructor. + * + * @param changelistId changelistId + * @param maxRevs maxRevs + * @param contentHistory contentHistory + * @param includeInherited includeInherited + * @param longOutput longOutput + * @param truncatedLongOutput truncatedLongOutput */ - public GetRevisionHistoryOptions(int changelistId, int maxRevs, - boolean contentHistory, boolean includeInherited, - boolean longOutput, boolean truncatedLongOutput) { + public GetRevisionHistoryOptions(int changelistId, int maxRevs, boolean contentHistory, boolean includeInherited, boolean longOutput, boolean truncatedLongOutput) { super(); this.changelistId = changelistId; this.maxRevs = maxRevs; @@ -112,16 +118,20 @@ public GetRevisionHistoryOptions(int changelistId, int maxRevs, this.longOutput = longOutput; this.truncatedLongOutput = truncatedLongOutput; } - + /** * Explicit-value constructor. - * + * + * @param changelistId changelistId + * @param maxRevs maxRevs + * @param contentHistory contentHistory + * @param includeInherited includeInherited + * @param longOutput longOutput + * @param truncatedLongOutput truncatedLongOutput + * @param omitNonContributaryIntegrations omitNonContributaryIntegrations * @since 2011.1 */ - public GetRevisionHistoryOptions(int changelistId, int maxRevs, - boolean contentHistory, boolean includeInherited, - boolean longOutput, boolean truncatedLongOutput, - boolean omitNonContributaryIntegrations) { + public GetRevisionHistoryOptions(int changelistId, int maxRevs, boolean contentHistory, boolean includeInherited, boolean longOutput, boolean truncatedLongOutput, boolean omitNonContributaryIntegrations) { super(); this.changelistId = changelistId; this.maxRevs = maxRevs; @@ -136,14 +146,7 @@ public GetRevisionHistoryOptions(int changelistId, int maxRevs, * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.getChangelistId(), - this.getMaxRevs(), - this.isContentHistory(), - this.isIncludeInherited(), - this.isLongOutput(), - this.isTruncatedLongOutput(), - this.isOmitNonContributaryIntegrations()); + this.optionList = this.processFields(OPTIONS_SPECS, this.getChangelistId(), this.getMaxRevs(), this.isContentHistory(), this.isIncludeInherited(), this.isLongOutput(), this.isTruncatedLongOutput(), this.isOmitNonContributaryIntegrations()); return this.optionList; } @@ -203,16 +206,18 @@ public GetRevisionHistoryOptions setTruncatedLongOutput(boolean truncatedLongOut /** * @since 2011.1 + * @return result */ public boolean isOmitNonContributaryIntegrations() { return omitNonContributaryIntegrations; } /** + * @param omitNonContributaryIntegrations option * @since 2011.1 + * @return result */ - public GetRevisionHistoryOptions setOmitNonContributaryIntegrations( - boolean omitNonContributaryIntegrations) { + public GetRevisionHistoryOptions setOmitNonContributaryIntegrations(boolean omitNonContributaryIntegrations) { this.omitNonContributaryIntegrations = omitNonContributaryIntegrations; return this; } diff --git a/src/main/java/com/perforce/p4java/option/server/GetServerProcessesOptions.java b/src/main/java/com/perforce/p4java/option/server/GetServerProcessesOptions.java index e4806a7..5f4144d 100644 --- a/src/main/java/com/perforce/p4java/option/server/GetServerProcessesOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/GetServerProcessesOptions.java @@ -1,26 +1,26 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for Perforce IOptionsServer.getServerProcesses method.

- * + * * See 'p4 help monitor' for help specifying the monitor 'show' flags. */ public class GetServerProcessesOptions extends Options { - + /** * Options: -a, -e, -l, -s R/T/P/I */ public static final String OPTIONS_SPECS = "b:a b:e b:l s:s"; - + /** * If true, includes the command args. Corresponds to the -a flag. */ @@ -56,46 +56,47 @@ public GetServerProcessesOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public GetServerProcessesOptions(String... options) { super(options); } - + /** * Explicit value constructor. + * + * @param includeCmdArgs includeCmdArgs + * @param includeCmdEnv includeCmdEnv + * @param longOutput longOutput + * @param processState processState */ - public GetServerProcessesOptions(boolean includeCmdArgs, boolean includeCmdEnv, - boolean longOutput, String processState) { + public GetServerProcessesOptions(boolean includeCmdArgs, boolean includeCmdEnv, boolean longOutput, String processState) { super(); this.includeCmdArgs = includeCmdArgs; this.includeCmdEnv = includeCmdEnv; this.longOutput = longOutput; this.processState = processState; } - + /** * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.isIncludeCmdArgs(), - this.isIncludeCmdEnv(), - this.isLongOutput(), - this.getProcessState()); + this.optionList = this.processFields(OPTIONS_SPECS, this.isIncludeCmdArgs(), this.isIncludeCmdEnv(), this.isLongOutput(), this.getProcessState()); return this.optionList; } diff --git a/src/main/java/com/perforce/p4java/option/server/GetStreamOptions.java b/src/main/java/com/perforce/p4java/option/server/GetStreamOptions.java index 1c57f47..69ea6f5 100644 --- a/src/main/java/com/perforce/p4java/option/server/GetStreamOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/GetStreamOptions.java @@ -3,12 +3,12 @@ */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for IOptionsServer.getStream method. * @@ -16,69 +16,71 @@ */ public class GetStreamOptions extends Options { - /** - * Options: -v - */ - public static final String OPTIONS_SPECS = "b:v"; + /** + * Options: -v + */ + public static final String OPTIONS_SPECS = "b:v"; - /** - * If true, expose the automatically generated client view for this stream. - * Corresponds to -v. - */ - protected boolean exposeClientView = false; + /** + * If true, expose the automatically generated client view for this stream. + * Corresponds to -v. + */ + protected boolean exposeClientView = false; - /** - * Default constructor. - */ - public GetStreamOptions() { - super(); - } + /** + * Default constructor. + */ + public GetStreamOptions() { + super(); + } - /** - * Strings-based constructor; see 'p4 help [command]' for possible options. - *

- * - * WARNING: you should not pass more than one option or argument in each - * string parameter. Each option or argument should be passed-in as its own - * separate string parameter, without any spaces between the option and the - * option value (if any). - *

- * - * NOTE: setting options this way always bypasses the internal options - * values, and getter methods against the individual values corresponding to - * the strings passed in to this constructor will not normally reflect the - * string's setting. Do not use this constructor unless you know what you're - * doing and / or you do not also use the field getters and setters. - * - * @see com.perforce.p4java.option.Options#Options(java.lang.String...) - */ - public GetStreamOptions(String... options) { - super(options); - } + /** + * Strings-based constructor; see 'p4 help [command]' for possible options. + *

+ * + * WARNING: you should not pass more than one option or argument in each + * string parameter. Each option or argument should be passed-in as its own + * separate string parameter, without any spaces between the option and the + * option value (if any). + *

+ * + * NOTE: setting options this way always bypasses the internal options + * values, and getter methods against the individual values corresponding to + * the strings passed in to this constructor will not normally reflect the + * string's setting. Do not use this constructor unless you know what you're + * doing and / or you do not also use the field getters and setters. + * + * @param options options + * @see com.perforce.p4java.option.Options#Options(java.lang.String...) + */ + public GetStreamOptions(String... options) { + super(options); + } - /** - * Explicit-value constructor. - */ - public GetStreamOptions(boolean exposeClientView) { - super(); - this.exposeClientView = exposeClientView; - } + /** + * Explicit-value constructor. + * + * @param exposeClientView exposeClientView + */ + public GetStreamOptions(boolean exposeClientView) { + super(); + this.exposeClientView = exposeClientView; + } - /** - * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) - */ - public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.isExposeClientView()); - return this.optionList; - } + /** + * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) + */ + public List processOptions(IServer server) throws OptionsException { + this.optionList = this.processFields(OPTIONS_SPECS, this.isExposeClientView()); + return this.optionList; + } - public boolean isExposeClientView() { - return exposeClientView; - } + public boolean isExposeClientView() { + return exposeClientView; + } - public GetStreamOptions setExposeClientView(boolean exposeClientView) { - this.exposeClientView = exposeClientView; - return this; - } + public GetStreamOptions setExposeClientView(boolean exposeClientView) { + this.exposeClientView = exposeClientView; + return this; + } } diff --git a/src/main/java/com/perforce/p4java/option/server/GetStreamsOptions.java b/src/main/java/com/perforce/p4java/option/server/GetStreamsOptions.java index 41a1e4e..9f6a0f3 100644 --- a/src/main/java/com/perforce/p4java/option/server/GetStreamsOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/GetStreamsOptions.java @@ -3,12 +3,12 @@ */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for IOptionsServer.getStreams method. * @@ -16,127 +16,127 @@ */ public class GetStreamsOptions extends Options { - /** - * Options: -U -F["filter"], -T["fields"], -m[max] - */ - public static final String OPTIONS_SPECS = "b:U s:F s:T i:m:gtz"; - - /** - * If true, lists unloaded task streams (see 'p4 help unload'). - * Corresponds to -U flag. - */ - protected boolean unloaded = false; - - /** - * The -F filter flag limits the output to files satisfying the - * expression given as 'filter'. This filter expression is similar to - * the one used by 'jobs -e jobview', except that fields must match - * those above and are case sensitive.

- * - * e.g. -F "Parent=//Ace/MAIN & Type=development" - */ - protected String filter = null; - - /** - * The -T fields flag (used with tagged output) limits the fields output - * to those specified by a list given as 'fields'. These field names can - * be separated by a space or a comma.

- * - * e.g. -T "Stream, Owner" - */ - protected String fields = null; - - /** - * If greater than zero, limit output to the first maxResults - * number of branches. Corresponds to -m flag. - */ - protected int maxResults = 0; - - /** - * Default constructor. - */ - public GetStreamsOptions() { - super(); - } - - /** - * Strings-based constructor; see 'p4 help [command]' for possible options. - *

- * - * WARNING: you should not pass more than one option or argument in each - * string parameter. Each option or argument should be passed-in as its own - * separate string parameter, without any spaces between the option and the - * option value (if any). - *

- * - * NOTE: setting options this way always bypasses the internal options - * values, and getter methods against the individual values corresponding to - * the strings passed in to this constructor will not normally reflect the - * string's setting. Do not use this constructor unless you know what you're - * doing and / or you do not also use the field getters and setters. - * - * @see com.perforce.p4java.option.Options#Options(java.lang.String...) - */ - public GetStreamsOptions(String... options) { - super(options); - } - - /** - * Explicit-value constructor. - */ - public GetStreamsOptions(String filter, String fields, - int maxResults) { - super(); - this.filter = filter; - this.fields = fields; - this.maxResults = maxResults; - } - - /** - * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) - */ - public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.isUnloaded(), - this.getFilter(), - this.getFields(), - this.getMaxResults()); - return this.optionList; - } - - public boolean isUnloaded() { - return unloaded; - } - - public GetStreamsOptions setUnloaded(boolean unloaded) { - this.unloaded = unloaded; - return this; - } - - public String getFilter() { - return filter; - } - - public GetStreamsOptions setFilter(String filter) { - this.filter = filter; - return this; - } - - public String getFields() { - return fields; - } - - public GetStreamsOptions setFields(String fields) { - this.fields = fields; - return this; - } - - public int getMaxResults() { - return maxResults; - } - - public GetStreamsOptions setMaxResults(int maxResults) { - this.maxResults = maxResults; - return this; - } + /** + * Options: -U -F["filter"], -T["fields"], -m[max] + */ + public static final String OPTIONS_SPECS = "b:U s:F s:T i:m:gtz"; + + /** + * If true, lists unloaded task streams (see 'p4 help unload'). + * Corresponds to -U flag. + */ + protected boolean unloaded = false; + + /** + * The -F filter flag limits the output to files satisfying the + * expression given as 'filter'. This filter expression is similar to + * the one used by 'jobs -e jobview', except that fields must match + * those above and are case sensitive.

+ * + * {@code e.g. -F "Parent=//Ace/MAIN & Type=development"} + */ + protected String filter = null; + + /** + * The -T fields flag (used with tagged output) limits the fields output + * to those specified by a list given as 'fields'. These field names can + * be separated by a space or a comma.

+ * + * e.g. -T "Stream, Owner" + */ + protected String fields = null; + + /** + * If greater than zero, limit output to the first maxResults + * number of branches. Corresponds to -m flag. + */ + protected int maxResults = 0; + + /** + * Default constructor. + */ + public GetStreamsOptions() { + super(); + } + + /** + * Strings-based constructor; see 'p4 help [command]' for possible options. + *

+ * + * WARNING: you should not pass more than one option or argument in each + * string parameter. Each option or argument should be passed-in as its own + * separate string parameter, without any spaces between the option and the + * option value (if any). + *

+ * + * NOTE: setting options this way always bypasses the internal options + * values, and getter methods against the individual values corresponding to + * the strings passed in to this constructor will not normally reflect the + * string's setting. Do not use this constructor unless you know what you're + * doing and / or you do not also use the field getters and setters. + * + * @param options options + * @see com.perforce.p4java.option.Options#Options(java.lang.String...) + */ + public GetStreamsOptions(String... options) { + super(options); + } + + /** + * Explicit-value constructor. + * + * @param filter filter + * @param fields fields + * @param maxResults maxResults + */ + public GetStreamsOptions(String filter, String fields, int maxResults) { + super(); + this.filter = filter; + this.fields = fields; + this.maxResults = maxResults; + } + + /** + * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) + */ + public List processOptions(IServer server) throws OptionsException { + this.optionList = this.processFields(OPTIONS_SPECS, this.isUnloaded(), this.getFilter(), this.getFields(), this.getMaxResults()); + return this.optionList; + } + + public boolean isUnloaded() { + return unloaded; + } + + public GetStreamsOptions setUnloaded(boolean unloaded) { + this.unloaded = unloaded; + return this; + } + + public String getFilter() { + return filter; + } + + public GetStreamsOptions setFilter(String filter) { + this.filter = filter; + return this; + } + + public String getFields() { + return fields; + } + + public GetStreamsOptions setFields(String fields) { + this.fields = fields; + return this; + } + + public int getMaxResults() { + return maxResults; + } + + public GetStreamsOptions setMaxResults(int maxResults) { + this.maxResults = maxResults; + return this; + } } diff --git a/src/main/java/com/perforce/p4java/option/server/GetSubmittedIntegrationsOptions.java b/src/main/java/com/perforce/p4java/option/server/GetSubmittedIntegrationsOptions.java index a4a2846..be3db9b 100644 --- a/src/main/java/com/perforce/p4java/option/server/GetSubmittedIntegrationsOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/GetSubmittedIntegrationsOptions.java @@ -1,17 +1,17 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for the IOptionsServer getSubmittedIntegrations method. - * + * * @see com.perforce.p4java.server.IOptionsServer#getSubmittedIntegrations(java.util.List, com.perforce.p4java.option.server.GetSubmittedIntegrationsOptions) */ public class GetSubmittedIntegrationsOptions extends Options { @@ -26,14 +26,14 @@ public class GetSubmittedIntegrationsOptions extends Options { * Corresponds to -b. */ protected String branchSpec = null; - + /** * If true, reverse the mappings in the branch view, with the * target files and source files exchanging place. * Corresponds to -r. */ protected boolean reverseMappings = false; - + /** * Default constructor. */ @@ -44,19 +44,20 @@ public GetSubmittedIntegrationsOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public GetSubmittedIntegrationsOptions(String... options) { @@ -65,9 +66,11 @@ public GetSubmittedIntegrationsOptions(String... options) { /** * Explicit-value constructor. + * + * @param branchSpec branchSpec + * @param reverseMappings reverseMappings */ - public GetSubmittedIntegrationsOptions(String branchSpec, - boolean reverseMappings) { + public GetSubmittedIntegrationsOptions(String branchSpec, boolean reverseMappings) { super(); this.branchSpec = branchSpec; this.reverseMappings = reverseMappings; @@ -77,9 +80,7 @@ public GetSubmittedIntegrationsOptions(String branchSpec, * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.getBranchSpec(), - this.isReverseMappings()); + this.optionList = this.processFields(OPTIONS_SPECS, this.getBranchSpec(), this.isReverseMappings()); return this.optionList; } diff --git a/src/main/java/com/perforce/p4java/option/server/GetUserGroupsOptions.java b/src/main/java/com/perforce/p4java/option/server/GetUserGroupsOptions.java index 3582565..1619297 100644 --- a/src/main/java/com/perforce/p4java/option/server/GetUserGroupsOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/GetUserGroupsOptions.java @@ -1,45 +1,45 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for server getUserGroups method. - * + * * @see com.perforce.p4java.server.IOptionsServer#getUserGroups(java.lang.String, com.perforce.p4java.option.server.GetUserGroupsOptions) */ public class GetUserGroupsOptions extends Options { - + /** * Options: -m[max], -i, -v, -g, -u, -o */ public static final String OPTIONS_SPECS = "i:m:gtz b:i b:v b:g b:u b:o"; - + /** * If positive, return only the first maxGroups groups. * Corresponds to the -m flag. */ protected int maxGroups = 0; - + /** * If true, also display groups that the specified user or group belongs * to indirectly via subgroups. Corresponds to the -i flag. */ protected boolean indirect = false; - + /** * If true, display the MaxResults, MaxScanRows, MaxLockTime, * and Timeout values for the named group. Corresponds to the * -v flag. */ protected boolean displayValues = false; - + /** * If true, indicates that the 'name' argument is a group. Corresponds to * the -g flag. @@ -68,19 +68,20 @@ public GetUserGroupsOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public GetUserGroupsOptions(String... options) { @@ -89,9 +90,12 @@ public GetUserGroupsOptions(String... options) { /** * Explicit-value constructor. + * + * @param maxGroups maxGroups + * @param indirect indirect + * @param displayValues displayValues */ - public GetUserGroupsOptions(int maxGroups, boolean indirect, - boolean displayValues) { + public GetUserGroupsOptions(int maxGroups, boolean indirect, boolean displayValues) { super(); this.maxGroups = maxGroups; this.indirect = indirect; @@ -102,13 +106,7 @@ public GetUserGroupsOptions(int maxGroups, boolean indirect, * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.getMaxGroups(), - this.isIndirect(), - this.isDisplayValues(), - this.isGroupName(), - this.isUserName(), - this.isOwnerName()); + this.optionList = this.processFields(OPTIONS_SPECS, this.getMaxGroups(), this.isIndirect(), this.isDisplayValues(), this.isGroupName(), this.isUserName(), this.isOwnerName()); return this.optionList; } diff --git a/src/main/java/com/perforce/p4java/option/server/GetUsersOptions.java b/src/main/java/com/perforce/p4java/option/server/GetUsersOptions.java index b38ebb6..6b5ac3f 100644 --- a/src/main/java/com/perforce/p4java/option/server/GetUsersOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/GetUsersOptions.java @@ -1,44 +1,44 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for server getUsers method. - * + * * @see com.perforce.p4java.server.IOptionsServer#getUsers(java.util.List, com.perforce.p4java.option.server.GetUsersOptions) */ public class GetUsersOptions extends Options { - + /** * Options: -m[max], -l, -a */ public static final String OPTIONS_SPECS = "i:m:gtz b:a b:l"; - + /** * If positive, return only the first maxUsers users. * Corresponds to the -m flag. */ protected int maxUsers = 0; - + /** * If true, include service users in the returned list; * corresponds to the -a flag. - * + * * @since 2011.1 */ protected boolean includeServiceUsers = false; - + /** * If true, include additional information in the output; * corresponds to the -l flag. - * + * * @since 2011.1 */ protected boolean extendedOutput = false; @@ -53,19 +53,20 @@ public GetUsersOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public GetUsersOptions(String... options) { @@ -74,15 +75,19 @@ public GetUsersOptions(String... options) { /** * Explicit-value constructor. + * @param maxUsers maxUsers */ public GetUsersOptions(int maxUsers) { super(); this.maxUsers = maxUsers; } - + /** * Explicit-value constructor. - * + * + * @param maxUsers maxUsers + * @param includeServiceUsers includeServiceUsers + * @param extendedOutput extendedOutput * @since 2011.1 */ public GetUsersOptions(int maxUsers, boolean includeServiceUsers, boolean extendedOutput) { @@ -97,9 +102,9 @@ public GetUsersOptions(int maxUsers, boolean includeServiceUsers, boolean extend */ public List processOptions(IServer server) throws OptionsException { this.optionList = this.processFields(OPTIONS_SPECS, - this.getMaxUsers(), - this.isIncludeServiceUsers(), - this.isExtendedOutput()); + this.getMaxUsers(), + this.isIncludeServiceUsers(), + this.isExtendedOutput()); return this.optionList; } @@ -114,13 +119,16 @@ public GetUsersOptions setMaxUsers(int maxUsers) { /** * @since 2011.1 + * @return result */ public boolean isIncludeServiceUsers() { return includeServiceUsers; } /** + * @param includeServiceUsers option * @since 2011.1 + * @return result */ public GetUsersOptions setIncludeServiceUsers(boolean includeServiceUsers) { this.includeServiceUsers = includeServiceUsers; @@ -129,13 +137,16 @@ public GetUsersOptions setIncludeServiceUsers(boolean includeServiceUsers) { /** * @since 2011.1 + * @return result */ public boolean isExtendedOutput() { return extendedOutput; } /** + * @param extendedOutput option * @since 2011.1 + * @return result */ public GetUsersOptions setExtendedOutput(boolean extendedOutput) { this.extendedOutput = extendedOutput; diff --git a/src/main/java/com/perforce/p4java/option/server/GraphCommitLogOptions.java b/src/main/java/com/perforce/p4java/option/server/GraphCommitLogOptions.java index 8dcb951..941f222 100644 --- a/src/main/java/com/perforce/p4java/option/server/GraphCommitLogOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/GraphCommitLogOptions.java @@ -11,7 +11,6 @@ * that forms the options part of the 'p4 graph log' command *

* Usage: log -n repo [ -u user -A date-B date -m N -N N -X N ] [ commit... ] - *

*/ public class GraphCommitLogOptions extends Options { @@ -68,16 +67,15 @@ public GraphCommitLogOptions() { /** * Constructs a GraphCommitLogOptions with the given arguments * - * @param repo - repo against which the 'p4 graph log' command is issued - * @param maxResults - maximum number of items to be returned by the graph log command - * @param startDate - Date starting from when the commit logs will be fetched - * @param endDate - Date used as the end date up to when the commit logs will be fetched + * @param repo - repo against which the 'p4 graph log' command is issued + * @param maxResults - maximum number of items to be returned by the graph log command + * @param startDate - Date starting from when the commit logs will be fetched + * @param endDate - Date used as the end date up to when the commit logs will be fetched * @param minNumberOfParents - lower bound for the number of parents a commit is expected to have as part of the fetch * @param maxNumberOfParents - upper bound for the number of parents a commit is expected to have as part of the fetch - * @param commitValue - Additional commit SHA values that can be used to filter the search + * @param commitValue - Additional commit SHA values that can be used to filter the search */ - public GraphCommitLogOptions(String repo, int maxResults, String startDate, String endDate, - int minNumberOfParents, int maxNumberOfParents, String... commitValue) { + public GraphCommitLogOptions(String repo, int maxResults, String startDate, String endDate, int minNumberOfParents, int maxNumberOfParents, String... commitValue) { this.repo = repo; this.maxResults = maxResults; this.startDate = startDate; @@ -94,13 +92,11 @@ public GraphCommitLogOptions(String repo, int maxResults, String startDate, Stri * possible to ignore it and do the best you can with what you've * got... * @return list of options strings associated with this Option - * @throws OptionsException + * @throws OptionsException on error */ @Override public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, this.repo, - this.user, this.maxResults, this.startDate, - this.endDate, this.minNumberOfParents, this.maxNumberOfParents); + this.optionList = this.processFields(OPTIONS_SPECS, this.repo, this.user, this.maxResults, this.startDate, this.endDate, this.minNumberOfParents, this.maxNumberOfParents); if (commitValue != null && commitValue.length > 0) { for (String commitValueItem : commitValue) { this.optionList.add(commitValueItem); @@ -243,7 +239,7 @@ public void setUser(String user) { } /** - * @return the user of the commit + * @return the user of the commit */ public String getUser() { return this.user = user; diff --git a/src/main/java/com/perforce/p4java/option/server/GraphRevListOptions.java b/src/main/java/com/perforce/p4java/option/server/GraphRevListOptions.java index 7bc41f5..9276397 100644 --- a/src/main/java/com/perforce/p4java/option/server/GraphRevListOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/GraphRevListOptions.java @@ -41,7 +41,7 @@ public GraphRevListOptions() { * possible to ignore it and do the best you can with what you've * got... * @return list of options strings associated with this Option. - * @throws OptionsException + * @throws OptionsException on error */ @Override public List processOptions(IServer server) throws OptionsException { diff --git a/src/main/java/com/perforce/p4java/option/server/GraphShowRefOptions.java b/src/main/java/com/perforce/p4java/option/server/GraphShowRefOptions.java index 8a826a2..d2c7723 100644 --- a/src/main/java/com/perforce/p4java/option/server/GraphShowRefOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/GraphShowRefOptions.java @@ -38,7 +38,7 @@ public GraphShowRefOptions() { * possible to ignore it and do the best you can with what you've * got... * @return list of options strings associated with this Option - * @throws OptionsException + * @throws OptionsException on error */ @Override public List processOptions(IServer server) throws OptionsException { diff --git a/src/main/java/com/perforce/p4java/option/server/JournalWaitOptions.java b/src/main/java/com/perforce/p4java/option/server/JournalWaitOptions.java index a551479..e22e5e1 100644 --- a/src/main/java/com/perforce/p4java/option/server/JournalWaitOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/JournalWaitOptions.java @@ -1,29 +1,29 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for IOptionsServer's journalWait method. */ public class JournalWaitOptions extends Options { - + /** * Options: -i */ public static final String OPTIONS_SPECS = "b:i"; - + /** * If true, turn off journal-wait. This allows the application to specify * "noWait" replication when using a forwarding replica or an edge server. * Corresponds to the -i flag.

- * + * * Note: this is a deep undoc command. */ protected boolean noWait = false; @@ -38,31 +38,31 @@ public JournalWaitOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public JournalWaitOptions(String... options) { super(options); } - + /** * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.isNoWait()); + this.optionList = this.processFields(OPTIONS_SPECS, this.isNoWait()); return this.optionList; } diff --git a/src/main/java/com/perforce/p4java/option/server/KeyOptions.java b/src/main/java/com/perforce/p4java/option/server/KeyOptions.java index 900c3fa..e1198bc 100644 --- a/src/main/java/com/perforce/p4java/option/server/KeyOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/KeyOptions.java @@ -1,35 +1,35 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for IOptionsServer's setKey method. */ public class KeyOptions extends Options { - + /** * Options: -u, -d, -i */ public static final String OPTIONS_SPECS = "b:u b:d b:i"; - + protected boolean undocKey = false; /** * If true, delete the counter. Corresponds to the -d flag. */ protected boolean delete = false; - + /** * If true, increment the key and return the new value. This option is used * instead of a value argument and can only be used with numeric key values. - * Corresponds to the -i flag.

+ * Corresponds to the -i flag. */ protected boolean incrementKey = false; @@ -43,42 +43,43 @@ public KeyOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public KeyOptions(String... options) { super(options); } - + /** * Explicit value constructor. + * + * @param delete delete + * @param incrementCounter incrementCounter */ public KeyOptions(boolean delete, boolean incrementCounter) { super(); this.delete = delete; this.incrementKey = incrementCounter; } - + /** * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.isUndocKey(), - this.isDelete(), - this.isIncrementKey()); + this.optionList = this.processFields(OPTIONS_SPECS, this.isUndocKey(), this.isDelete(), this.isIncrementKey()); return this.optionList; } diff --git a/src/main/java/com/perforce/p4java/option/server/ListOptions.java b/src/main/java/com/perforce/p4java/option/server/ListOptions.java index 89e21d5..4d4da01 100644 --- a/src/main/java/com/perforce/p4java/option/server/ListOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/ListOptions.java @@ -11,7 +11,6 @@ * that forms the options part of the 'p4 list' command *

* Usage: list [-l label [-d]] [-C] [-M] files... - *

*/ public class ListOptions extends Options { diff --git a/src/main/java/com/perforce/p4java/option/server/LogTailOptions.java b/src/main/java/com/perforce/p4java/option/server/LogTailOptions.java index b393b82..ec6b5c6 100644 --- a/src/main/java/com/perforce/p4java/option/server/LogTailOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/LogTailOptions.java @@ -1,36 +1,36 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for Perforce IOptionsServer.getLogtail methods. */ public class LogTailOptions extends Options { - + /** * Options: -b[blockSize], -s[startingOffset], -m[maxBlocks] */ public static final String OPTIONS_SPECS = "l:b:gtz l:s:gez i:m:gtz"; - + /** * If greater than zero, specifies the block size in bytes (default 8192). * Corresponds to the -b flag. */ protected long blockSize = 0; - + /** * If positive, enables you to specify the offset from the beginning of the * file (in bytes). Corresponds to the -s flag. */ protected long startingOffset = -1; - + /** * If greater than zero, specifies a maximum number of blocks to output. * This flag is ignored unless the -s flag is specified. @@ -48,27 +48,32 @@ public LogTailOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public LogTailOptions(String... options) { super(options); } - + /** * Explicit value constructor. + * + * @param blockSize blockSize + * @param startingOffset startingOffset + * @param maxBlocks maxBlocks */ public LogTailOptions(long blockSize, long startingOffset, int maxBlocks) { super(); @@ -76,22 +81,19 @@ public LogTailOptions(long blockSize, long startingOffset, int maxBlocks) { this.startingOffset = startingOffset; this.maxBlocks = maxBlocks; } - + /** * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.getBlockSize(), - this.getStartingOffset(), - this.getMaxBlocks()); + this.optionList = this.processFields(OPTIONS_SPECS, this.getBlockSize(), this.getStartingOffset(), this.getMaxBlocks()); return this.optionList; } /** * Gets the block size (in bytes). - * + * * @return the block size (in bytes) */ public long getBlockSize() { @@ -100,7 +102,7 @@ public long getBlockSize() { /** * Sets the block size (in bytes). - * + * * @param blockSize * the block size (in bytes) * @return the log tail options @@ -112,7 +114,7 @@ public LogTailOptions setBlockSize(long blockSize) { /** * Gets the offset from the beginning of the file (in bytes). - * + * * @return the starting offset (in bytes) */ public long getStartingOffset() { @@ -121,7 +123,7 @@ public long getStartingOffset() { /** * Sets the offset from the beginning of the file (in bytes). - * + * * @param startingOffset * the starting offset (in bytes) * @return the log tail options @@ -133,7 +135,7 @@ public LogTailOptions setStartingOffset(long startingOffset) { /** * Gets the maximum number of blocks to output. - * + * * @return the maximum blocks */ public int getMaxBlocks() { @@ -142,7 +144,7 @@ public int getMaxBlocks() { /** * Sets the maximum number of blocks to output. - * + * * @param maxBlocks * the maximum blocks * @return the log tail options diff --git a/src/main/java/com/perforce/p4java/option/server/Login2Options.java b/src/main/java/com/perforce/p4java/option/server/Login2Options.java index 4ae4774..d0a9c58 100644 --- a/src/main/java/com/perforce/p4java/option/server/Login2Options.java +++ b/src/main/java/com/perforce/p4java/option/server/Login2Options.java @@ -10,8 +10,8 @@ public class Login2Options extends Options { /** * Options: - * p4 login2 [ -p -R ] [ -h host ] [ -S state ] [ -m method ] [ username ] - * p4 login2 -s [ -a | -h host ] [ username ] + * p4 login2 [ -p -R ] [ -h host ] [ -S state ] [ -m method ] [ username ] + * p4 login2 -s [ -a | -h host ] [ username ] */ public static final String OPTIONS_SPECS = "b:p b:R s:h s:S s:m b:s b:a"; @@ -67,7 +67,7 @@ public Login2Options() { * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

* * NOTE: setting options this way always bypasses the internal options @@ -76,6 +76,7 @@ public Login2Options() { * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public Login2Options(String... options) { @@ -86,19 +87,11 @@ public Login2Options(String... options) { * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.persist, - this.restart, - this.host, - this.state, - this.method, - this.status, - this.allHosts); + this.optionList = this.processFields(OPTIONS_SPECS, this.persist, this.restart, this.host, this.state, this.method, this.status, this.allHosts); return this.optionList; } - public boolean isPersist() { return persist; } diff --git a/src/main/java/com/perforce/p4java/option/server/LoginOptions.java b/src/main/java/com/perforce/p4java/option/server/LoginOptions.java index 8af1d9b..d1cb662 100644 --- a/src/main/java/com/perforce/p4java/option/server/LoginOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/LoginOptions.java @@ -1,5 +1,5 @@ /** - * + * */ package com.perforce.p4java.option.server; @@ -14,12 +14,12 @@ */ public class LoginOptions extends Options { - + /** * Options: -a, -p, -h[host] */ public static final String OPTIONS_SPECS = "b:a b:p s:h b:2"; - + /** * If true, the ticket is valid on all hosts; corresponds to -a flag. */ @@ -38,30 +38,31 @@ public class LoginOptions extends Options { protected String host = null; protected boolean twoFactor = false; - + /** * Default constructor. */ public LoginOptions() { super(); } - + /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public LoginOptions(String... options) { @@ -70,8 +71,8 @@ public LoginOptions(String... options) { /** * Explicit-value constructor. - * - * @param allHosts + * + * @param allHosts allHosts */ public LoginOptions(boolean allHosts) { super(); @@ -80,9 +81,9 @@ public LoginOptions(boolean allHosts) { /** * Explicit-value constructor. - * - * @param allHosts - * @param dontWriteTicket + * + * @param allHosts allHosts + * @param dontWriteTicket dontWriteTicket */ public LoginOptions(boolean allHosts, boolean dontWriteTicket) { super(); @@ -92,10 +93,10 @@ public LoginOptions(boolean allHosts, boolean dontWriteTicket) { /** * Explicit-value constructor. - * - * @param allHosts - * @param dontWriteTicket - * @param host + * + * @param allHosts allHosts + * @param dontWriteTicket dontWriteTicket + * @param host host */ public LoginOptions(boolean allHosts, boolean dontWriteTicket, String host) { super(); @@ -108,11 +109,7 @@ public LoginOptions(boolean allHosts, boolean dontWriteTicket, String host) { * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.allHosts, - this.dontWriteTicket, - this.host, - this.twoFactor); + this.optionList = this.processFields(OPTIONS_SPECS, this.allHosts, this.dontWriteTicket, this.host, this.twoFactor); return this.optionList; } diff --git a/src/main/java/com/perforce/p4java/option/server/MatchingLinesOptions.java b/src/main/java/com/perforce/p4java/option/server/MatchingLinesOptions.java index 7cd23ec..f499d11 100644 --- a/src/main/java/com/perforce/p4java/option/server/MatchingLinesOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/MatchingLinesOptions.java @@ -3,96 +3,114 @@ */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options objects for the IOptionsServer getMatchingLines command. Note that * not all "p4 grep" options are currently implemented or recognized; see the * comments below for a list of recognized and non-recognized options and their * semantics. - * + * *

  *  The -a flag searches all revisions within the specific range, rather
  * 	than just the highest revision in the range.
- * 
+ *
  * 	The -i flag causes the pattern matching to be case insensitive, by
  * 	default matching is case sensitive.
- * 
+ *
  * 	The -n flag displays the matching line number after the file revision
  * 	number,  by default output of matched files consist of the revision
  * 	and the matched line separated by a colon ':'.
- * 
+ *
  * 	The -v flag displays files with non-matching lines.
- * 
+ *
  * 	The -F flag is used to interpret the pattern as a fixed string.
- * 
+ *
  * 	The -G flag is used to interpret the pattern as a regular expression,
  * 	the default behavior.
- * 
+ *
  * 	The -t flag instructs grep to treat binary files as text.  By default
  * 	only files of type text are selected for pattern matching.
- * 
- * 	The -A  flag displays num lines of trailing context after
+ *
+ * 	The -A <num> flag displays num lines of trailing context after
  * 	matching lines.
- * 
- * 	The -B  flag displays num lines of leading context before
+ *
+ * 	The -B <num> flag displays num lines of leading context before
  * 	matching lines.
- * 
- * 	The -C  flag displays num lines of output context.
- * 	
+ *
+ * 	The -C <num> flag displays num lines of output context.
+ *
  * 	The -s flag suppresses error messages that result from abandoning
  * 	files that have a maximum number of characters in a single line that
  * 	are greater than 4096.  By default grep will abandon these files and
  * 	report an error.
- * 	
+ *
  * 	The -L flag changes the output to display the name of each selected
  * 	file from which no output would normally have been displayed. The
  * 	scanning will stop on the first match.
- * 
+ *
  * 	The -l flag changes the output to display the name of each selected
  * 	file from which output would normally have been displayed. The
  * 	scanning will stop on the first match.
  * 
- * + * * @see com.perforce.p4java.server.IOptionsServer#getMatchingLines(java.util.List, java.lang.String, com.perforce.p4java.option.server.MatchingLinesOptions) */ public class MatchingLinesOptions extends Options { - + /** * Options: -a, -i, -n, -v, -A[n], -B[n], -C[n], -t, -F|-G */ public static final String OPTIONS_SPECS = "b:a b:i b:n b:v i:A:gtz i:B:gtz i:C:gtz b:t b:F"; - /** Corresponds to the p4 grep "-a" option */ + /** + * Corresponds to the p4 grep "-a" option + */ protected boolean allRevisions = false; - - /** Corresponds to the p4 grep -i option */ + + /** + * Corresponds to the p4 grep -i option + */ protected boolean caseInsensitive = false; - - /** Corresponds to the p4 grep -n option */ + + /** + * Corresponds to the p4 grep -n option + */ protected boolean includeLineNumbers = false; - - /** Corresponds to the p4 grep -v option */ + + /** + * Corresponds to the p4 grep -v option + */ protected boolean nonMatchingLines = false; - - /** Corresponds to the p4 grep -t option */ + + /** + * Corresponds to the p4 grep -t option + */ protected boolean searchBinaries = false; - - /** Corresponds to the p4 grep -C option; if zero, option is off */ + + /** + * Corresponds to the p4 grep -C option; if zero, option is off + */ protected int outputContext = 0; - - /** Corresponds to the p4 grep -A option; if zero, option is off */ + + /** + * Corresponds to the p4 grep -A option; if zero, option is off + */ protected int trailingContext = 0; - - /** Corresponds to the p4 grep -B option; if zero, option is off */ + + /** + * Corresponds to the p4 grep -B option; if zero, option is off + */ protected int leadingContext = 0; - - /** Corresponds to the p4 grep -F and -G options: if true, corresponds to -F; - * if false, to -G */ + + /** + * Corresponds to the p4 grep -F and -G options: if true, corresponds to -F; + * if false, to -G + */ protected boolean fixedPattern = false; /** @@ -104,12 +122,18 @@ public MatchingLinesOptions() { /** * Explicit value constructor. + * + * @param allRevisions allRevisions + * @param caseInsensitive caseInsensitive + * @param includeLineNumbers includeLineNumbers + * @param nonMatchingLines nonMatchingLines + * @param searchBinaries searchBinaries + * @param outputContext outputContext + * @param trailingContext trailingContext + * @param leadingContext leadingContext + * @param fixedPattern fixedPattern */ - public MatchingLinesOptions(boolean allRevisions, - boolean caseInsensitive, boolean includeLineNumbers, - boolean nonMatchingLines, boolean searchBinaries, - int outputContext, int trailingContext, int leadingContext, - boolean fixedPattern) { + public MatchingLinesOptions(boolean allRevisions, boolean caseInsensitive, boolean includeLineNumbers, boolean nonMatchingLines, boolean searchBinaries, int outputContext, int trailingContext, int leadingContext, boolean fixedPattern) { super(); this.allRevisions = allRevisions; this.caseInsensitive = caseInsensitive; @@ -125,22 +149,23 @@ public MatchingLinesOptions(boolean allRevisions, /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ - public MatchingLinesOptions(String ... options) { + public MatchingLinesOptions(String... options) { super(options); } @@ -148,16 +173,7 @@ public MatchingLinesOptions(String ... options) { * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.allRevisions, - this.caseInsensitive, - this.includeLineNumbers, - this.nonMatchingLines, - this.trailingContext, - this.leadingContext, - this.outputContext, - this.searchBinaries, - this.fixedPattern); + this.optionList = this.processFields(OPTIONS_SPECS, this.allRevisions, this.caseInsensitive, this.includeLineNumbers, this.nonMatchingLines, this.trailingContext, this.leadingContext, this.outputContext, this.searchBinaries, this.fixedPattern); return this.optionList; } diff --git a/src/main/java/com/perforce/p4java/option/server/MoveFileOptions.java b/src/main/java/com/perforce/p4java/option/server/MoveFileOptions.java index f6bef80..efae8ad 100644 --- a/src/main/java/com/perforce/p4java/option/server/MoveFileOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/MoveFileOptions.java @@ -1,40 +1,40 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.core.IChangelist; import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for IOptionsServer moveFile method. - * + * * @see com.perforce.p4java.server.IOptionsServer#moveFile(com.perforce.p4java.core.file.IFileSpec, com.perforce.p4java.core.file.IFileSpec, com.perforce.p4java.option.server.MoveFileOptions) */ public class MoveFileOptions extends Options { - + /** * Options: -c[changelist], -n, -f, -t[type], -k */ public static final String OPTIONS_SPECS = "i:c:clz b:n b:f b:k s:t"; - + /** * If not IChangelist.UNKNOWN, the files are opened in the numbered * pending changelist instead of the 'default' changelist. * Corresponds to the -c flag. */ protected int changelistId = IChangelist.UNKNOWN; - + /** * If true, don't actually perform the move, just return what would * happen if the move was performed. Corresponds to the -n flag. */ protected boolean listOnly = false; - + /** * If true, force a move to an existing target file; * the file must be synced and not opened. Note that the originating @@ -42,7 +42,7 @@ public class MoveFileOptions extends Options { * to the -f flag. */ protected boolean force = false; - + /** * if true, bypasses the client file rename. This option can be * used to tell the server that the user has already renamed a file on @@ -52,7 +52,7 @@ public class MoveFileOptions extends Options { * this true. Corresponds to the -k flag. */ protected boolean noClientMove = false; - + /** * If not null, the file is reopened as that filetype. Corresponds * to the -t flag. @@ -69,19 +69,20 @@ public MoveFileOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public MoveFileOptions(String... options) { @@ -90,9 +91,14 @@ public MoveFileOptions(String... options) { /** * Explicit-value constructor. + * + * @param changelistId changelistId + * @param listOnly listOnly + * @param force force + * @param noClientMove noClientMove + * @param fileType fileType */ - public MoveFileOptions(int changelistId, boolean listOnly, boolean force, - boolean noClientMove, String fileType) { + public MoveFileOptions(int changelistId, boolean listOnly, boolean force, boolean noClientMove, String fileType) { super(); this.changelistId = changelistId; this.listOnly = listOnly; @@ -105,12 +111,7 @@ public MoveFileOptions(int changelistId, boolean listOnly, boolean force, * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.getChangelistId(), - this.isListOnly(), - this.isForce(), - this.isNoClientMove(), - this.getFileType()); + this.optionList = this.processFields(OPTIONS_SPECS, this.getChangelistId(), this.isListOnly(), this.isForce(), this.isNoClientMove(), this.getFileType()); return this.optionList; } diff --git a/src/main/java/com/perforce/p4java/option/server/ObliterateFilesOptions.java b/src/main/java/com/perforce/p4java/option/server/ObliterateFilesOptions.java index af2a579..d6f9d9b 100644 --- a/src/main/java/com/perforce/p4java/option/server/ObliterateFilesOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/ObliterateFilesOptions.java @@ -3,15 +3,15 @@ */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options-based method options for IOptionsServer obliterateFiles method(s). - * + * * @see com.perforce.p4java.server.IOptionsServer#obliterateFiles(java.util.List, com.perforce.p4java.option.server.ObliterateFilesOptions) */ public class ObliterateFilesOptions extends Options { @@ -34,7 +34,7 @@ public class ObliterateFilesOptions extends Options { * a branch, then it's most likely that the archival search is not * necessary. This option is safe to use with the '-b' option. *

- * + * * Note: this is an 'undoc' flag; use 'p4 help undoc' for more details */ protected boolean skipArchiveSearchRemoval = false; @@ -45,7 +45,7 @@ public class ObliterateFilesOptions extends Options { * This flag is useful for removing old branches while keeping files of * interest (files that were modified). *

- * + * * Note: this is an 'undoc' flag; use 'p4 help undoc' for more details */ protected boolean branchedFirstHeadRevOnly = false; @@ -58,7 +58,7 @@ public class ObliterateFilesOptions extends Options { * reuse, because the old content on any client will not match the * newly-added repository files. *

- * + * * Note: this is an 'undoc' flag; use 'p4 help undoc' for more details */ protected boolean skipHaveSearch = false; @@ -73,19 +73,20 @@ public ObliterateFilesOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public ObliterateFilesOptions(String... options) { @@ -94,10 +95,13 @@ public ObliterateFilesOptions(String... options) { /** * Explicit-value constructor. + * + * @param executeObliterate executeObliterate + * @param skipArchiveSearchRemoval skipArchiveSearchRemoval + * @param branchedFirstHeadRevOnly branchedFirstHeadRevOnly + * @param skipHaveSearch skipHaveSearch */ - public ObliterateFilesOptions(boolean executeObliterate, - boolean skipArchiveSearchRemoval, boolean branchedFirstHeadRevOnly, - boolean skipHaveSearch) { + public ObliterateFilesOptions(boolean executeObliterate, boolean skipArchiveSearchRemoval, boolean branchedFirstHeadRevOnly, boolean skipHaveSearch) { super(); this.executeObliterate = executeObliterate; this.skipArchiveSearchRemoval = skipArchiveSearchRemoval; @@ -109,9 +113,7 @@ public ObliterateFilesOptions(boolean executeObliterate, * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.executeObliterate, this.skipArchiveSearchRemoval, - this.branchedFirstHeadRevOnly, this.skipHaveSearch); + this.optionList = this.processFields(OPTIONS_SPECS, this.executeObliterate, this.skipArchiveSearchRemoval, this.branchedFirstHeadRevOnly, this.skipHaveSearch); return this.optionList; } @@ -129,8 +131,7 @@ public boolean isSkipArchiveSearchRemoval() { return skipArchiveSearchRemoval; } - public ObliterateFilesOptions setSkipArchiveSearchRemoval( - boolean skipArchiveSearchRemoval) { + public ObliterateFilesOptions setSkipArchiveSearchRemoval(boolean skipArchiveSearchRemoval) { this.skipArchiveSearchRemoval = skipArchiveSearchRemoval; return this; } @@ -139,8 +140,7 @@ public boolean isBranchedFirstHeadRevOnly() { return branchedFirstHeadRevOnly; } - public ObliterateFilesOptions setBranchedFirstHeadRevOnly( - boolean branchedFirstHeadRevOnly) { + public ObliterateFilesOptions setBranchedFirstHeadRevOnly(boolean branchedFirstHeadRevOnly) { this.branchedFirstHeadRevOnly = branchedFirstHeadRevOnly; return this; } diff --git a/src/main/java/com/perforce/p4java/option/server/OpenedFilesOptions.java b/src/main/java/com/perforce/p4java/option/server/OpenedFilesOptions.java index c194b95..f244e26 100644 --- a/src/main/java/com/perforce/p4java/option/server/OpenedFilesOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/OpenedFilesOptions.java @@ -1,5 +1,5 @@ /** - * + * */ package com.perforce.p4java.option.server; @@ -13,41 +13,41 @@ /** * Options-based method options for IServer and IClient openedFiles method(s). *

- * + * * Note that when used with the IClient openedFiles method, the * allClients and clientName options are ignored; the clientName - * is (of course) filled in using the client's own name.

- * + * is (of course) filled in using the client's own name. + * * @see com.perforce.p4java.client.IClient#openedFiles(java.util.List, com.perforce.p4java.option.server.OpenedFilesOptions) */ public class OpenedFilesOptions extends Options { - + /** * Options: -a, -c[changelist], -C[client], -u[user], -m[max], -s */ public static final String OPTIONS_SPECS = "b:a i:c:cl s:C s:u i:m:gtz b:s"; - + /** * If true, list opened files in all clients. * Normally only files opened by the current client are listed. */ protected boolean allClients = false; - + /** * If not null, restrict the list of files to those opened on the named client. */ protected String clientName = null; - + /** * If positive, limit output to the first 'maxFiles' number of files. */ protected int maxFiles = 0; - + /** * If not null, restrict the list of files to those opened by the named user. */ protected String userName = null; - + /** * If non-negative, restrict the list to files opened under * the given changelist#. Normally files in any changelist (including @@ -72,19 +72,20 @@ public OpenedFilesOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public OpenedFilesOptions(String... options) { @@ -93,9 +94,14 @@ public OpenedFilesOptions(String... options) { /** * Explicit-value constructor. + * + * @param allClients allClients + * @param clientName clientName + * @param maxFiles maxFiles + * @param userName userName + * @param changelistId changelistId */ - public OpenedFilesOptions(boolean allClients, String clientName, - int maxFiles, String userName, int changelistId) { + public OpenedFilesOptions(boolean allClients, String clientName, int maxFiles, String userName, int changelistId) { super(); this.allClients = allClients; this.clientName = clientName; @@ -108,14 +114,7 @@ public OpenedFilesOptions(boolean allClients, String clientName, * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.allClients, - this.changelistId, - this.clientName, - this.userName, - this.maxFiles, - this.shortOutput - ); + this.optionList = this.processFields(OPTIONS_SPECS, this.allClients, this.changelistId, this.clientName, this.userName, this.maxFiles, this.shortOutput); return this.optionList; } diff --git a/src/main/java/com/perforce/p4java/option/server/OptionsHelper.java b/src/main/java/com/perforce/p4java/option/server/OptionsHelper.java index 1b8c941..3ec815a 100644 --- a/src/main/java/com/perforce/p4java/option/server/OptionsHelper.java +++ b/src/main/java/com/perforce/p4java/option/server/OptionsHelper.java @@ -61,7 +61,7 @@ public static String applyRule(String ruleName, String serverOptStr, boolean val * * This version of applyRules implements the rules specified below: *

-   * "gtz": don't return anything unless the value is > 0; typically used for
+   * "gtz": don't return anything unless the value is > 0; typically used for
    * 		things like maxUsers or maxRows.
    * "cl": ignore negative values; convert 0 to the string "default". Typically
    * 		used for changelists.
@@ -118,8 +118,8 @@ public static String applyRule(String ruleName, String serverOptStr, int value)
    *
    * This version of applyRules implements the rules specified below:
    * 
-   * "gtz": don't return anything unless the value is > 0.
-   * "gez": don't return anything unless the value is >= 0.
+   * "gtz": don't return anything unless the value is > 0.
+   * "gez": don't return anything unless the value is >= 0.
    * 
* If the passed-in ruleName is non-null and not recognized, the behaviour * is the same as if a null rule name was passed in. diff --git a/src/main/java/com/perforce/p4java/option/server/PropertyOptions.java b/src/main/java/com/perforce/p4java/option/server/PropertyOptions.java index 2861cc7..ac9faab 100644 --- a/src/main/java/com/perforce/p4java/option/server/PropertyOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/PropertyOptions.java @@ -1,5 +1,5 @@ /** - * + * */ package com.perforce.p4java.option.server; @@ -13,24 +13,24 @@ * Options class for IOptionsServer's setProperty and deleteProperty methods. */ public class PropertyOptions extends Options { - + /** * Options: -n name -v value [-s sequence] [-u user | -g group] */ public static final String OPTIONS_SPECS = "s:n s:v s:s s:u s:g"; - + /** * If not null, use this as the name of this property. * Corresponds to the -n flag. */ protected String name = null; - + /** * If not null, use this as the value of this property. * Corresponds to the -v flag. */ protected String value = null; - + /** * If greater than zero, use this as the sequence number of this property. * If the sequence is not specified, it defaults to 1. @@ -60,30 +60,36 @@ public PropertyOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public PropertyOptions(String... options) { super(options); } - + /** * Explicit value constructor. + * + * @param name name + * @param value value + * @param sequence sequence + * @param user user + * @param group group */ - public PropertyOptions(String name, String value, String sequence, - String user, String group) { + public PropertyOptions(String name, String value, String sequence, String user, String group) { super(); this.name = name; this.value = value; @@ -91,17 +97,12 @@ public PropertyOptions(String name, String value, String sequence, this.user = user; this.group = group; } - + /** * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.getName(), - this.getValue(), - this.getSequence(), - this.getUser(), - this.getGroup()); + this.optionList = this.processFields(OPTIONS_SPECS, this.getName(), this.getValue(), this.getSequence(), this.getUser(), this.getGroup()); return this.optionList; } diff --git a/src/main/java/com/perforce/p4java/option/server/ReloadOptions.java b/src/main/java/com/perforce/p4java/option/server/ReloadOptions.java index 0abe5e8..c8a565e 100644 --- a/src/main/java/com/perforce/p4java/option/server/ReloadOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/ReloadOptions.java @@ -1,34 +1,34 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for Perforce reload methods. *

- * + * * Note that the full semantics of these options are found in the main 'p4 help * reload' documentation. */ public class ReloadOptions extends Options { - + /** * Options: [-f] [-c client | -l label | -s stream] */ public static final String OPTIONS_SPECS = "b:f s:c s:l s:s"; - - + + /** * If true, forces the unloading of the specified client or label. * Corresponds to the -f flag. *

- * + * * By default, users can only unload their own clients or labels. The -f * flag requires 'admin' access, which is granted by 'p4 protect'. */ @@ -62,27 +62,32 @@ public ReloadOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public ReloadOptions(String... options) { super(options); } - + /** * Explicit value constructor. + * + * @param force force + * @param client client + * @param label label */ public ReloadOptions(boolean force, String client, String label) { super(); @@ -96,10 +101,10 @@ public ReloadOptions(boolean force, String client, String label) { */ public List processOptions(IServer server) throws OptionsException { this.optionList = this.processFields(OPTIONS_SPECS, - this.isForce(), - this.getClient(), - this.getLabel(), - this.getStream()); + this.isForce(), + this.getClient(), + this.getLabel(), + this.getStream()); return this.optionList; } diff --git a/src/main/java/com/perforce/p4java/option/server/ReposOptions.java b/src/main/java/com/perforce/p4java/option/server/ReposOptions.java index f0d749d..9444d50 100644 --- a/src/main/java/com/perforce/p4java/option/server/ReposOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/ReposOptions.java @@ -8,7 +8,7 @@ /** * Options required by the repos command - * + *

* -e|-E filter * -m max * -u user @@ -57,7 +57,7 @@ public ReposOptions() { * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

* * NOTE: setting options this way always bypasses the internal options @@ -66,6 +66,7 @@ public ReposOptions() { * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public ReposOptions(String... options) { diff --git a/src/main/java/com/perforce/p4java/option/server/SearchJobsOptions.java b/src/main/java/com/perforce/p4java/option/server/SearchJobsOptions.java index dd8739e..56a0fd6 100644 --- a/src/main/java/com/perforce/p4java/option/server/SearchJobsOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/SearchJobsOptions.java @@ -1,32 +1,32 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for the IOptionsServer's searchJobs method. */ public class SearchJobsOptions extends Options { - - /** - * Options: -m[max] - */ - public static final String OPTIONS_SPECS = "i:m:gtz"; - - - /** - * If greater than zero, limit output to the first maxResults - * number of job IDs. Corresponds to '-m max' flag. - */ - protected int maxResults = 0; - /** + /** + * Options: -m[max] + */ + public static final String OPTIONS_SPECS = "i:m:gtz"; + + + /** + * If greater than zero, limit output to the first maxResults + * number of job IDs. Corresponds to '-m max' flag. + */ + protected int maxResults = 0; + + /** * Default constructor. */ public SearchJobsOptions() { @@ -36,39 +36,42 @@ public SearchJobsOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public SearchJobsOptions(String... options) { super(options); } - + /** * Explicit value constructor. + * + * @param maxResults maxResults */ public SearchJobsOptions(int maxResults) { super(); this.maxResults = maxResults; } - + /** * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { this.optionList = this.processFields(OPTIONS_SPECS, - this.getMaxResults()); + this.getMaxResults()); return this.optionList; } diff --git a/src/main/java/com/perforce/p4java/option/server/SetFileAttributesOptions.java b/src/main/java/com/perforce/p4java/option/server/SetFileAttributesOptions.java index 8082e63..0a30166 100644 --- a/src/main/java/com/perforce/p4java/option/server/SetFileAttributesOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/SetFileAttributesOptions.java @@ -1,38 +1,38 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for the IOptionsServer setFileAttributes method. - * + * * @since 2011.1 */ public class SetFileAttributesOptions extends Options { - + /** * Options: -e, -f, -p */ public static final String OPTIONS_SPECS = "b:e b:f b:p"; - + /** * If true, indicates values are in hex format. * Corresponds to p4's -e flag. */ protected boolean hexValue = false; - + /** * If true, attributes are set on submitted files. * Corresponds to -f. */ protected boolean setOnSubmittedFiles = false; - + /** * If true, creates attributes whose value will be propagated * when the files are opened with 'p4 add', 'p4 edit', or 'p4 delete'. @@ -50,30 +50,34 @@ public SetFileAttributesOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public SetFileAttributesOptions(String... options) { super(options); } - + /** * Explicit-value constructor. + * + * @param hexValue hexValue + * @param setOnSubmittedFiles setOnSubmittedFiles + * @param propagateAttributes propagateAttributes */ - public SetFileAttributesOptions(boolean hexValue, - boolean setOnSubmittedFiles, boolean propagateAttributes) { + public SetFileAttributesOptions(boolean hexValue, boolean setOnSubmittedFiles, boolean propagateAttributes) { super(); this.hexValue = hexValue; this.setOnSubmittedFiles = setOnSubmittedFiles; @@ -84,10 +88,7 @@ public SetFileAttributesOptions(boolean hexValue, * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.isHexValue(), - this.isSetOnSubmittedFiles(), - this.isPropagateAttributes()); + this.optionList = this.processFields(OPTIONS_SPECS, this.isHexValue(), this.isSetOnSubmittedFiles(), this.isPropagateAttributes()); return this.optionList; } diff --git a/src/main/java/com/perforce/p4java/option/server/StreamIntegrationStatusOptions.java b/src/main/java/com/perforce/p4java/option/server/StreamIntegrationStatusOptions.java index 8d5e2cd..0431469 100644 --- a/src/main/java/com/perforce/p4java/option/server/StreamIntegrationStatusOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/StreamIntegrationStatusOptions.java @@ -1,14 +1,14 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Combined Options subclass for the server getStreamCachedIntegrationStatus * methods. @@ -57,19 +57,20 @@ public StreamIntegrationStatusOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public StreamIntegrationStatusOptions(String... options) { @@ -78,9 +79,13 @@ public StreamIntegrationStatusOptions(String... options) { /** * Explicit-value constructor. + * + * @param parentToStream parentToStream + * @param bidirectional bidirectional + * @param forceUpdate forceUpdate + * @param noRefresh noRefresh */ - public StreamIntegrationStatusOptions(boolean parentToStream, - boolean bidirectional, boolean forceUpdate, boolean noRefresh) { + public StreamIntegrationStatusOptions(boolean parentToStream, boolean bidirectional, boolean forceUpdate, boolean noRefresh) { super(); this.parentToStream = parentToStream; this.bidirectional = bidirectional; @@ -92,11 +97,7 @@ public StreamIntegrationStatusOptions(boolean parentToStream, * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.isParentToStream(), - this.isBidirectional(), - this.isForceUpdate(), - this.isNoRefresh()); + this.optionList = this.processFields(OPTIONS_SPECS, this.isParentToStream(), this.isBidirectional(), this.isForceUpdate(), this.isNoRefresh()); return this.optionList; } @@ -104,8 +105,7 @@ public boolean isParentToStream() { return parentToStream; } - public StreamIntegrationStatusOptions setParentToStream( - boolean parentToStream) { + public StreamIntegrationStatusOptions setParentToStream(boolean parentToStream) { this.parentToStream = parentToStream; return this; } @@ -114,8 +114,7 @@ public boolean isBidirectional() { return bidirectional; } - public StreamIntegrationStatusOptions setBidirectional( - boolean bidirectional) { + public StreamIntegrationStatusOptions setBidirectional(boolean bidirectional) { this.bidirectional = bidirectional; return this; } diff --git a/src/main/java/com/perforce/p4java/option/server/StreamOptions.java b/src/main/java/com/perforce/p4java/option/server/StreamOptions.java index 88899fa..b3a33a9 100644 --- a/src/main/java/com/perforce/p4java/option/server/StreamOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/StreamOptions.java @@ -1,24 +1,24 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Combined Options subclass for the server create / update / delete stream methods. */ public class StreamOptions extends Options { - + /** * Options: -f */ public static final String OPTIONS_SPECS = "b:f"; - + /** * If true, force the stream create / update / delete operation. * Corresponds to the -f flag. @@ -35,19 +35,20 @@ public StreamOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public StreamOptions(String... options) { @@ -56,6 +57,8 @@ public StreamOptions(String... options) { /** * Explicit-value constructor. + * + * @param forceUpdate forceUpdate */ public StreamOptions(boolean forceUpdate) { super(); diff --git a/src/main/java/com/perforce/p4java/option/server/SwitchClientViewOptions.java b/src/main/java/com/perforce/p4java/option/server/SwitchClientViewOptions.java index 78e9da9..4ca89d5 100644 --- a/src/main/java/com/perforce/p4java/option/server/SwitchClientViewOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/SwitchClientViewOptions.java @@ -40,7 +40,7 @@ public SwitchClientViewOptions() { * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

* * NOTE: setting options this way always bypasses the internal options @@ -49,6 +49,7 @@ public SwitchClientViewOptions() { * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public SwitchClientViewOptions(String... options) { @@ -57,8 +58,9 @@ public SwitchClientViewOptions(String... options) { /** * Explicit value constructor. + * + * @param force force option */ - public SwitchClientViewOptions(boolean force) { super(); this.force = force; diff --git a/src/main/java/com/perforce/p4java/option/server/TagFilesOptions.java b/src/main/java/com/perforce/p4java/option/server/TagFilesOptions.java index bd5e7ce..380c361 100644 --- a/src/main/java/com/perforce/p4java/option/server/TagFilesOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/TagFilesOptions.java @@ -1,26 +1,26 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for the IOptionsServer.tagFiles method. - * + * * @see com.perforce.p4java.server.IOptionsServer#tagFiles(java.util.List, java.lang.String, com.perforce.p4java.option.server.TagFilesOptions) */ public class TagFilesOptions extends Options { - + /** * Options: -d, -n */ public static final String OPTIONS_SPECS = "b:n b:d"; - + protected boolean listOnly = false; protected boolean delete = false; @@ -34,27 +34,31 @@ public TagFilesOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public TagFilesOptions(String... options) { super(options); } - + /** * Explicit-value constructor. + * + * @param listOnly listOnly + * @param delete delete */ public TagFilesOptions(boolean listOnly, boolean delete) { super(); diff --git a/src/main/java/com/perforce/p4java/option/server/TrustOptions.java b/src/main/java/com/perforce/p4java/option/server/TrustOptions.java index 0331acc..d237b2d 100644 --- a/src/main/java/com/perforce/p4java/option/server/TrustOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/TrustOptions.java @@ -1,19 +1,19 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for the Perforce IOptionsServer.addTrust method. */ public class TrustOptions extends Options { - + /** Options: -f, -n, -y, -r. */ public static final String OPTIONS_SPECS = "b:f b:n b:y b:r"; @@ -26,7 +26,7 @@ public class TrustOptions extends Options { * Like no option but prompting automatically refused. Corresponds to the -n flag. */ protected boolean autoRefuse = false; - + /** * Like no option but prompting automatically accepted. Corresponds to the -y flag. */ @@ -47,25 +47,26 @@ public TrustOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public TrustOptions(String... options) { super(options); } - + /** * Creates a new TrustOptions object, given the 'force', 'autoRefuse' and * 'autoAccept' flags. @@ -80,16 +81,12 @@ public TrustOptions(boolean force, boolean autoRefuse, boolean autoAccept) { this.autoRefuse = autoRefuse; this.autoAccept = autoAccept; } - + /** * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.isForce(), - this.isAutoRefuse(), - this.isAutoAccept(), - this.isReplacement()); + this.optionList = this.processFields(OPTIONS_SPECS, this.isForce(), this.isAutoRefuse(), this.isAutoAccept(), this.isReplacement()); return this.optionList; } diff --git a/src/main/java/com/perforce/p4java/option/server/UnloadOptions.java b/src/main/java/com/perforce/p4java/option/server/UnloadOptions.java index 98ec226..bc2467b 100644 --- a/src/main/java/com/perforce/p4java/option/server/UnloadOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/UnloadOptions.java @@ -1,36 +1,36 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Options class for Perforce unload methods. *

- * + * * Note that the full semantics of these options are found in the main 'p4 help * unload' documentation. */ public class UnloadOptions extends Options { - + /** * Options: p4 unload [-f -L -z] [-c client | -l label | -s stream] *

* Options: p4 unload [-f -L -z] [-a|-al|-ac] [-d date | -u user] */ public static final String OPTIONS_SPECS = "b:f b:L b:z s:c s:l s:s s:a s:d s:u"; - - + + /** * If true, forces the unloading of the specified client or label. * Corresponds to the -f flag. *

- * + * * By default, users can only unload their own clients or labels. The -f * flag requires 'admin' access, which is granted by 'p4 protect'. */ @@ -70,12 +70,12 @@ public class UnloadOptions extends Options { * If not null, specifies set of clients and/or labels are unloaded. * Corresponds to the -a, -al -ac flags. *

- * + * * If it is empty (empty string ""), it would unload all (-a) clients and * labels. If it is "c", it would unload all clients (-ac). If it is "l", it * would unload all labels (-al). *

- * + * * Note that if the -a flag is specified, the specified set of clients * and/or labels are unloaded. Specify -d and a date to unload all clients * and/or labels older than that date. When -a is specified, you must @@ -88,9 +88,9 @@ public class UnloadOptions extends Options { * If not null, unload all clients and/or labels older than that date. * Corresponds to the -d date flag. *

- * + * * The following are valid Perforce date string formats: - * + * *

 	 * yyyy/mm/dd
 	 * yyyy/mm/dd:hh:mm:ss
@@ -115,30 +115,35 @@ public UnloadOptions() {
 	/**
 	 * Strings-based constructor; see 'p4 help [command]' for possible options.
 	 * 

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public UnloadOptions(String... options) { super(options); } - + /** * Explicit value constructor. + * + * @param force force + * @param compress compress + * @param client client + * @param label label */ - public UnloadOptions(boolean force, boolean compress, String client, - String label) { + public UnloadOptions(boolean force, boolean compress, String client, String label) { super(); this.force = force; this.compress = compress; @@ -148,9 +153,14 @@ public UnloadOptions(boolean force, boolean compress, String client, /** * Explicit value constructor. + * + * @param force force + * @param compress compress + * @param all all + * @param date date + * @param user user */ - public UnloadOptions(boolean force, boolean compress, String all, - String date, String user) { + public UnloadOptions(boolean force, boolean compress, String all, String date, String user) { super(); this.force = force; this.compress = compress; @@ -163,16 +173,7 @@ public UnloadOptions(boolean force, boolean compress, String all, * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.isForce(), - this.isLocked(), - this.isCompress(), - this.getClient(), - this.getLabel(), - this.getStream(), - this.getAll(), - this.getDate(), - this.getUser()); + this.optionList = this.processFields(OPTIONS_SPECS, this.isForce(), this.isLocked(), this.isCompress(), this.getClient(), this.getLabel(), this.getStream(), this.getAll(), this.getDate(), this.getUser()); return this.optionList; } diff --git a/src/main/java/com/perforce/p4java/option/server/UpdateClientOptions.java b/src/main/java/com/perforce/p4java/option/server/UpdateClientOptions.java index 1379064..c0c0572 100644 --- a/src/main/java/com/perforce/p4java/option/server/UpdateClientOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/UpdateClientOptions.java @@ -1,25 +1,25 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Combined Options subclass for the server create / update / delete client methods. */ public class UpdateClientOptions extends Options { - + /** * Options: -f */ public static final String OPTIONS_SPECS = "b:f"; - + /** * If true, force the client create / update / delete operation. * Corresponds to the -f flag. @@ -36,19 +36,20 @@ public UpdateClientOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public UpdateClientOptions(String... options) { @@ -57,6 +58,7 @@ public UpdateClientOptions(String... options) { /** * Explicit-value constructor. + * @param forceUpdate forceUpdate option */ public UpdateClientOptions(boolean forceUpdate) { super(); diff --git a/src/main/java/com/perforce/p4java/option/server/UpdateUserGroupOptions.java b/src/main/java/com/perforce/p4java/option/server/UpdateUserGroupOptions.java index b4fc6b2..6a66bde 100644 --- a/src/main/java/com/perforce/p4java/option/server/UpdateUserGroupOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/UpdateUserGroupOptions.java @@ -1,26 +1,26 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Combined Options class for user group create / update / delete methods. * Note that not all methods honor all options -- see the individual Javadoc * for explanations. */ public class UpdateUserGroupOptions extends Options { - + /** * Options: -a, -A */ public static final String OPTIONS_SPECS = "b:a b:A"; - + /** * If true, allow a user without 'super' * access to modify the group only if that user is an @@ -45,19 +45,20 @@ public UpdateUserGroupOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public UpdateUserGroupOptions(String... options) { @@ -66,6 +67,8 @@ public UpdateUserGroupOptions(String... options) { /** * Explicit-value constructor. + * + * @param updateIfOwner updateIfOwner option */ public UpdateUserGroupOptions(boolean updateIfOwner) { super(); @@ -74,6 +77,9 @@ public UpdateUserGroupOptions(boolean updateIfOwner) { /** * Explicit-value constructor. + * + * @param updateIfOwner updateIfOwner + * @param addIfAdmin addIfAdmin */ public UpdateUserGroupOptions(boolean updateIfOwner, boolean addIfAdmin) { super(); @@ -85,9 +91,7 @@ public UpdateUserGroupOptions(boolean updateIfOwner, boolean addIfAdmin) { * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.isUpdateIfOwner(), - this.isAddIfAdmin()); + this.optionList = this.processFields(OPTIONS_SPECS, this.isUpdateIfOwner(), this.isAddIfAdmin()); return this.optionList; } diff --git a/src/main/java/com/perforce/p4java/option/server/UpdateUserOptions.java b/src/main/java/com/perforce/p4java/option/server/UpdateUserOptions.java index 5c708d2..e5c3633 100644 --- a/src/main/java/com/perforce/p4java/option/server/UpdateUserOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/UpdateUserOptions.java @@ -1,25 +1,25 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** * Combined Options subclass for the server create / update / delete user methods. */ public class UpdateUserOptions extends Options { - + /** * Options: -f */ public static final String OPTIONS_SPECS = "b:f"; - + /** * If true, force the user create / update / delete operation. * Corresponds to the -f flag. @@ -36,19 +36,20 @@ public UpdateUserOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public UpdateUserOptions(String... options) { @@ -57,6 +58,8 @@ public UpdateUserOptions(String... options) { /** * Explicit-value constructor. + * + * @param forceUpdate forceUpdate option */ public UpdateUserOptions(boolean forceUpdate) { super(); diff --git a/src/main/java/com/perforce/p4java/option/server/VerifyFilesOptions.java b/src/main/java/com/perforce/p4java/option/server/VerifyFilesOptions.java index 5a4fe33..b89477d 100644 --- a/src/main/java/com/perforce/p4java/option/server/VerifyFilesOptions.java +++ b/src/main/java/com/perforce/p4java/option/server/VerifyFilesOptions.java @@ -1,43 +1,43 @@ /** - * + * */ package com.perforce.p4java.option.server; -import java.util.List; - import com.perforce.p4java.exception.OptionsException; import com.perforce.p4java.option.Options; import com.perforce.p4java.server.IServer; +import java.util.List; + /** - * Options class for IOptionsServer.verifyFiles method.

- * + * Options class for IOptionsServer.verifyFiles method. + * * @see com.perforce.p4java.server.IOptionsServer#verifyFiles(java.util.List, com.perforce.p4java.option.server.VerifyFilesOptions) */ public class VerifyFilesOptions extends Options { - + /** *

 	 * Options:
 	 * 		[-t | -u | -v | -z] [-m max -q -s -X -b N] file[revRange] ...
-     * 		-U unloadfiles...
+	 * 		-U unloadfiles...
 	 * 
*/ public static final String OPTIONS_SPECS = "b:t b:u b:v b:z i:m:gtz b:q b:s b:X l:b:gez b:U"; - + /** * If true, causes 'p4 verify' to schedule transfer of the content of any * damaged revision. This option is for use only with a replica server and * cannot be used with the '-v' or '-u' options. Corresponds to the -t flag. */ protected boolean transferContent = false; - + /** * If true, computes and saves the digest only for revisions that have no * saved digest. Corresponds to the -u flag. */ protected boolean computeMissingDigest = false; - + /** * If true, computes and saves the digest for each revision, regardless of * whether the revision already has a saved digest. This option can be used @@ -81,7 +81,7 @@ public class VerifyFilesOptions extends Options { * skipped. Corresponds to the -s flag. */ protected boolean skipPlusXModifier = false; - + /** * If greater than zero, specifies the batch size. By default, 'p4 verify' * processes files in batches of 10000 files at a time. Specify -b 0 to @@ -90,7 +90,7 @@ public class VerifyFilesOptions extends Options { * single batch.. Corresponds to the -b N flag. */ protected long batchSize = 0; - + /** * If true, verifies files in the unload depot (see 'p4 help unload'). * Corresponds to the -U flag. @@ -106,19 +106,20 @@ public VerifyFilesOptions() { /** * Strings-based constructor; see 'p4 help [command]' for possible options. *

- * + * * WARNING: you should not pass more than one option or argument in each * string parameter. Each option or argument should be passed-in as its own * separate string parameter, without any spaces between the option and the - * option value (if any). + * option value (if any). *

- * + * * NOTE: setting options this way always bypasses the internal options * values, and getter methods against the individual values corresponding to * the strings passed in to this constructor will not normally reflect the * string's setting. Do not use this constructor unless you know what you're * doing and / or you do not also use the field getters and setters. - * + * + * @param options options * @see com.perforce.p4java.option.Options#Options(java.lang.String...) */ public VerifyFilesOptions(String... options) { @@ -129,17 +130,7 @@ public VerifyFilesOptions(String... options) { * @see com.perforce.p4java.option.Options#processOptions(com.perforce.p4java.server.IServer) */ public List processOptions(IServer server) throws OptionsException { - this.optionList = this.processFields(OPTIONS_SPECS, - this.isTransferContent(), - this.isComputeMissingDigest(), - this.isComputeDigest(), - this.isSkipComputedDigest(), - this.getMaxRevisions(), - this.isQuiet(), - this.isVerifySize(), - this.isSkipPlusXModifier(), - this.getBatchSize(), - this.isVerifyUnload()); + this.optionList = this.processFields(OPTIONS_SPECS, this.isTransferContent(), this.isComputeMissingDigest(), this.isComputeDigest(), this.isSkipComputedDigest(), this.getMaxRevisions(), this.isQuiet(), this.isVerifySize(), this.isSkipPlusXModifier(), this.getBatchSize(), this.isVerifyUnload()); return this.optionList; } diff --git a/src/main/java/com/perforce/p4java/server/AbstractAuthHelper.java b/src/main/java/com/perforce/p4java/server/AbstractAuthHelper.java index f41536d..f16553b 100644 --- a/src/main/java/com/perforce/p4java/server/AbstractAuthHelper.java +++ b/src/main/java/com/perforce/p4java/server/AbstractAuthHelper.java @@ -55,11 +55,12 @@ public abstract class AbstractAuthHelper { * user name and server address. The user name be non-null and the server * address must be non-null and be of the form server:port. * + * @param userName userName + * @param serverAddress serverAddress + * @param authMap authMap * @return - list of auth entries found in the specified auth map */ - protected static Map getMemoryEntry(final String userName, final String serverAddress, - final Map authMap) { - + protected static Map getMemoryEntry(final String userName, final String serverAddress, final Map authMap) { String p4Port = serverAddress; Map entryMap = new ConcurrentHashMap<>(); if (isNotBlank(userName) && isNotBlank(serverAddress) && nonNull(authMap)) { @@ -80,6 +81,7 @@ protected static Map getMemoryEntry(final String userName, final /** * Get all the auth entries found in the specified auth store in memory. * + * @param authMap authMap * @return - list of auth entries found in the specified auth map */ protected static List> getMemoryEntries(final Map authMap) { @@ -96,9 +98,7 @@ protected static List> getMemoryEntries(final Map> authList) { - + private static void popularAuthEntry(final int equals, final String line, final List> authList) { if (equals != -1) { int colon = indexOf(line, ':', equals); if (colon != -1 && colon + 1 < line.length()) { @@ -125,8 +125,7 @@ private static void popularAuthEntry(final int equals, final String line, * @param authValue - possibly null auth value * @param authMap - non-null auth map */ - protected static void saveMemoryEntry(final String userName, final String serverAddress, final String authValue, - final Map authMap) { + protected static void saveMemoryEntry(final String userName, final String serverAddress, final String authValue, final Map authMap) { if (isNotBlank(userName) && isNotBlank(serverAddress) && nonNull(authMap)) { String p4Port = serverAddress; @@ -147,6 +146,7 @@ protected static void saveMemoryEntry(final String userName, final String server /** * Get all the auth entries found in the specified auth file. * + * @param authFile authFile * @return - list of auth entries found in the specified auth file * @throws IOException - io exception from reading auth file */ @@ -181,13 +181,15 @@ protected static List> getFileEntries(final File authFile) t * @param serverAddress - non-null server address * @param authValue - possibly null auth value * @param authFile - non-null file + * @param lockTry lockTry + * @param lockDelay lockDelay + * @param lockWait lockWait + * @throws IOException on error */ - protected static void saveFileEntry(final String userName, final String serverAddress, final String authValue, - final File authFile, final int lockTry, final long lockDelay, final long lockWait) throws IOException { + protected static void saveFileEntry(final String userName, final String serverAddress, final String authValue, final File authFile, final int lockTry, final long lockDelay, final long lockWait) throws IOException { if (isNotBlank(userName) && isNotBlank(serverAddress) && nonNull(authFile)) { - String p4Port = firstMatch(lastIndexOf(serverAddress, ':') == -1, "localhost:" + serverAddress, - serverAddress); + String p4Port = firstMatch(lastIndexOf(serverAddress, ':') == -1, "localhost:" + serverAddress, serverAddress); Path authFilePath = authFile.toPath(); @@ -198,9 +200,7 @@ protected static void saveFileEntry(final String userName, final String serverAd } File lockFile = createLockFileIfNotExist(authFile); boolean locked = false; - try (RandomAccessFile lockFileRandomAccessor = new RandomAccessFile(lockFile, "rw"); - FileChannel fileChannel = lockFileRandomAccessor.getChannel(); - FileLock lock = tryLockFile(fileChannel, lockFile, lockTry, lockWait)) { + try (RandomAccessFile lockFileRandomAccessor = new RandomAccessFile(lockFile, "rw"); FileChannel fileChannel = lockFileRandomAccessor.getChannel(); FileLock lock = tryLockFile(fileChannel, lockFile, lockTry, lockWait)) { if (nonNull(lock) && lock.isValid()) { locked = true; @@ -208,13 +208,11 @@ protected static void saveFileEntry(final String userName, final String serverAd String newAuthValue = firstMatch(isNotBlank(authValue), authValuePrefix + authValue, EMPTY); try { - readAuthFileContentPlusNewAuthValueAndWriteToTempAuthFile(authFile, authValuePrefix, - newAuthValue); + readAuthFileContentPlusNewAuthValueAndWriteToTempAuthFile(authFile, authValuePrefix, newAuthValue); updateReadBit(authFile); } catch (IOException e) { e.printStackTrace(); - throwIOException(e, "P4TICKETS file: %s could not be overwritten.", - authFile.getAbsolutePath()); + throwIOException(e, "P4TICKETS file: %s could not be overwritten.", authFile.getAbsolutePath()); } // Update read bit of actual auth file @@ -243,12 +241,10 @@ private static File createLockFileIfNotExist(@Nonnull final File authFile) throw return lockFile; } - private static void readAuthFileContentPlusNewAuthValueAndWriteToTempAuthFile(final File authFile, - final String authValuePrefix, final String newAuthValue) throws IOException { + private static void readAuthFileContentPlusNewAuthValueAndWriteToTempAuthFile(final File authFile, final String authValuePrefix, final String newAuthValue) throws IOException { File tempAuth = File.createTempFile("p4auth_" + System.currentTimeMillis(), ".txt"); - try (BufferedReader reader = new BufferedReader(new FileReader(authFile)); - PrintWriter writer = new PrintWriter(tempAuth, "utf-8")) { + try (BufferedReader reader = new BufferedReader(new FileReader(authFile)); PrintWriter writer = new PrintWriter(tempAuth, "utf-8")) { boolean processed = false; // Only add current auth file content if a reader was // successfully created @@ -289,8 +285,7 @@ private static void readAuthFileContentPlusNewAuthValueAndWriteToTempAuthFile(fi } } - private static FileLock tryLockFile(@Nullable final FileChannel lockFileChannel, @Nonnull final File lockFile, - final int lockTry, final long lockWait) throws IOException { + private static FileLock tryLockFile(@Nullable final FileChannel lockFileChannel, @Nonnull final File lockFile, final int lockTry, final long lockWait) throws IOException { int lockTries = firstMatch(lockTry < 1, DEFAULT_LOCK_TRY, lockTry); long lockWaits = firstMatch(lockWait < 1, DEFAULT_LOCK_WAIT, lockWait); @@ -314,8 +309,7 @@ private static FileLock tryLockFile(@Nullable final FileChannel lockFileChannel, } else { if (lockFile.lastModified() > 0) { try { - Log.info("-----%s thread put to sleep, and it will retry lock %s times", currentThreadName, - lockTries - 1); + Log.info("-----%s thread put to sleep, and it will retry lock %s times", currentThreadName, lockTries - 1); TimeUnit.SECONDS.sleep(lockWaits); } catch (InterruptedException e) { Log.error("Error waiting for auth lock file: %s", e.getLocalizedMessage()); @@ -325,8 +319,7 @@ private static FileLock tryLockFile(@Nullable final FileChannel lockFileChannel, } while (lockTries-- > 0); if (isNull(fileLock) || !fileLock.isValid()) { - throwIOException("Error creating new auth lock file \"%s\" after retries: %s", - lockFile.getAbsolutePath(), lockTry); + throwIOException("Error creating new auth lock file \"%s\" after retries: %s", lockFile.getAbsolutePath(), lockTry); } } diff --git a/src/main/java/com/perforce/p4java/server/AuthTicket.java b/src/main/java/com/perforce/p4java/server/AuthTicket.java index a938600..c3d6bc8 100644 --- a/src/main/java/com/perforce/p4java/server/AuthTicket.java +++ b/src/main/java/com/perforce/p4java/server/AuthTicket.java @@ -3,7 +3,6 @@ /** * Object representing the three parts of a Perforce ticket, the server address, * the user name, and the ticket token value. - * */ public class AuthTicket { @@ -21,10 +20,10 @@ public AuthTicket() { /** * Create a ticket with the specified server address, user name, and ticket * value. - * - * @param serverAddress - * @param userName - * @param ticketValue + * + * @param serverAddress serverAddress + * @param userName userName + * @param ticketValue ticketValue */ public AuthTicket(String serverAddress, String userName, String ticketValue) { this.serverAddress = serverAddress; @@ -40,8 +39,7 @@ public String getServerAddress() { } /** - * @param serverAddress - * the serverAddress to set + * @param serverAddress the serverAddress to set */ public void setServerAddress(String serverAddress) { this.serverAddress = serverAddress; @@ -55,8 +53,7 @@ public String getUserName() { } /** - * @param userName - * the userName to set + * @param userName the userName to set */ public void setUserName(String userName) { this.userName = userName; @@ -70,8 +67,7 @@ public String getTicketValue() { } /** - * @param ticketValue - * the ticketValue to set + * @param ticketValue the ticketValue to set */ public void setTicketValue(String ticketValue) { this.ticketValue = ticketValue; @@ -101,8 +97,7 @@ public int hashCode() { * @see java.lang.Object#toString() */ public String toString() { - return this.serverAddress + "=" + this.userName + ":" - + this.getTicketValue(); + return this.serverAddress + "=" + this.userName + ":" + this.getTicketValue(); } } diff --git a/src/main/java/com/perforce/p4java/server/AuthTicketsHelper.java b/src/main/java/com/perforce/p4java/server/AuthTicketsHelper.java index 120e0e6..bfcf0dd 100644 --- a/src/main/java/com/perforce/p4java/server/AuthTicketsHelper.java +++ b/src/main/java/com/perforce/p4java/server/AuthTicketsHelper.java @@ -17,280 +17,232 @@ * the methods, the in-memory tickets map will be used instead. */ public class AuthTicketsHelper extends AbstractAuthHelper { - private static final AuthTicket[] EMPTY = new AuthTicket[0]; - private static final Map ticketsMap = new ConcurrentHashMap<>(); - - /** - * Get the first found ticket value that matches the specified user name and - * server address. The user name be non-null and the server address must be - * non-null and be of the form server:port. - * - * @return - ticket value or null if not found - * @throws IOException - io exception from reading tickets file - */ - public static String getTicketValue( - final String userName, - final String serverAddress, - final String ticketsFilePath) throws IOException { - - String ticketValue = null; - AuthTicket ticket = getTicket( - userName, - serverAddress, - ticketsFilePath); - - if (nonNull(ticket)) { - ticketValue = ticket.getTicketValue(); - } - return ticketValue; - } - - /** - * Get the first found ticket in the specified ticket file that matches the - * specified user name and server address. The server address must be - * non-null and be of the form server:port. The user name may be null and if - * that is the case the found first ticket for the specified server address - * will be returned. - * - * @param userName - possibly null user name to match against the found tickets - * @param serverAddress - non-null server address - * @param ticketsFilePath - path to tickets file to search - * @return - found ticket or null if not found - * @throws IOException - io exception from reading tickets file - */ - public static AuthTicket getTicket( - final String userName, - final String serverAddress, - final String ticketsFilePath) throws IOException { - - String p4Port = serverAddress; - AuthTicket foundTicket = null; - if (nonNull(serverAddress)) { - if (serverAddress.indexOf(':') == -1) { - p4Port = "localhost:" + serverAddress; - } - - for (AuthTicket ticket : getTickets(ticketsFilePath)) { - if (p4Port.equals(ticket.getServerAddress()) - && (isBlank(userName) || userName.equals(ticket.getUserName()))) { - - foundTicket = ticket; - break; - } - } - } - return foundTicket; - } - - /** - * Get all the tickets found in the file at the specified file path. - * - * @return - array of tickets found in the specified tickets file at the specified path - * @throws IOException - io exception from reading tickets file - */ - public static AuthTicket[] getTickets(final String ticketsFilePath) throws IOException { - File file = isNotBlank(ticketsFilePath) ? new File(ticketsFilePath) : null; - return getTickets(file); - } - - /** - * Get all the tickets found in the specified file. - * - * @return - array of tickets found in the specified tickets file - * @throws IOException - io exception from reading tickets file - */ - public static AuthTicket[] getTickets(final File ticketsFile) throws IOException { - AuthTicket[] tickets = EMPTY; - List> authList = nonNull(ticketsFile) ? getFileEntries(ticketsFile) : getMemoryEntries(ticketsMap); - if (nonNull(authList)) { - List ticketList = new CopyOnWriteArrayList<>(); - for (Map map : authList) { - if (nonNull(map)) { - String serverAddress = map.get(SERVER_ADDRESS_MAP_KEY); - String userName = map.get(USER_NAME_MAP_KEY); - String ticketValue = map.get(AUTH_VALUE_MAP_KEY); - AuthTicket ticket = new AuthTicket( - serverAddress, - userName, - ticketValue); - ticketList.add(ticket); - } - } - tickets = ticketList.toArray(new AuthTicket[ticketList.size()]); - } - - return tickets; - } - - /** - * Get the first found ticket in the specified ticket file that matches the - * specified server address. The server address must be non-null and be of - * the form server:port. - * - * @param serverAddress - non-null server address - * @param ticketsFilePath - path to tickets file to search - * @return - found ticket or null if not found - * @throws IOException - io exception from reading tickets file - */ - public static AuthTicket getTicket( - final String serverAddress, - final String ticketsFilePath) throws IOException { - - return getTicket(null, serverAddress, ticketsFilePath); - } - - /** - * Save the specified ticket as an entry into the specified tickets file. - * This method will replace the current entry for the user name and server - * address in the tickets file. If a current entry is not found then the - * specified entry will be appended to the file. - * - * @param ticket - non-null ticket - * @param ticketsFilePath - non-null path - */ - public static void saveTicket( - final AuthTicket ticket, - final String ticketsFilePath) throws IOException { - - File file = isNotBlank(ticketsFilePath) ? new File(ticketsFilePath) : null; - saveTicket(ticket, file); - } - - /** - * Save the specified ticket as an entry into the specified tickets file. - * This method will replace the current entry for the user name and server - * address in the tickets file. If a current entry is not found then the - * specified entry will be appended to the file. - * - * @param ticket - non-null ticket - * @param ticketsFile - non-null file - */ - public static void saveTicket( - final AuthTicket ticket, - final File ticketsFile) throws IOException { - - if (nonNull(ticket)) { - saveTicket( - ticket.getUserName(), - ticket.getServerAddress(), - ticket.getTicketValue(), - ticketsFile); - } - } - - /** - * Save the specified parameters as an entry into the specified tickets - * file. This method will replace the current entry for the user name and - * server address in the tickets file. If a current entry is not found then - * the specified entry will be appended to the file. - * - * @param userName - non-null user name - * @param serverAddress - non-null server address - * @param ticketValue - non-null ticket value - * @param ticketsFilePath - non-null file path - */ - public static void saveTicket( - final String userName, - final String serverAddress, - final String ticketValue, - final String ticketsFilePath) throws IOException { - - File file = isNotBlank(ticketsFilePath) ? new File(ticketsFilePath) : null; - saveTicket(userName, serverAddress, ticketValue, file); - } - - /** - * Save the specified parameters as an entry into the specified tickets - * file. This method will replace the current entry for the user name and - * server address in the tickets file. If a current entry is not found then - * the specified entry will be appended to the file. If the specified ticket - * value is null then the current entry in the specified file will be - * removed if found. - * - * @param userName - non-null user name - * @param serverAddress - non-null server address - * @param ticketValue - possibly null ticket value - * @param ticketsFile - non-null file - */ - public static void saveTicket( - final String userName, - final String serverAddress, - final String ticketValue, - final File ticketsFile) throws IOException { - - saveTicket(userName, serverAddress, ticketValue, ticketsFile, 0, 0, 0); - } - - /** - * Save the specified parameters as an entry into the specified tickets - * file. This method will replace the current entry for the user name and - * server address in the tickets file. If a current entry is not found then - * the specified entry will be appended to the file. - * - * @param userName - non-null user name - * @param serverAddress - non-null server address - * @param ticketValue - non-null ticket value - * @param ticketsFilePath - non-null file path - * @param lockTry - number of tries for locking - * @param lockDelay - delay time (ms) for locking - * @param lockWait - wait time (ms) for other process/thread to finish locking - */ - public static void saveTicket( - final String userName, - final String serverAddress, - final String ticketValue, - final String ticketsFilePath, - final int lockTry, - final long lockDelay, - final long lockWait) throws IOException { - - File file = isNotBlank(ticketsFilePath) ? new File(ticketsFilePath) : null; - saveTicket( - userName, - serverAddress, - ticketValue, - file, - lockTry, - lockDelay, - lockWait); - } - - /** - * Save the specified parameters as an entry into the specified tickets - * file. This method will replace the current entry for the user name and - * server address in the tickets file. If a current entry is not found then - * the specified entry will be appended to the file. If the specified ticket - * value is null then the current entry in the specified file will be - * removed if found. - * - * @param userName - non-null user name - * @param serverAddress - non-null server address - * @param ticketValue - possibly null ticket value - * @param ticketsFile - non-null file - * @param lockTry - number of tries for locking - * @param lockDelay - delay time (ms) for locking - * @param lockWait - wait time (ms) for other process/thread to finish locking - */ - public static void saveTicket( - final String userName, - final String serverAddress, - final String ticketValue, - final File ticketsFile, - final int lockTry, - final long lockDelay, - final long lockWait) throws IOException { - - if (nonNull(ticketsFile)) { - saveFileEntry( - userName, - serverAddress, - ticketValue, - ticketsFile, - lockTry, - lockDelay, - lockWait); - } else { - saveMemoryEntry(userName, serverAddress, ticketValue, ticketsMap); - } - } + private static final AuthTicket[] EMPTY = new AuthTicket[0]; + private static final Map ticketsMap = new ConcurrentHashMap<>(); + + /** + * Get the first found ticket value that matches the specified user name and + * server address. The user name be non-null and the server address must be + * non-null and be of the form server:port. + * + * @param userName userName + * @param serverAddress serverAddress + * @param ticketsFilePath ticketsFilePath + * @return - ticket value or null if not found + * @throws IOException - io exception from reading tickets file + */ + public static String getTicketValue(final String userName, final String serverAddress, final String ticketsFilePath) throws IOException { + + String ticketValue = null; + AuthTicket ticket = getTicket(userName, serverAddress, ticketsFilePath); + + if (nonNull(ticket)) { + ticketValue = ticket.getTicketValue(); + } + return ticketValue; + } + + /** + * Get the first found ticket in the specified ticket file that matches the + * specified user name and server address. The server address must be + * non-null and be of the form server:port. The user name may be null and if + * that is the case the found first ticket for the specified server address + * will be returned. + * + * @param userName - possibly null user name to match against the found tickets + * @param serverAddress - non-null server address + * @param ticketsFilePath - path to tickets file to search + * @return - found ticket or null if not found + * @throws IOException - io exception from reading tickets file + */ + public static AuthTicket getTicket(final String userName, final String serverAddress, final String ticketsFilePath) throws IOException { + + String p4Port = serverAddress; + AuthTicket foundTicket = null; + if (nonNull(serverAddress)) { + if (serverAddress.indexOf(':') == -1) { + p4Port = "localhost:" + serverAddress; + } + + for (AuthTicket ticket : getTickets(ticketsFilePath)) { + if (p4Port.equals(ticket.getServerAddress()) && (isBlank(userName) || userName.equals(ticket.getUserName()))) { + + foundTicket = ticket; + break; + } + } + } + return foundTicket; + } + + /** + * Get all the tickets found in the file at the specified file path. + * + * @param ticketsFilePath ticketsFilePath + * @return - array of tickets found in the specified tickets file at the specified path + * @throws IOException - io exception from reading tickets file + */ + public static AuthTicket[] getTickets(final String ticketsFilePath) throws IOException { + File file = isNotBlank(ticketsFilePath) ? new File(ticketsFilePath) : null; + return getTickets(file); + } + + /** + * Get all the tickets found in the specified file. + * + * @param ticketsFile ticketsFile + * @return - array of tickets found in the specified tickets file + * @throws IOException - io exception from reading tickets file + */ + public static AuthTicket[] getTickets(final File ticketsFile) throws IOException { + AuthTicket[] tickets = EMPTY; + List> authList = nonNull(ticketsFile) ? getFileEntries(ticketsFile) : getMemoryEntries(ticketsMap); + if (nonNull(authList)) { + List ticketList = new CopyOnWriteArrayList<>(); + for (Map map : authList) { + if (nonNull(map)) { + String serverAddress = map.get(SERVER_ADDRESS_MAP_KEY); + String userName = map.get(USER_NAME_MAP_KEY); + String ticketValue = map.get(AUTH_VALUE_MAP_KEY); + AuthTicket ticket = new AuthTicket(serverAddress, userName, ticketValue); + ticketList.add(ticket); + } + } + tickets = ticketList.toArray(new AuthTicket[ticketList.size()]); + } + + return tickets; + } + + /** + * Get the first found ticket in the specified ticket file that matches the + * specified server address. The server address must be non-null and be of + * the form server:port. + * + * @param serverAddress - non-null server address + * @param ticketsFilePath - path to tickets file to search + * @return - found ticket or null if not found + * @throws IOException - io exception from reading tickets file + */ + public static AuthTicket getTicket(final String serverAddress, final String ticketsFilePath) throws IOException { + + return getTicket(null, serverAddress, ticketsFilePath); + } + + /** + * Save the specified ticket as an entry into the specified tickets file. + * This method will replace the current entry for the user name and server + * address in the tickets file. If a current entry is not found then the + * specified entry will be appended to the file. + * + * @param ticket - non-null ticket + * @param ticketsFilePath - non-null path + * @throws IOException on error + */ + public static void saveTicket(final AuthTicket ticket, final String ticketsFilePath) throws IOException { + + File file = isNotBlank(ticketsFilePath) ? new File(ticketsFilePath) : null; + saveTicket(ticket, file); + } + + /** + * Save the specified ticket as an entry into the specified tickets file. + * This method will replace the current entry for the user name and server + * address in the tickets file. If a current entry is not found then the + * specified entry will be appended to the file. + * + * @param ticket - non-null ticket + * @param ticketsFile - non-null file + * @throws IOException on error + */ + public static void saveTicket(final AuthTicket ticket, final File ticketsFile) throws IOException { + + if (nonNull(ticket)) { + saveTicket(ticket.getUserName(), ticket.getServerAddress(), ticket.getTicketValue(), ticketsFile); + } + } + + /** + * Save the specified parameters as an entry into the specified tickets + * file. This method will replace the current entry for the user name and + * server address in the tickets file. If a current entry is not found then + * the specified entry will be appended to the file. + * + * @param userName - non-null user name + * @param serverAddress - non-null server address + * @param ticketValue - non-null ticket value + * @param ticketsFilePath - non-null file path + * @throws IOException on error + */ + public static void saveTicket(final String userName, final String serverAddress, final String ticketValue, final String ticketsFilePath) throws IOException { + + File file = isNotBlank(ticketsFilePath) ? new File(ticketsFilePath) : null; + saveTicket(userName, serverAddress, ticketValue, file); + } + + /** + * Save the specified parameters as an entry into the specified tickets + * file. This method will replace the current entry for the user name and + * server address in the tickets file. If a current entry is not found then + * the specified entry will be appended to the file. If the specified ticket + * value is null then the current entry in the specified file will be + * removed if found. + * + * @param userName - non-null user name + * @param serverAddress - non-null server address + * @param ticketValue - possibly null ticket value + * @param ticketsFile - non-null file + * @throws IOException on error + */ + public static void saveTicket(final String userName, final String serverAddress, final String ticketValue, final File ticketsFile) throws IOException { + + saveTicket(userName, serverAddress, ticketValue, ticketsFile, 0, 0, 0); + } + + /** + * Save the specified parameters as an entry into the specified tickets + * file. This method will replace the current entry for the user name and + * server address in the tickets file. If a current entry is not found then + * the specified entry will be appended to the file. + * + * @param userName - non-null user name + * @param serverAddress - non-null server address + * @param ticketValue - non-null ticket value + * @param ticketsFilePath - non-null file path + * @param lockTry - number of tries for locking + * @param lockDelay - delay time (ms) for locking + * @param lockWait - wait time (ms) for other process/thread to finish locking + * @throws IOException on error + */ + public static void saveTicket(final String userName, final String serverAddress, final String ticketValue, final String ticketsFilePath, final int lockTry, final long lockDelay, final long lockWait) throws IOException { + + File file = isNotBlank(ticketsFilePath) ? new File(ticketsFilePath) : null; + saveTicket(userName, serverAddress, ticketValue, file, lockTry, lockDelay, lockWait); + } + + /** + * Save the specified parameters as an entry into the specified tickets + * file. This method will replace the current entry for the user name and + * server address in the tickets file. If a current entry is not found then + * the specified entry will be appended to the file. If the specified ticket + * value is null then the current entry in the specified file will be + * removed if found. + * + * @param userName - non-null user name + * @param serverAddress - non-null server address + * @param ticketValue - possibly null ticket value + * @param ticketsFile - non-null file + * @param lockTry - number of tries for locking + * @param lockDelay - delay time (ms) for locking + * @param lockWait - wait time (ms) for other process/thread to finish locking + * @throws IOException on error + */ + public static void saveTicket(final String userName, final String serverAddress, final String ticketValue, final File ticketsFile, final int lockTry, final long lockDelay, final long lockWait) throws IOException { + + if (nonNull(ticketsFile)) { + saveFileEntry(userName, serverAddress, ticketValue, ticketsFile, lockTry, lockDelay, lockWait); + } else { + saveMemoryEntry(userName, serverAddress, ticketValue, ticketsMap); + } + } } diff --git a/src/main/java/com/perforce/p4java/server/Fingerprint.java b/src/main/java/com/perforce/p4java/server/Fingerprint.java index 6cd977b..281f803 100644 --- a/src/main/java/com/perforce/p4java/server/Fingerprint.java +++ b/src/main/java/com/perforce/p4java/server/Fingerprint.java @@ -2,8 +2,8 @@ /** * Object representing the three parts of a Perforce fingerprint, the server - * address, the user name, and the ticket token value.

- * + * address, the user name, and the ticket token value. + *

* Note: currently the user portion should be "******" as it is not used. */ public class Fingerprint { @@ -22,10 +22,10 @@ public Fingerprint() { /** * Create a fingerprint with the specified server address, user name, and * fingerprint value. - * - * @param serverAddress - * @param userName - * @param fingerprintValue + * + * @param serverAddress serverAddress + * @param userName userName + * @param fingerprintValue fingerprintValue */ public Fingerprint(String serverAddress, String userName, String fingerprintValue) { this.serverAddress = serverAddress; @@ -41,8 +41,7 @@ public String getServerAddress() { } /** - * @param serverAddress - * the serverAddress to set + * @param serverAddress the serverAddress to set */ public void setServerAddress(String serverAddress) { this.serverAddress = serverAddress; @@ -56,8 +55,7 @@ public String getUserName() { } /** - * @param userName - * the userName to set + * @param userName the userName to set */ public void setUserName(String userName) { this.userName = userName; @@ -71,8 +69,7 @@ public String getFingerprintValue() { } /** - * @param fingerprintValue - * the fingerprintValue to set + * @param fingerprintValue the fingerprintValue to set */ public void setFingerprintValue(String fingerprintValue) { this.fingerprintValue = fingerprintValue; diff --git a/src/main/java/com/perforce/p4java/server/FingerprintsHelper.java b/src/main/java/com/perforce/p4java/server/FingerprintsHelper.java index 5bdedcf..bc38bdf 100644 --- a/src/main/java/com/perforce/p4java/server/FingerprintsHelper.java +++ b/src/main/java/com/perforce/p4java/server/FingerprintsHelper.java @@ -11,278 +11,225 @@ * This class is designed to lookup fingerprints from a trust file or the * in-memory fingerprints map. If a null trust file parameter is passed to the * methods, the in-memory fingerprints map will be used instead. - * */ public class FingerprintsHelper extends AbstractAuthHelper { - private static final Fingerprint[] EMPTY = new Fingerprint[0]; + private static final Fingerprint[] EMPTY = new Fingerprint[0]; - private static Map fingerprintsMap = new ConcurrentHashMap<>(); + private static Map fingerprintsMap = new ConcurrentHashMap<>(); - /** - * Get the first found fingerprint value that matches the specified user - * name and server address. The user name be non-null and the server address - * must be non-null and be of the form server:port. - * - * @param userName - * @param serverAddress - * @param trustFilePath - * @return - fingerprint value or null if not found - * @throws IOException - * - io exception from reading trust file - */ - public static String getFingerprintValue(String userName, String serverAddress, - String trustFilePath) throws IOException { - String fingerprintValue = null; - Fingerprint fingerprint = getFingerprint(userName, serverAddress, trustFilePath); - if (fingerprint != null) { - fingerprintValue = fingerprint.getFingerprintValue(); - } - return fingerprintValue; - } + /** + * Get the first found fingerprint value that matches the specified user + * name and server address. The user name be non-null and the server address + * must be non-null and be of the form server:port. + * + * @param userName userName + * @param serverAddress serverAddress + * @param trustFilePath trustFilePath + * @return - fingerprint value or null if not found + * @throws IOException - io exception from reading trust file + */ + public static String getFingerprintValue(String userName, String serverAddress, String trustFilePath) throws IOException { + String fingerprintValue = null; + Fingerprint fingerprint = getFingerprint(userName, serverAddress, trustFilePath); + if (fingerprint != null) { + fingerprintValue = fingerprint.getFingerprintValue(); + } + return fingerprintValue; + } - /** - * Get all the fingerprints found in the file at the specified file path. - * - * @param trustFilePath - * @return - array of fingerprints found in the specified trust file at the - * specified path - * @throws IOException - * - io exception from reading trust file - */ - public static Fingerprint[] getFingerprints(String trustFilePath) throws IOException { - File file = trustFilePath != null ? new File(trustFilePath) : null; - Fingerprint[] fingerprints = getFingerprints(file); - return fingerprints; - } + /** + * Get all the fingerprints found in the file at the specified file path. + * + * @param trustFilePath trustFilePath + * @return - array of fingerprints found in the specified trust file at the + * specified path + * @throws IOException - io exception from reading trust file + */ + public static Fingerprint[] getFingerprints(String trustFilePath) throws IOException { + File file = trustFilePath != null ? new File(trustFilePath) : null; + Fingerprint[] fingerprints = getFingerprints(file); + return fingerprints; + } - /** - * Get all the fingerprints found in the specified file. - * - * @param trustFile - * @return - array of fingerprints found in the specified trust file - * @throws IOException - * - io exception from reading trust file - */ - public static Fingerprint[] getFingerprints(File trustFile) throws IOException { - Fingerprint[] fingerprints = EMPTY; - List> authList = trustFile != null ? getFileEntries(trustFile) - : getMemoryEntries(fingerprintsMap); - if (authList != null) { - List fingerprintList = new ArrayList(); - for (Map map : authList) { - if (map != null) { - String serverAddress = map.get(SERVER_ADDRESS_MAP_KEY); - String userName = map.get(USER_NAME_MAP_KEY); - String fingerprintValue = map.get(AUTH_VALUE_MAP_KEY); - Fingerprint fingerprint = new Fingerprint(serverAddress, userName, - fingerprintValue); - fingerprintList.add(fingerprint); - } - } - fingerprints = fingerprintList.toArray(new Fingerprint[0]); - } - return fingerprints; - } + /** + * Get all the fingerprints found in the specified file. + * + * @param trustFile trustFile + * @return - array of fingerprints found in the specified trust file + * @throws IOException - io exception from reading trust file + */ + public static Fingerprint[] getFingerprints(File trustFile) throws IOException { + Fingerprint[] fingerprints = EMPTY; + List> authList = trustFile != null ? getFileEntries(trustFile) : getMemoryEntries(fingerprintsMap); + if (authList != null) { + List fingerprintList = new ArrayList(); + for (Map map : authList) { + if (map != null) { + String serverAddress = map.get(SERVER_ADDRESS_MAP_KEY); + String userName = map.get(USER_NAME_MAP_KEY); + String fingerprintValue = map.get(AUTH_VALUE_MAP_KEY); + Fingerprint fingerprint = new Fingerprint(serverAddress, userName, fingerprintValue); + fingerprintList.add(fingerprint); + } + } + fingerprints = fingerprintList.toArray(new Fingerprint[0]); + } + return fingerprints; + } - /** - * Get the first found fingerprint in the specified trust file that matches - * the specified user name and server address. The server address must be - * non-null and be of the form server:port. The user name may be null and if - * that is the case the found first fingerprint for the specified server - * address will be returned. - * - * @param userName - * - possibly null user name to match against the found - * fingerprints - * @param serverAddress - * - non-null server address - * @param trustFilePath - * - path to trust file to search - * @return - found fingerprint or null if not found - * @throws IOException - * - io exception from reading trust file - */ - public static Fingerprint getFingerprint(String userName, String serverAddress, - String trustFilePath) throws IOException { - Fingerprint foundFingerprint = null; - if (serverAddress != null) { - if (serverAddress.indexOf(':') == -1) { - serverAddress = "localhost:" + serverAddress; - } - for (Fingerprint fingerprint : getFingerprints(trustFilePath)) { - if (serverAddress.equals(fingerprint.getServerAddress()) - && (userName == null || userName.equals(fingerprint.getUserName()))) { - foundFingerprint = fingerprint; - break; - } - } - } - return foundFingerprint; - } + /** + * Get the first found fingerprint in the specified trust file that matches + * the specified user name and server address. The server address must be + * non-null and be of the form server:port. The user name may be null and if + * that is the case the found first fingerprint for the specified server + * address will be returned. + * + * @param userName - possibly null user name to match against the found + * fingerprints + * @param serverAddress - non-null server address + * @param trustFilePath - path to trust file to search + * @return - found fingerprint or null if not found + * @throws IOException - io exception from reading trust file + */ + public static Fingerprint getFingerprint(String userName, String serverAddress, String trustFilePath) throws IOException { + Fingerprint foundFingerprint = null; + if (serverAddress != null) { + if (serverAddress.indexOf(':') == -1) { + serverAddress = "localhost:" + serverAddress; + } + for (Fingerprint fingerprint : getFingerprints(trustFilePath)) { + if (serverAddress.equals(fingerprint.getServerAddress()) && (userName == null || userName.equals(fingerprint.getUserName()))) { + foundFingerprint = fingerprint; + break; + } + } + } + return foundFingerprint; + } - /** - * Get the first found fingerprint in the specified fingerprint file that - * matches the specified server address. The server address must be non-null - * and be of the form server:port. - * - * @param serverAddress - * - non-null server address - * @param trustFilePath - * - path to trust file to search - * @return - found fingerprint or null if not found - * @throws IOException - * - io exception from reading trust file - */ - public static Fingerprint getFingerprint(String serverAddress, String trustFilePath) - throws IOException { - return getFingerprint(null, serverAddress, trustFilePath); - } + /** + * Get the first found fingerprint in the specified fingerprint file that + * matches the specified server address. The server address must be non-null + * and be of the form server:port. + * + * @param serverAddress - non-null server address + * @param trustFilePath - path to trust file to search + * @return - found fingerprint or null if not found + * @throws IOException - io exception from reading trust file + */ + public static Fingerprint getFingerprint(String serverAddress, String trustFilePath) throws IOException { + return getFingerprint(null, serverAddress, trustFilePath); + } - /** - * Save the specified fingerprint as an entry into the specified trust file. - * This method will replace the current entry for the user name and server - * address in the trust file. If a current entry is not found then the - * specified entry will be appended to the file. - * - * @param fingerprint - * - non-null fingerprint - * @param trustFilePath - * - non-null path - * @throws IOException - */ - public static void saveFingerprint(Fingerprint fingerprint, String trustFilePath) - throws IOException { - File file = trustFilePath != null ? new File(trustFilePath) : null; - saveFingerprint(fingerprint, file); - } + /** + * Save the specified fingerprint as an entry into the specified trust file. + * This method will replace the current entry for the user name and server + * address in the trust file. If a current entry is not found then the + * specified entry will be appended to the file. + * + * @param fingerprint - non-null fingerprint + * @param trustFilePath - non-null path + * @throws IOException on error + */ + public static void saveFingerprint(Fingerprint fingerprint, String trustFilePath) throws IOException { + File file = trustFilePath != null ? new File(trustFilePath) : null; + saveFingerprint(fingerprint, file); + } - /** - * Save the specified fingerprint as an entry into the specified trust file. - * This method will replace the current entry for the user name and server - * address in the trust file. If a current entry is not found then the - * specified entry will be appended to the file. - * - * @param fingerprint - * - non-null fingerprint - * @param trustFile - * - non-null file - * @throws IOException - */ - public static void saveFingerprint(Fingerprint fingerprint, File trustFile) throws IOException { - if (fingerprint != null) { - saveFingerprint(fingerprint.getUserName(), fingerprint.getServerAddress(), - fingerprint.getFingerprintValue(), trustFile); - } - } + /** + * Save the specified fingerprint as an entry into the specified trust file. + * This method will replace the current entry for the user name and server + * address in the trust file. If a current entry is not found then the + * specified entry will be appended to the file. + * + * @param fingerprint - non-null fingerprint + * @param trustFile - non-null file + * @throws IOException on error + */ + public static void saveFingerprint(Fingerprint fingerprint, File trustFile) throws IOException { + if (fingerprint != null) { + saveFingerprint(fingerprint.getUserName(), fingerprint.getServerAddress(), fingerprint.getFingerprintValue(), trustFile); + } + } - /** - * Save the specified parameters as an entry into the specified trust file. - * This method will replace the current entry for the user name and server - * address in the trust file. If a current entry is not found then the - * specified entry will be appended to the file. - * - * @param userName - * - non-null user name - * @param serverAddress - * - non-null server address - * @param fingerprintValue - * - non-null fingerprint value - * @param trustFilePath - * - non-null file path - * @throws IOException - */ - public static void saveFingerprint(String userName, String serverAddress, - String fingerprintValue, String trustFilePath) throws IOException { - File file = trustFilePath != null ? new File(trustFilePath) : null; - saveFingerprint(userName, serverAddress, fingerprintValue, file); - } + /** + * Save the specified parameters as an entry into the specified trust file. + * This method will replace the current entry for the user name and server + * address in the trust file. If a current entry is not found then the + * specified entry will be appended to the file. + * + * @param userName - non-null user name + * @param serverAddress - non-null server address + * @param fingerprintValue - non-null fingerprint value + * @param trustFilePath - non-null file path + * @throws IOException on error + */ + public static void saveFingerprint(String userName, String serverAddress, String fingerprintValue, String trustFilePath) throws IOException { + File file = trustFilePath != null ? new File(trustFilePath) : null; + saveFingerprint(userName, serverAddress, fingerprintValue, file); + } - /** - * Save the specified parameters as an entry into the specified trust file. - * This method will replace the current entry for the user name and server - * address in the trust file. If a current entry is not found then the - * specified entry will be appended to the file. - * - * @param userName - * - non-null user name - * @param serverAddress - * - non-null server address - * @param fingerprintValue - * - non-null fingerprint value - * @param trustFilePath - * - non-null file path - * @param lockTry - * - number of tries for locking - * @param lockDelay - * - delay time (ms) for locking - * @param lockWait - * - wait time (ms) for other process/thread to finish locking - * @throws IOException - */ - public static void saveFingerprint(String userName, String serverAddress, - String fingerprintValue, String trustFilePath, int lockTry, long lockDelay, - long lockWait) throws IOException { - File file = trustFilePath != null ? new File(trustFilePath) : null; - saveFingerprint(userName, serverAddress, fingerprintValue, file, lockTry, lockDelay, - lockWait); - } + /** + * Save the specified parameters as an entry into the specified trust file. + * This method will replace the current entry for the user name and server + * address in the trust file. If a current entry is not found then the + * specified entry will be appended to the file. + * + * @param userName - non-null user name + * @param serverAddress - non-null server address + * @param fingerprintValue - non-null fingerprint value + * @param trustFilePath - non-null file path + * @param lockTry - number of tries for locking + * @param lockDelay - delay time (ms) for locking + * @param lockWait - wait time (ms) for other process/thread to finish locking + * @throws IOException on error + */ + public static void saveFingerprint(String userName, String serverAddress, String fingerprintValue, String trustFilePath, int lockTry, long lockDelay, long lockWait) throws IOException { + File file = trustFilePath != null ? new File(trustFilePath) : null; + saveFingerprint(userName, serverAddress, fingerprintValue, file, lockTry, lockDelay, lockWait); + } - /** - * Save the specified parameters as an entry into the specified trust file. - * This method will replace the current entry for the user name and server - * address in the trust file. If a current entry is not found then the - * specified entry will be appended to the file. If the specified - * fingerprint value is null then the current entry in the specified file - * will be removed if found. - * - * @param userName - * - non-null user name - * @param serverAddress - * - non-null server address - * @param fingerprintValue - * - possibly null fingerprint value - * @param trustFile - * - non-null file - * @throws IOException - */ - public static void saveFingerprint(String userName, String serverAddress, - String fingerprintValue, File trustFile) throws IOException { - saveFingerprint(userName, serverAddress, fingerprintValue, trustFile, 0, 0, 0); - } + /** + * Save the specified parameters as an entry into the specified trust file. + * This method will replace the current entry for the user name and server + * address in the trust file. If a current entry is not found then the + * specified entry will be appended to the file. If the specified + * fingerprint value is null then the current entry in the specified file + * will be removed if found. + * + * @param userName - non-null user name + * @param serverAddress - non-null server address + * @param fingerprintValue - possibly null fingerprint value + * @param trustFile - non-null file + * @throws IOException on error + */ + public static void saveFingerprint(String userName, String serverAddress, String fingerprintValue, File trustFile) throws IOException { + saveFingerprint(userName, serverAddress, fingerprintValue, trustFile, 0, 0, 0); + } - /** - * Save the specified parameters as an entry into the specified trust file. - * This method will replace the current entry for the user name and server - * address in the trust file. If a current entry is not found then the - * specified entry will be appended to the file. If the specified - * fingerprint value is null then the current entry in the specified file - * will be removed if found. - * - * @param userName - * - non-null user name - * @param serverAddress - * - non-null server address - * @param fingerprintValue - * - possibly null fingerprint value - * @param trustFile - * - non-null file - * @param lockTry - * - number of tries for locking - * @param lockDelay - * - delay time (ms) for locking - * @param lockWait - * - wait time (ms) for other process/thread to finish locking - * @throws IOException - */ - public static void saveFingerprint(String userName, String serverAddress, - String fingerprintValue, File trustFile, int lockTry, long lockDelay, long lockWait) - throws IOException { - if (trustFile != null) { - saveFileEntry(userName, serverAddress, fingerprintValue, trustFile, lockTry, lockDelay, - lockWait); - } else { - saveMemoryEntry(userName, serverAddress, fingerprintValue, fingerprintsMap); - } - } + /** + * Save the specified parameters as an entry into the specified trust file. + * This method will replace the current entry for the user name and server + * address in the trust file. If a current entry is not found then the + * specified entry will be appended to the file. If the specified + * fingerprint value is null then the current entry in the specified file + * will be removed if found. + * + * @param userName - non-null user name + * @param serverAddress - non-null server address + * @param fingerprintValue - possibly null fingerprint value + * @param trustFile - non-null file + * @param lockTry - number of tries for locking + * @param lockDelay - delay time (ms) for locking + * @param lockWait - wait time (ms) for other process/thread to finish locking + * @throws IOException on error + */ + public static void saveFingerprint(String userName, String serverAddress, String fingerprintValue, File trustFile, int lockTry, long lockDelay, long lockWait) throws IOException { + if (trustFile != null) { + saveFileEntry(userName, serverAddress, fingerprintValue, trustFile, lockTry, lockDelay, lockWait); + } else { + saveMemoryEntry(userName, serverAddress, fingerprintValue, fingerprintsMap); + } + } } diff --git a/src/main/java/com/perforce/p4java/server/IHelixCommandExecutor.java b/src/main/java/com/perforce/p4java/server/IHelixCommandExecutor.java index 56f9d91..925adce 100644 --- a/src/main/java/com/perforce/p4java/server/IHelixCommandExecutor.java +++ b/src/main/java/com/perforce/p4java/server/IHelixCommandExecutor.java @@ -1,290 +1,258 @@ package com.perforce.p4java.server; -import java.io.InputStream; -import java.util.List; -import java.util.Map; -import javax.annotation.Nonnull; - import com.perforce.p4java.exception.AccessException; import com.perforce.p4java.exception.ConnectionException; import com.perforce.p4java.exception.P4JavaException; import com.perforce.p4java.exception.RequestException; import com.perforce.p4java.server.callback.IFilterCallback; -public interface IHelixCommandExecutor { +import javax.annotation.Nonnull; +import java.io.InputStream; +import java.util.List; +import java.util.Map; - List> execMapCmdList( - @Nonnull CmdSpec cmdSpec, - String[] cmdArgs, - Map inMap) throws ConnectionException, AccessException; +public interface IHelixCommandExecutor { - /** - * Issue an arbitrary P4Java command to the Perforce server and return the - * results as a list of maps. - *

- *

- * This method is intended for low-level commands in the spirit and format - * of the p4 command line interpreter, and offers a simple way to issue - * commands to the associated Perforce server without the overhead of the - * more abstract Java interfaces and methods. - *

- *

- * No guidance is given here on the format of the returned map; however, it - * produces the same output as the p4 command line interpreter in -G (Python - * map) mode. - *

- *

- * Note that this method does not allow you to set "usage" options for the - * command; these may be added later. Note also that although option - * arguments passed to this method must be in a form recognized by the p4 - * command line interpreter, that does not mean the method is being - * implemented by the interpreter -- the actual implementation depends on - * the options used to get the server object in the first place from the - * server factory. - * - * @param cmdName the command to be issued; must be non-null, and correspond to - * a Perforce command recognized by P4Java and defined in - * CmdSpec. - * @param cmdArgs the array of command arguments (options and file arguments, - * etc.) to be sent to the Perforce server. These must be in the - * form used by the corresponding p4 command line interpreter. - * Ignored if null. - * @param inMap an optional map to be sent to the server as standard input, - * using the Python map format (-G) form. You must remember to - * issue the relevant command-specific option to enable this if - * needed. - * @return a non-null Java List of results; these results are as returned - * from issuing the command using the -G option with the p4 command - * line interpreter. - * @throws ConnectionException - * if the Perforce server is unreachable or is not connected. - * @throws RequestException - * if the Perforce server encounters an error during its - * processing of the request - * @throws AccessException - * if the Perforce server denies access to the caller - * @since 2013.1 - */ - List> execMapCmdList( - String cmdName, - String[] cmdArgs, - Map inMap) - throws ConnectionException, AccessException, RequestException; + List> execMapCmdList(@Nonnull CmdSpec cmdSpec, String[] cmdArgs, Map inMap) throws ConnectionException, AccessException; - /** - * Issue an arbitrary P4Java command to the Perforce server and return the - * results as a list of maps. - *

- *

- * This method is intended for low-level commands in the spirit and format - * of the p4 command line interpreter, and offers a simple way to issue - * commands to the associated Perforce server without the overhead of the - * more abstract Java interfaces and methods. - *

- *

- * No guidance is given here on the format of the returned map; however, it - * produces the same output as the p4 command line interpreter in -G (Python - * map) mode. - *

- *

- * Note that this method does not allow you to set "usage" options for the - * command; these may be added later. Note also that although option - * arguments passed to this method must be in a form recognized by the p4 - * command line interpreter, that does not mean the method is being - * implemented by the interpreter -- the actual implementation depends on - * the options used to get the server object in the first place from the - * server factory. - * - * @param cmdName the command to be issued; must be non-null, and correspond to - * a Perforce command recognized by P4Java and defined in - * CmdSpec. - * @param cmdArgs the array of command arguments (options and file arguments, - * etc.) to be sent to the Perforce server. These must be in the - * form used by the corresponding p4 command line interpreter. - * Ignored if null. - * @param inMap an optional map to be sent to the server as standard input, - * using the Python map format (-G) form. You must remember to - * issue the relevant command-specific option to enable this if - * needed. - * @param filterCallback an optional filter callback to decide on skipping or keeping - * individual key/value pairs as part of the results map. - * @return a non-null Java List of results; these results are as returned - * from issuing the command using the -G option with the p4 command - * line interpreter. - * @throws P4JavaException if an error occurs processing this method and its parameters. - * @since 2013.1 - */ - List> execMapCmdList( - String cmdName, - String[] cmdArgs, - Map inMap, - IFilterCallback filterCallback) throws P4JavaException; + /** + * Issue an arbitrary P4Java command to the Perforce server and return the + * results as a list of maps. + *

+ * This method is intended for low-level commands in the spirit and format + * of the p4 command line interpreter, and offers a simple way to issue + * commands to the associated Perforce server without the overhead of the + * more abstract Java interfaces and methods. + *

+ * No guidance is given here on the format of the returned map; however, it + * produces the same output as the p4 command line interpreter in -G (Python + * map) mode. + *

+ * Note that this method does not allow you to set "usage" options for the + * command; these may be added later. Note also that although option + * arguments passed to this method must be in a form recognized by the p4 + * command line interpreter, that does not mean the method is being + * implemented by the interpreter -- the actual implementation depends on + * the options used to get the server object in the first place from the + * server factory. + * + * @param cmdName the command to be issued; must be non-null, and correspond to + * a Perforce command recognized by P4Java and defined in + * CmdSpec. + * @param cmdArgs the array of command arguments (options and file arguments, + * etc.) to be sent to the Perforce server. These must be in the + * form used by the corresponding p4 command line interpreter. + * Ignored if null. + * @param inMap an optional map to be sent to the server as standard input, + * using the Python map format (-G) form. You must remember to + * issue the relevant command-specific option to enable this if + * needed. + * @return a non-null Java List of results; these results are as returned + * from issuing the command using the -G option with the p4 command + * line interpreter. + * @throws ConnectionException if the Perforce server is unreachable or is not connected. + * @throws RequestException if the Perforce server encounters an error during its + * processing of the request + * @throws AccessException if the Perforce server denies access to the caller + * @since 2013.1 + */ + List> execMapCmdList(String cmdName, String[] cmdArgs, Map inMap) throws ConnectionException, AccessException, RequestException; - /** - * Issue an arbitrary P4Java command to the Perforce server and get the - * results as a stream. - *

- *

- * This method is intended for low-level commands in the spirit and format - * of the p4 command line interpreter, and offers a simple way to issue - * commands to the associated Perforce server without the overhead of the - * more abstract Java interfaces and methods. - *

- *

- * Note that this method is intended for things like getting file contents, - * and may have unpredictable results on commands not originally expected to - * return i/o streams. - *

- *

- * Note that this method does not allow you to set "usage" options for the - * command; these may be added later. Note also that although option - * arguments passed to this method must be in a form recognized by P4Java - * (as defined by the CmdSpec enum), that does not mean the method is - * being implemented by the interpreter -- the actual implementation depends - * on the options used to get the server object in the first place from the - * server factory. - * - * @param cmdName the command to be issued; must be non-null, and correspond to - * a Perforce command recognized by P4Java and defined in - * CmdSpec. - * @param cmdArgs the array of command arguments (options and file arguments, - * etc.) to be sent to the Perforce server. These must be in the - * form used by the corresponding p4 command line interpreter. - * Ignored if null. - * @return an InputStream on the command output. This will never be null, - * but it may be empty. You must properly close this stream - * after use or temporary files may be left lying around the VM's - * java.io.tmpdir area. - * @throws ConnectionException if the Perforce server is unreachable or is not connected. - * @throws RequestException if the Perforce server encounters an error during its - * processing of the request - * @throws AccessException if the Perforce server denies access to the caller - */ + /** + * Issue an arbitrary P4Java command to the Perforce server and return the + * results as a list of maps. + *

+ * This method is intended for low-level commands in the spirit and format + * of the p4 command line interpreter, and offers a simple way to issue + * commands to the associated Perforce server without the overhead of the + * more abstract Java interfaces and methods. + *

+ * No guidance is given here on the format of the returned map; however, it + * produces the same output as the p4 command line interpreter in -G (Python + * map) mode. + *

+ * Note that this method does not allow you to set "usage" options for the + * command; these may be added later. Note also that although option + * arguments passed to this method must be in a form recognized by the p4 + * command line interpreter, that does not mean the method is being + * implemented by the interpreter -- the actual implementation depends on + * the options used to get the server object in the first place from the + * server factory. + * + * @param cmdName the command to be issued; must be non-null, and correspond to + * a Perforce command recognized by P4Java and defined in + * CmdSpec. + * @param cmdArgs the array of command arguments (options and file arguments, + * etc.) to be sent to the Perforce server. These must be in the + * form used by the corresponding p4 command line interpreter. + * Ignored if null. + * @param inMap an optional map to be sent to the server as standard input, + * using the Python map format (-G) form. You must remember to + * issue the relevant command-specific option to enable this if + * needed. + * @param filterCallback an optional filter callback to decide on skipping or keeping + * individual key/value pairs as part of the results map. + * @return a non-null Java List of results; these results are as returned + * from issuing the command using the -G option with the p4 command + * line interpreter. + * @throws P4JavaException if an error occurs processing this method and its parameters. + * @since 2013.1 + */ + List> execMapCmdList(String cmdName, String[] cmdArgs, Map inMap, IFilterCallback filterCallback) throws P4JavaException; - InputStream execStreamCmd(String cmdName, String[] cmdArgs) - throws ConnectionException, RequestException, AccessException; + /** + * Issue an arbitrary P4Java command to the Perforce server and get the + * results as a stream. + *

+ * This method is intended for low-level commands in the spirit and format + * of the p4 command line interpreter, and offers a simple way to issue + * commands to the associated Perforce server without the overhead of the + * more abstract Java interfaces and methods. + *

+ * Note that this method is intended for things like getting file contents, + * and may have unpredictable results on commands not originally expected to + * return i/o streams. + *

+ * Note that this method does not allow you to set "usage" options for the + * command; these may be added later. Note also that although option + * arguments passed to this method must be in a form recognized by P4Java + * (as defined by the CmdSpec enum), that does not mean the method is + * being implemented by the interpreter -- the actual implementation depends + * on the options used to get the server object in the first place from the + * server factory. + * + * @param cmdName the command to be issued; must be non-null, and correspond to + * a Perforce command recognized by P4Java and defined in + * CmdSpec. + * @param cmdArgs the array of command arguments (options and file arguments, + * etc.) to be sent to the Perforce server. These must be in the + * form used by the corresponding p4 command line interpreter. + * Ignored if null. + * @return an InputStream on the command output. This will never be null, + * but it may be empty. You must properly close this stream + * after use or temporary files may be left lying around the VM's + * java.io.tmpdir area. + * @throws ConnectionException if the Perforce server is unreachable or is not connected. + * @throws RequestException if the Perforce server encounters an error during its + * processing of the request + * @throws AccessException if the Perforce server denies access to the caller + */ + InputStream execStreamCmd(String cmdName, String[] cmdArgs) throws ConnectionException, RequestException, AccessException; - /** - * @deprecated use {@link com.perforce.p4java.impl.mapbased.server.cmd.ResultMapParser#handleFileErrorStr(Map)} - */ - @Deprecated - String handleFileErrorStr(Map map) - throws ConnectionException, AccessException; + /** + * @param map Perforce command results map + * @return possibly-null info/warning/error/fatal string + * @throws ConnectionException on error + * @throws AccessException on error + * @deprecated use {@link com.perforce.p4java.impl.mapbased.server.cmd.ResultMapParser#handleFileErrorStr(Map)} + */ + @Deprecated + String handleFileErrorStr(Map map) throws ConnectionException, AccessException; - /** - *

- * Gets the info/warning/error/fatal message from the passed-in Perforce - * command results map. If no info/warning/error/fatal message found in the - * results map it returns null. - *

- *

- * Note that the minimum severity code is MessageSeverityCode.E_INFO. - * Therefore, only message with severity code >= MessageSeverityCode.E_INFO - * will be returned. - *

- *

- * RPC impl errors come across the wire as a map in the form usually like - * this: - *

- *

-     * fmt0=Access for user '%user%' has not been enabled by 'p4 protect'.,
-     * func=client-Message, user=nouser, code0=822483067
-     * 
- *

- * Note that the code0 entry will be used to get the severity level; the - * fmt0 entry contains the message. - *

- * - * @param map Perforce command results map - * @return possibly-null info/warning/error/fatal string - * @since 2011.2 - * @deprecated use {@link com.perforce.p4java.impl.mapbased.server.cmd.ResultMapParser#getErrorOrInfoStr(Map)} - */ - @Deprecated - String getErrorOrInfoStr(Map map); + /** + * Gets the info/warning/error/fatal message from the passed-in Perforce + * command results map. If no info/warning/error/fatal message found in the + * results map it returns null. + *

+ * Note that the minimum severity code is MessageSeverityCode.E_INFO. + * Therefore, only message with severity code >= MessageSeverityCode.E_INFO + * will be returned. + *

+ * RPC impl errors come across the wire as a map in the form usually like + * this: + *

+	 * fmt0=Access for user '%user%' has not been enabled by 'p4 protect'.,
+	 * func=client-Message, user=nouser, code0=822483067
+	 * 
+ * Note that the code0 entry will be used to get the severity level; the + * fmt0 entry contains the message. + *

+ * + * @param map Perforce command results map + * @return possibly-null info/warning/error/fatal string + * @since 2011.2 + * @deprecated use {@link com.perforce.p4java.impl.mapbased.server.cmd.ResultMapParser#getErrorOrInfoStr(Map)} + */ + @Deprecated + String getErrorOrInfoStr(Map map); - /** - * @deprecated use {@link com.perforce.p4java.impl.mapbased.server.cmd.ResultMapParser#handleErrorStr(Map)} - */ - @Deprecated - boolean handleErrorStr(Map map) - throws RequestException, AccessException; + /** + * @param map Perforce command results map + * @return possibly-null info/warning/error/fatal string + * @throws RequestException on error + * @throws AccessException on error + * @deprecated use {@link com.perforce.p4java.impl.mapbased.server.cmd.ResultMapParser#handleErrorStr(Map)} + */ + @Deprecated + boolean handleErrorStr(Map map) throws RequestException, AccessException; - /** - *

- * Gets the error/fatal message from the passed-in Perforce command results - * map. If no error/fatal message found in the results map it returns null. - *

- *

- * Note that the minimum severity code is MessageSeverityCode.E_FAILED. - * Therefore, only message with severity code >= - * MessageSeverityCode.E_FAILED will be returned. - *

- *

- * RPC impl errors come across the wire as a map in the form usually like - * this: - *

- *

-     * fmt0=Access for user '%user%' has not been enabled by 'p4 protect'.,
-     * func=client-Message, user=nouser, code0=822483067
-     * 
- *

- * Note that the code0 entry will be used to get the severity level; the - * fmt0 entry contains the message. - *

- * - * @param map Perforce command results map - * @return possibly-null error/fatal string - * @since 2011.2 - * @deprecated use {@link com.perforce.p4java.impl.mapbased.server.cmd.ResultMapParser#getErrorStr(Map)} - */ - @Deprecated - String getErrorStr(Map map); + /** + * Gets the error/fatal message from the passed-in Perforce command results + * map. If no error/fatal message found in the results map it returns null. + *

+ * Note that the minimum severity code is MessageSeverityCode.E_FAILED. + * Therefore, only message with severity code >= + * MessageSeverityCode.E_FAILED will be returned. + *

+ * RPC impl errors come across the wire as a map in the form usually like + * this: + *

+	 * fmt0=Access for user '%user%' has not been enabled by 'p4 protect'.,
+	 * func=client-Message, user=nouser, code0=822483067
+	 * 
+ * Note that the code0 entry will be used to get the severity level; the + * fmt0 entry contains the message. + *

+ * + * @param map Perforce command results map + * @return possibly-null error/fatal string + * @since 2011.2 + * @deprecated use {@link com.perforce.p4java.impl.mapbased.server.cmd.ResultMapParser#getErrorStr(Map)} + */ + @Deprecated + String getErrorStr(Map map); - /** - * @deprecated use {@link com.perforce.p4java.impl.mapbased.server.cmd.ResultMapParser#isAuthFail(String)} - */ - @Deprecated - boolean isAuthFail(String errStr); + /** + * @param errStr error string + * @return true if error + * @deprecated use {@link com.perforce.p4java.impl.mapbased.server.cmd.ResultMapParser#isAuthFail(String)} + */ + @Deprecated + boolean isAuthFail(String errStr); - /** - *

- * Gets the info message from the passed-in Perforce command results map. If - * no info message found in the results map it returns null. - *

- *

- * Note that the severity code is MessageSeverityCode.E_INFO. Therefore, - * only message with severity code = MessageSeverityCode.E_INFO will be - * returned. - *

- *

- * RPC impl errors come across the wire as a map in the form usually like - * this: - *

- *

-     * fmt0=Access for user '%user%' has not been enabled by 'p4 protect'.,
-     * func=client-Message, user=nouser, code0=822483067
-     * 
- *

- * Note that the code0 entry will be used to get the severity level; the - * fmt0 entry contains the message. - *

- * - * @param map Perforce command results map - * @return possibly-null info string - * @since 2011.2 - * @deprecated use {@link com.perforce.p4java.impl.mapbased.server.cmd.ResultMapParser#getInfoStr(Map)} - */ - @Deprecated - String getInfoStr(Map map); + /** + * Gets the info message from the passed-in Perforce command results map. If + * no info message found in the results map it returns null. + *

+ * Note that the severity code is MessageSeverityCode.E_INFO. Therefore, + * only message with severity code = MessageSeverityCode.E_INFO will be + * returned. + *

+ * RPC impl errors come across the wire as a map in the form usually like + * this: + *

+	 * fmt0=Access for user '%user%' has not been enabled by 'p4 protect'.,
+	 * func=client-Message, user=nouser, code0=822483067
+	 * 
+ * Note that the code0 entry will be used to get the severity level; the + * fmt0 entry contains the message. + *

+ * + * @param map Perforce command results map + * @return possibly-null info string + * @since 2011.2 + * @deprecated use {@link com.perforce.p4java.impl.mapbased.server.cmd.ResultMapParser#getInfoStr(Map)} + */ + @Deprecated + String getInfoStr(Map map); - /** - * Checks if is info message. - * - * @param map the map - * @return true, if is info message - * @deprecated use {@link com.perforce.p4java.impl.mapbased.server.cmd.ResultMapParser#isInfoMessage(Map)} - */ - @Deprecated - boolean isInfoMessage(Map map); + /** + * Checks if is info message. + * + * @param map the map + * @return true, if is info message + * @deprecated use {@link com.perforce.p4java.impl.mapbased.server.cmd.ResultMapParser#isInfoMessage(Map)} + */ + @Deprecated + boolean isInfoMessage(Map map); } diff --git a/src/main/java/com/perforce/p4java/server/IServer.java b/src/main/java/com/perforce/p4java/server/IServer.java index 2025fd6..48f05b7 100644 --- a/src/main/java/com/perforce/p4java/server/IServer.java +++ b/src/main/java/com/perforce/p4java/server/IServer.java @@ -21,7 +21,84 @@ import com.perforce.p4java.server.callback.IProgressCallback; import com.perforce.p4java.server.callback.ISSOCallback; import com.perforce.p4java.server.callback.IStreamingCallback; -import com.perforce.p4java.server.delegator.*; +import com.perforce.p4java.server.delegator.IAttributeDelegator; +import com.perforce.p4java.server.delegator.IBranchDelegator; +import com.perforce.p4java.server.delegator.IBranchesDelegator; +import com.perforce.p4java.server.delegator.IChangeDelegator; +import com.perforce.p4java.server.delegator.IChangesDelegator; +import com.perforce.p4java.server.delegator.IClientDelegator; +import com.perforce.p4java.server.delegator.IClientsDelegator; +import com.perforce.p4java.server.delegator.ICommitDelegator; +import com.perforce.p4java.server.delegator.IConfigureDelegator; +import com.perforce.p4java.server.delegator.ICounterDelegator; +import com.perforce.p4java.server.delegator.ICountersDelegator; +import com.perforce.p4java.server.delegator.IDBSchemaDelegator; +import com.perforce.p4java.server.delegator.IDepotDelegator; +import com.perforce.p4java.server.delegator.IDepotsDelegator; +import com.perforce.p4java.server.delegator.IDescribeDelegator; +import com.perforce.p4java.server.delegator.IDiff2Delegator; +import com.perforce.p4java.server.delegator.IDirsDelegator; +import com.perforce.p4java.server.delegator.IDiskspaceDelegator; +import com.perforce.p4java.server.delegator.IDuplicateDelegator; +import com.perforce.p4java.server.delegator.IExportDelegator; +import com.perforce.p4java.server.delegator.IExtensionDelegator; +import com.perforce.p4java.server.delegator.IFileAnnotateDelegator; +import com.perforce.p4java.server.delegator.IFileLogDelegator; +import com.perforce.p4java.server.delegator.IFilesDelegator; +import com.perforce.p4java.server.delegator.IFixDelegator; +import com.perforce.p4java.server.delegator.IFixesDelegator; +import com.perforce.p4java.server.delegator.IFstatDelegator; +import com.perforce.p4java.server.delegator.IGraphCommitLogDelegator; +import com.perforce.p4java.server.delegator.IGraphListTreeDelegator; +import com.perforce.p4java.server.delegator.IGraphReceivePackDelegator; +import com.perforce.p4java.server.delegator.IGraphRevListDelegator; +import com.perforce.p4java.server.delegator.IGraphShowRefDelegator; +import com.perforce.p4java.server.delegator.IGrepDelegator; +import com.perforce.p4java.server.delegator.IGroupDelegator; +import com.perforce.p4java.server.delegator.IGroupsDelegator; +import com.perforce.p4java.server.delegator.IInfoDelegator; +import com.perforce.p4java.server.delegator.IIntegratedDelegator; +import com.perforce.p4java.server.delegator.IInterchangesDelegator; +import com.perforce.p4java.server.delegator.IJobDelegator; +import com.perforce.p4java.server.delegator.IJobSpecDelegator; +import com.perforce.p4java.server.delegator.IJobsDelegator; +import com.perforce.p4java.server.delegator.IJournalWaitDelegator; +import com.perforce.p4java.server.delegator.IKeyDelegator; +import com.perforce.p4java.server.delegator.IKeysDelegator; +import com.perforce.p4java.server.delegator.ILabelDelegator; +import com.perforce.p4java.server.delegator.ILabelsDelegator; +import com.perforce.p4java.server.delegator.ILicenseDelegator; +import com.perforce.p4java.server.delegator.ILogTailDelegator; +import com.perforce.p4java.server.delegator.ILogin2Delegator; +import com.perforce.p4java.server.delegator.ILoginDelegator; +import com.perforce.p4java.server.delegator.ILogoutDelegator; +import com.perforce.p4java.server.delegator.IMonitorDelegator; +import com.perforce.p4java.server.delegator.IMoveDelegator; +import com.perforce.p4java.server.delegator.IObliterateDelegator; +import com.perforce.p4java.server.delegator.IOpenedDelegator; +import com.perforce.p4java.server.delegator.IPasswdDelegator; +import com.perforce.p4java.server.delegator.IPrintDelegator; +import com.perforce.p4java.server.delegator.IPropertyDelegator; +import com.perforce.p4java.server.delegator.IProtectDelegator; +import com.perforce.p4java.server.delegator.IProtectsDelegator; +import com.perforce.p4java.server.delegator.IReloadDelegator; +import com.perforce.p4java.server.delegator.IRenameUserDelegator; +import com.perforce.p4java.server.delegator.IReposDelegator; +import com.perforce.p4java.server.delegator.IReviewDelegator; +import com.perforce.p4java.server.delegator.IReviewsDelegator; +import com.perforce.p4java.server.delegator.ISearchDelegator; +import com.perforce.p4java.server.delegator.ISizesDelegator; +import com.perforce.p4java.server.delegator.ISpecDelegator; +import com.perforce.p4java.server.delegator.IStatDelegator; +import com.perforce.p4java.server.delegator.IStreamDelegator; +import com.perforce.p4java.server.delegator.IStreamlogDelegator; +import com.perforce.p4java.server.delegator.IStreamsDelegator; +import com.perforce.p4java.server.delegator.ITagDelegator; +import com.perforce.p4java.server.delegator.ITriggersDelegator; +import com.perforce.p4java.server.delegator.IUnloadDelegator; +import com.perforce.p4java.server.delegator.IUserDelegator; +import com.perforce.p4java.server.delegator.IUsersDelegator; +import com.perforce.p4java.server.delegator.IVerifyDelegator; import java.io.InputStream; import java.nio.charset.UnsupportedCharsetException; @@ -32,14 +109,12 @@ /** * Provides an interface onto a Perforce SCM server. *

- *

* This is the main interface for Perforce services that are typically Perforce * client workspace-independent, or that affect entire Perforce depots or * servers. Some of these services are also available through various client, * job, changelist, etc., interfaces methods, but in general, most Perforce * services are always available through methods on this interface as well. *

- *

* IServer interfaces for specific Perforce servers are issued by the P4Javs * server factory class, ServerFactory; the factory can return interfaces that * use a small variety of communication protocols to access the Perforce server. @@ -47,44 +122,42 @@ * @see com.perforce.p4java.server.ServerFactory */ -public interface IServer extends IHelixCommandExecutor, IAttributeDelegator, IBranchDelegator, IBranchesDelegator, - IChangeDelegator, IChangesDelegator, IClientDelegator, IClientsDelegator, IConfigureDelegator, - ICounterDelegator, ICountersDelegator, IDBSchemaDelegator, IDepotDelegator, IDepotsDelegator, - IReposDelegator, IDescribeDelegator, IDiff2Delegator, IDirsDelegator, IDiskspaceDelegator, - IDuplicateDelegator, IExportDelegator, IFileAnnotateDelegator, IFileLogDelegator, IFilesDelegator, - IFixDelegator, IFixesDelegator, IFstatDelegator, IGrepDelegator, IGroupDelegator, IGroupsDelegator, - IInfoDelegator, IIntegratedDelegator, IInterchangesDelegator, IStatDelegator, IJobDelegator, - IJobsDelegator, IJobSpecDelegator, IJournalWaitDelegator, IKeyDelegator, IKeysDelegator, - ILabelDelegator, ILabelsDelegator, ILoginDelegator, ILogoutDelegator, ILogTailDelegator, - IMonitorDelegator, IMoveDelegator, IObliterateDelegator, IOpenedDelegator, IPasswdDelegator, - IPrintDelegator, IPropertyDelegator, IProtectDelegator, IProtectsDelegator, IReloadDelegator, - IRenameUserDelegator, IReviewDelegator, IReviewsDelegator, ISearchDelegator, ISizesDelegator, - IStreamDelegator, IStreamsDelegator, ITagDelegator, ITriggersDelegator, IUnloadDelegator, - IUserDelegator, IUsersDelegator, IVerifyDelegator, IGraphListTreeDelegator, ICommitDelegator, - IGraphRevListDelegator, IGraphCommitLogDelegator, IGraphReceivePackDelegator, IListDelegator, - IGraphShowRefDelegator, ILogin2Delegator, ISpecDelegator, ILicenseDelegator, IExtensionDelegator, - IStreamlogDelegator{ +public interface IServer extends IHelixCommandExecutor, IAttributeDelegator, IBranchDelegator, IBranchesDelegator, IChangeDelegator, IChangesDelegator, IClientDelegator, IClientsDelegator, IConfigureDelegator, ICounterDelegator, ICountersDelegator, IDBSchemaDelegator, IDepotDelegator, IDepotsDelegator, IReposDelegator, IDescribeDelegator, IDiff2Delegator, IDirsDelegator, IDiskspaceDelegator, IDuplicateDelegator, IExportDelegator, IFileAnnotateDelegator, IFileLogDelegator, IFilesDelegator, IFixDelegator, IFixesDelegator, IFstatDelegator, IGrepDelegator, IGroupDelegator, IGroupsDelegator, IInfoDelegator, IIntegratedDelegator, IInterchangesDelegator, IStatDelegator, IJobDelegator, IJobsDelegator, IJobSpecDelegator, IJournalWaitDelegator, IKeyDelegator, IKeysDelegator, ILabelDelegator, ILabelsDelegator, ILoginDelegator, ILogoutDelegator, ILogTailDelegator, IMonitorDelegator, IMoveDelegator, IObliterateDelegator, IOpenedDelegator, IPasswdDelegator, IPrintDelegator, IPropertyDelegator, IProtectDelegator, IProtectsDelegator, IReloadDelegator, IRenameUserDelegator, IReviewDelegator, IReviewsDelegator, ISearchDelegator, ISizesDelegator, IStreamDelegator, IStreamsDelegator, ITagDelegator, ITriggersDelegator, IUnloadDelegator, IUserDelegator, IUsersDelegator, IVerifyDelegator, IGraphListTreeDelegator, ICommitDelegator, IGraphRevListDelegator, IGraphCommitLogDelegator, IGraphReceivePackDelegator, IListDelegator, IGraphShowRefDelegator, ILogin2Delegator, ISpecDelegator, ILicenseDelegator, IExtensionDelegator, IStreamlogDelegator { String ATTRIBUTE_STREAM_MAP_KEY = "attributeInstream"; + /** * Property key for overriding the default tagged/non-tagged behavior of a * command. This is a per-command property, set on a command's "inMap". */ String IN_MAP_USE_TAGS_KEY = "useTags"; + /** + * Try to get the Perforce server version. This is likely to be the first + * time + * actual connectivity is tested for the server... + * Since this is called before we know much about the state or type of the + * Perforce server, we do virtually no real error checking or recovery -- we + * either get a suitable response and dig out the server version, or we just + * leave things alone. + *

+ * NOTE: has the side effect of setting the server impl's serverVersion + * field. + * + * @return version + * @throws ConnectionException on error + */ int getServerVersion() throws ConnectionException; /** * Connect to the Perforce server associated with this server object. *

- *

* This method's detailed semantics depend on the underlying transport * implementation, but in general, it's intended to be called before any * attempt is made to issue a command to the associated Perforce server. * It's also intended to be called after any (intentional or accidental) * disconnect. *

- *

* Note that certain implementations may try to request a client, etc., on * connection (in response to property values passed in through the URL, * etc.), which may cause a RequestException to be generated. @@ -95,7 +168,6 @@ public interface IServer extends IHelixCommandExecutor, IAttributeDelegator, IBr * processing of the request * @throws ConfigException if local I/O exception occurs */ - void connect() throws ConnectionException, AccessException, RequestException, ConfigException; /** @@ -108,9 +180,7 @@ public interface IServer extends IHelixCommandExecutor, IAttributeDelegator, IBr * processing of the request. * @throws AccessException if the Perforce server denies access to the caller. */ - - String createUserGroup(IUserGroup group) - throws ConnectionException, RequestException, AccessException; + String createUserGroup(IUserGroup group) throws ConnectionException, RequestException, AccessException; /** * Delete a Perforce user group from the Perforce server. @@ -122,42 +192,38 @@ String createUserGroup(IUserGroup group) * processing of the request. * @throws AccessException if the Perforce server denies access to the caller. */ - - String deleteUserGroup(IUserGroup group) - throws ConnectionException, RequestException, AccessException; + String deleteUserGroup(IUserGroup group) throws ConnectionException, RequestException, AccessException; /** * Disconnect from this Perforce server. Does not affect the current * IServer's current user, password, or client settings, but if you later * reconnect to the same Perforce server, you may also need to re-login. *

- *

* This command should be run at the point at which this server is not going * to be used any more, and attempts to disconnect from the associated * server. "Disconnect" here has different meanings according to the * underlying transport mechanism, but in practice it will mean that * attempting to use this server object to issue Perforce commands will * fail, usually with a ConnectionException exception. + * + * @throws ConnectionException on error + * @throws AccessException on error */ - void disconnect() throws ConnectionException, AccessException; /** * Issue an arbitrary P4Java command to the Perforce server and return the * results as a map. *

- *

* This method is intended for low-level commands in the spirit and format * of the p4 command line interpreter, and offers a simple way to issue * commands to the associated Perforce server without the overhead of the * more abstract Java interfaces and methods. *

- *

* No guidance is given here on the format of the returned map; however, it * produces the same output as the p4 command line interpreter in -G (Python * map) mode. *

- *

* Note that this method does not allow you to set "usage" options for the * command; these may be added later. Note also that although option * arguments passed to this method must be in a form recognized by the p4 @@ -185,22 +251,18 @@ String deleteUserGroup(IUserGroup group) * @throws P4JavaException if an error occurs processing this method and its parameters * @since 2011.1 */ - - Map[] execInputStringMapCmd(String cmdName, String[] cmdArgs, String inString) - throws P4JavaException; + Map[] execInputStringMapCmd(String cmdName, String[] cmdArgs, String inString) throws P4JavaException; /** * Issue a streaming map command to the Perforce server, using an optional * string for any input expected by the server (such as label or job specs, * etc.). *

- *

* Streaming commands allow users to get each result from a suitably-issued * command as it comes in from the server, rather than waiting for the * entire command method to complete (and getting the results back as a * completed List or Map or whatever). *

- *

* The results are sent to the user using the IStreamingCallback * handleResult method; see the IStreamingCallback Javadoc for details. The * payload passed to handleResult is usually the raw map gathered together @@ -209,7 +271,6 @@ Map[] execInputStringMapCmd(String cmdName, String[] cmdArgs, St * much the same way as a user unpacks or processes the results from the * other low-level exec methods like execMapCommand. *

- *

* NOTE: 'streaming' here has nothing at all to do with Perforce 'streams', * which are (or will be) implemented elsewhere. * @@ -237,25 +298,21 @@ Map[] execInputStringMapCmd(String cmdName, String[] cmdArgs, St * {@link com.perforce.p4java.server.IOptionsServer#execInputStringStreamingMapCmd(java.lang.String, java.lang.String[], java.lang.String, com.perforce.p4java.server.callback.IStreamingCallback, int)} */ @Deprecated - void execInputStringStreamingMapComd(String cmdName, String[] cmdArgs, String inString, - IStreamingCallback callback, int key) throws P4JavaException; + void execInputStringStreamingMapComd(String cmdName, String[] cmdArgs, String inString, IStreamingCallback callback, int key) throws P4JavaException; /** * Issue an arbitrary P4Java command to the Perforce server and return the * results as a map. *

- *

* This method is intended for low-level commands in the spirit and format * of the p4 command line interpreter, and offers a simple way to issue * commands to the associated Perforce server without the overhead of the * more abstract Java interfaces and methods. *

- *

* No guidance is given here on the format of the returned map; however, it * produces the same output as the p4 command line interpreter in -G (Python * map) mode. *

- *

* Note that this method does not allow you to set "usage" options for the * command; these may be added later. Note also that although option * arguments passed to this method must be in a form recognized by the p4 @@ -283,15 +340,12 @@ void execInputStringStreamingMapComd(String cmdName, String[] cmdArgs, String in * processing of the request * @throws AccessException if the Perforce server denies access to the caller */ - - Map[] execMapCmd(String cmdName, String[] cmdArgs, Map inMap) - throws ConnectionException, RequestException, AccessException; + Map[] execMapCmd(String cmdName, String[] cmdArgs, Map inMap) throws ConnectionException, RequestException, AccessException; /** * Issue an arbitrary P4Java command to the Perforce server and return the * results as a map without invoking any command callbacks. *

- *

* Basically equivalent to execMapCmd with temporary disabling of any * ICommandCallback calls and / or listeners; this turns out to be useful * for various reasons we won't go into here... @@ -316,16 +370,12 @@ Map[] execMapCmd(String cmdName, String[] cmdArgs, Map[] execQuietMapCmd(String cmdName, String[] cmdArgs, - Map inMap) - throws ConnectionException, RequestException, AccessException; + Map[] execQuietMapCmd(String cmdName, String[] cmdArgs, Map inMap) throws ConnectionException, RequestException, AccessException; /** * Issue an arbitrary P4Java command to the Perforce server and get the * results as a stream without invoking any command callbacks. *

- *

* Basically equivalent to execStreamCmd with temporary disabling of any * ICommandCallback calls and / or listeners; this turns out to be useful * for various reasons we won't go into here... @@ -347,22 +397,18 @@ Map[] execQuietMapCmd(String cmdName, String[] cmdArgs, * processing of the request * @throws AccessException if the Perforce server denies access to the caller */ - - InputStream execQuietStreamCmd(String cmdName, String[] cmdArgs) - throws ConnectionException, RequestException, AccessException; + InputStream execQuietStreamCmd(String cmdName, String[] cmdArgs) throws ConnectionException, RequestException, AccessException; /** * Issue a streaming map command to the Perforce server, using an optional * map for any input expected by the server (such as label or job specs, * etc.). *

- *

* Streaming commands allow users to get each result from a suitably-issued * command as it comes in from the server, rather than waiting for the * entire command method to complete (and getting the results back as a * completed List or Map or whatever). *

- *

* The results are sent to the user using the IStreamingCallback * handleResult method; see the IStreamingCallback Javadoc for details. The * payload passed to handleResult is usually the raw map gathered together @@ -371,7 +417,6 @@ InputStream execQuietStreamCmd(String cmdName, String[] cmdArgs) * much the same way as a user unpacks or processes the results from the * other low-level exec methods like execMapCommand. *

- *

* NOTE: 'streaming' here has nothing at all to do with Perforce 'streams', * which are (or will be) implemented elsewhere. * @@ -394,23 +439,18 @@ InputStream execQuietStreamCmd(String cmdName, String[] cmdArgs) * @throws P4JavaException if an error occurs processing this method and its parameters. * @since 2011.1 */ - - void execStreamingMapCommand(String cmdName, String[] cmdArgs, Map inMap, - IStreamingCallback callback, int key) throws P4JavaException; + void execStreamingMapCommand(String cmdName, String[] cmdArgs, Map inMap, IStreamingCallback callback, int key) throws P4JavaException; /** - * * Issue a parallelised streaming map command to the Perforce server, using an optional * map for any input expected by the server (such as label or job specs, * etc.). *

- *

* Streaming commands allow users to get each result from a suitably-issued * command as it comes in from the server, rather than waiting for the * entire command method to complete (and getting the results back as a * completed List or Map or whatever). *

- *

* The results are sent to the user using the IStreamingCallback * handleResult method; see the IStreamingCallback Javadoc for details. The * payload passed to handleResult is usually the raw map gathered together @@ -419,33 +459,30 @@ void execStreamingMapCommand(String cmdName, String[] cmdArgs, Map - *

* NOTE: 'streaming' here has nothing at all to do with Perforce 'streams', * which are (or will be) implemented elsewhere. * - * @param cmdName the command to be issued; must be non-null, and correspond to - * a Perforce command recognized by P4Java and defined in - * CmdSpec. - * @param cmdArgs the array of command arguments (options and file arguments, - * etc.) to be sent to the Perforce server. These must be in the - * form used by the corresponding p4 command line interpreter. - * Ignored if null. - * @param inMap an optional map to be sent to the server as standard input, - * using the Python map format (-G) form. You must remember to - * issue the relevant command-specific option to enable this if - * needed. - * @param callback a non-null IStreamingCallback to be used to process the - * incoming results. - * @param key an opaque integer key that is passed to the IStreamingCallback - * callback methods to identify the action as being associated - * with this specific call. + * @param cmdName the command to be issued; must be non-null, and correspond to + * a Perforce command recognized by P4Java and defined in + * CmdSpec. + * @param cmdArgs the array of command arguments (options and file arguments, + * etc.) to be sent to the Perforce server. These must be in the + * form used by the corresponding p4 command line interpreter. + * Ignored if null. + * @param inMap an optional map to be sent to the server as standard input, + * using the Python map format (-G) form. You must remember to + * issue the relevant command-specific option to enable this if + * needed. + * @param callback a non-null IStreamingCallback to be used to process the + * incoming results. + * @param key an opaque integer key that is passed to the IStreamingCallback + * callback methods to identify the action as being associated + * with this specific call. * @param parallelCallback IParallelCallback used to parallelise the task - * @throws P4JavaException + * @throws P4JavaException on error * @since 2017.1 */ - public void execStreamingMapCommand(String cmdName, String[] cmdArgs, Map inMap, - IStreamingCallback callback, int key, IParallelCallback parallelCallback) - throws P4JavaException; + public void execStreamingMapCommand(String cmdName, String[] cmdArgs, Map inMap, IStreamingCallback callback, int key, IParallelCallback parallelCallback) throws P4JavaException; /** * Return the current Perforce authentication ticket being used by this @@ -454,7 +491,6 @@ public void execStreamingMapCommand(String cmdName, String[] cmdArgs, Map - *

* This is one of the guaranteed "live" method on this interface, and will * return the diff output as it exists when called (rather than when the * underlying implementation object was created). This can be an expensive * method to evaluate, and can generate reams and reams (and reams) of * output, so don't use it willy-nilly. *

- *

* Note that unlike the corresponding command-line command, which keeps * going in the face of errors by moving on to the next file (or whatever), * any errors encountered in this method will cause an exception from this @@ -505,10 +539,7 @@ public void execStreamingMapCommand(String cmdName, String[] cmdArgs, Map getCommitFiles(final String repo, final String commit) - throws ConnectionException, RequestException, AccessException; + List getCommitFiles(final String repo, final String commit) throws ConnectionException, RequestException, AccessException; /** * Get the current charset name for the server connection. May be null, in @@ -529,7 +559,6 @@ List getCommitFiles(final String repo, final String commit) * * @return charset name associated with this server; may be null. */ - String getCharsetName(); int getGenericCode(Map map); @@ -539,14 +568,12 @@ List getCommitFiles(final String repo, final String commit) * (unsupported). Corresponds fairly closely to the p4 interchanges command * for filespecs. *

- *

* Note that if showFiles is true, the returned files are attached to the * associated changelist, and can be retrieved using the getFiles(false) * method -- and note that if you call getFiles(true) you will get a * refreshed list of all files associated with the changelist, which * is probably different from the list associated with the integration. *

- *

* Note also that if there are no qualifying changes, this method will * return an empty list rather than throw an exception; this behaviour is * different to that seen with the p4 command line which will throw an @@ -568,24 +595,19 @@ List getCommitFiles(final String repo, final String commit) * processing of the request * @throws AccessException if the Perforce server denies access to the caller */ - - List getInterchanges(IFileSpec fromFile, IFileSpec toFile, boolean showFiles, - boolean longDesc, int maxChangelistId) - throws ConnectionException, RequestException, AccessException; + List getInterchanges(IFileSpec fromFile, IFileSpec toFile, boolean showFiles, boolean longDesc, int maxChangelistId) throws ConnectionException, RequestException, AccessException; /** * Get a list of changes and / or associated files not yet integrated, based * on branchspecs (unsupported). Corresponds fairly closely to the p4 * interchanges command for branchspecs. *

- *

* Note that if showFiles is true, the returned files are attached to the * associated changelist, and can be retrieved using the getFiles(false) * method -- and note that if you call getFiles(true) you will get a * refreshed list of all files associated with the changelist, which * is probably different from the list associated with the integration. *

- *

* Note also that if there are no qualifying changes, this method will * return an empty list rather than throw an exception; this behaviour is * different to that seen with the p4 command line which will throw an @@ -601,6 +623,7 @@ List getInterchanges(IFileSpec fromFile, IFileSpec toFile, boolean * @param maxChangelistId if greater than zero, only consider integration * @param reverseMapping if true, reverse the mappings in the branch view, with the * target files and source files exchanging place. + * @param biDirectional if true, bi-directional option * @return non-null (but possibly empty) list of qualifying changelists. * Note that the changelists returned here may not have all fields * set (only description, ID, date, user, and client are known to be @@ -610,22 +633,16 @@ List getInterchanges(IFileSpec fromFile, IFileSpec toFile, boolean * processing of the request * @throws AccessException if the Perforce server denies access to the caller */ - - List getInterchanges(String branchSpecName, List fromFileList, - List toFileList, boolean showFiles, boolean longDesc, int maxChangelistId, - boolean reverseMapping, boolean biDirectional) - throws ConnectionException, RequestException, AccessException; + List getInterchanges(String branchSpecName, List fromFileList, List toFileList, boolean showFiles, boolean longDesc, int maxChangelistId, boolean reverseMapping, boolean biDirectional) throws ConnectionException, RequestException, AccessException; /** * Return an array of strings representing "known" charsets (e.g. "utf8" or * "utf32le". *

- *

* Note that in this context, "known" simply means that Perforce servers * supported by this API can potentially recognize the charset name and * (hopefully) act accordingly. *

- *

* Charset support in Perforce is described in more detail in the main p4 * command documentation; in summary, although the list returned here is * comprehensive and quite impressive, unless the Perforce server is @@ -638,7 +655,6 @@ List getInterchanges(String branchSpecName, List fromFil * @return a non-null array of strings representing lower-case charset names * known to the server. */ - String[] getKnownCharsets(); /** @@ -650,7 +666,6 @@ List getInterchanges(String branchSpecName, List fromFil * * @return Properties object; may be empty but will not be null. */ - Properties getProperties(); /** @@ -663,7 +678,6 @@ List getInterchanges(String branchSpecName, List fromFil * @return positive integer version number or -1 if not known or * unavailable. */ - int getServerVersionNumber(); int getSeverityCode(Map map); @@ -673,13 +687,11 @@ List getInterchanges(String branchSpecName, List fromFil * * @return non-null ServerStatus representing the server status. */ - ServerStatus getStatus(); /** * Get a list of Perforce user groups from the server. *

- *

* Note that the Perforce server considers it an error to have both indirect * and displayValues parameters set true; this will cause the server to * throw a RequestException with an appropriate usage message. @@ -690,16 +702,14 @@ List getInterchanges(String branchSpecName, List fromFil * belongs to indirectly via subgroups. * @param displayValues if true, display the MaxResults, MaxScanRows, MaxLockTime, and * Timeout values for the named group. - * @param maxGroups if > 0, display only the first m results. + * @param maxGroups if > 0, display only the first m results. * @return a non-zero but possibly-empty list of qualifying groups. * @throws ConnectionException if the Perforce server is unreachable or is not connected. * @throws RequestException if the Perforce server encounters an error during its * processing of the request. * @throws AccessException if the Perforce server denies access to the caller. */ - - List getUserGroups(String userOrGroupName, boolean indirect, boolean displayValues, - int maxGroups) throws ConnectionException, RequestException, AccessException; + List getUserGroups(String userOrGroupName, boolean indirect, boolean displayValues, int maxGroups) throws ConnectionException, RequestException, AccessException; /** * Return the user name currently associated with this server, if any. User @@ -708,7 +718,6 @@ List getUserGroups(String userOrGroupName, boolean indirect, boolean * @return the user name currently associated with this server, if any; null * otherwise. */ - String getUserName(); /** @@ -727,7 +736,6 @@ List getUserGroups(String userOrGroupName, boolean indirect, boolean * @return IClient representing the current client, or null if no client * associated with this server. */ - IClient getCurrentClient(); /** @@ -742,7 +750,6 @@ List getUserGroups(String userOrGroupName, boolean indirect, boolean * Return true iff and the server object is connected to the associated * Perforce server. *

- *

* The meaning of "connected" is generally dependent on the underlying * transport layer, but in general, if the server is not connected, issuing * server commands to the associated Perforce server will fail with a @@ -750,13 +757,11 @@ List getUserGroups(String userOrGroupName, boolean indirect, boolean * * @return - true iff connected, false otherwise */ - boolean isConnected(); /** * Register a P4Java command callback with this Perforce server. *

- *

* See the ICommandCallback javadocs for callback semantics. Note that only * one command callback can be active and registered for a given server at * any one time. @@ -765,13 +770,11 @@ List getUserGroups(String userOrGroupName, boolean indirect, boolean * callbacks are disabled. * @return the previous command callback, if it existed; null otherwise */ - ICommandCallback registerCallback(ICommandCallback callback); /** * Register a P4Java command progress callback with this Perforce server. *

- *

* See the IProgressCallback javadocs for callback semantics. Note that only * one progress callback can be active and registered for a given server at * any one time. @@ -780,19 +783,16 @@ List getUserGroups(String userOrGroupName, boolean indirect, boolean * callbacks are disabled. * @return the previous progress callback, if it existed; null otherwise */ - IProgressCallback registerProgressCallback(IProgressCallback callback); /** * Register a Perforce Single Sign On (SSO) callback and key for this * server. *

- *

* See the ISSOCallback Javadoc comments for an explanation of the SSO * callback feature; note that only one SSO callback can be active and * registered for a given P4Jserver object at any one time. *

- *

* Note that SSO callbacks work only with the (default) pure Java (RPC) * protocol implementation. * @@ -801,22 +801,19 @@ List getUserGroups(String userOrGroupName, boolean indirect, boolean * @param ssoKey opaque string to be passed untouched to the callback; can be * null, in which case null is passed in to the callback */ - void registerSSOCallback(ISSOCallback callback, String ssoKey); /** * Register a Perforce browser callback to launch the browser for a given * url for this server. *

- *

* See the IBrowserCallback Javadoc comments for an explanation of the browser * callback feature; note that only one browser callback can be active and * registered for a given P4server object at any one time. *

- *

* * @param browserCallback BrowserCallback object to be registered; if null, browser - * callbacks are disabled. + * callbacks are disabled. */ void registerBrowserCallback(IBrowserCallback browserCallback); @@ -826,7 +823,6 @@ List getUserGroups(String userOrGroupName, boolean indirect, boolean * associated Perforce server; otherwise, the auth ticket will be used to * authenticate against the Perforce server for each call to the server. *

- *

* No checking is performed on the passed-in ticket, and any changes to * existing tickets can cause authentication failures, so you should ensure * the passed-in ticket is valid and makes sense for the current context. @@ -869,20 +865,18 @@ List getUserGroups(String userOrGroupName, boolean indirect, boolean * @throws UnsupportedCharsetException if the Perforce server doesn't support or recognize the * charset name. */ - boolean setCharsetName(String charsetName) throws UnsupportedCharsetException; /** * Set the Perforce client associated with this server. * + * @param client client object * @throws ConnectionException if the Perforce server is unreachable or is not connected. * @throws RequestException if the Perforce server encounters an error during its * processing of the request * @throws AccessException if the Perforce server denies access to the caller */ - - void setCurrentClient(IClient client) - throws ConnectionException, RequestException, AccessException; + void setCurrentClient(IClient client) throws ConnectionException, RequestException, AccessException; /** * Set the Perforce user name to be used with this server. This does not @@ -890,14 +884,12 @@ void setCurrentClient(IClient client) * session. Once set, the user name is used with all commands where it makes * sense. *

- *

* Note that the auth ticket (if available) for this user will also be set * to this server instance. * * @param userName Perforce user name; can be null, which is interpreted as * "don't associate a user name with this server". */ - void setUserName(String userName); /** @@ -908,7 +900,6 @@ void setCurrentClient(IClient client) * working directory is used instead (which is almost always a safe option * unless you're using Perforce alt roots). *

- *

* Note: no checking is done at call time for correctness (or otherwise) of * the passed-in path. * @@ -918,13 +909,13 @@ void setCurrentClient(IClient client) /** * Set the Perforce P4CLIENTPATH - directories the client can access. - * + *

* A list of directories to which Perforce applications are permitted to write. * Any attempt by a Perforce application to access or modify files outside these * areas of the filesystem will result in an error message. To specify more than * one directory, separate the directories with semicolons. * - * @param clientPath + * @param clientPath client path */ void setClientPath(String clientPath); @@ -945,7 +936,6 @@ void setCurrentClient(IClient client) * processing of the request * @throws AccessException if the Perforce server denies access to the caller */ - boolean supportsSmartMove() throws ConnectionException, RequestException, AccessException; /** @@ -961,7 +951,6 @@ void setCurrentClient(IClient client) * processing of the request * @throws AccessException if the Perforce server denies access to the caller */ - boolean supportsUnicode() throws ConnectionException, RequestException, AccessException; /** @@ -976,7 +965,5 @@ void setCurrentClient(IClient client) * processing of the request. * @throws AccessException if the Perforce server denies access to the caller. */ - - String updateUserGroup(IUserGroup group, boolean updateIfOwner) - throws ConnectionException, RequestException, AccessException; + String updateUserGroup(IUserGroup group, boolean updateIfOwner) throws ConnectionException, RequestException, AccessException; } diff --git a/src/main/java/com/perforce/p4java/server/IServerAddress.java b/src/main/java/com/perforce/p4java/server/IServerAddress.java index 4e69f23..a4f3aab 100644 --- a/src/main/java/com/perforce/p4java/server/IServerAddress.java +++ b/src/main/java/com/perforce/p4java/server/IServerAddress.java @@ -15,9 +15,8 @@ * part specifies which network implementation to use and whether it is a secure * (SSL) connection. The optional query string part can be used to set P4Java * properties. - *

- * - *

+ *
+ * 
{@code
  * The P4Java URI syntax:
  * 
  * protocol://host:port?query
@@ -40,7 +39,7 @@
  * p4java://myp4server:1777
  * 
  * p4javassl://myp4server.xyz.com:1777?key0=value0&key1=value1
- * 
+ * }
*/ public interface IServerAddress { diff --git a/src/main/java/com/perforce/p4java/server/IServerImplMetadata.java b/src/main/java/com/perforce/p4java/server/IServerImplMetadata.java index 62624b6..d2e2446 100644 --- a/src/main/java/com/perforce/p4java/server/IServerImplMetadata.java +++ b/src/main/java/com/perforce/p4java/server/IServerImplMetadata.java @@ -10,7 +10,7 @@ */ public interface IServerImplMetadata { - + /** * Describes the various known implementation types. There is currently * only one implementation type, but this may change in the long term. @@ -20,53 +20,55 @@ enum ImplType { * Type is unknown. Don't use this implementation.... */ UNKNOWN, - + /** * Java-native RPC protocol implementation. */ NATIVE_RPC - }; - + } + + ; + /** - * Return a short name for this implementation, intended for use in menu + * @return a short name for this implementation, intended for use in menu * pulldowns, etc. May contain spaces, but won't usually be more than 32 * characters long. */ String getScreenName(); - + /** - * Return the canonical name of the implementation class + * @return the canonical name of the implementation class * associated with this implementation. */ String getImplClassName(); /** - * Returns true IFF this implementation will be used if the non-specific + * @return true IFF this implementation will be used if the non-specific * implementation scheme "p4j" is provided in the URI passed in to the * server factory. There will be only one such default implementation * for each factory. */ boolean isDefault(); - + /** - * Get the implementation type associated with this implementation. + * @return the implementation type associated with this implementation. */ ImplType getImplType(); - + /** - * Get the URI scheme part to be used to specify this implementation + * @return the URI scheme part to be used to specify this implementation * to the server factory. */ String getUriScheme(); - + /** - * Get the earliest Perforce server version that this implementation + * @return the earliest Perforce server version that this implementation * will work reliably against. Typically in the form 20073 or 20091, etc. */ int getMinimumServerLevel(); - + /** - * Return any comments associated with the implementation. These + * @return any comments associated with the implementation. These * should note any special restrictions or dependencies associated with * the implementation that the user might need to know; this string * may be null. diff --git a/src/main/java/com/perforce/p4java/server/PerforceCharsets.java b/src/main/java/com/perforce/p4java/server/PerforceCharsets.java index f60be24..8b251d8 100644 --- a/src/main/java/com/perforce/p4java/server/PerforceCharsets.java +++ b/src/main/java/com/perforce/p4java/server/PerforceCharsets.java @@ -14,20 +14,16 @@ /** * Encapsulates Perforce-wide charset information for servers. *

- *

* Unfortunately, support for Unicode and associated charsets is somewhat * server- and installation-dependent, and not easy to divine unless you're * already talking to a Perforce server -- by which time it's too late. This * class is an attempt to make it easier to cut that Gordian knot... *

- *

* Note that the names below are not actually the standard name for the charset * in some cases: e.g. UTF-8 should be "utf-8" not "utf8", but we follow the * Perforce server's rules here. *

- *

* The following are special cases. - *

*

  * "auto" (Guess a P4CHARSET based on client OS params)
  * "none" (same as unsetting P4CHARSET)
@@ -82,8 +78,8 @@ public class PerforceCharsets {
 	 */
 	/*
 	 * Conversions from p4 charsets to Java charsets take from from
-     * http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html
-     */
+	 * http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html
+	 */
 	private static final Map p4ToJavaCharsets;
 
 	static {
@@ -171,6 +167,7 @@ public static String[] getKnownCharsets() {
 	 * charset name. Multiple Perforce charsets can be mapped to a Java charset
 	 * (i.e. Perforce "utf8-bom" and "utf8unchecked" are mapped to Java "UTF-8")
 	 *
+	 * @param javaCharsetName charset
 	 * @return - Perforce charset name
 	 */
 	public static String getP4CharsetName(String javaCharsetName) {
@@ -191,6 +188,7 @@ public static String getP4CharsetName(String javaCharsetName) {
 	/**
 	 * Get the matching Java charset for a given P4 charset name.
 	 *
+	 * @param p4CharsetName charset
 	 * @return - Java charset
 	 */
 	public static Charset getP4Charset(String p4CharsetName) {
@@ -208,6 +206,7 @@ public static Charset getP4Charset(String p4CharsetName) {
 	/**
 	 * Get Java equivalent charset name for a p4 charset name
 	 *
+	 * @param p4CharsetName charset
 	 * @return - Java charset name
 	 */
 	public static String getJavaCharsetName(String p4CharsetName) {
@@ -218,6 +217,10 @@ public static String getJavaCharsetName(String p4CharsetName) {
 		return javaCharsetName;
 	}
 
+	/**
+	 * @param p4CharsetName charset
+	 * @return true, if client charset has BOM
+	 */
 	public static boolean hasClientBOM(String p4CharsetName) {
 		if (p4CharsetName != null && !p4CharsetName.isEmpty()) {
 			return p4ToClientBOM.containsKey(p4CharsetName);
@@ -228,6 +231,7 @@ public static boolean hasClientBOM(String p4CharsetName) {
 	/**
 	 * Is the P4 charset name specified supported?
 	 *
+	 * @param p4CharsetName charset
 	 * @return - true if supported, false otherwise
 	 */
 	public static boolean isSupported(String p4CharsetName) {
diff --git a/src/main/java/com/perforce/p4java/server/ServerFactory.java b/src/main/java/com/perforce/p4java/server/ServerFactory.java
index d0f06bf..8ab45d1 100644
--- a/src/main/java/com/perforce/p4java/server/ServerFactory.java
+++ b/src/main/java/com/perforce/p4java/server/ServerFactory.java
@@ -39,57 +39,57 @@
  */
 
 public class ServerFactory {
-	
+
 	public static final String TRACE_PREFIX = "ServerFactory";
-	
+
 	/**
 	 * The pseudo-protocol used in URIs to signal that the factory should make its own
 	 * decision about what protocol and server to use.
 	 */
 	public static final String DEFAULT_PROTOCOL_SPEC = IServerAddress.Protocol.P4JAVA.toString();
-	
+
 	/**
 	 * Default protocol name, i.e. the name used when the protocol name is
 	 * specified as "p4java" in a suitable URL. Currently it always maps to
 	 * the native RPC implementation, but this is not guaranteed.
 	 */
-	
+
 	public static final String DEFAULT_PROTOCOL_NAME = OneShotServerImpl.PROTOCOL_NAME;
-	
+
 	/**
 	 * Default SSL protocol name, i.e. the name used when the protocol name is
 	 * specified as "p4javassl" in a suitable URL. Currently it always maps to
 	 * the native SSL RPC implementation, but this is not guaranteed.
 	 */
-	
+
 	public static final String DEFAULT_SSL_PROTOCOL_NAME = OneShotServerImpl.SSL_PROTOCOL_NAME;
 
 	public static final String ZEROCONF_CLASS_NAME = "javax.jmdns.JmDNS";
-	
+
 	/**
 	 * The factory's protocol scheme / implementation map. Not intended
 	 * for public consumption; also not really intended for large numbers of
 	 * implementation classes.
 	 */
-	
+
 	@SuppressWarnings("rawtypes")
 	private static Map implMap = new HashMap();
-	
+
 	private static ISystemFileCommandsHelper rpcFileCommandsHelper = null;
-	
+
 	/**
 	 * The JmDNS zeroconf helper.
 	 */
 	@SuppressWarnings("deprecation")
 	private static ZeroconfHelper zcHelper = null;
-	
+
 	/**
 	 * Initialize the factory. This includes setting the rpcFileCommandsHelper
 	 * to a default JDK 6 implementation of the ISystemFileCommandsHelper interface;
 	 * this can be replaced by an explicit call to setRpcFileSystemHelper later if
 	 * this is inappropriate for a specific context.
 	 */
-	
+
 	static {
 		// Set up server protocol name to implementation class mapping:
 		implMap.put(Protocol.P4JAVA, OneShotServerImpl.class);
@@ -104,180 +104,179 @@ public class ServerFactory {
 				+ "; date: " + Metadata.getP4JDateString());
 		Log.info("Using default charset: " + CharsetDefs.DEFAULT
 				+ "; JVM charset: " + CharsetDefs.LOCAL);
-		rpcFileCommandsHelper = OSUtils.isWindows() 
-		        ? new WindowsRpcSystemFileCommandsHelper() : new RpcSystemFileCommandsHelper();
+		rpcFileCommandsHelper = OSUtils.isWindows()
+				? new WindowsRpcSystemFileCommandsHelper() : new RpcSystemFileCommandsHelper();
 		Log.info("Using default RPC system file command helper: "
 				+ rpcFileCommandsHelper.getClass().getCanonicalName());
 	}
-	
+
 	/**
-	 * Return a non-null list of implementation metadata about available IServer
+	 * @return a non-null list of implementation metadata about available IServer
 	 * implementations. This can be useful for presenting implementation choices to
 	 * end users, or for debugging, etc.
 	 */
-	@SuppressWarnings({ "unchecked", "rawtypes" })
+	@SuppressWarnings({"unchecked", "rawtypes"})
 	public static List getAvailableImplementationMetadata() {
 		Map implMetadataMap = new HashMap();
 		for (Protocol key : implMap.keySet()) {
 			Class implClass = (Class) implMap.get(key);
-			
+
 			IServerImplMetadata md = getImplMetadata(implClass);
-			
+
 			if (md != null) {
 				implMetadataMap.put(implClass, md);
 			}
 		}
 		return new ArrayList(implMetadataMap.values());
 	}
-	
+
 	/**
 	 * Return an IServer interface onto an underlying Perforce server at the host
 	 * address specified by serverUriString using the protocol implementation and
 	 * passed-in properties. Note that we use the term "URL" here a lot when we typically
 	 * mean "URI"; this is mostly done to pre-empt confusion, but we may tighten
-	 * usage up a lot over time.

- * + * usage up a lot over time. + *

* The format of the server URI string is protocol + "://" + hostaddr [+ ":" + port] [+ queryString], * e.g. "p4java://example.perforce.com:1666" or "p4java://192.168.1.2:1999" or - * "p4jrpc://example.perforce.com:1199?progName=p4javaTest21&progVersion=Alpha203B". + * {@code p4jrpc://example.perforce.com:1199?progName=p4javaTest21&progVersion=Alpha203B} * The protocol, port, and hostaddr fields can't be missing, but the port and hostaddr fields * can be anything acceptable to the protocol, e.g. typically something like an IP address or - * hostname coupled with a port number.

- * + * hostname coupled with a port number. + *

* The protocol part specifies which network implementation to use; the value "p4java" * (DEFAULT_PROTOCOL_NAME) will tell the factory to use the default protocol, the details * of which are not spelled out here, and which should always be used unless you have * good reason to use an alternative (other protocol part values are possible, but should - * not generally be used unless suggested by Perforce support staff).

- * + * not generally be used unless suggested by Perforce support staff). + *

* To connect to an SSL-enabled Perforce server, use one of the SSL protocols defined in - * the IServerAddress.Protocol enum (i.e. "p4javassl", "p4rpcssl" or "p4jrpcntsssl").

- * + * the IServerAddress.Protocol enum (i.e. "p4javassl", "p4rpcssl" or "p4jrpcntsssl"). + *

* For advanced users, the optional queryString part can be used to set P4Java properties * from the URI; these override any correspondingly-named properties sent programmatically through * the props parameter (see next paragraph). These URI query strings are not interpreted, * but are simply put as-is into the properties passed to the individual server implementation * class. Note: this method does not do any query string replacement of things like * %20 to spaces, etc. (this really isn't needed here as the query parts are passed - * as-is to the underlying implementation(s)).

- * + * as-is to the underlying implementation(s)). + *

* The props argument can be used to pass in any protocol-specific properties; these * are typically described in usage or implementation notes supplied elsewhere, and are - * not typically used by end-users.

- * + * not typically used by end-users. + *

* IServer objects returned by this method may have been retrieved from a cache of * previously-used objects, but they are guaranteed to be ready for use by the consumer, * and to be for that consumer's exclusive use only. - * + * * @param serverUriString non-null server address in URI form. - * @param props protocol-specific properties; may be null + * @param props protocol-specific properties; may be null * @return a non-null IServer object ready for use by the consumer. - * @throws URISyntaxException if the passed-in URI string does not conform to - * the Perforce URI specs detailed above. - * @throws ConnectionException if the factory is unable to connect to the server - * named by serverUrl + * @throws URISyntaxException if the passed-in URI string does not conform to + * the Perforce URI specs detailed above. + * @throws ConnectionException if the factory is unable to connect to the server + * named by serverUrl * @throws NoSuchObjectException if no implementation class can be found for - * the protocol specified in the passed-in URI protocol (scheme part); - * @throws ConfigException if the underlying protocol supplier detects a misconfiguration - * @throws ResourceException if the factory does not have the resources available to - * service the request + * the protocol specified in the passed-in URI protocol (scheme part); + * @throws ConfigException if the underlying protocol supplier detects a misconfiguration + * @throws ResourceException if the factory does not have the resources available to + * service the request */ - public static IServer getServer(String serverUriString, Properties props) - throws URISyntaxException, ConnectionException, NoSuchObjectException, - ConfigException, ResourceException{ + throws URISyntaxException, ConnectionException, NoSuchObjectException, + ConfigException, ResourceException { return getOptionsServer(serverUriString, props); } - + /** * Return an IOptionsServer onto an underlying Perforce server at the host * address specified by serverUriString using the protocol implementation and - * passed-in properties and a default UsageOptions object.

- * + * passed-in properties and a default UsageOptions object. + *

* Basically a convenience wrapper for calling the main getOptionsServer method * with a null UsageOptions argument -- see that method's Javadoc for full * documentation. - * + * * @param serverUriString non-null server address in URI form. - * @param props protocol-specific properties; may be null + * @param props protocol-specific properties; may be null * @return a non-null IOptionsServer object ready for use by the consumer. - * @throws URISyntaxException if the passed-in URI string does not conform to - * the Perforce URI specs detailed above. - * @throws ConnectionException if the factory is unable to connect to the server - * named by serverUrl + * @throws URISyntaxException if the passed-in URI string does not conform to + * the Perforce URI specs detailed above. + * @throws ConnectionException if the factory is unable to connect to the server + * named by serverUrl * @throws NoSuchObjectException if no implementation class can be found for - * the protocol specified in the passed-in URI protocol (scheme part); - * @throws ConfigException if the underlying protocol supplier detects a misconfiguration - * @throws ResourceException if the factory does not have the resources available to - * service the request + * the protocol specified in the passed-in URI protocol (scheme part); + * @throws ConfigException if the underlying protocol supplier detects a misconfiguration + * @throws ResourceException if the factory does not have the resources available to + * service the request */ public static IOptionsServer getOptionsServer(String serverUriString, Properties props) - throws URISyntaxException, ConnectionException, NoSuchObjectException, - ConfigException, ResourceException { + throws URISyntaxException, ConnectionException, NoSuchObjectException, + ConfigException, ResourceException { return getOptionsServer(serverUriString, props, null); } - + /** * Return an IOptionsServer interface onto an underlying Perforce server at the host * address specified by serverUriString using the protocol implementation and * passed-in properties and usage options. Note that we use the term "URL" here a lot * when we typically mean "URI"; this is mostly done to pre-empt confusion, but we may - * tighten usage up a lot over time.

- * + * tighten usage up a lot over time. + *

* The format of the server URI string is protocol + "://" + hostaddr [+ ":" + port] [+ queryString], * e.g. "p4java://example.perforce.com:1666" or "p4java://192.168.1.2:1999" or - * "p4java://example.perforce.com:1199?progName=p4javaTest21&progVersion=Alpha203B". + * {@code p4java://example.perforce.com:1199?progName=p4javaTest21&progVersion=Alpha203B} * The protocol, port, and hostaddr fields can't be missing, but the port and hostaddr fields * can be anything acceptable to the protocol, e.g. typically something like an IP address or - * hostname coupled with a port number.

- * + * hostname coupled with a port number. + *

* The protocol part specifies which network implementation to use; the value "p4java" * (DEFAULT_PROTOCOL_NAME) will tell the factory to use the default protocol, the details * of which are not spelled out here, and which should always be used unless you have * good reason to use an alternative (other protocol part values are possible, but should - * not generally be used unless suggested by Perforce support staff).

- * + * not generally be used unless suggested by Perforce support staff). + *

* To connect to an SSL-enabled Perforce server, use one of the SSL protocols defined in - * the IServerAddress.Protocol enum (i.e. "p4javassl", "p4rpcssl" or "p4jrpcntsssl").

- * + * the IServerAddress.Protocol enum (i.e. "p4javassl", "p4rpcssl" or "p4jrpcntsssl"). + *

* For advanced users, the optional queryString part can be used to set P4Java properties * from the URI; these override any correspondingly-named properties sent programmatically through * the props parameter (see next paragraph). These URI query strings are not interpreted, * but are simply put as-is into the properties passed to the individual server implementation * class. Note: this method does not do any query string replacement of things like * %20 to spaces, etc. (this really isn't needed here as the query parts are passed - * as-is to the underlying implementation(s)).

- * + * as-is to the underlying implementation(s)). + *

* The props argument can be used to pass in any protocol-specific properties; these * are typically described in usage or implementation notes supplied elsewhere, and are - * not typically used by end-users.

- * + * not typically used by end-users. + *

* IServer objects returned by this method may have been retrieved from a cache of * previously-used objects, but they are guaranteed to be ready for use by the consumer, * and to be for that consumer's exclusive use only. - * + * * @param serverUriString non-null server address in URI form. - * @param props protocol-specific properties; may be null. - * @param opts UsageOptions object to be associated with the new server object - * specifying the server's usage options; if null, a new usage options object - * is constructed using the default UsageOptions constructor and associated - * default values using the passed-in properties object (if not null); this is - * then associated with the new server object. + * @param props protocol-specific properties; may be null. + * @param opts UsageOptions object to be associated with the new server object + * specifying the server's usage options; if null, a new usage options object + * is constructed using the default UsageOptions constructor and associated + * default values using the passed-in properties object (if not null); this is + * then associated with the new server object. * @return a non-null IOptionsServer object ready for use by the consumer. - * @throws URISyntaxException if the passed-in URI string does not conform to - * the Perforce URI specs detailed above. - * @throws ConnectionException if the factory is unable to connect to the server - * named by serverUrl + * @throws URISyntaxException if the passed-in URI string does not conform to + * the Perforce URI specs detailed above. + * @throws ConnectionException if the factory is unable to connect to the server + * named by serverUrl * @throws NoSuchObjectException if no implementation class can be found for - * the protocol specified in the passed-in URI protocol (scheme part); - * @throws ConfigException if the underlying protocol supplier detects a misconfiguration - * @throws ResourceException if the factory does not have the resources available to - * service the request + * the protocol specified in the passed-in URI protocol (scheme part); + * @throws ConfigException if the underlying protocol supplier detects a misconfiguration + * @throws ResourceException if the factory does not have the resources available to + * service the request */ - @SuppressWarnings({ "unchecked", "rawtypes" }) + @SuppressWarnings({"unchecked", "rawtypes"}) public static IOptionsServer getOptionsServer(String serverUriString, Properties props, UsageOptions opts) - throws URISyntaxException, ConnectionException, NoSuchObjectException, - ConfigException, ResourceException { + throws URISyntaxException, ConnectionException, NoSuchObjectException, + ConfigException, ResourceException { if (serverUriString == null) { throw new NullPointerError("Null server serverUriString passed to server factory"); } @@ -299,14 +298,14 @@ public static IOptionsServer getOptionsServer(String serverUriString, Properties if (serverAddress.getPort() < 0) { throw new URISyntaxException(serverUriString, "missing or malformed Perforce server port specifier"); } - + IServerImplMetadata implMetadata = getImplMetadata(implMap.get(serverAddress.getProtocol())); - + if (implMetadata == null) { throw new NoSuchObjectException("No such server implementation found for protocol '" - + serverAddress.getProtocol().toString() + "'"); + + serverAddress.getProtocol().toString() + "'"); } - + // Combine the properties if (serverAddress.getProperties() != null) { if (props == null) { @@ -314,86 +313,84 @@ public static IOptionsServer getOptionsServer(String serverUriString, Properties } props.putAll(serverAddress.getProperties()); } - + try { Class serverImplClass = Class.forName(implMetadata.getImplClassName()); Log.info("Using Server implementation class: " + serverImplClass.getCanonicalName()); - + IServerControl serverImpl = (IServerControl) serverImplClass.newInstance(); serverImpl.init(serverAddress.getHost(), serverAddress.getPort(), props, opts, serverAddress.getProtocol().isSecure(), serverAddress.getRsh()); - return (IOptionsServer) serverImpl; // This part may also cause a cast exception... + return (IOptionsServer) serverImpl; // This part may also cause a cast exception... } catch (ClassNotFoundException cnfe) { Log.error("Unable to instantiate Perforce server implementation class '" + implMetadata.getImplClassName() + "' (class not found)"); Log.exception(cnfe); throw new NoSuchObjectException( - "No such p4j server implementation class found for protocol", - cnfe); - } catch(ClassCastException cce) { + "No such p4j server implementation class found for protocol", + cnfe); + } catch (ClassCastException cce) { Log.error("Unable to instantiate Perforce server implementation class '" + implMetadata.getImplClassName() + "' (class cast error)"); Log.exception(cce); throw new ConfigException( - "Specified Perforce server implementation class does not implement required interface(s)", - cce); + "Specified Perforce server implementation class does not implement required interface(s)", + cce); } catch (InstantiationException ie) { Log.error("Unable to instantiate Perforce server implementation class '" + implMetadata.getImplClassName() + "' (instantiation failed)"); Log.exception(ie); throw new ConfigException( - "Unable to instantiate Perforce server implementation class '" - + implMetadata.getImplClassName() + "'", - ie); + "Unable to instantiate Perforce server implementation class '" + + implMetadata.getImplClassName() + "'", + ie); } catch (IllegalAccessException iae) { Log.error("Unable to instantiate Perforce server implementation class '" + implMetadata.getImplClassName() + "' (illegal access exception)"); Log.exception(iae); throw new ConfigException( - "Unable to instantiate Perforce server class '" - + implMetadata.getImplClassName() + "'", - iae); + "Unable to instantiate Perforce server class '" + + implMetadata.getImplClassName() + "'", + iae); } } - + /** * Deprecated way to get an IServer object -- see getServer(String, Properties) for * the correct way to get a server. - * - * @deprecated as of the 2009.2 release, use the getServer(String, Properties) method - * due to that Java's URI class does not accept hostnames with anything - * other than alphanumeric characters: even common hostnames like - * "perforce_p" will fail, often silently. + * * @param serverUrl non-null server URI in the format described above - * @param props protocol-specific properties; may be null - * + * @param props protocol-specific properties; may be null * @return a non-null IServer object ready for use by the consumer. - * - * @throws ConnectionException if the factory is unable to connect to the server - * named by serverUrl + * @throws ConnectionException if the factory is unable to connect to the server + * named by serverUrl * @throws NoSuchObjectException if no implementation class can be found for - * the protocol specified in the passed-in URI protocol (scheme part); - * @throws ConfigException if the underlying protocol supplier detects a misconfiguration - * @throws ResourceException if the factory does not have the resources available to - * service the request - * @throws URISyntaxException if the passed-in URI is malformed. + * the protocol specified in the passed-in URI protocol (scheme part); + * @throws ConfigException if the underlying protocol supplier detects a misconfiguration + * @throws ResourceException if the factory does not have the resources available to + * service the request + * @throws URISyntaxException if the passed-in URI is malformed. + * @deprecated as of the 2009.2 release, use the getServer(String, Properties) method + * due to that Java's URI class does not accept hostnames with anything + * other than alphanumeric characters: even common hostnames like + * "perforce_p" will fail, often silently. */ - + @Deprecated public static IServer getServer(URI serverUrl, Properties props) - throws ConnectionException, NoSuchObjectException, - ConfigException, ResourceException, URISyntaxException { - + throws ConnectionException, NoSuchObjectException, + ConfigException, ResourceException, URISyntaxException { + if (serverUrl == null) { throw new NullPointerError("Null server URI passed to server factory"); } return getServer(serverUrl.toString(), props); } - + private static IServerImplMetadata getImplMetadata( - final Class implClass) { - + final Class implClass) { + if (implClass == null) { return null; } @@ -410,7 +407,7 @@ public String getScreenName() { } return "Unknown"; } - + public String getComments() { try { return (String) implClass.getField(Server.IMPL_COMMENTS_FIELD_NAME).get(null); @@ -479,69 +476,68 @@ public String getImplClassName() { } }; } - + /** * Register an ISystemFileCommandsHelper for the RPC implementations. See * the documentation for the ISystemFileCommandsHelper interface for more - * semantic and usage details.

- * + * semantic and usage details. + *

* Helper classes are needed for certain hosted implementations and for some * JDK 5 installations, and are shared across an entire instance of P4Java. * Please do not register a helper class unless you know what you're doing and - * you're OK with the dire consequences of getting a helper class implementation wrong.

- * + * you're OK with the dire consequences of getting a helper class implementation wrong. + *

* Note that if the fsCmdHelper parameter is null, the default internal implementation * will be used, which is usually fine for JDK 6 systems. - * - * @see com.perforce.p4java.impl.generic.sys.ISystemFileCommandsHelper + * * @param fsCmdHelper file helper interface implementation; if null, use the - * JVM default implementation(s). + * JVM default implementation(s). + * @see com.perforce.p4java.impl.generic.sys.ISystemFileCommandsHelper */ public static void setRpcFileSystemHelper(ISystemFileCommandsHelper fsCmdHelper) { rpcFileCommandsHelper = fsCmdHelper; Log.info("setting RPC system file helper to " + (fsCmdHelper == null ? "null" : "class " + fsCmdHelper.getClass().getCanonicalName())); } - + /** - * Return the current SystemFileCommands helper, if any. + * @return the current SystemFileCommands helper, if any. */ public static ISystemFileCommandsHelper getRpcFileSystemHelper() { return rpcFileCommandsHelper; } - + /** * Return a list of Perforce servers registered locally with zeroconf at * the time the method was called. See the Perforce knowledge base * articles at http://kb.perforce.com/AdminTasks/Zeroconf for an * introduction to Perforce zeroconf usage, and zeroconf.org for - * zeroconf in general.

- * + * zeroconf in general. + *

* This method uses the javax.jmdns JmDNS package (available through * Sourceforge, etc.), and that package must be visible to the current * class loader for this method to work. If the server factory is unable * to find a suitable JmDNS package using the current class loader, * this method will throw a ConfigException. The JmDNS package is not - * supplied with P4Java and must be downloaded and installed separately.

- * + * supplied with P4Java and must be downloaded and installed separately. + *

* Note that zeroconf discovery can take some time (in the order of tens * of seconds in some cases), and only works for local subnets, so the * first call to this method may return nothing even though there's a * suitable server out there on the same subnet. Subsequent calls are - * usually more successful.

- * + * usually more successful. + *

* Note also that we recommend you call the associated isZeroconfAvailable * method first to check whether zeroconf is even available for this P4Java * instance -- this can save a lot of overhead and / or annoying log * messages. - * + * * @return non-null (but possibly-empty) list of ZeroconfServerInfo objects - * for Perforce servers registered when this method is called. + * for Perforce servers registered when this method is called. * @throws ConfigException if the server factory can't load and use a suitable - * JmDNS zeroconf package using the current class loader. - * - * @deprecated As of release 2013.1, ZeroConf is no longer supported by the - * Perforce server 2013.1. + * JmDNS zeroconf package using the current class loader. + * @deprecated As of release 2013.1, ZeroConf is no longer supported by the + * Perforce server 2013.1. */ @Deprecated public static List getZeroconfServers() throws ConfigException { @@ -550,23 +546,22 @@ public static List getZeroconfServers() throws ConfigExcepti } return zcHelper.getZeroconfServers(); } - + /** * Returns true if the server factory has a suitable zeroconf service browsing * implementation available to it. Should probably be used at least once before * calling the getZeroConfServers method to avoid unnecessary overhead. - * + * * @return true iff zeroconf browsing services are available to the server factory. - * - * @deprecated As of release 2013.1, ZeroConf is no longer supported by the - * Perforce server 2013.1. + * @deprecated As of release 2013.1, ZeroConf is no longer supported by the + * Perforce server 2013.1. */ @Deprecated public static boolean isZeroConfAvailable() { if (zcHelper == null) { zcHelper = new ZeroconfHelper(); } - + return zcHelper.isZeroConfAvailable(); } } diff --git a/src/main/java/com/perforce/p4java/server/ZeroconfServerInfo.java b/src/main/java/com/perforce/p4java/server/ZeroconfServerInfo.java index 96e87a0..b34e45b 100644 --- a/src/main/java/com/perforce/p4java/server/ZeroconfServerInfo.java +++ b/src/main/java/com/perforce/p4java/server/ZeroconfServerInfo.java @@ -1,5 +1,5 @@ /** - * + * */ package com.perforce.p4java.server; @@ -8,25 +8,25 @@ * with and locally-visible to zeroconf (assuming zeroconf is available and * loaded with P4Java). See ServerFactory.getZeroconfServers and associated * methods for a full explanation of Perforce zeroconf usage.

- * + * * Most of the fields defined below should be self-explanatory, but note that any * or all of them may be null, and the semantics and format of the description * and version strings are not defined here at all (but the version string is * usually in the standard Perforce format if this ZeroconfServerInfo object was * cobbled together from a valid zerconf registration). - * - * @deprecated As of release 2013.1, ZeroConf is no longer supported by the + * + * @deprecated As of release 2013.1, ZeroConf is no longer supported by the * Perforce server 2013.1. */ @Deprecated public class ZeroconfServerInfo { - + /** * The port number used to indicate that the port has not * been validly set anywhere. */ public static int P4D_ZEROCONF_NOPORT = -1; - + private String name = null; private String type = null; private String description = null; @@ -34,7 +34,7 @@ public class ZeroconfServerInfo { private String hostAddress = null; private String hostName = null; private int port = P4D_ZEROCONF_NOPORT; - + /** * Default constructor -- sets all fields to null except * port, which is set to P4D_ZEROCONF_NOPORT. @@ -44,9 +44,16 @@ public ZeroconfServerInfo() { /** * Explicit-value constructor. + * + * @param name name + * @param type type + * @param description description + * @param version version + * @param hostAddress hostAddress + * @param hostName hostName + * @param port port */ - public ZeroconfServerInfo(String name, String type, String description, - String version, String hostAddress, String hostName, int port) { + public ZeroconfServerInfo(String name, String type, String description, String version, String hostAddress, String hostName, int port) { this.name = name; this.type = type; this.description = description; @@ -95,7 +102,7 @@ public int getPort() { public void setPort(int port) { this.port = port; } - + public String getDescription() { return description; } @@ -128,12 +135,12 @@ public String toString() { strBuilder.append(":" + getPort()); strBuilder.append(" (" + getHostAddress() + ")"); } - + if (getDescription() != null) { strBuilder.append(" Description: " + getDescription()); strBuilder.append(";"); } - + if (getVersion() != null) { strBuilder.append(" Version: " + getVersion()); strBuilder.append(";"); diff --git a/src/main/java/com/perforce/p4java/server/callback/IBrowserCallback.java b/src/main/java/com/perforce/p4java/server/callback/IBrowserCallback.java index 32cc75f..1106cec 100644 --- a/src/main/java/com/perforce/p4java/server/callback/IBrowserCallback.java +++ b/src/main/java/com/perforce/p4java/server/callback/IBrowserCallback.java @@ -1,12 +1,10 @@ package com.perforce.p4java.server.callback; -import com.perforce.p4java.exception.InvalidUrlException; - public interface IBrowserCallback { /** - * - * @param url + * @param url url + * @throws Exception on error */ public void launchBrowser(String url) throws Exception; diff --git a/src/main/java/com/perforce/p4java/server/callback/ICommandCallback.java b/src/main/java/com/perforce/p4java/server/callback/ICommandCallback.java index 2741ea1..75bad58 100644 --- a/src/main/java/com/perforce/p4java/server/callback/ICommandCallback.java +++ b/src/main/java/com/perforce/p4java/server/callback/ICommandCallback.java @@ -5,28 +5,26 @@ /** * Provides a simple server command and command results notification callback - * interface for P4Java consumers.

- * + * interface for P4Java consumers. + *

* The intention of the server series of methods is to notify the consumer * that P4Java has issued a Perforce server command or received a result * back from the server. The format of the results passed to the callback * method are generally intended to mimic what would have been seen from - * a p4 command line command, but they may not always be identical.

- * + * a p4 command line command, but they may not always be identical. + *

* NOTE: you must ensure that there are no threading or reentrancy issues * with your implementation of this interface, and that calling any of the methods * here will not cause the caller (P4Java) to block or spend too much time processing - * the callback.

- * - * + * the callback. */ public interface ICommandCallback { /** * Report that P4Java is about to issue a Perforce server command. This - * is called immediately before the command itself is issued.

- * + * is called immediately before the command itself is issued. + *

* The int return value is intended to be an opaque key for associated * completedServerCommand, receivedServerInfoLine, and receivedServerErrorLine * calls, allowing the consumer to correlate subsequent calls with the @@ -35,22 +33,22 @@ public interface ICommandCallback { * In any case, this key will be unique across all calls (simultaneous or otherwise) * to a given IServer, but is not guaranteed to be unique across an entire * P4Java instance. - * - * @param key -- opaque integer key for correlation with subsidiary calls. + * + * @param key -- opaque integer key for correlation with subsidiary calls. * @param commandString non-null "normalised" p4 command string. */ void issuingServerCommand(int key, String commandString); - + /** * Report the completion of a Perforce server command, and, as a bonus, * report how long in milliseconds it took from start to finish. Note that * the duration reported may not be absolutely accurate, but is probably - * useful for relative comparisons. - * - * @param key -- opaque integer key as returned from the associated - * issuingServerCommand call. + * useful for relative comparisons. + * + * @param key -- opaque integer key as returned from the associated + * issuingServerCommand call. * @param millisecsTaken -- rough measure of the milliseconds elapsed - * since the original issuing of this command to its completion. + * since the original issuing of this command to its completion. */ void completedServerCommand(int key, long millisecsTaken); @@ -59,33 +57,33 @@ public interface ICommandCallback { * These are typically informational messages from the server that * flag files being opened for edit, etc., but they may also include * trigger output on forms submission, etc. - * - * @param key -- opaque integer key as returned from the associated - * issuingServerCommand call. + * + * @param key -- opaque integer key as returned from the associated + * issuingServerCommand call. * @param infoLine non-null info message. May contain newlines. */ void receivedServerInfoLine(int key, String infoLine); - + /** * Report receiving an error message result from the Perforce server. - * - * @param key -- opaque integer key as returned from the associated - * issuingServerCommand call. + * + * @param key -- opaque integer key as returned from the associated + * issuingServerCommand call. * @param errorLine non-null error message. May contain newlines. */ void receivedServerErrorLine(int key, String errorLine); - + /** * Report receiving a server message, which may be an error, an info message, * a warning, etc., but will not typically be an actual result. * This method can be used in place of the separate receivedServerInfoLine * and receivedServerErrorLine for more general usage. - * - * @param key opaque integer key as returned from the associated - * issuingServerCommand call. - * @param genericCode Perforce generic code, as documented in MessageGenericCode. + * + * @param key opaque integer key as returned from the associated + * issuingServerCommand call. + * @param genericCode Perforce generic code, as documented in MessageGenericCode. * @param severityCode Perforce severity code, as documented in MessageSeverityCode. - * @param message non-null message. May contain newlines. + * @param message non-null message. May contain newlines. */ void receivedServerMessage(int key, int genericCode, int severityCode, String message); } diff --git a/src/main/java/com/perforce/p4java/server/callback/IFilterCallback.java b/src/main/java/com/perforce/p4java/server/callback/IFilterCallback.java index 0e5aee7..92c57d2 100644 --- a/src/main/java/com/perforce/p4java/server/callback/IFilterCallback.java +++ b/src/main/java/com/perforce/p4java/server/callback/IFilterCallback.java @@ -3,22 +3,22 @@ */ package com.perforce.p4java.server.callback; +import com.perforce.p4java.exception.P4JavaException; + import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; -import com.perforce.p4java.exception.P4JavaException; - /** * Interface used to filter out individual key/value pairs from the results map * using the execMapCmd and/or other command methods. Users can implement this * interface if they want to skip certain key/value pairs or all subsequence - * pairs from getting into the results map.

- * + * pairs from getting into the results map. + *

* The callbacks occur during critical sections of the underlying RPC protocol * handlers and that callback implementers should ensure that the callback * methods return as quickly as possible and that they do not themselves call - * back into the server layer.

- * + * back into the server layer. + *

* If any of the callback methods throw a P4JavaException the system will * rethrow the same exception from the main streaming command method after * attempting to clean up; similarly with P4JavaErrors. In either case, while @@ -27,48 +27,48 @@ * carefully from that point on (in the case of 'ordinary' P4JavaExceptions, * the underlying state is actually typically stable and OK for continuing on, * with a possible delay due to non-terminated results still being sent to the - * API; however, all bets are off with the P4JavaError case).

+ * API; however, all bets are off with the P4JavaError case). */ public interface IFilterCallback { - + /** * Per every RCP packet received from the Perforce server, callback to the * consumer to reset any counters and other variables. - * + * * @throws P4JavaException if any problem that should stop normal command processing. */ void reset() throws P4JavaException; - + /** * When called, this method signals to the consumer that an individual * key/value pair is being processed for the current received RPC packet * from the Perforce server. The consumer needs to make a decision to skip * or keep this key/value pair in the results map. The consumer can also * decide to skip all (with some exceptions) subsequent pairs for the rest - * of the current received RPC packet.

- * + * of the current received RPC packet. + *

* Consumers are assumed to be able to make sense of the key/value pair * quickly and on their own -- no help is (currently...) given to consumers - * with this.

- * + * with this. + *

* NOTE: this method is called in a critical section of the underlying P4Java * client / server protocol handler, and must not cause any undue delays or * calls back into the server. Serious protocol-level errors and / or major * performance problems can result from even minor implementation errors with * this method (and these problems can be extremely difficult to debug), so * you are on your own if you use this feature. - * - * @param key possibly-null key (string) part of the key/value pair. - * @param value possibly-null value (object) part of the key/value pair. + * + * @param key possibly-null key (string) part of the key/value pair. + * @param value possibly-null value (object) part of the key/value pair. * @param skipSubsequent reference parameter passed-in from the RPC layer. - * Set this to true if the callback wants to skip subsequent - * key/value pairs for the rest of the current received RPC packet. - * Note that some RPC protocol related key/value pairs (i.e. - * 'func', etc.) are not skipped. + * Set this to true if the callback wants to skip subsequent + * key/value pairs for the rest of the current received RPC packet. + * Note that some RPC protocol related key/value pairs (i.e. + * 'func', etc.) are not skipped. * @return true if the callback wants skip this key/value pair from getting - * into the results map; false otherwise (keep this key/value - * pair in the results map). + * into the results map; false otherwise (keep this key/value + * pair in the results map). * @throws P4JavaException if any problem that should stop normal command processing. */ boolean skip(String key, Object value, final AtomicBoolean skipSubsequent) throws P4JavaException; @@ -76,17 +76,17 @@ public interface IFilterCallback { /** * Per every RCP packet received from the Perforce server, callback to the * consumer to get a map of do-not-skip keys for informing the RPC layer not - * to skip them.

- * + * to skip them. + *

* Only the map keys are used for lookups; the map values are not used. This * is normally used coincide with the 'skipSubsequent' callback reference - * parameter set to true in the 'skip()' method.

- * + * parameter set to true in the 'skip()' method. + *

* NOTE: since this method is called frequently, the do-not-skip keys map * should probably be constructed once and outside of this method. Maybe a * good place to build this map is in a constructor or an initialization * method. - * + * * @return possibly-null map of do-not-skip keys. * @throws P4JavaException if any problem that should stop normal command processing. */ diff --git a/src/main/java/com/perforce/p4java/server/callback/ILogCallback.java b/src/main/java/com/perforce/p4java/server/callback/ILogCallback.java index cec76ab..929b711 100644 --- a/src/main/java/com/perforce/p4java/server/callback/ILogCallback.java +++ b/src/main/java/com/perforce/p4java/server/callback/ILogCallback.java @@ -7,8 +7,8 @@ * General P4Java-wide logger callback interface. Designed to be * used by consumers to receive logging events from the P4Java * classes and methods; these can then be logged appropriately - * in the consumer's own log(s) or reported in a popup, etc.

- * + * in the consumer's own log(s) or reported in a popup, etc. + *

* Logging messages can range from mundane reports of connection * startup and shutdown to detailed exception and tracing events, * and consumers should plan accordingly. In particular, tracing @@ -18,94 +18,90 @@ * optional but might be useful for your own tracing purposes; warnings * and errors should always be logged, as P4Java only uses these for * things it regards as possible signs of something going wrong ahead of - * time (warnings), or real errors.

- * + * time (warnings), or real errors. + *

* Note that there is only one such listener per instance of P4Java, * which effectively means per server factory instance rather than - * per IServer.

- * + * per IServer. + *

* Note also that the format of the strings reported through this * mechanism is not well-defined, and that the intention here is that * the consumer should wrap the messages in their own logging formatting - * with date / time prepended, etc.

- * + * with date / time prepended, etc. + *

* NOTE: you must ensure that there are no threading or reentrancy issues * with your implementation of this interface, and that calling any of the methods * here will not cause the caller (P4Java) to block or spend too much time processing - * the callback.

+ * the callback. */ public interface ILogCallback { - + /** * Defines the various trace levels available. Should be more * or less self-explanatory... */ enum LogTraceLevel { - NONE, - COARSE, - FINE, - SUPERFINE, - ALL; - }; - + NONE, COARSE, FINE, SUPERFINE, ALL; + } + /** * Report a P4Java-internal error. These are usually fatal * errors encountered deep within P4Java, and will typically be accompanied * by an exception or other throwable. These should always be logged by the * consumer if possible. - * + * * @param errorString non-null error string; may contain newlines. */ void internalError(String errorString); - + /** * Report an unexpected or otherwise interesting exception seen internally. * Such exceptions are almost always the sign of something going horribly * wrong, so these should always be logged if possible. The exceptions * here are almost always immediately preceded by an internalError message * that gives a more abstract view of what's going wrong. - * + * * @param thr non-null Throwable. */ void internalException(Throwable thr); - + /** * Report a P4Java-internal warning. These are usually non-fatal * issues encountered withing P4Java, and probably will not be accompanied * by an exception, but should probably be logged by the consumer. - * + * * @param warnString non-null warning message; may contain newlines. */ void internalWarn(String warnString); - + /** * Report a P4Java-internal informational event. These are typically "just * letting you know" messages that can be logged or ignored with impunity. - * + * * @param infoString non-null info message; may contain newlines. */ void internalInfo(String infoString); - + /** * Report some P4Java-internal statistics. These statistics are typically * just statistics gathered over the course of some time period that may be * useful to Perforce or end users; these can be logged or ignored with impunity. - * + * * @param statsString non-null stats message; may contain newlines. */ void internalStats(String statsString); - + /** * Report an internal P4Java trace message at the passed-in trace level. - * - * @param traceLevel trace level for associated message + * + * @param traceLevel trace level for associated message * @param traceMessage non-null trace message; may contain newlines. */ void internalTrace(LogTraceLevel traceLevel, String traceMessage); - + /** - * Return the trace level being used in the callback. Used within P4Java + * @return the trace level being used in the callback. Used within P4Java * to determine whether it's worth constructing trace messages on the fly * or to ignore certain tracing calls. */ diff --git a/src/main/java/com/perforce/p4java/server/callback/IProgressCallback.java b/src/main/java/com/perforce/p4java/server/callback/IProgressCallback.java index c4f463b..462e188 100644 --- a/src/main/java/com/perforce/p4java/server/callback/IProgressCallback.java +++ b/src/main/java/com/perforce/p4java/server/callback/IProgressCallback.java @@ -1,18 +1,18 @@ /** - * + * */ package com.perforce.p4java.server.callback; /** * Provides a simple server command and command progress callback * and control interface for P4Java consumers.

- * + * * The intention here is to provide consumers with a very simple way to * measure command progress and to stop a command mid-stream. The underlying * P4Java transport mechanism calls the tick() callback every time a "significant" * part of a command is finished, and the callback return value determines whether the * command should continue normally or be terminated cleanly ASAP.

- * + * * In context, the significant event is almost always the * start of processing for the next file spec to be processed (in a sync, a * long-running files or fstat command, a submit, etc), and the tick marker, @@ -21,30 +21,29 @@ * Note that only a few commands can get the file path back in the payload, * so you cannot rely on it being non-null; however, if it's not null, it's * likely to be of interest to the end-user.

- * + * * This scheme means the consumer should have some basic idea of the likely * order of magnitude of the number of ticks that will be generated, and * to be able to generate a suitable visual progress bar or popup using * this information.

- * + * * This callback scheme is only properly implemented in the RPC protocol * version of P4Java, and only commands likely to be long-running and / or * "interesting" currently participate in this scheme; these are typically commands * like submit, sync, files, and fstat, but no guarantee is given yet for * any particular command.

- * + * * NOTE: under error conditions it is not guaranteed that the stop() method * will be called; consumers should clear the callback's state manually under * these conditions.

- * + * * NOTE: you must ensure that there are no threading or reentrancy issues * with your implementation of this interface, and that calling any of the methods * here will not cause the caller (P4Java) to block or spend too much time processing * the callback. The callback is called in the middle of Perforce client / server * communications in the thread context of the protocol handler, and any significant - * delay here may cause serious performance issues or even botched commands.

+ * delay here may cause serious performance issues or even botched commands. */ - public interface IProgressCallback { /** @@ -54,31 +53,31 @@ public interface IProgressCallback { * used with command callbacks (see ICommandCallback) for the same command if * command callbacks are enabled (this allows consumers to correlate progress and * results by key matching).

- * + * * In any case, whether command callbacks are enabled or not, this key will be unique * across all calls (simultaneous or otherwise) to a given IServer, but is not * guaranteed to be unique across an entire P4Java instance. - * + * * @param key -- opaque integer key for correlation with subsidiary calls. */ void start(int key); - + /** * Signal the completion of a significant event, and poll the callback for * whether to continue the command. If this callback returns false, the underlying * protocol will do its best to stop the current command dead in its tracks and * clean up.

- * + * * Note that command cancellation done through this tick method is not guaranteed to * have any effect at all, nor are the side-effects of such a cancellation necessarily * predictable or safe. In general the default RPC implementation attempts to do a * reasonable job of things, but the command-line and RPC-NTS implementations ignore * any cancel notices completely.

- * + * * Note also that command cancellation does not work for connection delays; * current implementations force users to wait for connection timeouts. This will * probably change in future releases. - * + * * @param key -- opaque integer key as given by the associated start call. * @param tickMarker possibly-interesting possibly non-null tick payload; * if not null, will normally be something meaningful to the consumer @@ -87,12 +86,12 @@ public interface IProgressCallback { * @return true if you want the command to continue; false otherwise. */ boolean tick(int key, String tickMarker); - + /** * The current tick sequence has finished. Usually issued when the user command * has completed. Not guaranteed to be delivered when an error has occurred in * the command processing. - * + * * @param key -- opaque integer key as given by the associated start call. */ void stop(int key); diff --git a/src/main/java/com/perforce/p4java/server/delegator/IAttributeDelegator.java b/src/main/java/com/perforce/p4java/server/delegator/IAttributeDelegator.java index 2c4b435..80bf653 100644 --- a/src/main/java/com/perforce/p4java/server/delegator/IAttributeDelegator.java +++ b/src/main/java/com/perforce/p4java/server/delegator/IAttributeDelegator.java @@ -3,15 +3,15 @@ */ package com.perforce.p4java.server.delegator; -import java.io.InputStream; -import java.util.List; -import java.util.Map; -import javax.annotation.Nonnull; - import com.perforce.p4java.core.file.IFileSpec; import com.perforce.p4java.exception.P4JavaException; import com.perforce.p4java.option.server.SetFileAttributesOptions; +import javax.annotation.Nonnull; +import java.io.InputStream; +import java.util.List; +import java.util.Map; + /** * Delegator class for the Java API version of the p4 attribute command. * Supported options are: @@ -20,13 +20,53 @@ */ public interface IAttributeDelegator { + /** + * Unset file attributes on one or more files (unsupported). See the main + * Perforce documentation for an explanation of file attributes, which are + * potentially complex and difficult to use efficiently. Attributes can + * currently only be retrieved using the getExtendedFiles (fstat) operation. + *

+ * @param files non-null list of files to be affected + * @param attribute attribute to remove from perforce + * @param opts SetFileAttributesOptions object describing optional + * parameters; if null, no options are set. + * @return non-null but possibly empty list of filespec results for the + * operation. + * @throws P4JavaException if an error occurs processing this method and its parameters. + * @since 2011.1 + */ + public List unsetFileAttribute( + List files, + String attribute, + SetFileAttributesOptions opts) throws P4JavaException; + + /** + * Set file attributes on one. See the main + * Perforce documentation for an explanation of file attributes, which are + * potentially complex and difficult to use efficiently. Attributes can + * currently only be retrieved using the getExtendedFiles (fstat) operation. + *

+ * @param files non-null list of files to be affected + * @param attributes a non-null Map of attribute name / value pairs; if any value + * is null, that attribute is removed. + * @param opts SetFileAttributesOptions object describing optional + * parameters; if null, no options are set. + * @return non-null but possibly empty list of filespec results for the + * operation. + * @throws P4JavaException if an error occurs processing this method and its parameters. + * @since 2011.1 + */ + public List unsetFileAttributes( + List files, + List attributes, + SetFileAttributesOptions opts) throws P4JavaException; + /** * Set file attributes on one or more files (unsupported). See the main * Perforce documentation for an explanation of file attributes, which are * potentially complex and difficult to use efficiently. Attributes can * currently only be retrieved using the getExtendedFiles (fstat) operation. *

- *

* Note that this method only accepts String attribute values; if the * attribute is intended to be binary, use the setHexValue setter on the * associated SetFileAttributesOptions object and hexify the value, or, @@ -35,12 +75,10 @@ public interface IAttributeDelegator { * the Perforce server using the prevailing character set. If this is a * problem, use hex encoding or the stream variant of this method *

- *

* Note that attributes can only be removed from a file by setting the * appropriate value of the name / value pair passed-in through the * attributes map to null. *

- *

* Note that the filespecs returned by this method, if valid, contain only * the depot path and version information; no other field can be assumed to * be valid. Note also that, while the p4 command line executable returns a @@ -48,11 +86,11 @@ public interface IAttributeDelegator { * attributes, this method never returns more than one result for each file * affected. * - * @param opts SetFileAttributesOptions object describing optional - * parameters; if null, no options are set. + * @param files non-null list of files to be affected * @param attributes a non-null Map of attribute name / value pairs; if any value * is null, that attribute is removed. - * @param files non-null list of files to be affected + * @param opts SetFileAttributesOptions object describing optional + * parameters; if null, no options are set. * @return non-null but possibly empty list of filespec results for the * operation. * @throws P4JavaException if an error occurs processing this method and its parameters. @@ -70,7 +108,6 @@ public List setFileAttributes( * are potentially complex and difficult to use efficiently. Attributes can * currently only be retrieved using the getExtendedFiles (fstat) operation. *

- *

* This method is intended to allow for unmediated binary definitions of * file attribute contents, and is typically used for things like thumbnails * that are too big to be conveniently handled using hex conversion with the @@ -82,7 +119,6 @@ public List setFileAttributes( * no problem at all, but something in the megabyte range or larger might be * problematic at both ends. *

- *

* Note that this method will leave the passed-in stream open, but (in * general) the stream's read pointer will be at the end of the stream when * this method returns. You are responsible for closing the stream if @@ -93,19 +129,16 @@ public List setFileAttributes( * otherwise generally ignored -- you must check the actual results of this * operation yourself. *

- *

* Note that the server currently only supports setting file attributes * using a stream for one filespec at a time, but for reasons of symmetry * you must pass in a list of (one) filespec. Note that this doesn't * necessarily mean only one file is affected in the depot, just that * only one file spec is used to specify the affected file(s). *

- *

* Note that attributes can only be removed from a file by setting the * appropriate value of the name / value pair passed-in through the * attributes map to null. *

- *

* Note that the filespecs returned by this method, if valid, contain only * the depot path and version information; no other field can be assumed to * be valid. Note also that, while the p4 command line executable returns a @@ -113,12 +146,12 @@ public List setFileAttributes( * attributes, this method never returns more than one result for each file * affected. * - * @param opts SetFileAttributesOptions object describing optional - * parameters; if null, no options are set. + * @param files non-null list of files to be affected. * @param attributeName the non-null name of the attribute to be set. * @param inStream non-null InputStream ready for reading the attribute value * from. - * @param files non-null list of files to be affected. + * @param opts SetFileAttributesOptions object describing optional + * parameters; if null, no options are set. * @return non-null but possibly empty list of filespec results for the * operation. * @throws P4JavaException if an error occurs processing this method and its parameters. diff --git a/src/main/java/com/perforce/p4java/server/delegator/IClientDelegator.java b/src/main/java/com/perforce/p4java/server/delegator/IClientDelegator.java index f4be82e..c60f703 100644 --- a/src/main/java/com/perforce/p4java/server/delegator/IClientDelegator.java +++ b/src/main/java/com/perforce/p4java/server/delegator/IClientDelegator.java @@ -14,137 +14,139 @@ import javax.annotation.Nonnull; public interface IClientDelegator { - IClient getClient(final String clientName) - throws ConnectionException, RequestException, AccessException; - - IClient getClient(@Nonnull IClientSummary clientSummary) - throws ConnectionException, RequestException, AccessException; - - IClient getClientTemplate(String clientName) - throws ConnectionException, RequestException, AccessException; - - IClient getClientTemplate(String clientName, final boolean allowExistent) - throws ConnectionException, RequestException, AccessException; - - /** - * Get a template of a non-existent named Perforce client. This will only - * return an IClient for clients that don't exist unless the allowExistent - * parameter is set to true. This method is designed to be able to get the - * server returned default values it uses when a non-existent client is - * requested. - * - * @param clientName Not blank Perforce client name. - * @param getClientTemplateOptions GetClientTemplateOptions object describing optional - * parameters; if null, no options are set. - * @return IClient representing the specified Perforce client template, or null if no such - * client template. - * @throws P4JavaException if any error occurs in the processing of this method. - */ - IClient getClientTemplate(String clientName, GetClientTemplateOptions getClientTemplateOptions) - throws P4JavaException; - - String createClient(@Nonnull final IClient newClient) - throws ConnectionException, RequestException, AccessException; - - void createTempClient(@Nonnull final IClient newClient) - throws ConnectionException, RequestException, AccessException; - - String updateClient(@Nonnull final IClient client) - throws ConnectionException, RequestException, AccessException; - - /** - * Update an existing Perforce client on the current Perforce server. This - * client does not need to be the current client, and no association with - * the passed-in client is made by the server (i.e. it's not made the - * current client). - * - * @param client non-null IClient defining the Perforce client to be updated - * @param force if true, tell the server to attempt to force the update regardless of the - * consequences. You're on your own with this one... - * @return possibly-null operation result message string from the Perforce server - * @throws RequestException if any error occurs in the processing of this method. - * @since 2011.2 - */ - String updateClient(IClient client, final boolean force) - throws ConnectionException, RequestException, AccessException; - - /** - * Update an existing Perforce client on the current Perforce server. This - * client does not need to be the current client, and no association with - * the passed-in client is made by the server (i.e. it's not made the - * current client). - * - * @param client non-null IClient defining the Perforce client to be updated - * @param opts UpdateClientOptions object describing optional parameters; if null, no options - * are set. - * @return possibly-null operation result message string from the Perforce server - * @throws P4JavaException if any error occurs in the processing of this method. - * @since 2011.2 - */ - String updateClient(IClient client, final UpdateClientOptions opts) - throws P4JavaException; - - String deleteClient(String clientName, final boolean force) - throws ConnectionException, RequestException, AccessException; - - /** - * Delete a Perforce client from a Perforce server. The effects this has on - * the client and the server are not well-defined here, and you should - * probably consult the relevant Perforce documentation for your specific - * case. In any event, you can cause quite a lot of inconvenience (and maybe - * even damage) doing a forced delete without preparing properly for it, - * especially if the client is the server object's current client. - * - * @param clientName non-null name of the client to be deleted from the server. - * @param opts DeleteClientOptions object describing optional parameters; if null, no - * options are set. - * @return possibly-null operation result message string from the Perforce server. - * @throws P4JavaException if any error occurs in the processing of this method. - */ - String deleteClient(String clientName, final DeleteClientOptions opts) - throws P4JavaException; - - /** - * Switch the target client spec's view without invoking the editor. With -t - * to switch to a view defined in another client spec. Switching views is - * not allowed in a client that has opened files. The -f flag can be used - * with -s to force switching with opened files. View switching has no - * effect on files in a client workspace until 'p4 sync' is run. - * - * @param templateClientName non-null name of the template client who's view will be used for - * the target (or current) client to switched to. - * @param targetClientName possibly-null name of the target client whose view will be changed - * to the template client's view. If null, the current client will be - * used. - * @param opts SwitchClientViewOptions object describing optional parameters; if - * null, no options are set. - * @return possibly-null operation result message string from the Perforce server - * @throws P4JavaException if any error occurs in the processing of this method. - * @since 2011.2 - */ - String switchClientView(String templateClientName, - final String targetClientName, - SwitchClientViewOptions opts) throws P4JavaException; - - /** - * Switch the target client spec's view without invoking the editor. With -S - * to switch to the specified stream's view. Switching views is not allowed - * in a client that has opened files. The -f flag can be used with -s to - * force switching with opened files. View switching has no effect on files - * in a client workspace until 'p4 sync' is run. - * - * @param streamPath non-null stream's path in a stream depot, of the form - * //depotname/streamname who's view will be used for the target (or - * current) client to switched to. - * @param targetClientName possibly-null name of the target client whose view will be changed to - * the stream's view. If null, the current client will be used. - * @param opts SwitchClientViewOptions object describing optional parameters; if - * null, no options are set. - * @return possibly-null operation result message string from the Perforce server - * @throws P4JavaException if any error occurs in the processing of this method. - * @since 2011.2 - */ - String switchStreamView(String streamPath, - final String targetClientName, - SwitchClientViewOptions opts) throws P4JavaException; + IClient getClient(final String clientName) + throws ConnectionException, RequestException, AccessException; + + IClient getClient(@Nonnull IClientSummary clientSummary) + throws ConnectionException, RequestException, AccessException; + + IClient getClientTemplate(String clientName) + throws ConnectionException, RequestException, AccessException; + + IClient getClientTemplate(String clientName, final boolean allowExistent) + throws ConnectionException, RequestException, AccessException; + + /** + * Get a template of a non-existent named Perforce client. This will only + * return an IClient for clients that don't exist unless the allowExistent + * parameter is set to true. This method is designed to be able to get the + * server returned default values it uses when a non-existent client is + * requested. + * + * @param clientName Not blank Perforce client name. + * @param getClientTemplateOptions GetClientTemplateOptions object describing optional + * parameters; if null, no options are set. + * @return IClient representing the specified Perforce client template, or null if no such + * client template. + * @throws P4JavaException if any error occurs in the processing of this method. + */ + IClient getClientTemplate(String clientName, GetClientTemplateOptions getClientTemplateOptions) + throws P4JavaException; + + String createClient(@Nonnull final IClient newClient) + throws ConnectionException, RequestException, AccessException; + + void createTempClient(@Nonnull final IClient newClient) + throws ConnectionException, RequestException, AccessException; + + String updateClient(@Nonnull final IClient client) + throws ConnectionException, RequestException, AccessException; + + /** + * Update an existing Perforce client on the current Perforce server. This + * client does not need to be the current client, and no association with + * the passed-in client is made by the server (i.e. it's not made the + * current client). + * + * @param client non-null IClient defining the Perforce client to be updated + * @param force if true, tell the server to attempt to force the update regardless of the + * consequences. You're on your own with this one... + * @return possibly-null operation result message string from the Perforce server + * @throws RequestException if any error occurs in the processing of this method. + * @throws ConnectionException on error + * @throws AccessException on error + * @since 2011.2 + */ + String updateClient(IClient client, final boolean force) + throws ConnectionException, RequestException, AccessException; + + /** + * Update an existing Perforce client on the current Perforce server. This + * client does not need to be the current client, and no association with + * the passed-in client is made by the server (i.e. it's not made the + * current client). + * + * @param client non-null IClient defining the Perforce client to be updated + * @param opts UpdateClientOptions object describing optional parameters; if null, no options + * are set. + * @return possibly-null operation result message string from the Perforce server + * @throws P4JavaException if any error occurs in the processing of this method. + * @since 2011.2 + */ + String updateClient(IClient client, final UpdateClientOptions opts) + throws P4JavaException; + + String deleteClient(String clientName, final boolean force) + throws ConnectionException, RequestException, AccessException; + + /** + * Delete a Perforce client from a Perforce server. The effects this has on + * the client and the server are not well-defined here, and you should + * probably consult the relevant Perforce documentation for your specific + * case. In any event, you can cause quite a lot of inconvenience (and maybe + * even damage) doing a forced delete without preparing properly for it, + * especially if the client is the server object's current client. + * + * @param clientName non-null name of the client to be deleted from the server. + * @param opts DeleteClientOptions object describing optional parameters; if null, no + * options are set. + * @return possibly-null operation result message string from the Perforce server. + * @throws P4JavaException if any error occurs in the processing of this method. + */ + String deleteClient(String clientName, final DeleteClientOptions opts) + throws P4JavaException; + + /** + * Switch the target client spec's view without invoking the editor. With -t + * to switch to a view defined in another client spec. Switching views is + * not allowed in a client that has opened files. The -f flag can be used + * with -s to force switching with opened files. View switching has no + * effect on files in a client workspace until 'p4 sync' is run. + * + * @param templateClientName non-null name of the template client who's view will be used for + * the target (or current) client to switched to. + * @param targetClientName possibly-null name of the target client whose view will be changed + * to the template client's view. If null, the current client will be + * used. + * @param opts SwitchClientViewOptions object describing optional parameters; if + * null, no options are set. + * @return possibly-null operation result message string from the Perforce server + * @throws P4JavaException if any error occurs in the processing of this method. + * @since 2011.2 + */ + String switchClientView(String templateClientName, + final String targetClientName, + SwitchClientViewOptions opts) throws P4JavaException; + + /** + * Switch the target client spec's view without invoking the editor. With -S + * to switch to the specified stream's view. Switching views is not allowed + * in a client that has opened files. The -f flag can be used with -s to + * force switching with opened files. View switching has no effect on files + * in a client workspace until 'p4 sync' is run. + * + * @param streamPath non-null stream's path in a stream depot, of the form + * //depotname/streamname who's view will be used for the target (or + * current) client to switched to. + * @param targetClientName possibly-null name of the target client whose view will be changed to + * the stream's view. If null, the current client will be used. + * @param opts SwitchClientViewOptions object describing optional parameters; if + * null, no options are set. + * @return possibly-null operation result message string from the Perforce server + * @throws P4JavaException if any error occurs in the processing of this method. + * @since 2011.2 + */ + String switchStreamView(String streamPath, + final String targetClientName, + SwitchClientViewOptions opts) throws P4JavaException; } diff --git a/src/main/java/com/perforce/p4java/server/delegator/IClientsDelegator.java b/src/main/java/com/perforce/p4java/server/delegator/IClientsDelegator.java index 6192ebe..de01ee9 100644 --- a/src/main/java/com/perforce/p4java/server/delegator/IClientsDelegator.java +++ b/src/main/java/com/perforce/p4java/server/delegator/IClientsDelegator.java @@ -1,7 +1,5 @@ package com.perforce.p4java.server.delegator; -import java.util.List; - import com.perforce.p4java.client.IClientSummary; import com.perforce.p4java.exception.AccessException; import com.perforce.p4java.exception.ConnectionException; @@ -9,54 +7,59 @@ import com.perforce.p4java.exception.RequestException; import com.perforce.p4java.option.server.GetClientsOptions; +import java.util.List; + /** * @author Sean Shou * @since 15/09/2016 */ public interface IClientsDelegator { - /** - * Get a list of IClientSummary objects for all Perforce clients known to this Perforce - * server.

- *

- * Note that this method returns light-weight IClientSummary objects rather than full - * IClient objects; if you need the heavy-weight IClient objects, you should use getClient(). - *

- * Note also that the returned IClient objects are not "complete", in the sense - * that implementations are free to leave certain attributes null for performance - * reasons. In general, at least the client's name, root, description, last modification - * time are guaranteed correct. - * - * @param opts GetClientsOptions object describing optional parameters; if null, no options are - * set. - * @return non-null (but possibly empty) list of Client objects for Perforce clients known to - * this Perforce server. - * @throws P4JavaException if any error occurs in the processing of this method. - */ - List getClients(GetClientsOptions opts) throws P4JavaException; + /** + * Get a list of IClientSummary objects for all Perforce clients known to this Perforce + * server. + *

+ * Note that this method returns light-weight IClientSummary objects rather than full + * IClient objects; if you need the heavy-weight IClient objects, you should use getClient(). + *

+ * Note also that the returned IClient objects are not "complete", in the sense + * that implementations are free to leave certain attributes null for performance + * reasons. In general, at least the client's name, root, description, last modification + * time are guaranteed correct. + * + * @param opts GetClientsOptions object describing optional parameters; if null, no options are + * set. + * @return non-null (but possibly empty) list of Client objects for Perforce clients known to + * this Perforce server. + * @throws P4JavaException if any error occurs in the processing of this method. + */ + List getClients(GetClientsOptions opts) throws P4JavaException; - /** - * Get a list of IClientSummary objects for all Perforce clients known to this Perforce - * server.

- *

- * Note that this method returns light-weight IClientSummary objects rather than full - * IClient objects; if you need the heavy-weight IClient objects, you should use getClient(). - *

- * Note also that the returned IClient objects are not "complete", in the sense - * that implementations are free to leave certain attributes null for performance - * reasons. In general, at least the client's name, root, description, last modification - * time are guaranteed correct. - * - * @param userName user name - * @param nameFilter limits output to clients whose name matches the nameFilter pattern. - * Corresponds to -enameFilter flag - * @param maxResults If greater than zero, limit output to the first maxResults number of - * clients. - * @return non-null (but possibly empty) list of Client objects for Perforce clients known to - */ - List getClients( - String userName, - String nameFilter, - int maxResults) - throws ConnectionException, RequestException, AccessException; + /** + * Get a list of IClientSummary objects for all Perforce clients known to this Perforce + * server. + *

+ * Note that this method returns light-weight IClientSummary objects rather than full + * IClient objects; if you need the heavy-weight IClient objects, you should use getClient(). + *

+ * Note also that the returned IClient objects are not "complete", in the sense + * that implementations are free to leave certain attributes null for performance + * reasons. In general, at least the client's name, root, description, last modification + * time are guaranteed correct. + * + * @param userName user name + * @param nameFilter limits output to clients whose name matches the nameFilter pattern. + * Corresponds to -enameFilter flag + * @param maxResults If greater than zero, limit output to the first maxResults number of + * clients. + * @return non-null (but possibly empty) list of Client objects for Perforce clients known to + * @throws ConnectionException on error + * @throws RequestException on error + * @throws AccessException on error + */ + List getClients( + String userName, + String nameFilter, + int maxResults) + throws ConnectionException, RequestException, AccessException; } diff --git a/src/main/java/com/perforce/p4java/server/delegator/IDepotsDelegator.java b/src/main/java/com/perforce/p4java/server/delegator/IDepotsDelegator.java index 4448368..a1b0661 100644 --- a/src/main/java/com/perforce/p4java/server/delegator/IDepotsDelegator.java +++ b/src/main/java/com/perforce/p4java/server/delegator/IDepotsDelegator.java @@ -26,6 +26,10 @@ public interface IDepotsDelegator { /** * Gets depots with type and namefilter + * + * @param opts options + * @return list of depots + * @throws P4JavaException on error */ List getDepots(GetDepotsOptions opts) throws P4JavaException; } diff --git a/src/main/java/com/perforce/p4java/server/delegator/IDescribeDelegator.java b/src/main/java/com/perforce/p4java/server/delegator/IDescribeDelegator.java index d061287..c03b0f7 100644 --- a/src/main/java/com/perforce/p4java/server/delegator/IDescribeDelegator.java +++ b/src/main/java/com/perforce/p4java/server/delegator/IDescribeDelegator.java @@ -20,206 +20,181 @@ */ public interface IDescribeDelegator { - /** - * Get an InputStream onto the file diffs associated with a specific - * submitted changelist. This method (like the similar "p4 describe" - * command) will not return diffs for pending changelists. - *

- * - * This is one of the guaranteed "live" method on this interface, and will - * return the diff output as it exists when called (rather than when the - * underlying implementation object was created). This can be an expensive - * method to evaluate, and can generate reams and reams (and reams) of - * output, so don't use it willy-nilly. - *

- * - * Note that unlike the corresponding command-line command, which keeps - * going in the face of errors by moving on to the next file (or whatever), - * any errors encountered in this method will cause an exception from this - * method at the first error, so plan accordingly.... - * - * @param id - * the ID of the target changelist. - * @param opts - * GetChangelistDiffsOptions object describing optional - * parameters; if null, no options are set. - * @return InputStream onto the diff stream. Note that while this stream - * will not be null, it may be empty. - * @throws P4JavaException - * if any error occurs in the processing of this method. - */ - - InputStream getChangelistDiffs(int id, GetChangelistDiffsOptions opts) throws P4JavaException; - - /** - * Get an InputStream onto the file diffs associated with a specific - * submitted changelist. This method (like the similar "p4 describe" - * command) will not return diffs for pending changelists. - *

- * - * This is one of the guaranteed "live" method on this interface, and will - * return the diff output as it exists when called (rather than when the - * underlying implementation object was created). This can be an expensive - * method to evaluate, and can generate reams and reams (and reams) of - * output, so don't use it willy-nilly. - *

- * - * Note that unlike the corresponding command-line command, which keeps - * going in the face of errors by moving on to the next file (or whatever), - * any errors encountered in this method will cause an exception from this - * method at the first error, so plan accordingly.... - * - * @param id - * the ID of the target changelist - * @param options - * DescribeOptions behavioural options for method. - * @return InputStream onto the diff stream. Note that while this stream - * will not be null, it may be empty - * @throws ConnectionException - * if the Perforce server is unreachable or is not connected. - * @throws RequestException - * if the Perforce server encounters an error during its - * processing of the request - * @throws AccessException - * if the Perforce server denies access to the caller - */ - - InputStream getChangelistDiffsStream(int id, DescribeOptions options) - throws ConnectionException, RequestException, AccessException; - - /** - * Get a list of the Perforce depot files associated with a Perforce - * changelist. - *

- *

- * The IFileSpec objects returned are not guaranteed to have any fields - * except depot path, version, and action valid. - *

- *

- * Changelists that are pending will not have files visible through this - * method; you should use the client openedFiles method for retrieving files - * in that situation. - * - * @param id numeric changelist identifier - * @return non-null (but possibly empty) list of files associated with the - * changelist. - * @throws ConnectionException if the Perforce server is unreachable or is not connected. - * @throws RequestException if the Perforce server encounters an error during its - * processing of the request - * @throws AccessException if the Perforce server denies access to the caller - */ - - List getChangelistFiles(int id) - throws ConnectionException, RequestException, AccessException; - - /** - * Get a list of the Perforce depot files associated with a Perforce - * changelist. - *

- *

- * The IFileSpec objects returned are not guaranteed to have any fields - * except depot path, version, and action valid. - *

- *

- * Changelists that are pending will not have files visible through this - * method; you should use the client openedFiles method for retrieving files - * in that situation. - * - * @param id numeric changelist identifier - * @param max limit the number of files returned - * @return non-null (but possibly empty) list of files associated with the - * changelist. - * @throws ConnectionException if the Perforce server is unreachable or is not connected. - * @throws RequestException if the Perforce server encounters an error during its - * processing of the request - * @throws AccessException if the Perforce server denies access to the caller - * @since 2017.2 - */ - - List getChangelistFiles(int id, int max) - throws ConnectionException, RequestException, AccessException; - - /** - * Get an extended list of the Perforce depot files associated with a Perforce - * changelist. - *

- *

- * The IExtendedFileSpec objects returned are not guaranteed to have any fields - * except depot path, version, and action valid. - *

- *

- * Changelists that are pending will not have files visible through this - * method; you should use the client openedFiles method for retrieving files - * in that situation. - * - * @param id numeric changelist identifier - * @return non-null (but possibly empty) list of extended files associated with the - * changelist. - * @throws ConnectionException if the Perforce server is unreachable or is not connected. - * @throws RequestException if the Perforce server encounters an error during its - * processing of the request - * @throws AccessException if the Perforce server denies access to the caller - */ - - List getChangelistExtendedFiles(int id) - throws ConnectionException, RequestException, AccessException; - - /** - * Get an extended list of the Perforce depot files associated with a Perforce - * changelist. - *

- *

- * The IExtendedFileSpec objects returned are not guaranteed to have any fields - * except depot path, version, and action valid. - *

- *

- * Changelists that are pending will not have files visible through this - * method; you should use the client openedFiles method for retrieving files - * in that situation. - * - * @param id numeric changelist identifier - * @param max limit the number of files returned - * @return non-null (but possibly empty) list of extended files associated with the - * changelist. - * @throws ConnectionException if the Perforce server is unreachable or is not connected. - * @throws RequestException if the Perforce server encounters an error during its - * processing of the request - * @throws AccessException if the Perforce server denies access to the caller - * @since 2017.2 - */ - - List getChangelistExtendedFiles(int id, int max) - throws ConnectionException, RequestException, AccessException; - - /** - * Get a list of shelved files associated with a Perforce pending - * changelist. - *

- * - * @param changelistId - * numeric pending changelist identifier - * @return non-null (but possibly empty) list of shelved files associated - * with the pending changelist. - * @throws P4JavaException - * if an error occurs processing this method and its parameters. - * @since 2014.1 - */ - List getShelvedFiles(final int changelistId) throws P4JavaException; - - /** - * Get a list of shelved files associated with a Perforce pending - * changelist. - *

- * - * @param changelistId - * numeric pending changelist identifier - *@param max - * limit the number of files returned - * @return non-null (but possibly empty) list of shelved files associated - * with the pending changelist. - * @throws P4JavaException - * if an error occurs processing this method and its parameters. - * @since 2017.2 - */ - List getShelvedFiles(final int changelistId, final int max) throws P4JavaException; + /** + * Get an InputStream onto the file diffs associated with a specific + * submitted changelist. This method (like the similar "p4 describe" + * command) will not return diffs for pending changelists. + *

+ * This is one of the guaranteed "live" method on this interface, and will + * return the diff output as it exists when called (rather than when the + * underlying implementation object was created). This can be an expensive + * method to evaluate, and can generate reams and reams (and reams) of + * output, so don't use it willy-nilly. + *

+ * Note that unlike the corresponding command-line command, which keeps + * going in the face of errors by moving on to the next file (or whatever), + * any errors encountered in this method will cause an exception from this + * method at the first error, so plan accordingly.... + * + * @param id the ID of the target changelist. + * @param opts GetChangelistDiffsOptions object describing optional + * parameters; if null, no options are set. + * @return InputStream onto the diff stream. Note that while this stream + * will not be null, it may be empty. + * @throws P4JavaException if any error occurs in the processing of this method. + */ + + InputStream getChangelistDiffs(int id, GetChangelistDiffsOptions opts) throws P4JavaException; + + /** + * Get an InputStream onto the file diffs associated with a specific + * submitted changelist. This method (like the similar "p4 describe" + * command) will not return diffs for pending changelists. + *

+ * This is one of the guaranteed "live" method on this interface, and will + * return the diff output as it exists when called (rather than when the + * underlying implementation object was created). This can be an expensive + * method to evaluate, and can generate reams and reams (and reams) of + * output, so don't use it willy-nilly. + *

+ * Note that unlike the corresponding command-line command, which keeps + * going in the face of errors by moving on to the next file (or whatever), + * any errors encountered in this method will cause an exception from this + * method at the first error, so plan accordingly.... + * + * @param id the ID of the target changelist + * @param options DescribeOptions behavioural options for method. + * @return InputStream onto the diff stream. Note that while this stream + * will not be null, it may be empty + * @throws ConnectionException if the Perforce server is unreachable or is not connected. + * @throws RequestException if the Perforce server encounters an error during its + * processing of the request + * @throws AccessException if the Perforce server denies access to the caller + */ + + InputStream getChangelistDiffsStream(int id, DescribeOptions options) + throws ConnectionException, RequestException, AccessException; + + /** + * Get a list of the Perforce depot files associated with a Perforce + * changelist. + *

+ * The IFileSpec objects returned are not guaranteed to have any fields + * except depot path, version, and action valid. + *

+ * Changelists that are pending will not have files visible through this + * method; you should use the client openedFiles method for retrieving files + * in that situation. + * + * @param id numeric changelist identifier + * @return non-null (but possibly empty) list of files associated with the + * changelist. + * @throws ConnectionException if the Perforce server is unreachable or is not connected. + * @throws RequestException if the Perforce server encounters an error during its + * processing of the request + * @throws AccessException if the Perforce server denies access to the caller + */ + + List getChangelistFiles(int id) + throws ConnectionException, RequestException, AccessException; + + /** + * Get a list of the Perforce depot files associated with a Perforce + * changelist. + *

+ * The IFileSpec objects returned are not guaranteed to have any fields + * except depot path, version, and action valid. + *

+ * Changelists that are pending will not have files visible through this + * method; you should use the client openedFiles method for retrieving files + * in that situation. + * + * @param id numeric changelist identifier + * @param max limit the number of files returned + * @return non-null (but possibly empty) list of files associated with the + * changelist. + * @throws ConnectionException if the Perforce server is unreachable or is not connected. + * @throws RequestException if the Perforce server encounters an error during its + * processing of the request + * @throws AccessException if the Perforce server denies access to the caller + * @since 2017.2 + */ + + List getChangelistFiles(int id, int max) + throws ConnectionException, RequestException, AccessException; + + /** + * Get an extended list of the Perforce depot files associated with a Perforce + * changelist. + *

+ * The IExtendedFileSpec objects returned are not guaranteed to have any fields + * except depot path, version, and action valid. + *

+ * Changelists that are pending will not have files visible through this + * method; you should use the client openedFiles method for retrieving files + * in that situation. + * + * @param id numeric changelist identifier + * @return non-null (but possibly empty) list of extended files associated with the + * changelist. + * @throws ConnectionException if the Perforce server is unreachable or is not connected. + * @throws RequestException if the Perforce server encounters an error during its + * processing of the request + * @throws AccessException if the Perforce server denies access to the caller + */ + + List getChangelistExtendedFiles(int id) + throws ConnectionException, RequestException, AccessException; + + /** + * Get an extended list of the Perforce depot files associated with a Perforce + * changelist. + *

+ * The IExtendedFileSpec objects returned are not guaranteed to have any fields + * except depot path, version, and action valid. + *

+ * Changelists that are pending will not have files visible through this + * method; you should use the client openedFiles method for retrieving files + * in that situation. + * + * @param id numeric changelist identifier + * @param max limit the number of files returned + * @return non-null (but possibly empty) list of extended files associated with the + * changelist. + * @throws ConnectionException if the Perforce server is unreachable or is not connected. + * @throws RequestException if the Perforce server encounters an error during its + * processing of the request + * @throws AccessException if the Perforce server denies access to the caller + * @since 2017.2 + */ + + List getChangelistExtendedFiles(int id, int max) + throws ConnectionException, RequestException, AccessException; + + /** + * Get a list of shelved files associated with a Perforce pending + * changelist. + *

+ * + * @param changelistId numeric pending changelist identifier + * @return non-null (but possibly empty) list of shelved files associated + * with the pending changelist. + * @throws P4JavaException if an error occurs processing this method and its parameters. + * @since 2014.1 + */ + List getShelvedFiles(final int changelistId) throws P4JavaException; + + /** + * Get a list of shelved files associated with a Perforce pending + * changelist. + *

+ * + * @param changelistId numeric pending changelist identifier + * @param max limit the number of files returned + * @return non-null (but possibly empty) list of shelved files associated + * with the pending changelist. + * @throws P4JavaException if an error occurs processing this method and its parameters. + * @since 2017.2 + */ + List getShelvedFiles(final int changelistId, final int max) throws P4JavaException; } diff --git a/src/main/java/com/perforce/p4java/server/delegator/IDiff2Delegator.java b/src/main/java/com/perforce/p4java/server/delegator/IDiff2Delegator.java index 7f79f57..0127c6f 100644 --- a/src/main/java/com/perforce/p4java/server/delegator/IDiff2Delegator.java +++ b/src/main/java/com/perforce/p4java/server/delegator/IDiff2Delegator.java @@ -1,8 +1,5 @@ package com.perforce.p4java.server.delegator; -import java.io.InputStream; -import java.util.List; - import com.perforce.p4java.core.IFileDiff; import com.perforce.p4java.core.file.DiffType; import com.perforce.p4java.core.file.IFileSpec; @@ -12,138 +9,140 @@ import com.perforce.p4java.exception.RequestException; import com.perforce.p4java.option.server.GetFileDiffsOptions; +import java.io.InputStream; +import java.util.List; + /** * @author Sean Shou * @since 27/09/2016 */ public interface IDiff2Delegator { - /** - * Run diff on the Perforce server of two files in the depot.

- *

- * With a branch view, fromFile and toFile are optional; fromFile limits - * the scope of the source file set, and toFile limits the scope of the - * target. If only one file argument is given, it is assumed to be toFile.

- *

- * This method corresponds closely to the standard diff2 command, and that - * command's documentation should be consulted for the overall and detailed - * semantics.

- * - * @param file1 (optional, with a branch view) source file IFileSpec - * @param file2 (optional, with a branch view) target file IFileSpec - * @param branchSpecName optional branch spec name - * @param opts GetFileDiffsOptions object describing optional parameters; if null, no - * options are set. - * @return non-null but possibly empty array of file diffs - * @throws P4JavaException if an error occurs processing this method and its parameters. - */ - List getFileDiffs( - IFileSpec file1, - IFileSpec file2, - String branchSpecName, - GetFileDiffsOptions opts) throws P4JavaException; + /** + * Run diff on the Perforce server of two files in the depot. + *

+ * With a branch view, fromFile and toFile are optional; fromFile limits + * the scope of the source file set, and toFile limits the scope of the + * target. If only one file argument is given, it is assumed to be toFile. + *

+ * This method corresponds closely to the standard diff2 command, and that + * command's documentation should be consulted for the overall and detailed + * semantics.

+ * + * @param file1 (optional, with a branch view) source file IFileSpec + * @param file2 (optional, with a branch view) target file IFileSpec + * @param branchSpecName optional branch spec name + * @param opts GetFileDiffsOptions object describing optional parameters; if null, no + * options are set. + * @return non-null but possibly empty array of file diffs + * @throws P4JavaException if an error occurs processing this method and its parameters. + */ + List getFileDiffs( + IFileSpec file1, + IFileSpec file2, + String branchSpecName, + GetFileDiffsOptions opts) throws P4JavaException; - /** - * Run diff on the Perforce server of two files in the depot. - *

- *

- * This method corresponds closely to the standard diff2 command, and that - * command's documentation should be consulted for the overall and detailed - * semantics. In particular, the various potentially-valid combinations of - * branch spec and file specs can be complicated and won't be repeated here. - *

- * - * @param file1 optional first file IFileSpec - * @param file2 optional second file IFileSpec - * @param branchSpecName optional branch spec name - * @param quiet if true, suppresses the display of the header lines of files - * whose content and types are identical and suppresses the - * actual diff for all files. - * @param includeNonTextDiffs if true, forces 'p4 diff2' to diff even files with non-text - * (binary) types - * @param gnuDiffs see "-u" option in the main diff2 documentation. - * @return non-null but possibly empty array of file diffs - * @throws ConnectionException if the Perforce server is unreachable or is not connected. - * @throws RequestException if the Perforce server encounters an error during its - * processing of the request - * @throws AccessException if the Perforce server denies access to the caller - */ - List getFileDiffs( - IFileSpec file1, - IFileSpec file2, - String branchSpecName, - DiffType diffType, - boolean quiet, - boolean includeNonTextDiffs, - boolean gnuDiffs) throws ConnectionException, RequestException, AccessException; + /** + * Run diff on the Perforce server of two files in the depot. + *

+ * This method corresponds closely to the standard diff2 command, and that + * command's documentation should be consulted for the overall and detailed + * semantics. In particular, the various potentially-valid combinations of + * branch spec and file specs can be complicated and won't be repeated here. + *

+ * + * @param file1 optional first file IFileSpec + * @param file2 optional second file IFileSpec + * @param branchSpecName optional branch spec name + * @param diffType diff type + * @param quiet if true, suppresses the display of the header lines of files + * whose content and types are identical and suppresses the + * actual diff for all files. + * @param includeNonTextDiffs if true, forces 'p4 diff2' to diff even files with non-text + * (binary) types + * @param gnuDiffs see "-u" option in the main diff2 documentation. + * @return non-null but possibly empty array of file diffs + * @throws ConnectionException if the Perforce server is unreachable or is not connected. + * @throws RequestException if the Perforce server encounters an error during its + * processing of the request + * @throws AccessException if the Perforce server denies access to the caller + */ + List getFileDiffs( + IFileSpec file1, + IFileSpec file2, + String branchSpecName, + DiffType diffType, + boolean quiet, + boolean includeNonTextDiffs, + boolean gnuDiffs) throws ConnectionException, RequestException, AccessException; - /** - * Run diff on the Perforce server of two files in the depot.

- *

- * With a branch view, fromFile and toFile are optional; fromFile limits - * the scope of the source file set, and toFile limits the scope of the - * target. If only one file argument is given, it is assumed to be toFile.

- *

- * This method corresponds closely to the standard diff2 command, and that - * command's documentation should be consulted for the overall and detailed - * semantics.

- *

- * As with other streams-based IServer methods, callers should ensure that - * the stream returned here is always explicitly closed after use; if not - * closed, the stream's associated temporary files managed by P4Java - * (if they exist) may not be properly deleted. - * - * @param file1 (optional, with a branch view) source file IFileSpec - * @param file2 (optional, with a branch view) target file IFileSpec - * @param branchSpecName optional branch spec name - * @param opts GetFileDiffsOptions object describing optional parameters; if null, no - * options are set. - * @return non-null but possibly empty InputStream of diffs and headers as returned from the - * server. - * @throws P4JavaException if an error occurs processing this method and its parameters. - */ - InputStream getFileDiffsStream( - IFileSpec file1, - IFileSpec file2, - String branchSpecName, - GetFileDiffsOptions opts) throws P4JavaException; + /** + * Run diff on the Perforce server of two files in the depot. + *

+ * With a branch view, fromFile and toFile are optional; fromFile limits + * the scope of the source file set, and toFile limits the scope of the + * target. If only one file argument is given, it is assumed to be toFile. + *

+ * This method corresponds closely to the standard diff2 command, and that + * command's documentation should be consulted for the overall and detailed + * semantics. + *

+ * As with other streams-based IServer methods, callers should ensure that + * the stream returned here is always explicitly closed after use; if not + * closed, the stream's associated temporary files managed by P4Java + * (if they exist) may not be properly deleted. + * + * @param file1 (optional, with a branch view) source file IFileSpec + * @param file2 (optional, with a branch view) target file IFileSpec + * @param branchSpecName optional branch spec name + * @param opts GetFileDiffsOptions object describing optional parameters; if null, no + * options are set. + * @return non-null but possibly empty InputStream of diffs and headers as returned from the + * server. + * @throws P4JavaException if an error occurs processing this method and its parameters. + */ + InputStream getFileDiffsStream( + IFileSpec file1, + IFileSpec file2, + String branchSpecName, + GetFileDiffsOptions opts) throws P4JavaException; - /** - * Run diff on the Perforce server of two files in the depot. - *

- *

- * This method corresponds closely to the standard diff2 command, and that - * command's documentation should be consulted for the overall and detailed - * semantics. In particular, the various potentially-valid combinations of - * branch spec and file specs can be complicated and won't be repeated here. - *

- *

- * As with other streams-based IServer methods, callers should ensure that - * the stream returned here is always explicitly closed after use; if not - * closed, the stream's associated temporary files managed by P4Java (if - * they exist) may not be properly deleted. - * - * @param file1 optional first file IFileSpec - * @param file2 optional second file IFileSpec - * @param branchSpecName optional branch spec name - * @param quiet if true, suppresses the display of the header lines of files - * whose content and types are identical and suppresses the - * actual diff for all files. - * @param includeNonTextDiffs if true, forces 'p4 diff2' to diff even files with non-text - * (binary) types - * @param gnuDiffs see "-u" option in the main diff2 documentation. - * @return non-null but possibly empty InputStream of diffs and headers as - * returned from the server. - * @throws ConnectionException if the Perforce server is unreachable or is not connected. - * @throws RequestException if the Perforce server encounters an error during its - * processing of the request - * @throws AccessException if the Perforce server denies access to the caller - */ - InputStream getServerFileDiffs( - IFileSpec file1, - IFileSpec file2, - String branchSpecName, - DiffType diffType, - boolean quiet, - boolean includeNonTextDiffs, - boolean gnuDiffs) throws ConnectionException, RequestException, AccessException; + /** + * Run diff on the Perforce server of two files in the depot. + *

+ * This method corresponds closely to the standard diff2 command, and that + * command's documentation should be consulted for the overall and detailed + * semantics. In particular, the various potentially-valid combinations of + * branch spec and file specs can be complicated and won't be repeated here. + *

+ * As with other streams-based IServer methods, callers should ensure that + * the stream returned here is always explicitly closed after use; if not + * closed, the stream's associated temporary files managed by P4Java (if + * they exist) may not be properly deleted. + * + * @param file1 optional first file IFileSpec + * @param file2 optional second file IFileSpec + * @param branchSpecName optional branch spec name + * @param diffType diff type + * @param quiet if true, suppresses the display of the header lines of files + * whose content and types are identical and suppresses the + * actual diff for all files. + * @param includeNonTextDiffs if true, forces 'p4 diff2' to diff even files with non-text + * (binary) types + * @param gnuDiffs see "-u" option in the main diff2 documentation. + * @return non-null but possibly empty InputStream of diffs and headers as + * returned from the server. + * @throws ConnectionException if the Perforce server is unreachable or is not connected. + * @throws RequestException if the Perforce server encounters an error during its + * processing of the request + * @throws AccessException if the Perforce server denies access to the caller + */ + InputStream getServerFileDiffs( + IFileSpec file1, + IFileSpec file2, + String branchSpecName, + DiffType diffType, + boolean quiet, + boolean includeNonTextDiffs, + boolean gnuDiffs) throws ConnectionException, RequestException, AccessException; } diff --git a/src/main/java/com/perforce/p4java/server/delegator/IDuplicateDelegator.java b/src/main/java/com/perforce/p4java/server/delegator/IDuplicateDelegator.java index 7dc3b4e..e59882d 100644 --- a/src/main/java/com/perforce/p4java/server/delegator/IDuplicateDelegator.java +++ b/src/main/java/com/perforce/p4java/server/delegator/IDuplicateDelegator.java @@ -11,13 +11,13 @@ */ public interface IDuplicateDelegator { /** - * Duplicate revisions with integration history (unsupported).

+ * Duplicate revisions with integration history (unsupported). *

* Duplicate revisions as if they always existed. All aspects of the source * revisions are mirrored to the target revisions, including changelist * number, date, attributes, and contents. The target revision must not * already exist and the target file must not be opened (for any operation) - * on any client.

+ * on any client. *

* Note that integration records are duplicated as well. 'p4 duplicate' * followed by a 'p4 obliterate' (of the source revisions) is in effect a diff --git a/src/main/java/com/perforce/p4java/server/delegator/IExportDelegator.java b/src/main/java/com/perforce/p4java/server/delegator/IExportDelegator.java index d132e56..982be1f 100644 --- a/src/main/java/com/perforce/p4java/server/delegator/IExportDelegator.java +++ b/src/main/java/com/perforce/p4java/server/delegator/IExportDelegator.java @@ -1,9 +1,5 @@ package com.perforce.p4java.server.delegator; -import java.util.List; -import java.util.Map; -import javax.annotation.Nonnull; - import com.perforce.p4java.exception.AccessException; import com.perforce.p4java.exception.ConnectionException; import com.perforce.p4java.exception.P4JavaException; @@ -11,125 +7,122 @@ import com.perforce.p4java.option.server.ExportRecordsOptions; import com.perforce.p4java.server.callback.IStreamingCallback; +import javax.annotation.Nonnull; +import java.util.List; +import java.util.Map; + /** * Interface to handle the Export command. */ public interface IExportDelegator { - /** - * Get a list of exported journal or checkpoint records (admin / superuser - * command). - *

- *

- * See the main p4 export command documentation for full semantics and usage - * details. - *

- *

- * Note that the 'skip*' options in ExportRecordsOptions are specific to - * P4Java only; they are not Perforce command options. These options are for - * field handling rules in the lower layers of P4Java. The field rules are - * for identifying the fields that should skip charset translation of their - * values; leaving their values as bytes instead of converting them to - * strings. Please see ExportRecordsOptions for usage details. - * - * @param useJournal *If true, specifies a journal number and optional offset position (journal - * number/offset) from which to start exporting. Corresponds to the '-j - * token' flag.

- *

- * If false, specifies a checkpoint number and optional offset position - * (checkpoint number#offset) from which to start exporting. Corresponds to - * the '-c token' flag. - * @param maxRecs If greater than zero, limits the number of lines (records) exported. - * Corresponds to the '-l lines' flag. - * @param sourceNum If positive, specifies a journal or checkpoint number. Corresponds to the - * 'token' part of the '-j token' and '-c token' flags.

- *

- * The '-j token' flag specifies a journal number and optional position (in - * the form: journal number/offset) from which to start exporting. The -c - * token flag specifies a checkpoint number and optional position (in the - * form: checkpoint number#offset) from which to start exporting. - * @param offset If positive, specifies a journal or checkpoint optional offset position - * (journal number/offset or checkpoint number#offset) from which to start - * exporting. - * @param format If true, formats non-textual datatypes appropriately. Corresponds to the - * '-f' flag. - * @param journalPrefix If non-null, specifies a file name prefix to match the one used with 'p4d - * -jc '. Corresponds to the '-J' flag. - * @param filter If non-null, limits output to records that match the filter pattern. - * Corresponds to the '-F' flag. - * @return export records list - * @throws ConnectionException - * @throws RequestException - * @throws AccessException - */ - List> getExportRecords( - boolean useJournal, - long maxRecs, - int sourceNum, - long offset, - boolean format, - String journalPrefix, - String filter) throws ConnectionException, RequestException, AccessException; + /** + * Get a list of exported journal or checkpoint records (admin / superuser + * command). + *

+ * See the main p4 export command documentation for full semantics and usage + * details. + *

+ * Note that the 'skip*' options in ExportRecordsOptions are specific to + * P4Java only; they are not Perforce command options. These options are for + * field handling rules in the lower layers of P4Java. The field rules are + * for identifying the fields that should skip charset translation of their + * values; leaving their values as bytes instead of converting them to + * strings. Please see ExportRecordsOptions for usage details. + * + * @param useJournal *If true, specifies a journal number and optional offset position (journal + * number/offset) from which to start exporting. Corresponds to the '-j + * token' flag. + *

+ * If false, specifies a checkpoint number and optional offset position + * (checkpoint number#offset) from which to start exporting. Corresponds to + * the '-c token' flag. + * @param maxRecs If greater than zero, limits the number of lines (records) exported. + * Corresponds to the '-l lines' flag. + * @param sourceNum If positive, specifies a journal or checkpoint number. Corresponds to the + * 'token' part of the '-j token' and '-c token' flags. + *

+ * The '-j token' flag specifies a journal number and optional position (in + * the form: journal number/offset) from which to start exporting. The -c + * token flag specifies a checkpoint number and optional position (in the + * form: checkpoint number#offset) from which to start exporting. + * @param offset If positive, specifies a journal or checkpoint optional offset position + * (journal number/offset or checkpoint number#offset) from which to start + * exporting. + * @param format If true, formats non-textual datatypes appropriately. Corresponds to the + * '-f' flag. + * @param journalPrefix If non-null, specifies a file name prefix to match the one used with 'p4d + * -jc prefix'. Corresponds to the '-J' flag. + * @param filter If non-null, limits output to records that match the filter pattern. + * Corresponds to the '-F' flag. + * @return export records list + * @throws ConnectionException on error + * @throws RequestException on error + * @throws AccessException on error + */ + List> getExportRecords( + boolean useJournal, + long maxRecs, + int sourceNum, + long offset, + boolean format, + String journalPrefix, + String filter) throws ConnectionException, RequestException, AccessException; - /** - * Get a list of exported journal or checkpoint records (admin / superuser - * command). - *

- *

- * See the main p4 export command documentation for full semantics and usage - * details. - *

- *

- * Note that the 'skip*' options in ExportRecordsOptions are specific to - * P4Java only; they are not Perforce command options. These options are for - * field handling rules in the lower layers of P4Java. The field rules are - * for identifying the fields that should skip charset translation of their - * values; leaving their values as bytes instead of converting them to - * strings. Please see ExportRecordsOptions for usage details. - * - * @param opts ExportRecordsOptions object describing optional parameters; if null, no options - * are set. - * @return non-null but possibly empty list of maps representing exported journal or checkpoint - * records. - * @throws P4JavaException if an error occurs processing this method and its parameters. - */ - List> getExportRecords(ExportRecordsOptions opts) throws P4JavaException; + /** + * Get a list of exported journal or checkpoint records (admin / superuser + * command). + *

+ * See the main p4 export command documentation for full semantics and usage + * details. + *

+ * Note that the 'skip*' options in ExportRecordsOptions are specific to + * P4Java only; they are not Perforce command options. These options are for + * field handling rules in the lower layers of P4Java. The field rules are + * for identifying the fields that should skip charset translation of their + * values; leaving their values as bytes instead of converting them to + * strings. Please see ExportRecordsOptions for usage details. + * + * @param opts ExportRecordsOptions object describing optional parameters; if null, no options + * are set. + * @return non-null but possibly empty list of maps representing exported journal or checkpoint + * records. + * @throws P4JavaException if an error occurs processing this method and its parameters. + */ + List> getExportRecords(ExportRecordsOptions opts) throws P4JavaException; - /** - * Get each exported journal or checkpoint record (admin / superuser - * command) as it comes in from the server, rather than waiting for the - * entire command to complete. - *

- *

- * The results are sent to the user using the IStreamingCallback - * handleResult method; see the IStreamingCallback Javadoc for details. The - * payload passed to handleResult is usually the raw map gathered together - * deep in the RPC protocol layer, and the user is assumed to have the - * knowledge and technology to be able to parse it and use it suitably in - * much the same way as a user unpacks or processes the results from the - * other low-level exec methods like execMapCommand. - *

- *

- * See the main p4 export command documentation for full semantics and usage - * details. - *

- *

- * Note that the 'skip*' options in ExportRecordsOptions are specific to - * P4Java only; they are not Perforce command options. These options are for - * field handling rules in the lower layers of P4Java. The field rules are - * for identifying the fields that should skip charset translation of their - * values; leaving their values as bytes instead of converting them to - * strings. Please see ExportRecordsOptions for usage details. - * - * @param opts ExportRecordsOptions object describing optional parameters; if null, no - * options are set. - * @param callback a non-null IStreamingCallback to be used to process the incoming results. - * @param key an opaque integer key that is passed to the IStreamingCallback callback - * methods to identify the action as being associated with this specific call. - * @throws P4JavaException if an error occurs processing this method and its parameters. - * @since 2012.3 - */ - void getStreamingExportRecords( - ExportRecordsOptions opts, - @Nonnull IStreamingCallback callback, - int key) throws P4JavaException; + /** + * Get each exported journal or checkpoint record (admin / superuser + * command) as it comes in from the server, rather than waiting for the + * entire command to complete. + *

+ * The results are sent to the user using the IStreamingCallback + * handleResult method; see the IStreamingCallback Javadoc for details. The + * payload passed to handleResult is usually the raw map gathered together + * deep in the RPC protocol layer, and the user is assumed to have the + * knowledge and technology to be able to parse it and use it suitably in + * much the same way as a user unpacks or processes the results from the + * other low-level exec methods like execMapCommand. + *

+ * See the main p4 export command documentation for full semantics and usage + * details. + *

+ * Note that the 'skip*' options in ExportRecordsOptions are specific to + * P4Java only; they are not Perforce command options. These options are for + * field handling rules in the lower layers of P4Java. The field rules are + * for identifying the fields that should skip charset translation of their + * values; leaving their values as bytes instead of converting them to + * strings. Please see ExportRecordsOptions for usage details. + * + * @param opts ExportRecordsOptions object describing optional parameters; if null, no + * options are set. + * @param callback a non-null IStreamingCallback to be used to process the incoming results. + * @param key an opaque integer key that is passed to the IStreamingCallback callback + * methods to identify the action as being associated with this specific call. + * @throws P4JavaException if an error occurs processing this method and its parameters. + * @since 2012.3 + */ + void getStreamingExportRecords( + ExportRecordsOptions opts, + @Nonnull IStreamingCallback callback, + int key) throws P4JavaException; } diff --git a/src/main/java/com/perforce/p4java/server/delegator/IExtensionDelegator.java b/src/main/java/com/perforce/p4java/server/delegator/IExtensionDelegator.java index af7ec16..a9f218d 100644 --- a/src/main/java/com/perforce/p4java/server/delegator/IExtensionDelegator.java +++ b/src/main/java/com/perforce/p4java/server/delegator/IExtensionDelegator.java @@ -7,7 +7,6 @@ import javax.annotation.Nullable; import java.util.List; -import java.util.Map; public interface IExtensionDelegator { /** @@ -30,12 +29,13 @@ public interface IExtensionDelegator { /** - * Creates sample extension with the given name. As a result a folder will be created with main.lua + * Creates sample extension with the given name. As a result a folder extnName will be created with main.lua * and manifest.json in it. * command: extension [ --sample name ] * * @param extnName - name of the extension - * @throws P4JavaException + * @return result + * @throws P4JavaException on error */ String sampleExtension(String extnName) throws P4JavaException; @@ -44,7 +44,8 @@ public interface IExtensionDelegator { * command: extension [ --package dir ] * * @param dirName - Directory name containing main.lua and manifest.json for the extension - * @throws P4JavaException + * @return result + * @throws P4JavaException on error */ String packageExtension(String dirName) throws P4JavaException; @@ -53,7 +54,9 @@ public interface IExtensionDelegator { * command: extension [ --install file [--yes] [--cert] [--allow-unsigned] ] * * @param extnPackageName - Name of the extension package file. For ex. p4java-obliterate-extn.p4-extension - * @throws P4JavaException + * @param allowUnsigned if true + * @return extension summary + * @throws P4JavaException on error */ ExtensionSummary installExtension(String extnPackageName, boolean allowUnsigned) throws P4JavaException; @@ -61,22 +64,22 @@ public interface IExtensionDelegator { /** * Creates/updates an extension's global/instance config. * - * @param extension - * @param namespace + * @param extension extension + * @param namespace name space * @param instanceConfig - If provided, creates/updates this instance config. - * @return - * @throws P4JavaException + * @return result + * @throws P4JavaException on error */ String createExtensionConfig(IExtension extension, String namespace, @Nullable String instanceConfig) throws P4JavaException; /** * Updates an extension's global/instance config. * - * @param extension - * @param namespace + * @param extension extension + * @param namespace name space * @param instanceConfig - If provided updates this instance config. - * @return - * @throws P4JavaException + * @return result + * @throws P4JavaException on error */ String updateExtensionConfig(IExtension extension, String namespace, @Nullable String instanceConfig) throws P4JavaException; @@ -84,29 +87,29 @@ public interface IExtensionDelegator { * Lists extensions or configs based on type. * * @param type - Can be "extensions" or "configs" - * @return - * @throws P4JavaException + * @return list of extensions + * @throws P4JavaException on error */ List listExtensions(String type) throws P4JavaException; /** * Deletes an extension along with all of its configuration. * - * @param namespace - * @param extnName - * @return - * @throws P4JavaException + * @param namespace name space + * @param extnName extension name + * @return result + * @throws P4JavaException on error */ String deleteExtension(String namespace, String extnName) throws P4JavaException; /** * Retrieves an extension/config. * - * @param namespace - * @param name + * @param namespace name space + * @param name extension name * @param instanceName Optional, only required for instance config - * @return - * @throws P4JavaException + * @return extension config + * @throws P4JavaException on error */ Extension getExtensionConfig(String namespace, String name, @Nullable String instanceName) throws P4JavaException; } diff --git a/src/main/java/com/perforce/p4java/server/delegator/IFileLogDelegator.java b/src/main/java/com/perforce/p4java/server/delegator/IFileLogDelegator.java index 0b42335..382ad5d 100644 --- a/src/main/java/com/perforce/p4java/server/delegator/IFileLogDelegator.java +++ b/src/main/java/com/perforce/p4java/server/delegator/IFileLogDelegator.java @@ -1,8 +1,5 @@ package com.perforce.p4java.server.delegator; -import java.util.List; -import java.util.Map; - import com.perforce.p4java.core.file.IFileRevisionData; import com.perforce.p4java.core.file.IFileSpec; import com.perforce.p4java.exception.AccessException; @@ -10,47 +7,53 @@ import com.perforce.p4java.exception.P4JavaException; import com.perforce.p4java.option.server.GetRevisionHistoryOptions; +import java.util.List; +import java.util.Map; + /** * Interface for FileLogDelegator implementations. */ public interface IFileLogDelegator { - /** - * Get the revision history data for one or more Perforce files. - * - * @param fileSpecs fileSpecs to be processed; if null or empty, an empty Map is - * returned. - * @param maxRevs If positive, displays at most 'maxRevs' revisions per file of the - * file[rev] argument specified. Corresponds to -m. - * @param contentHistory If true, display file content history instead of file name - * history. Corresponds to -h. - * @param includeInherited If true, causes inherited file history to be displayed as well. - * Corresponds to -i. - * @param longOutput If true, produces long output with the full text of the changelist - * descriptions. Corresponds to -l. - * @param truncatedLongOutput If true, produces long output with the full text of the changelist - * descriptions truncated to 250 characters. Corresponds to -L. - */ - Map> getRevisionHistory( - List fileSpecs, - int maxRevs, - boolean contentHistory, - boolean includeInherited, - boolean longOutput, - boolean truncatedLongOutput) throws ConnectionException, AccessException; + /** + * Get the revision history data for one or more Perforce files. + * + * @param fileSpecs fileSpecs to be processed; if null or empty, an empty Map is + * returned. + * @param maxRevs If positive, displays at most 'maxRevs' revisions per file of the + * file[rev] argument specified. Corresponds to -m. + * @param contentHistory If true, display file content history instead of file name + * history. Corresponds to -h. + * @param includeInherited If true, causes inherited file history to be displayed as well. + * Corresponds to -i. + * @param longOutput If true, produces long output with the full text of the changelist + * descriptions. Corresponds to -l. + * @param truncatedLongOutput If true, produces long output with the full text of the changelist + * descriptions truncated to 250 characters. Corresponds to -L. + * @return map spec revision data + * @throws ConnectionException on error + * @throws AccessException on error + */ + Map> getRevisionHistory( + List fileSpecs, + int maxRevs, + boolean contentHistory, + boolean includeInherited, + boolean longOutput, + boolean truncatedLongOutput) throws ConnectionException, AccessException; - /** - * Get the revision history data for one or more Perforce files. - *

- * - * @param fileSpecs fileSpecs to be processed; if null or empty, an empty Map is returned. - * @param opts GetRevisionHistoryOptions object describing optional parameters; if null, no - * options are set. - * @return a non-null map of lists of revision data for qualifying files; the map is keyed by - * the IFileSpec of the associated file, meaning that errors are signaled using the normal - * IFileSpec getOpStatus() method. - * @throws P4JavaException if any error occurs in the processing of this method. - */ - Map> getRevisionHistory( - List fileSpecs, - GetRevisionHistoryOptions opts) throws P4JavaException; + /** + * Get the revision history data for one or more Perforce files. + *

+ * + * @param fileSpecs fileSpecs to be processed; if null or empty, an empty Map is returned. + * @param opts GetRevisionHistoryOptions object describing optional parameters; if null, no + * options are set. + * @return a non-null map of lists of revision data for qualifying files; the map is keyed by + * the IFileSpec of the associated file, meaning that errors are signaled using the normal + * IFileSpec getOpStatus() method. + * @throws P4JavaException if any error occurs in the processing of this method. + */ + Map> getRevisionHistory( + List fileSpecs, + GetRevisionHistoryOptions opts) throws P4JavaException; } diff --git a/src/main/java/com/perforce/p4java/server/delegator/ILabelDelegator.java b/src/main/java/com/perforce/p4java/server/delegator/ILabelDelegator.java index f005080..71850c0 100644 --- a/src/main/java/com/perforce/p4java/server/delegator/ILabelDelegator.java +++ b/src/main/java/com/perforce/p4java/server/delegator/ILabelDelegator.java @@ -16,7 +16,6 @@ public interface ILabelDelegator { /** * Get a specific named Perforce label. *

- *

* Unlike the getLabelList method, the getViewMapping method on the returned * label will be valid. Note though that changes to the returned label or * its view will not be reflected on to the server unless the updateLabel diff --git a/src/main/java/com/perforce/p4java/server/delegator/ILabelsDelegator.java b/src/main/java/com/perforce/p4java/server/delegator/ILabelsDelegator.java index 8ca8e3e..44ba573 100644 --- a/src/main/java/com/perforce/p4java/server/delegator/ILabelsDelegator.java +++ b/src/main/java/com/perforce/p4java/server/delegator/ILabelsDelegator.java @@ -1,7 +1,5 @@ package com.perforce.p4java.server.delegator; -import java.util.List; - import com.perforce.p4java.core.ILabelSummary; import com.perforce.p4java.core.file.IFileSpec; import com.perforce.p4java.exception.AccessException; @@ -10,53 +8,48 @@ import com.perforce.p4java.exception.RequestException; import com.perforce.p4java.option.server.GetLabelsOptions; +import java.util.List; + /** * Interface to handle the Labels command. */ public interface ILabelsDelegator { - /** - * Get a list of Perforce labels, optionally tied to a specific set of - * files. - *

- *

- * Note that the ILabel objects returned here do not have views associated - * with them (i.e. the getViewMapping() method will return an empty list. If - * you need to get the view mapping for a specific label, use the getLabel() - * method. - * - * @param user if non-null, limit labels to those owned by the named user - * @param maxLabels if larger than zero, return only the first maxLabels (or - * fewer) qualifying labels - * @param nameFilter if not null, limits output to labels whose name matches the - * nameFilter pattern, e.g. -e 'svr-dev-rel*' - * @param fileList if not null, limits its report to labels that contain those - * files - * @return non-null (but possibly-empty) list of qualifying Perforce labels - * @throws ConnectionException if the Perforce server is unreachable or is not connected. - * @throws RequestException if the Perforce server encounters an error during its - * processing of the request - * @throws AccessException if the Perforce server denies access to the caller - */ - List getLabels( - String user, - int maxLabels, - String nameFilter, - List fileList) throws ConnectionException, RequestException, AccessException; + /** + * Get a list of Perforce labels, optionally tied to a specific set of + * files. + *

+ * Note that the ILabel objects returned here do not have views associated + * with them (i.e. the getViewMapping() method will return an empty list. If + * you need to get the view mapping for a specific label, use the getLabel() + * method. + * + * @param user if non-null, limit labels to those owned by the named user + * @param maxLabels if larger than zero, return only the first maxLabels (or + * fewer) qualifying labels + * @param nameFilter if not null, limits output to labels whose name matches the + * nameFilter pattern, e.g. -e 'svr-dev-rel*' + * @param fileList if not null, limits its report to labels that contain those + * files + * @return non-null (but possibly-empty) list of qualifying Perforce labels + * @throws ConnectionException if the Perforce server is unreachable or is not connected. + * @throws RequestException if the Perforce server encounters an error during its + * processing of the request + * @throws AccessException if the Perforce server denies access to the caller + */ + List getLabels(String user, int maxLabels, String nameFilter, List fileList) throws ConnectionException, RequestException, AccessException; - /** - * Get a list of Perforce labels, optionally tied to a specific set of files.

- *

- * Note that the ILabel objects returned here do not have views associated with - * them (i.e. the getViewMapping() method will return an empty list. If you need - * to get the view mapping for a specific label, use the getLabel() method. - * - * @param fileList if not null, limits its report to labels that contain those files - * @param opts GetLabelsOptions object describing optional parameters; if null, no options are - * set. - * @return non-null (but possibly-empty) list of qualifying Perforce labels - * @throws P4JavaException if any error occurs in the processing of this method. - */ - List getLabels( - List fileList, - GetLabelsOptions opts) throws P4JavaException; + /** + * Get a list of Perforce labels, optionally tied to a specific set of files. + *

+ * Note that the ILabel objects returned here do not have views associated with + * them (i.e. the getViewMapping() method will return an empty list. If you need + * to get the view mapping for a specific label, use the getLabel() method. + * + * @param fileList if not null, limits its report to labels that contain those files + * @param opts GetLabelsOptions object describing optional parameters; if null, no options are + * set. + * @return non-null (but possibly-empty) list of qualifying Perforce labels + * @throws P4JavaException if any error occurs in the processing of this method. + */ + List getLabels(List fileList, GetLabelsOptions opts) throws P4JavaException; } diff --git a/src/main/java/com/perforce/p4java/server/delegator/IMoveDelegator.java b/src/main/java/com/perforce/p4java/server/delegator/IMoveDelegator.java index 0c56df4..7ba8c90 100644 --- a/src/main/java/com/perforce/p4java/server/delegator/IMoveDelegator.java +++ b/src/main/java/com/perforce/p4java/server/delegator/IMoveDelegator.java @@ -1,9 +1,5 @@ package com.perforce.p4java.server.delegator; -import java.util.List; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import com.perforce.p4java.core.file.IFileSpec; import com.perforce.p4java.exception.AccessException; import com.perforce.p4java.exception.ConnectionException; @@ -11,88 +7,88 @@ import com.perforce.p4java.exception.RequestException; import com.perforce.p4java.option.server.MoveFileOptions; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.List; + /** * Interface to handle the Move command. */ public interface IMoveDelegator { - /** - * Move a file already opened for edit or add (the fromFile) to the - * destination file (the toFile). A file can be moved many times before it - * is submitted; moving it back to its original location will reopen it for - * edit. The full semantics of this operation (which can be confusing) are - * found in the main 'p4 help' documentation. - *

- *

- * Note that this operation is not supported on servers earlier than 2009.1; - * any attempt to use this on earlier servers will result in a - * RequestException with a suitable message. Similarly, not all underlying - * IServer implementations will work with this either, and will also result - * in a suitable RequestException. - *

- *

- * Note also that the move command is special in that almost alone among - * Perforce file-based commands, it does not allow full filespecs with - * version specifiers; these are currently quietly stripped off in the move - * command implementation here, which may lead to unexpected behaviour if - * you pass in specific versions expecting them to be honoured. - * - * @param changelistId if not IChangelist.UNKNOWN, the files are opened in the - * numbered pending changelist instead of the 'default' - * changelist. - * @param listOnly if true, don't actually perform the move, just return what - * would happen if the move was performed - * @param noClientMove if true, bypasses the client file rename. This option can be - * used to tell the server that the user has already renamed a - * file on the client. The use of this option can confuse the - * server if you are wrong about the client's contents. Only - * works for 2009.2 and later servers; earlier servers will - * produce a RequestException if you set this true. - * @param fileType if not null, the file is reopened as that filetype. - * @param fromFile the original file; must be already open for edit. - * @param toFile the target file. - * @return list of IFileSpec objects representing the results of this move - * @throws ConnectionException if the Perforce server is unreachable or is not connected. - * @throws RequestException if the Perforce server encounters an error during its - * processing of the request - * @throws AccessException if the Perforce server denies access to the caller - */ - List moveFile( - int changelistId, - boolean listOnly, - boolean noClientMove, - String fileType, - @Nonnull IFileSpec fromFile, - @Nonnull IFileSpec toFile) - throws ConnectionException, RequestException, AccessException; + /** + * Move a file already opened for edit or add (the fromFile) to the + * destination file (the toFile). A file can be moved many times before it + * is submitted; moving it back to its original location will reopen it for + * edit. The full semantics of this operation (which can be confusing) are + * found in the main 'p4 help' documentation. + *

+ * Note that this operation is not supported on servers earlier than 2009.1; + * any attempt to use this on earlier servers will result in a + * RequestException with a suitable message. Similarly, not all underlying + * IServer implementations will work with this either, and will also result + * in a suitable RequestException. + *

+ * Note also that the move command is special in that almost alone among + * Perforce file-based commands, it does not allow full filespecs with + * version specifiers; these are currently quietly stripped off in the move + * command implementation here, which may lead to unexpected behaviour if + * you pass in specific versions expecting them to be honoured. + * + * @param changelistId if not IChangelist.UNKNOWN, the files are opened in the + * numbered pending changelist instead of the 'default' + * changelist. + * @param listOnly if true, don't actually perform the move, just return what + * would happen if the move was performed + * @param noClientMove if true, bypasses the client file rename. This option can be + * used to tell the server that the user has already renamed a + * file on the client. The use of this option can confuse the + * server if you are wrong about the client's contents. Only + * works for 2009.2 and later servers; earlier servers will + * produce a RequestException if you set this true. + * @param fileType if not null, the file is reopened as that filetype. + * @param fromFile the original file; must be already open for edit. + * @param toFile the target file. + * @return list of IFileSpec objects representing the results of this move + * @throws ConnectionException if the Perforce server is unreachable or is not connected. + * @throws RequestException if the Perforce server encounters an error during its + * processing of the request + * @throws AccessException if the Perforce server denies access to the caller + */ + List moveFile( + int changelistId, + boolean listOnly, + boolean noClientMove, + String fileType, + @Nonnull IFileSpec fromFile, + @Nonnull IFileSpec toFile) + throws ConnectionException, RequestException, AccessException; - /** - * Move a file already opened for edit or add (the fromFile) to the - * destination file (the toFile). A file can be moved many times before it - * is submitted; moving it back to its original location will reopen it for - * edit. The full semantics of this operation (which can be confusing) are - * found in the main 'p4 help' documentation. - *

- *

- * Note that this operation is not supported on servers earlier than 2009.1; - * any attempt to use this on earlier servers will result in a - * RequestException with a suitable message. - *

- *

- * Note also that the move command is special in that almost alone among - * Perforce file-based commands, it does not allow full filespecs with - * version specifiers; these are currently quietly stripped off in the move - * command implementation here, which may lead to unexpected behaviour if - * you pass in specific versions expecting them to be honoured. - * - * @param fromFile the original file; must be already open for edit. - * @param toFile the target file. - * @param opts MoveFileOptions object describing optional parameters; if - * null, no options are set. - * @return list of IFileSpec objects representing the results of this move. - * @throws P4JavaException if any error occurs in the processing of this method. - */ - List moveFile( - @Nonnull IFileSpec fromFile, - @Nonnull IFileSpec toFile, - @Nullable MoveFileOptions opts) throws P4JavaException; + /** + * Move a file already opened for edit or add (the fromFile) to the + * destination file (the toFile). A file can be moved many times before it + * is submitted; moving it back to its original location will reopen it for + * edit. The full semantics of this operation (which can be confusing) are + * found in the main 'p4 help' documentation. + *

+ * Note that this operation is not supported on servers earlier than 2009.1; + * any attempt to use this on earlier servers will result in a + * RequestException with a suitable message. + *

+ * Note also that the move command is special in that almost alone among + * Perforce file-based commands, it does not allow full filespecs with + * version specifiers; these are currently quietly stripped off in the move + * command implementation here, which may lead to unexpected behaviour if + * you pass in specific versions expecting them to be honoured. + * + * @param fromFile the original file; must be already open for edit. + * @param toFile the target file. + * @param opts MoveFileOptions object describing optional parameters; if + * null, no options are set. + * @return list of IFileSpec objects representing the results of this move. + * @throws P4JavaException if any error occurs in the processing of this method. + */ + List moveFile( + @Nonnull IFileSpec fromFile, + @Nonnull IFileSpec toFile, + @Nullable MoveFileOptions opts) throws P4JavaException; } diff --git a/src/main/java/com/perforce/p4java/server/delegator/IObliterateDelegator.java b/src/main/java/com/perforce/p4java/server/delegator/IObliterateDelegator.java index d177b4f..9db9bd7 100644 --- a/src/main/java/com/perforce/p4java/server/delegator/IObliterateDelegator.java +++ b/src/main/java/com/perforce/p4java/server/delegator/IObliterateDelegator.java @@ -1,52 +1,48 @@ package com.perforce.p4java.server.delegator; -import java.util.List; -import javax.annotation.Nonnull; - import com.perforce.p4java.core.file.IFileSpec; import com.perforce.p4java.core.file.IObliterateResult; import com.perforce.p4java.exception.P4JavaException; import com.perforce.p4java.option.server.ObliterateFilesOptions; +import javax.annotation.Nonnull; +import java.util.List; + /** * Interface to handle the Obliterate command. */ public interface IObliterateDelegator { - /** - * Obliterate permanently remove files and their history from the server. - *

- *

- * Obliterate retrieves the disk space used by the obliterated files in the - * archive and clears the files from the metadata that is maintained by the - * server. Files in client workspaces are not physically affected, but they - * are no longer under Perforce control. - *

- *

- * By default, obliterate displays a preview of the results. To execute the - * operation, you must specify the -y flag (opts.executeObliterate). - * Obliterate requires 'admin' access, which is granted by 'p4 protect'. - *

- *

- * The "obliterate" command returns an IObliterateResult for each file - * passed into the command. Each IObliterateResult object contains a summary - * of various types of records deleted (or added) and a non-null list of - * returned filespecs have the equivalent of purgeFile and purgeRev output - * in the depotPath and endRevision fileds of the associated filespecs, and - * that no other file spec fields are valid. Sometimes, the server doesn't - * return any "purgeFile" and "purgeRev" values. - *

- *

- * Note: error and info messages are stored in filespec objects. - *

- * - * @param fileSpecs non-null list of files to be obliterated - * @param opts possibly-null ObliterateFilesOptions object specifying method - * options. - * @return a non-null list of IObliterateResult objects containing the - * records purged. - * @throws P4JavaException if an error occurs processing this method and its parameters - * @since 2011.2 - */ - List obliterateFiles(@Nonnull List fileSpecs, - ObliterateFilesOptions opts) throws P4JavaException; + /** + * Obliterate permanently remove files and their history from the server. + *

+ * Obliterate retrieves the disk space used by the obliterated files in the + * archive and clears the files from the metadata that is maintained by the + * server. Files in client workspaces are not physically affected, but they + * are no longer under Perforce control. + *

+ * By default, obliterate displays a preview of the results. To execute the + * operation, you must specify the -y flag (opts.executeObliterate). + * Obliterate requires 'admin' access, which is granted by 'p4 protect'. + *

+ * The "obliterate" command returns an IObliterateResult for each file + * passed into the command. Each IObliterateResult object contains a summary + * of various types of records deleted (or added) and a non-null list of + * returned filespecs have the equivalent of purgeFile and purgeRev output + * in the depotPath and endRevision fileds of the associated filespecs, and + * that no other file spec fields are valid. Sometimes, the server doesn't + * return any "purgeFile" and "purgeRev" values. + *

+ * Note: error and info messages are stored in filespec objects. + *

+ * + * @param fileSpecs non-null list of files to be obliterated + * @param opts possibly-null ObliterateFilesOptions object specifying method + * options. + * @return a non-null list of IObliterateResult objects containing the + * records purged. + * @throws P4JavaException if an error occurs processing this method and its parameters + * @since 2011.2 + */ + List obliterateFiles(@Nonnull List fileSpecs, + ObliterateFilesOptions opts) throws P4JavaException; } diff --git a/src/main/java/com/perforce/p4java/server/delegator/IPasswdDelegator.java b/src/main/java/com/perforce/p4java/server/delegator/IPasswdDelegator.java index 283b943..2c66233 100644 --- a/src/main/java/com/perforce/p4java/server/delegator/IPasswdDelegator.java +++ b/src/main/java/com/perforce/p4java/server/delegator/IPasswdDelegator.java @@ -6,28 +6,28 @@ * Implementation to handle the Passwd command. */ public interface IPasswdDelegator { - /** - * Change a user's password on the server. After a password is changed for a - * user, the user must login again with the new password. Specifying a - * username as an argument to this command requires 'super' access granted - * by 'p4 protect' - *

- *

- * Note: setting the 'newPassword' to null or empty will delete the - * password. - * - * @param oldPassword possibly-null or possibly-empty user's old password. If null - * or empty, it assumes the current password is not set. - * @param newPassword non-null and non-empty user's new password. - * @param userName possibly-null possibly-null name of the target user whose - * password will be changed to the new password. If null, the - * current user will be used. If non-null, this command requires - * 'super' access granted by 'p4 protect'. - * @throws P4JavaException if any error occurs in the processing of this method. - * @since 2011.2 - */ - String changePassword( - String oldPassword, - String newPassword, - String userName) throws P4JavaException; + /** + * Change a user's password on the server. After a password is changed for a + * user, the user must login again with the new password. Specifying a + * username as an argument to this command requires 'super' access granted + * by 'p4 protect' + *

+ * Note: setting the 'newPassword' to null or empty will delete the + * password. + * + * @param oldPassword possibly-null or possibly-empty user's old password. If null + * or empty, it assumes the current password is not set. + * @param newPassword non-null and non-empty user's new password. + * @param userName possibly-null possibly-null name of the target user whose + * password will be changed to the new password. If null, the + * current user will be used. If non-null, this command requires + * 'super' access granted by 'p4 protect'. + * @return result + * @throws P4JavaException if any error occurs in the processing of this method. + * @since 2011.2 + */ + String changePassword( + String oldPassword, + String newPassword, + String userName) throws P4JavaException; } diff --git a/src/main/java/com/perforce/p4java/server/delegator/IPrintDelegator.java b/src/main/java/com/perforce/p4java/server/delegator/IPrintDelegator.java index 2d365e9..c2c4ad7 100644 --- a/src/main/java/com/perforce/p4java/server/delegator/IPrintDelegator.java +++ b/src/main/java/com/perforce/p4java/server/delegator/IPrintDelegator.java @@ -1,8 +1,5 @@ package com.perforce.p4java.server.delegator; -import java.io.InputStream; -import java.util.List; - import com.perforce.p4java.core.file.IFileSpec; import com.perforce.p4java.exception.AccessException; import com.perforce.p4java.exception.ConnectionException; @@ -10,44 +7,47 @@ import com.perforce.p4java.exception.RequestException; import com.perforce.p4java.option.server.GetFileContentsOptions; +import java.io.InputStream; +import java.util.List; + /** * Interface to handle the Print command. */ public interface IPrintDelegator { - InputStream getFileContents( - List fileSpecs, - boolean allRevs, - boolean noHeaderLine) throws ConnectionException, RequestException, AccessException; + InputStream getFileContents( + List fileSpecs, + boolean allRevs, + boolean noHeaderLine) throws ConnectionException, RequestException, AccessException; - /** - * Return an InputStream onto the contents of one or more revisions of one or more Perforce depot - * file contents.

- *

- * If file is specified as a Perforce client workspace file name, the client view is used to find - * the corresponding depot file. If a file argument has a revision, then all files as of that - * revision are streamed. If a file argument has a revision range, then only files selected by - * that revision range are streamed, and the highest revision in the range is used for each file. - * Normally, only the head revision is printed.

- *

- * The underlying input stream is not guaranteed to support mark() and skip() operations, and in - * some cases can be absolutely ginormously long it is also not guaranteed to be printable, and - * will be in the charset encoding stored in the Perforce server.

- *

- * You should close the InputStreamReader after use in order to release any underlying - * stream-related resources. Failure to do this may lead to the proliferation of temp files or - * long-term memory wastage or even leaks.

- *

- * Note that unlike the corresponding command-line command, which keeps going in the face of - * errors by moving on to the next file (or whatever), any errors encountered in this method will - * cause an exception from this method at the first error, so plan accordingly.... - * - * @param fileSpecs non-null list of depot or client file specs defining files to be streamed - * @param opts GetFileContentsOptions object describing optional parameters; if null, no - * options are set. - * @return a non-null but possibly-empty InputStream onto the file / revision contents. - * @throws P4JavaException if any error occurs in the processing of this method. - */ - InputStream getFileContents( - List fileSpecs, - GetFileContentsOptions opts) throws P4JavaException; + /** + * Return an InputStream onto the contents of one or more revisions of one or more Perforce depot + * file contents. + *

+ * If file is specified as a Perforce client workspace file name, the client view is used to find + * the corresponding depot file. If a file argument has a revision, then all files as of that + * revision are streamed. If a file argument has a revision range, then only files selected by + * that revision range are streamed, and the highest revision in the range is used for each file. + * Normally, only the head revision is printed. + *

+ * The underlying input stream is not guaranteed to support mark() and skip() operations, and in + * some cases can be absolutely ginormously long it is also not guaranteed to be printable, and + * will be in the charset encoding stored in the Perforce server. + *

+ * You should close the InputStreamReader after use in order to release any underlying + * stream-related resources. Failure to do this may lead to the proliferation of temp files or + * long-term memory wastage or even leaks. + *

+ * Note that unlike the corresponding command-line command, which keeps going in the face of + * errors by moving on to the next file (or whatever), any errors encountered in this method will + * cause an exception from this method at the first error, so plan accordingly.... + * + * @param fileSpecs non-null list of depot or client file specs defining files to be streamed + * @param opts GetFileContentsOptions object describing optional parameters; if null, no + * options are set. + * @return a non-null but possibly-empty InputStream onto the file / revision contents. + * @throws P4JavaException if any error occurs in the processing of this method. + */ + InputStream getFileContents( + List fileSpecs, + GetFileContentsOptions opts) throws P4JavaException; } diff --git a/src/main/java/com/perforce/p4java/server/delegator/IPropertyDelegator.java b/src/main/java/com/perforce/p4java/server/delegator/IPropertyDelegator.java index 45e30f3..4b9d20e 100644 --- a/src/main/java/com/perforce/p4java/server/delegator/IPropertyDelegator.java +++ b/src/main/java/com/perforce/p4java/server/delegator/IPropertyDelegator.java @@ -1,69 +1,65 @@ package com.perforce.p4java.server.delegator; -import java.util.List; - import com.perforce.p4java.admin.IProperty; import com.perforce.p4java.exception.P4JavaException; import com.perforce.p4java.option.server.GetPropertyOptions; import com.perforce.p4java.option.server.PropertyOptions; +import java.util.List; + /** * Interface to handle the Property command. */ public interface IPropertyDelegator { - /** - * Updates a property value in the Perforce server, or adds the property - * value to the Perforce server if it is not yet there. - *

- *

- * This method require that the user have 'admin' access granted by 'p4 - * protect'. - * - * @param name non-null property name. - * @param value property value. - * @param opts PropertyOptions object describing optional parameters; if - * null, no options are set. - * @return non-null result message string from the set (add/update) - * operation. - * @throws P4JavaException if an error occurs processing this method and its parameters. - * @since 2013.1 - */ - String setProperty(String name, String value, PropertyOptions opts) - throws P4JavaException; + /** + * Updates a property value in the Perforce server, or adds the property + * value to the Perforce server if it is not yet there. + *

+ * This method require that the user have 'admin' access granted by 'p4 + * protect'. + * + * @param name non-null property name. + * @param value property value. + * @param opts PropertyOptions object describing optional parameters; if + * null, no options are set. + * @return non-null result message string from the set (add/update) + * operation. + * @throws P4JavaException if an error occurs processing this method and its parameters. + * @since 2013.1 + */ + String setProperty(String name, String value, PropertyOptions opts) + throws P4JavaException; - /** - * Gets a list of one or more property values from the Perforce server. - *

- *

- * The -A flag require that the user have 'admin' access granted by 'p4 - * protect'. - *

- *

- * Note that specifying the -n flag when using the -l flag substantially - * improves the performance of this command. - * - * @param opts GetPropertyOptions object describing optional parameters; if - * null, no options are set. - * @return a non-null (but possibly empty) list of property values. - * @throws P4JavaException if an error occurs processing this method and its parameters. - * @since 2013.1 - */ - List getProperty(GetPropertyOptions opts) throws P4JavaException; + /** + * Gets a list of one or more property values from the Perforce server. + *

+ * The -A flag require that the user have 'admin' access granted by 'p4 + * protect'. + *

+ * Note that specifying the -n flag when using the -l flag substantially + * improves the performance of this command. + * + * @param opts GetPropertyOptions object describing optional parameters; if + * null, no options are set. + * @return a non-null (but possibly empty) list of property values. + * @throws P4JavaException if an error occurs processing this method and its parameters. + * @since 2013.1 + */ + List getProperty(GetPropertyOptions opts) throws P4JavaException; - /** - * Deletes a property value from the Perforce server. - *

- *

- * This method require that the user have 'admin' access granted by 'p4 - * protect'. - * - * @param name non-null property name. - * @param opts PropertyOptions object describing optional parameters; if - * null, no options are set. - * @return non-null result message string from the delete operation. - * @throws P4JavaException if an error occurs processing this method and its parameters. - * @since 2013.1 - */ - String deleteProperty(String name, PropertyOptions opts) - throws P4JavaException; + /** + * Deletes a property value from the Perforce server. + *

+ * This method require that the user have 'admin' access granted by 'p4 + * protect'. + * + * @param name non-null property name. + * @param opts PropertyOptions object describing optional parameters; if + * null, no options are set. + * @return non-null result message string from the delete operation. + * @throws P4JavaException if an error occurs processing this method and its parameters. + * @since 2013.1 + */ + String deleteProperty(String name, PropertyOptions opts) + throws P4JavaException; } diff --git a/src/main/java/com/perforce/p4java/server/delegator/IProtectDelegator.java b/src/main/java/com/perforce/p4java/server/delegator/IProtectDelegator.java index c28355b..9b2978d 100644 --- a/src/main/java/com/perforce/p4java/server/delegator/IProtectDelegator.java +++ b/src/main/java/com/perforce/p4java/server/delegator/IProtectDelegator.java @@ -15,7 +15,6 @@ public interface IProtectDelegator { * Create or replace the protections table data on the Perforce server with * these new protection entries. *

- *

* Each entry in the table contains a protection mode, a group/user * indicator, the group/user name, client host ID and a depot file path * pattern. Users receive the highest privilege that is granted on any @@ -35,13 +34,11 @@ String createProtectionEntries(@Nonnull List entryList) * Replace the protections table data on the Perforce server with these new * protection entries. *

- *

* Each entry in the table contains a protection mode, a group/user * indicator, the group/user name, client host ID and a depot file path * pattern. Users receive the highest privilege that is granted on any * entry. *

- *

* Warning: this will overwrite the existing protections table data. * * @param entryList non-null list of protection entries. diff --git a/src/main/java/com/perforce/p4java/server/delegator/IProtectsDelegator.java b/src/main/java/com/perforce/p4java/server/delegator/IProtectsDelegator.java index fcd0792..869cd3b 100644 --- a/src/main/java/com/perforce/p4java/server/delegator/IProtectsDelegator.java +++ b/src/main/java/com/perforce/p4java/server/delegator/IProtectsDelegator.java @@ -1,7 +1,5 @@ package com.perforce.p4java.server.delegator; -import java.util.List; - import com.perforce.p4java.admin.IProtectionEntry; import com.perforce.p4java.core.file.IFileSpec; import com.perforce.p4java.exception.AccessException; @@ -10,63 +8,63 @@ import com.perforce.p4java.exception.RequestException; import com.perforce.p4java.option.server.GetProtectionEntriesOptions; +import java.util.List; + /** * Interface to handle the Protects command. */ public interface IProtectsDelegator { - /** - * Get a list of Perforce protection entries for the passed-in arguments. - *

- *

- * Note that the behavior of this method is unspecified when using clashing - * options (e.g. having both userName and groupName set non-null). Consult - * the main Perforce admin documentation for semantics and usage. - *

- *

- * Note that the annotations in the file paths will be dropped. The reason - * is the Perforce server 'protects' command requires a file list devoid of - * annotated revision specificity. - * - * @param allUsers if true, protection lines for all users are displayed. - * @param hostName only protection entries that apply to the given host (IP - * address) are displayed. - * @param userName protection lines Perforce user "userName" are displayed. - * @param groupName protection lines for Perforce group "groupName" are displayed. - * @param fileList if non-null, only those protection entries that apply to the - * specified files are displayed. - * @return non-null but possibly empty list of protection entries. - * @throws ConnectionException if the Perforce server is unreachable or is not connected. - * @throws RequestException if the Perforce server encounters an error during its - * processing of the request. - * @throws AccessException if the Perforce server denies access to the caller. - */ - List getProtectionEntries( - boolean allUsers, - String hostName, - String userName, - String groupName, - List fileList) - throws ConnectionException, RequestException, AccessException; + /** + * Get a list of Perforce protection entries for the passed-in arguments. + *

+ * Note that the behavior of this method is unspecified when using clashing + * options (e.g. having both userName and groupName set non-null). Consult + * the main Perforce admin documentation for semantics and usage. + *

+ * Note that the annotations in the file paths will be dropped. The reason + * is the Perforce server 'protects' command requires a file list devoid of + * annotated revision specificity. + * + * @param allUsers if true, protection lines for all users are displayed. + * @param hostName only protection entries that apply to the given host (IP + * address) are displayed. + * @param userName protection lines Perforce user "userName" are displayed. + * @param groupName protection lines for Perforce group "groupName" are displayed. + * @param fileList if non-null, only those protection entries that apply to the + * specified files are displayed. + * @return non-null but possibly empty list of protection entries. + * @throws ConnectionException if the Perforce server is unreachable or is not connected. + * @throws RequestException if the Perforce server encounters an error during its + * processing of the request. + * @throws AccessException if the Perforce server denies access to the caller. + */ + List getProtectionEntries( + boolean allUsers, + String hostName, + String userName, + String groupName, + List fileList) + throws ConnectionException, RequestException, AccessException; - /** - * Get a list of Perforce protection entries for the passed-in arguments.

- *

- * Note that the behavior of this method is unspecified when using clashing - * options (e.g. having both userName and groupName set non-null). Consult the - * main Perforce admin documentation for semantics and usage.

- *

- * Note that any annotations in the file paths will be ignored. The reason is - * the Perforce server 'protects' command requires a file list devoid of annotated - * revision specificity. - * - * @param fileList if non-null, only those protection entries that apply to the specified files - * are displayed. - * @param opts GetProtectionEntriesOptions object describing optional parameters; if null, no - * options are set. - * @return non-null but possibly empty list of protection entries. - * @throws P4JavaException if any error occurs in the processing of this method. - */ - List getProtectionEntries( - List fileList, - GetProtectionEntriesOptions opts) throws P4JavaException; + /** + * Get a list of Perforce protection entries for the passed-in arguments. + *

+ * Note that the behavior of this method is unspecified when using clashing + * options (e.g. having both userName and groupName set non-null). Consult the + * main Perforce admin documentation for semantics and usage. + *

+ * Note that any annotations in the file paths will be ignored. The reason is + * the Perforce server 'protects' command requires a file list devoid of annotated + * revision specificity. + * + * @param fileList if non-null, only those protection entries that apply to the specified files + * are displayed. + * @param opts GetProtectionEntriesOptions object describing optional parameters; if null, no + * options are set. + * @return non-null but possibly empty list of protection entries. + * @throws P4JavaException if any error occurs in the processing of this method. + */ + List getProtectionEntries( + List fileList, + GetProtectionEntriesOptions opts) throws P4JavaException; } diff --git a/src/main/java/com/perforce/p4java/server/delegator/IReloadDelegator.java b/src/main/java/com/perforce/p4java/server/delegator/IReloadDelegator.java index e543eb8..b340257 100644 --- a/src/main/java/com/perforce/p4java/server/delegator/IReloadDelegator.java +++ b/src/main/java/com/perforce/p4java/server/delegator/IReloadDelegator.java @@ -10,7 +10,6 @@ public interface IReloadDelegator { /** * Reload an unloaded client or label. *

- *

* Note that by default, users can only unload their own clients or labels. * The -f flag requires 'admin' access, which is granted by 'p4 protect'. * The full semantics of this operation are found in the main 'p4 help diff --git a/src/main/java/com/perforce/p4java/server/delegator/IRenameUserDelegator.java b/src/main/java/com/perforce/p4java/server/delegator/IRenameUserDelegator.java index fba13af..f5f4b25 100644 --- a/src/main/java/com/perforce/p4java/server/delegator/IRenameUserDelegator.java +++ b/src/main/java/com/perforce/p4java/server/delegator/IRenameUserDelegator.java @@ -6,44 +6,38 @@ * Interface to handle the RenameUser command. */ public interface IRenameUserDelegator { - /** - * Completely renames a user, modifying all database records which mention - * the user. - *

- *

- * This includes all workspaces, labels, branches, streams, etc. which are - * owned by the user, all pending, shelved, and committed changes created by - * the user, any files that the user has opened or shelved, any fixes that - * the user made to jobs, any properties that apply to the user, any groups - * that the user is in, and the user record itself. - *

- *

- * The username is not changed in descriptive text fields (such as job - * descriptions, change descriptions, or workspace descriptions), only where - * it appears as the owner or user field of the database record. - *

- *

- * Protection table entries that apply to the user are updated only if the - * Name: field exactly matches the user name; if the Name: field contains - * wildcards, it is not modified. - *

- *

- * The only job field that is processed is attribute code 103. If you have - * included the username in other job fields they will have to be processed - * separately. - *

- *

- * The full semantics of this operation are found in the main 'p4 help' - * documentation. - *

- *

- * This method requires 'super' access granted by 'p4 protect'. - * - * @param oldUserName the old user name to be changed. - * @param newUserName the new user name to be changed to. - * @return non-null result message string from the reload operation. - * @throws P4JavaException if an error occurs processing this method and its parameters. - * @since 2014.1 - */ - String renameUser(String oldUserName, String newUserName) throws P4JavaException; + /** + * Completely renames a user, modifying all database records which mention + * the user. + *

+ * This includes all workspaces, labels, branches, streams, etc. which are + * owned by the user, all pending, shelved, and committed changes created by + * the user, any files that the user has opened or shelved, any fixes that + * the user made to jobs, any properties that apply to the user, any groups + * that the user is in, and the user record itself. + *

+ * The username is not changed in descriptive text fields (such as job + * descriptions, change descriptions, or workspace descriptions), only where + * it appears as the owner or user field of the database record. + *

+ * Protection table entries that apply to the user are updated only if the + * Name: field exactly matches the user name; if the Name: field contains + * wildcards, it is not modified. + *

+ * The only job field that is processed is attribute code 103. If you have + * included the username in other job fields they will have to be processed + * separately. + *

+ * The full semantics of this operation are found in the main 'p4 help' + * documentation. + *

+ * This method requires 'super' access granted by 'p4 protect'. + * + * @param oldUserName the old user name to be changed. + * @param newUserName the new user name to be changed to. + * @return non-null result message string from the reload operation. + * @throws P4JavaException if an error occurs processing this method and its parameters. + * @since 2014.1 + */ + String renameUser(String oldUserName, String newUserName) throws P4JavaException; } diff --git a/src/main/java/com/perforce/p4java/server/delegator/IReposDelegator.java b/src/main/java/com/perforce/p4java/server/delegator/IReposDelegator.java index b0aa9db..28c44f9 100644 --- a/src/main/java/com/perforce/p4java/server/delegator/IReposDelegator.java +++ b/src/main/java/com/perforce/p4java/server/delegator/IReposDelegator.java @@ -15,12 +15,9 @@ public interface IReposDelegator { * Gets the repos. * * @return a list of repos - * @throws ConnectionException - * the connection exception - * @throws RequestException - * the request exception - * @throws AccessException - * the access exception + * @throws ConnectionException the connection exception + * @throws RequestException the request exception + * @throws AccessException the access exception */ List getRepos() throws ConnectionException, RequestException, AccessException; @@ -38,9 +35,9 @@ public interface IReposDelegator { * * @param clientName the name of the client workspace * @return a list of repos - * @throws ConnectionException - * @throws RequestException - * @throws AccessException + * @throws ConnectionException on error + * @throws RequestException on error + * @throws AccessException on error */ List getRepos(String clientName) throws ConnectionException, RequestException, AccessException; } diff --git a/src/main/java/com/perforce/p4java/server/delegator/IReviewDelegator.java b/src/main/java/com/perforce/p4java/server/delegator/IReviewDelegator.java index 4bb91f5..904c46b 100644 --- a/src/main/java/com/perforce/p4java/server/delegator/IReviewDelegator.java +++ b/src/main/java/com/perforce/p4java/server/delegator/IReviewDelegator.java @@ -1,42 +1,38 @@ package com.perforce.p4java.server.delegator; -import java.util.List; - import com.perforce.p4java.core.IReviewChangelist; import com.perforce.p4java.exception.P4JavaException; import com.perforce.p4java.option.server.GetReviewChangelistsOptions; +import java.util.List; + /** * Interface to handle the Review command. */ public interface IReviewDelegator { - /** - * Get a list of all submitted changelists equal or above a provided - * changelist number that have not been reviewed before. - *

- *

- * If only the 'changelistId' option is provided, return a list of - * changelists that have not been reviewed before, equal or above the - * specified changelist#. - *

- *

- * If only the 'counter' option is provided, return a list of changelists - * that have not been reviewed before, above the specified counter's - * changelist#. - *

- *

- * If both the 'changelistId' and 'counter' options are specified, 'p4 - * review' sets the counter to that changelist# and produces no output. This - * functionality has been superceded by the 'p4 counter' command. The user - * must have permission to set counters. - * - * @param opts GetReviewChangelistsOptions object describing optional - * parameters; if null, no options are set. - * @return non-null but possibly empty list of IReviewChangelist objects; - * note that these objects will have null update and access fields. - * @throws P4JavaException if any error occurs in the processing of this method. - * @since 2012.2 - */ - List getReviewChangelists(GetReviewChangelistsOptions opts) - throws P4JavaException; + /** + * Get a list of all submitted changelists equal or above a provided + * changelist number that have not been reviewed before. + *

+ * If only the 'changelistId' option is provided, return a list of + * changelists that have not been reviewed before, equal or above the + * specified changelist#. + *

+ * If only the 'counter' option is provided, return a list of changelists + * that have not been reviewed before, above the specified counter's + * changelist#. + *

+ * If both the 'changelistId' and 'counter' options are specified, 'p4 + * review' sets the counter to that changelist# and produces no output. This + * functionality has been superceded by the 'p4 counter' command. The user + * must have permission to set counters. + * + * @param opts GetReviewChangelistsOptions object describing optional + * parameters; if null, no options are set. + * @return non-null but possibly empty list of IReviewChangelist objects; + * note that these objects will have null update and access fields. + * @throws P4JavaException if any error occurs in the processing of this method. + * @since 2012.2 + */ + List getReviewChangelists(GetReviewChangelistsOptions opts) throws P4JavaException; } diff --git a/src/main/java/com/perforce/p4java/server/delegator/IReviewsDelegator.java b/src/main/java/com/perforce/p4java/server/delegator/IReviewsDelegator.java index db0bdd2..1dbe5bc 100644 --- a/src/main/java/com/perforce/p4java/server/delegator/IReviewsDelegator.java +++ b/src/main/java/com/perforce/p4java/server/delegator/IReviewsDelegator.java @@ -1,7 +1,5 @@ package com.perforce.p4java.server.delegator; -import java.util.List; - import com.perforce.p4java.core.IUserSummary; import com.perforce.p4java.core.file.IFileSpec; import com.perforce.p4java.exception.AccessException; @@ -10,49 +8,45 @@ import com.perforce.p4java.exception.RequestException; import com.perforce.p4java.option.server.GetReviewsOptions; +import java.util.List; + /** * Interface to handle the Reviews command. */ public interface IReviewsDelegator { - /** - * Get a list of all users who have subscribed to review the named files. - *

- * Note that the returned IUserSummary objects will have null access and - * update dates associated with them. - * - * @param fileSpecs if not null, use this list as the list of named files rather - * than all files. - * @param opts GetReviewsOptions object describing optional parameters; if - * null, no options are set. - * @return non-null but possibly empty list of IUserSummary objects; note - * that these objects will have null update and access fields. - * @throws P4JavaException if any error occurs in the processing of this method. - */ - List getReviews( - List fileSpecs, - GetReviewsOptions opts) throws P4JavaException; + /** + * Get a list of all users who have subscribed to review the named files. + *

+ * Note that the returned IUserSummary objects will have null access and + * update dates associated with them. + * + * @param fileSpecs if not null, use this list as the list of named files rather + * than all files. + * @param opts GetReviewsOptions object describing optional parameters; if + * null, no options are set. + * @return non-null but possibly empty list of IUserSummary objects; note + * that these objects will have null update and access fields. + * @throws P4JavaException if any error occurs in the processing of this method. + */ + List getReviews(List fileSpecs, GetReviewsOptions opts) throws P4JavaException; - /** - * Get a list of all users who have subscribed to review the named files, - * the files in the numbered changelist, or all files by default. - *

- *

- * Note that the returned IUserSummary objects will have null access and - * update dates associated with them. - * - * @param changelistId if not IChangelist.UNKNOWN, use this changelist ID. - * @param fileSpecs if not null, use this list as the list of named files rather - * than all files. - * @return non-null but possibly empty list of IUserSummary objects; note - * that these objects will have null update and access fields. - * @throws ConnectionException if the Perforce server is unreachable or is not connected. - * @throws RequestException if the Perforce server encounters an error during its - * processing of the request - * @throws AccessException if the Perforce server denies access to the caller - */ - List getReviews( - int changelistId, - List fileSpecs) - throws ConnectionException, RequestException, AccessException; + /** + * Get a list of all users who have subscribed to review the named files, + * the files in the numbered changelist, or all files by default. + *

+ * Note that the returned IUserSummary objects will have null access and + * update dates associated with them. + * + * @param changelistId if not IChangelist.UNKNOWN, use this changelist ID. + * @param fileSpecs if not null, use this list as the list of named files rather + * than all files. + * @return non-null but possibly empty list of IUserSummary objects; note + * that these objects will have null update and access fields. + * @throws ConnectionException if the Perforce server is unreachable or is not connected. + * @throws RequestException if the Perforce server encounters an error during its + * processing of the request + * @throws AccessException if the Perforce server denies access to the caller + */ + List getReviews(int changelistId, List fileSpecs) throws ConnectionException, RequestException, AccessException; } diff --git a/src/main/java/com/perforce/p4java/server/delegator/ISearchDelegator.java b/src/main/java/com/perforce/p4java/server/delegator/ISearchDelegator.java index 653311e..8dcdefb 100644 --- a/src/main/java/com/perforce/p4java/server/delegator/ISearchDelegator.java +++ b/src/main/java/com/perforce/p4java/server/delegator/ISearchDelegator.java @@ -1,30 +1,28 @@ package com.perforce.p4java.server.delegator; -import java.util.List; - import com.perforce.p4java.exception.P4JavaException; import com.perforce.p4java.option.server.SearchJobsOptions; +import java.util.List; + /** * Interface to handle the Search command. */ public interface ISearchDelegator { - /** - * Search for jobs that contain the specified words in the search engine's - * index. - *

- *

- * Note that this is an 'undoc' Perforce command. - *

- *

- * See also 'p4 help index'. - * - * @param words non-null words to be searched. - * @param opts SearchJobsOptions object describing optional parameters; if - * null, no options are set. - * @return non-null (but possibly-empty) list of job IDs. - * @throws P4JavaException if an error occurs processing this method and its parameters. - * @since 2013.1 - */ - List searchJobs(String words, SearchJobsOptions opts) throws P4JavaException; + /** + * Search for jobs that contain the specified words in the search engine's + * index. + *

+ * Note that this is an 'undoc' Perforce command. + *

+ * See also 'p4 help index'. + * + * @param words non-null words to be searched. + * @param opts SearchJobsOptions object describing optional parameters; if + * null, no options are set. + * @return non-null (but possibly-empty) list of job IDs. + * @throws P4JavaException if an error occurs processing this method and its parameters. + * @since 2013.1 + */ + List searchJobs(String words, SearchJobsOptions opts) throws P4JavaException; } diff --git a/src/main/java/com/perforce/p4java/server/delegator/ISizesDelegator.java b/src/main/java/com/perforce/p4java/server/delegator/ISizesDelegator.java index 849796e..be4e688 100644 --- a/src/main/java/com/perforce/p4java/server/delegator/ISizesDelegator.java +++ b/src/main/java/com/perforce/p4java/server/delegator/ISizesDelegator.java @@ -1,31 +1,29 @@ package com.perforce.p4java.server.delegator; -import java.util.List; - import com.perforce.p4java.core.file.IFileSize; import com.perforce.p4java.core.file.IFileSpec; import com.perforce.p4java.exception.P4JavaException; import com.perforce.p4java.option.server.GetFileSizesOptions; +import java.util.List; + /** * Interface to handle the Sizes command. */ public interface ISizesDelegator { - /** - * Gets a list of file sizes for one or more files in the depot.

- *

- * For specified file specification, get the depot file name, revision, file - * count and file size. If you use client syntax for the file specification, - * the view mapping is used to list the corresponding depot files. - * - * @param fileSpecs filespecs to be processed; if null or empty, an empty list is returned. - * @param opts GetFileSizesOptions object describing optional parameters; if null, no options - * are set. - * @return a non-null (but possibly empty) list of file sizes. - * @throws P4JavaException if any error occurs in the processing of this method. - * @since 2013.2 - */ - List getFileSizes( - List fileSpecs, - GetFileSizesOptions opts) throws P4JavaException; + /** + * Gets a list of file sizes for one or more files in the depot. + *

+ * For specified file specification, get the depot file name, revision, file + * count and file size. If you use client syntax for the file specification, + * the view mapping is used to list the corresponding depot files. + * + * @param fileSpecs filespecs to be processed; if null or empty, an empty list is returned. + * @param opts GetFileSizesOptions object describing optional parameters; if null, no options + * are set. + * @return a non-null (but possibly empty) list of file sizes. + * @throws P4JavaException if any error occurs in the processing of this method. + * @since 2013.2 + */ + List getFileSizes(List fileSpecs, GetFileSizesOptions opts) throws P4JavaException; } diff --git a/src/main/java/com/perforce/p4java/server/delegator/IStreamlogDelegator.java b/src/main/java/com/perforce/p4java/server/delegator/IStreamlogDelegator.java index abd3af7..1621f06 100644 --- a/src/main/java/com/perforce/p4java/server/delegator/IStreamlogDelegator.java +++ b/src/main/java/com/perforce/p4java/server/delegator/IStreamlogDelegator.java @@ -14,12 +14,13 @@ public interface IStreamlogDelegator { * recent revision to the first. If the stream was opened for edit * and submitted, the change list information is displayed. * Otherwise only the maximum change num at the time of edit is displayed. + * * @param streamPaths Stream paths to get history. - * @param opts Command options. - * @see com.perforce.p4java.option.server.StreamlogOptions#StreamlogOptions(java.lang.String...) + * @param opts Command options. * @return List of Streamlog. + * @throws P4JavaException on error + * @see com.perforce.p4java.option.server.StreamlogOptions#StreamlogOptions(java.lang.String...) * @see IStreamlog - * @throws P4JavaException * @since 2021.2 */ Map> getStreamlog(List streamPaths, StreamlogOptions opts) throws P4JavaException; diff --git a/src/main/java/com/perforce/p4java/server/delegator/IStreamsDelegator.java b/src/main/java/com/perforce/p4java/server/delegator/IStreamsDelegator.java index 773a746..14f2218 100644 --- a/src/main/java/com/perforce/p4java/server/delegator/IStreamsDelegator.java +++ b/src/main/java/com/perforce/p4java/server/delegator/IStreamsDelegator.java @@ -1,33 +1,30 @@ package com.perforce.p4java.server.delegator; -import java.util.List; - import com.perforce.p4java.core.IStreamSummary; import com.perforce.p4java.exception.P4JavaException; import com.perforce.p4java.option.server.GetStreamsOptions; +import java.util.List; + /** * Interface to handle the Streams command. */ public interface IStreamsDelegator { - /** - * Get a list of all summary Perforce streams known to the Perforce server. - *

- *

- * Note that the IStreamSummary objects returned here do not have stream - * paths. You must call the getStream method on a specific stream to get - * valid paths for a stream. - * - * @param streamPaths if specified, the list of streams is limited to those matching - * the supplied list of stream paths, of the form - * //depotname/streamname - * @param opts object describing optional parameters; if null, no options are - * set. - * @return non-null (but possibly-empty) list of IStreamSummary objects. - * @throws P4JavaException if any error occurs in the processing of this method. - * @since 2011.2 - */ - List getStreams( - List streamPaths, - GetStreamsOptions opts) throws P4JavaException; + /** + * Get a list of all summary Perforce streams known to the Perforce server. + *

+ * Note that the IStreamSummary objects returned here do not have stream + * paths. You must call the getStream method on a specific stream to get + * valid paths for a stream. + * + * @param streamPaths if specified, the list of streams is limited to those matching + * the supplied list of stream paths, of the form + * //depotname/streamname + * @param opts object describing optional parameters; if null, no options are + * set. + * @return non-null (but possibly-empty) list of IStreamSummary objects. + * @throws P4JavaException if any error occurs in the processing of this method. + * @since 2011.2 + */ + List getStreams(List streamPaths, GetStreamsOptions opts) throws P4JavaException; } diff --git a/src/main/java/com/perforce/p4java/server/delegator/ITriggersDelegator.java b/src/main/java/com/perforce/p4java/server/delegator/ITriggersDelegator.java index cec2675..8535e6a 100644 --- a/src/main/java/com/perforce/p4java/server/delegator/ITriggersDelegator.java +++ b/src/main/java/com/perforce/p4java/server/delegator/ITriggersDelegator.java @@ -1,76 +1,70 @@ package com.perforce.p4java.server.delegator; -import java.io.InputStream; -import java.util.List; -import javax.annotation.Nonnull; - import com.perforce.p4java.admin.ITriggerEntry; import com.perforce.p4java.exception.P4JavaException; +import javax.annotation.Nonnull; +import java.io.InputStream; +import java.util.List; + /** * Interface to handle the Triggers command. */ public interface ITriggersDelegator { - /** - * Create or replace the triggers table data on the Perforce server with - * these new trigger entries. - *

- *

- * This method require that the user have 'super' access granted by 'p4 - * protect'. - *

- *

- * Warning: this will overwrite the existing triggers table data. - * - * @param entryList non-null list of trigger entries. - * @return possibly-null status message string as returned from the server - * @throws P4JavaException if an error occurs processing this method and its parameters. - * @since 2014.1 - */ - String createTriggerEntries(@Nonnull List entryList) throws P4JavaException; + /** + * Create or replace the triggers table data on the Perforce server with + * these new trigger entries. + *

+ * This method require that the user have 'super' access granted by 'p4 + * protect'. + *

+ * Warning: this will overwrite the existing triggers table data. + * + * @param entryList non-null list of trigger entries. + * @return possibly-null status message string as returned from the server + * @throws P4JavaException if an error occurs processing this method and its parameters. + * @since 2014.1 + */ + String createTriggerEntries(@Nonnull List entryList) throws P4JavaException; - /** - * Get a list of Perforce trigger entries. - *

- *

- * This method require that the user have 'super' access granted by 'p4 - * protect'. - * - * @return non-null but possibly empty list of trigger entries. - * @throws P4JavaException if any error occurs in the processing of this method. - * @since 2014.1 - */ - List getTriggerEntries() throws P4JavaException; + /** + * Get a list of Perforce trigger entries. + *

+ * This method require that the user have 'super' access granted by 'p4 + * protect'. + * + * @return non-null but possibly empty list of trigger entries. + * @throws P4JavaException if any error occurs in the processing of this method. + * @since 2014.1 + */ + List getTriggerEntries() throws P4JavaException; - /** - * Replace the triggers table data on the Perforce server with these new - * triggers entries. - *

- *

- * This method require that the user have 'super' access granted by 'p4 - * protect'. - *

- *

- * Warning: this will overwrite the existing triggers table data. - * - * @param entryList non-null list of trigger entries. - * @return possibly-null status message string as returned from the server - * @throws P4JavaException if an error occurs processing this method and its parameters. - * @since 2014.1 - */ - String updateTriggerEntries(@Nonnull List entryList) throws P4JavaException; + /** + * Replace the triggers table data on the Perforce server with these new + * triggers entries. + *

+ * This method require that the user have 'super' access granted by 'p4 + * protect'. + *

+ * Warning: this will overwrite the existing triggers table data. + * + * @param entryList non-null list of trigger entries. + * @return possibly-null status message string as returned from the server + * @throws P4JavaException if an error occurs processing this method and its parameters. + * @since 2014.1 + */ + String updateTriggerEntries(@Nonnull List entryList) throws P4JavaException; - /** - * Get an InputStream onto the entries of the Perforce triggers table. - *

- *

- * This method require that the user have 'super' access granted by 'p4 - * protect'. - * - * @return a non-null but possibly empty InputStream onto the triggers - * table's entries. - * @throws P4JavaException if any error occurs in the processing of this method. - * @since 2014.1 - */ - InputStream getTriggersTable() throws P4JavaException; + /** + * Get an InputStream onto the entries of the Perforce triggers table. + *

+ * This method require that the user have 'super' access granted by 'p4 + * protect'. + * + * @return a non-null but possibly empty InputStream onto the triggers + * table's entries. + * @throws P4JavaException if any error occurs in the processing of this method. + * @since 2014.1 + */ + InputStream getTriggersTable() throws P4JavaException; } diff --git a/src/main/java/com/perforce/p4java/server/delegator/IUnloadDelegator.java b/src/main/java/com/perforce/p4java/server/delegator/IUnloadDelegator.java index 7b7fd17..d51498a 100644 --- a/src/main/java/com/perforce/p4java/server/delegator/IUnloadDelegator.java +++ b/src/main/java/com/perforce/p4java/server/delegator/IUnloadDelegator.java @@ -7,19 +7,18 @@ * Interface to handle the Unload command. */ public interface IUnloadDelegator { - /** - * Unloads a client or label to the unload depot. - *

- *

- * Note that by default, users can only unload their own clients or labels. - * The -f flag requires 'admin' access, which is granted by 'p4 protect'. - * The full semantics of this operation are found in the main 'p4 help - * unload' documentation. - * - * @param opts possibly-null UnloadOptions object specifying method options. - * @return non-null result message string from the unload operation. - * @throws P4JavaException if an error occurs processing this method and its parameters. - * @since 2012.3 - */ - String unload(UnloadOptions opts) throws P4JavaException; + /** + * Unloads a client or label to the unload depot. + *

+ * Note that by default, users can only unload their own clients or labels. + * The -f flag requires 'admin' access, which is granted by 'p4 protect'. + * The full semantics of this operation are found in the main 'p4 help + * unload' documentation. + * + * @param opts possibly-null UnloadOptions object specifying method options. + * @return non-null result message string from the unload operation. + * @throws P4JavaException if an error occurs processing this method and its parameters. + * @since 2012.3 + */ + String unload(UnloadOptions opts) throws P4JavaException; } diff --git a/src/main/java/com/perforce/p4java/server/delegator/IUsersDelegator.java b/src/main/java/com/perforce/p4java/server/delegator/IUsersDelegator.java index f4cdaf6..3194401 100644 --- a/src/main/java/com/perforce/p4java/server/delegator/IUsersDelegator.java +++ b/src/main/java/com/perforce/p4java/server/delegator/IUsersDelegator.java @@ -1,7 +1,5 @@ package com.perforce.p4java.server.delegator; -import java.util.List; - import com.perforce.p4java.core.IUserSummary; import com.perforce.p4java.exception.AccessException; import com.perforce.p4java.exception.ConnectionException; @@ -9,51 +7,48 @@ import com.perforce.p4java.exception.RequestException; import com.perforce.p4java.option.server.GetUsersOptions; +import java.util.List; + /** * Interface to handle the Users command. */ public interface IUsersDelegator { - /** - * Get a list of Perforce users known to this Perforce server. Note that - * maxUsers and the user list are supposed to be mutually exclusive in - * usage, but this is not enforced by P4Java as the restriction doesn't - * make much sense and may be lifted in the Perforce server later.

- *

- * Note that this implementation differs a bit from the p4 command line - * version in that it simply doesn't return any output for unmatched users. - * - * @param userList if non-null, restrict output to users matching the passed-in list of users. - * @param opts GetUsersOptions object describing optional parameters; if null, no options are - * set - * @return non-null (but possibly empty) list of non-null IUserSummary objects representing the - * underlying Perforce users (if any). - * @throws P4JavaException if any error occurs in the processing of this method. - */ - List getUsers( - List userList, - GetUsersOptions opts) throws P4JavaException; + /** + * Get a list of Perforce users known to this Perforce server. Note that + * maxUsers and the user list are supposed to be mutually exclusive in + * usage, but this is not enforced by P4Java as the restriction doesn't + * make much sense and may be lifted in the Perforce server later. + *

+ * Note that this implementation differs a bit from the p4 command line + * version in that it simply doesn't return any output for unmatched users. + * + * @param userList if non-null, restrict output to users matching the passed-in list of users. + * @param opts GetUsersOptions object describing optional parameters; if null, no options are + * set + * @return non-null (but possibly empty) list of non-null IUserSummary objects representing the + * underlying Perforce users (if any). + * @throws P4JavaException if any error occurs in the processing of this method. + */ + List getUsers(List userList, GetUsersOptions opts) throws P4JavaException; - /** - * Get a list of Perforce users known to this Perforce server. Note that - * maxUsers and the user list are supposed to be mutually exclusive in - * usage, but this is not enforced by P4Java as the restriction doesn't make - * much sense and may be lifted in the Perforce server later. - *

- *

- * Note that this implementation differs a bit from the p4 command line - * version in that it simply doesn't return any output for unmatched users. - * - * @param userList if non-null, restrict output to users matching the passed-in - * list of users. - * @param maxUsers if positive, only return the first maxUsers users. - * @return non-null (but possibly empty) list of non-null IUserSummary - * objects representing the underlying Perforce users (if any). - * @throws ConnectionException if the Perforce server is unreachable or is not connected. - * @throws RequestException if the Perforce server encounters an error during its - * processing of the request - * @throws AccessException if the Perforce server denies access to the caller - */ - List getUsers( - List userList, - int maxUsers) throws ConnectionException, RequestException, AccessException; + /** + * Get a list of Perforce users known to this Perforce server. Note that + * maxUsers and the user list are supposed to be mutually exclusive in + * usage, but this is not enforced by P4Java as the restriction doesn't make + * much sense and may be lifted in the Perforce server later. + *

+ * Note that this implementation differs a bit from the p4 command line + * version in that it simply doesn't return any output for unmatched users. + * + * @param userList if non-null, restrict output to users matching the passed-in + * list of users. + * @param maxUsers if positive, only return the first maxUsers users. + * @return non-null (but possibly empty) list of non-null IUserSummary + * objects representing the underlying Perforce users (if any). + * @throws ConnectionException if the Perforce server is unreachable or is not connected. + * @throws RequestException if the Perforce server encounters an error during its + * processing of the request + * @throws AccessException if the Perforce server denies access to the caller + */ + List getUsers(List userList, int maxUsers) throws ConnectionException, RequestException, AccessException; } diff --git a/src/main/java/com/perforce/p4java/server/delegator/IVerifyDelegator.java b/src/main/java/com/perforce/p4java/server/delegator/IVerifyDelegator.java index cb49234..e984350 100644 --- a/src/main/java/com/perforce/p4java/server/delegator/IVerifyDelegator.java +++ b/src/main/java/com/perforce/p4java/server/delegator/IVerifyDelegator.java @@ -1,31 +1,29 @@ package com.perforce.p4java.server.delegator; -import java.util.List; - import com.perforce.p4java.core.file.IExtendedFileSpec; import com.perforce.p4java.core.file.IFileSpec; import com.perforce.p4java.exception.P4JavaException; import com.perforce.p4java.option.server.VerifyFilesOptions; +import java.util.List; + /** * Interface to handle the Verify command. */ public interface IVerifyDelegator { - /** - * Verify that the server archives are intact.

- *

- * This method require that the user be an operator or have 'admin' access, - * which is granted by 'p4 protect'. - * - * @param fileSpecs filespecs to be processed; if null or empty, an empty list is returned. - * @param opts VerifyFilesOptions object describing optional parameters; if null, no options - * are set. - * @return non-null (but possibly empty) list of files with revision-specific information and an - * MD5 digest of the revision's contents. - * @throws P4JavaException if an error occurs processing this method and its parameters. - * @since 2014.1 - */ - List verifyFiles( - List fileSpecs, - VerifyFilesOptions opts) throws P4JavaException; + /** + * Verify that the server archives are intact. + *

+ * This method require that the user be an operator or have 'admin' access, + * which is granted by 'p4 protect'. + * + * @param fileSpecs filespecs to be processed; if null or empty, an empty list is returned. + * @param opts VerifyFilesOptions object describing optional parameters; if null, no options + * are set. + * @return non-null (but possibly empty) list of files with revision-specific information and an + * MD5 digest of the revision's contents. + * @throws P4JavaException if an error occurs processing this method and its parameters. + * @since 2014.1 + */ + List verifyFiles(List fileSpecs, VerifyFilesOptions opts) throws P4JavaException; } diff --git a/src/main/java/com/perforce/p4java/util/FilesHelper.java b/src/main/java/com/perforce/p4java/util/FilesHelper.java index 1ab3edc..35e2ebf 100755 --- a/src/main/java/com/perforce/p4java/util/FilesHelper.java +++ b/src/main/java/com/perforce/p4java/util/FilesHelper.java @@ -17,12 +17,17 @@ public class FilesHelper { /** * Copy source file to destination file. + * + * @param source source + * @param destination destination + * @return status + * @throws IOException on error */ public static boolean copy(File source, File destination) throws IOException { boolean copied = false; if (source != null && destination != null) { - FileInputStream reader = null; - FileOutputStream writer = null; + FileInputStream reader = null; + FileOutputStream writer = null; try { ISystemFileCommandsHelper helper = ServerFactory.getRpcFileSystemHelper(); if (helper == null) { @@ -60,6 +65,9 @@ public static boolean copy(File source, File destination) throws IOException { /** * Create all directories, including nonexistent parent directories. + * + * @param file file + * @return status */ public static boolean mkdirs(File file) { if (file != null) { @@ -67,7 +75,7 @@ public static boolean mkdirs(File file) { if (parent != null) { File parentDir = new File(parent); if (!parentDir.exists()) { - if(parentDir.mkdirs()) { + if (parentDir.mkdirs()) { return true; } else { return parentDir.exists(); @@ -76,7 +84,7 @@ public static boolean mkdirs(File file) { } return true; } - + return false; } } diff --git a/src/main/java/com/perforce/p4java/util/PropertiesHelper.java b/src/main/java/com/perforce/p4java/util/PropertiesHelper.java index 696c0dd..435c3a7 100644 --- a/src/main/java/com/perforce/p4java/util/PropertiesHelper.java +++ b/src/main/java/com/perforce/p4java/util/PropertiesHelper.java @@ -13,7 +13,9 @@ public class PropertiesHelper { /** - * Return the first property string value found from the passed-in + * @param props props + * @param keys keys + * @return the first property string value found from the passed-in * properties with the specified keys. */ public static String getProperty(Properties props, String[] keys) { @@ -21,7 +23,10 @@ public static String getProperty(Properties props, String[] keys) { } /** - * Return the first property string value found from the passed-in + * @param props props + * @param keys keys + * @param defaultValue defaultValue + * @return the first property string value found from the passed-in * properties with the specified keys. If it can't find a value, * then return the passed-in defaultValue. */ @@ -45,7 +50,10 @@ public static String getProperty(Properties props, String[] keys, String default } /** - * Return the first property value found as an int, if possible. + * @param props props + * @param keys keys + * @param defaultValue defaultValue + * @return the first property value found as an int, if possible. * If it can't find a value, then return the passed-in defaultValue. */ public static int getPropertyAsInt(Properties props, String[] keys, int defaultValue) { @@ -56,9 +64,7 @@ public static int getPropertyAsInt(Properties props, String[] keys, int defaultV try { retVal = new Integer(propStr); } catch (Exception exc) { - Log.warn("Integer property conversion error; prop name: '" - + Arrays.toString(keys) + "'; prop value: " - + propStr); + Log.warn("Integer property conversion error; prop name: '" + Arrays.toString(keys) + "'; prop value: " + propStr); Log.exception(exc); } } @@ -67,7 +73,10 @@ public static int getPropertyAsInt(Properties props, String[] keys, int defaultV } /** - * Return the property value as a long, if possible. If it can't find + * @param props props + * @param keys keys + * @param defaultValue defaultValue + * @return the property value as a long, if possible. If it can't find * a value by the specified key, then return the passed-in defaultValue. */ public static long getPropertyAsLong(Properties props, String[] keys, long defaultValue) { @@ -78,9 +87,7 @@ public static long getPropertyAsLong(Properties props, String[] keys, long defau try { retVal = new Long(propStr); } catch (Exception exc) { - Log.warn("Long property conversion error; prop name: '" - + Arrays.toString(keys) + "'; prop value: " - + propStr); + Log.warn("Long property conversion error; prop name: '" + Arrays.toString(keys) + "'; prop value: " + propStr); Log.exception(exc); } }