Skip to content

Commit

Permalink
2024.2 Code Drop
Browse files Browse the repository at this point in the history
  • Loading branch information
ajindal-mdx committed Dec 19, 2024
1 parent 36b3329 commit b439d94
Show file tree
Hide file tree
Showing 21 changed files with 646 additions and 259 deletions.
414 changes: 194 additions & 220 deletions LICENSE.txt

Large diffs are not rendered by default.

44 changes: 40 additions & 4 deletions RELEASE.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Release Notes for
P4Java, the Perforce Java API

Version 2024.1
Version 2024.2

Introduction

Expand All @@ -20,7 +20,7 @@ Introduction

Requirements

* Perforce server at Release 2015.1 or higher.
* Perforce server at Release 2021.1 or higher.

* Java: full standard JDK 11 or later. Implementation as
discussed in "Known Limitations" below.
Expand All @@ -30,7 +30,7 @@ Requirements

SSL and Trust

Perforce server 2015.1 or higher supports 256-bit SSL connections
Perforce server 2021.1 or higher supports 256-bit SSL connections
and trust establishment via accepting the fingerprint of the SSL
certificate's public key. The standard JDK comes with 128-bit
encryption level ciphers. In order to use P4Java to connect to
Expand Down Expand Up @@ -108,7 +108,7 @@ Known Limitations
mean either true shift-jis or CP932 by the Perforce server and
many Windows tools. There is currently no workaround known.

* The Perforce server (2015.1 or higher) only support 256-bit
* The Perforce server (2021.1 or higher) only support 256-bit
encryption. Due to current US export control restrictions
for some countries, the standard JDK package only comes with
128-bit encryption level ciphers. In order to use P4Java to
Expand All @@ -123,6 +123,42 @@ Known Limitations
* P4Java would not support file operations on altsync enabled clients.

-------------------------------------------
Updates in 2024.2 (2024.2/2695691) (2024/12/13)

#2693987 (Job #123372)
Fixed a bug where localWhere should include path of the sparse stream instead
of the mainline from which the sparse stream is created

#2692452 (Job #123888)
Added 'long' value support for 'TicketExpiration' field while login

#2693212, #2693848 (Job #123268)
Added support of P4IGNORE from env variable working for absolute path
Added support for all patterns in ignore file

#2687877, #2686707 (Job #122068)
Added support of -m flag for "p4 protects" command

#2684594 (Job #123229)
Added support for user case insensitive suboption for "p4 labels" command

#2684552 (Job #122974)
Added support for user case insensitive suboption for "p4 clients" command

#2684551 (Job #122978)
Added support for user case insensitive suboption for "p4 branches" command

#2684163, #2685729 (Job #123231)
Added support for multiple client and user option with a generic case-insensitive
sub option for "p4 changes" command

#2684163, #2681088 (Job #122972)
Added support for client and user case insensitive option for
"p4 changes -c and -u"

#2684152, #2688244 (Job #121727)
Added support for Sparse Streams

-------------------------------------------
Updates in 2024.1 Patch 1 (2024.1/2674354) (2024/10/29)
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ dependencies {
testImplementation 'org.apache.commons:commons-exec:1.3'
testImplementation 'org.apache.commons:commons-compress:1.21'
testImplementation 'junit:junit:4.13.1'
testImplementation 'org.mockito:mockito-core:4.0.0'
testImplementation 'org.mockito:mockito-core:5.5.0'
testImplementation 'com.googlecode.java-diff-utils:diffutils:1.3.0'
}

Expand Down
7 changes: 7 additions & 0 deletions src/main/java/com/perforce/p4java/admin/IProtectionEntry.java
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,11 @@ public interface IProtectionEntry extends IMapEntry {
* the path excluded indicator (true/false)
*/
void setPathExcluded(boolean pathExcluded);

/**
* Returns the single word summary
*
* @return permMax
*/
String getPermMax();
}
8 changes: 5 additions & 3 deletions src/main/java/com/perforce/p4java/core/IStreamSummary.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,20 @@ public interface IStreamSummary extends IServerResource {

/**
* Types of streams include 'mainline', 'release', 'development', 'virtual'
* and 'task'. The default is 'development'.
* 'task', 'sparsedev' and 'sparserel'. The default is 'development'.
* <p>
* 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
* be changed. A 'task' stream is a lightweight short-lived stream that only
* promotes modified content to the repository, branched data is stored in
* shadow tables that are removed when the task stream is deleted or
* unloaded.
* unloaded. A 'sparsedev' stream is for development with the same flow
* control as a stream of type development and a 'sparserel' stream is for
* release with the same flow control as a stream of type release
*/
public enum Type {
MAINLINE, RELEASE, DEVELOPMENT, VIRTUAL, TASK, UNKNOWN;
MAINLINE, RELEASE, DEVELOPMENT, VIRTUAL, TASK, UNKNOWN, SPARSEDEV, SPARSEREL;

/**
* Return a suitable Stream type as inferred from the passed-in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import static com.perforce.p4java.impl.mapbased.rpc.func.RpcFunctionMapKey.HOST;
import static com.perforce.p4java.impl.mapbased.rpc.func.RpcFunctionMapKey.IS_GROUP;
import static com.perforce.p4java.impl.mapbased.rpc.func.RpcFunctionMapKey.PERM;
import static com.perforce.p4java.impl.mapbased.rpc.func.RpcFunctionMapKey.PERM_MAX;
import static com.perforce.p4java.impl.mapbased.rpc.func.RpcFunctionMapKey.UNMAP;
import static com.perforce.p4java.impl.mapbased.rpc.func.RpcFunctionMapKey.USER;
import static java.util.Objects.nonNull;
Expand Down Expand Up @@ -67,6 +68,11 @@ public class ProtectionEntry extends MapEntry implements IProtectionEntry {
*/
private String name = null;

/**
* If -m flag is true, a single word summary of the maximum access level is reported.
*/
private String permMax = null;

/**
* Default constructor -- sets all fields to null, zero, or false.
*/
Expand Down Expand Up @@ -134,6 +140,7 @@ public ProtectionEntry(final Map<String, Object> map, final int order) {
if (map.containsKey(UNMAP)) {
type = EntryType.EXCLUDE;
}
permMax = parseString(map, PERM_MAX);
}
}

Expand Down Expand Up @@ -216,6 +223,12 @@ public void setPathExcluded(boolean pathExcluded) {
}
}

@Override

public String getPermMax() {
return permMax;
}

/**
* Add exclude ('-') to a string. If it is a double quoted string, add the
* exclude immediately after the first double quote char.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ public List<IFileSpec> localWhere(List<IFileSpec> fileSpecs) {
if (mt.translate(mt.get(i), MapTableT.RHS, s) != null) {
String depotPath = mt.translate(mt.get(i), MapTableT.RHS, s);
spec.setDepotPath(depotPath);
//Last view mapping should override all
if (spec.getDepotPath() != null) {
break;
}
}
}
resultList.add(spec);
Expand All @@ -88,6 +92,9 @@ public List<IFileSpec> localWhere(List<IFileSpec> fileSpecs) {
if (mt.translate(mt.get(i), MapTableT.LHS, s) != null) {
String clientPath = mt.translate(mt.get(i), MapTableT.LHS, s);
spec.setClientPath(clientPath);
if (spec.getClientPath() != null) {
break;
}
}
}
spec = clientPathToLocalPath(spec, client);
Expand All @@ -98,6 +105,10 @@ public List<IFileSpec> localWhere(List<IFileSpec> fileSpecs) {
if (mt.translate(mt.get(i), MapTableT.RHS, s) != null) {
String depotPath = mt.translate(mt.get(i), MapTableT.RHS, s);
spec.setDepotPath(depotPath);
//Last view mapping should override all
if (spec.getDepotPath() != null) {
break;
}
}
}
spec = clientPathToLocalPath(spec, client);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ public class RpcFunctionMapKey {
public static final String KEY = "key";
public static final String LABEL_REC_DELETED = "labelRecDeleted";
public static final String LABEL = "label";
public static final String LADDR = "listenAddr";
public static final String LINEEND = "LineEnd";
public static final String LOCAL_FILE = "localFile";
public static final String LOWER = "lower";
Expand Down Expand Up @@ -214,6 +215,7 @@ public class RpcFunctionMapKey {
public static final String SERVERID = "serverID";
public static final String SERVERLICENSE = "serverLicense";
public static final String SERVERROOT = "serverRoot";
public static final String SERVERTYPE = "serverType";
public static final String SERVERUPTIME = "serverUptime";
public static final String SERVERVERSION = "serverVersion";
public static final String SET = "set";
Expand All @@ -230,7 +232,10 @@ public class RpcFunctionMapKey {
public static final String STATUS = "status";
public static final String SUBMITOPTIONS = "SubmitOptions";
public static final String SUMMARY = "summary";
public static final String SVRID = "svrid";
public static final String SVRNAME = "svrname";
public static final String SVRTYPE = "svrtype";
public static final String SVRVERSION = "svrversion";
public static final String SYNCTIME = "syncTime";
public static final String TAG = "tag";
public static final String THEIRNAME = "theirName";
Expand Down Expand Up @@ -296,6 +301,8 @@ public class RpcFunctionMapKey {

public static final String URL = "url";

public static final String PERM_MAX = "permMax";

/**
* RPC keys map
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ public boolean match(File file) throws FileNotFoundException, IOException {
}

/**
* Check all ignore files up to the client root directory.
* Check for the ignore file as an absolute path
* or check the ignore file up to the client root directory.
*
* @param file
* the file
Expand All @@ -88,23 +89,62 @@ public boolean match(File file) throws FileNotFoundException, IOException {
*/
private boolean checkIgnoreFiles(File file) throws IOException {
if (file != null) {
// Signal for inverse match
// when ignoreFileName is in the form of absolute path
File ignoreFile = new File(ignoreFileName);
if (ignoreFile.exists() && !ignoreFileName.startsWith(".")) {
if (checkIgnorePatternInSubDirectories(ignoreFile, file)) {
return true;
}
}
// when ignoreFileName is in the form of a relative path of client root
else {
File clientRootDir = new File(clientRoot);
File fileDir = file;
do {
fileDir = fileDir.getParentFile();
if (fileDir != null) {
ignoreFile = new File(fileDir, ignoreFileName);
if (ignoreFile.exists()) {
if (checkIgnorePatternInSubDirectories(ignoreFile, file)) {
return true;
}
}
}
} while (fileDir != null && !fileDir.getAbsoluteFile().equals(clientRootDir));
}
}

return false;
}

/**
* Checks for the ignore file patterns in all the directories and sub-directories
*
* @param ignoreFile
* the ignore file
* @param file
* the file
* @return true, if successful
* @throws IOException
* Signals that an I/O exception has occurred.
*/
private boolean checkIgnorePatternInSubDirectories(File ignoreFile, File file) throws IOException {
if (file != null && ignoreFile.exists()) {
// Signal for inverse match (if negation is used in ignore rules)
Negate negate = this.new Negate();

File clientRootDir = new File(clientRoot);
File fileDir = file;

do {
fileDir = fileDir.getParentFile();
if (fileDir != null) {
File ignoreFile = new File(fileDir, ignoreFileName);
if (ignoreFile.exists()) {
if (checkIgnoreFile(ignoreFile, fileDir, file, negate)) {
// Inverse match
if (negate.isMatch()) {
return false;
}
return true;
if (traverseIgnoreFileForPattern(ignoreFile, fileDir, file, negate)) {
// Inverse match
if (negate.isMatch()) {
return false;
}
return true;
}
}
} while (fileDir != null && !fileDir.getAbsoluteFile().equals(clientRootDir));
Expand All @@ -128,7 +168,7 @@ private boolean checkIgnoreFiles(File file) throws IOException {
* @throws IOException
* Signals that an I/O exception has occurred.
*/
private boolean checkIgnoreFile(File ignoreFile, File currentDir, File file, Negate negate)
private boolean traverseIgnoreFileForPattern(File ignoreFile, File currentDir, File file, Negate negate)
throws IOException {

BufferedReader br = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,9 @@ protected RpcPacketDispatcherResult clientCrypto(RpcConnection rpcConnection, Co
boolean proxy = props.containsKey(RpcFunctionMapKey.IPADDR) && props.containsKey(RpcFunctionMapKey.SVRNAME) && props.containsKey(RpcFunctionMapKey.PORT);

String svcUser = props.getProperty(RpcFunctionMapKey.SVRNAME);
String svrId = props.getProperty(RpcFunctionMapKey.SVRID);
String svrType = props.getProperty(RpcFunctionMapKey.SVRTYPE);
String svrVersion = props.getProperty(RpcFunctionMapKey.SVRVERSION);

try {
// Use the auth ticket associated with specified server address
Expand Down Expand Up @@ -695,11 +698,10 @@ protected RpcPacketDispatcherResult clientCrypto(RpcConnection rpcConnection, Co
respMap.put(RpcFunctionMapKey.TOKEN2, resp);
}

if (proxy) {
if (proxy && daddr0 != null) {
respMap.put(RpcFunctionMapKey.CADDR, props.getProperty(RpcFunctionMapKey.IPADDR));
}
respMap.put(RpcFunctionMapKey.LADDR, props.getProperty(RpcFunctionMapKey.PORT));

if (daddr0 != null) {
digester.reset();
digester.update(svcUser.getBytes());
if (svcTicketStr != null) {
Expand All @@ -712,6 +714,16 @@ protected RpcPacketDispatcherResult clientCrypto(RpcConnection rpcConnection, Co
respMap.put("svrname0", svcUser);
respMap.put(RpcFunctionMapKey.DADDR + "0", daddr0);
respMap.put("dhash0", resp);

if(svrType != null) {
respMap.put(RpcFunctionMapKey.SERVERTYPE + "0", svrType);
}
if(svrId != null) {
respMap.put(RpcFunctionMapKey.SERVERID + "0", svrId);
}
if(svrVersion != null) {
respMap.put(RpcFunctionMapKey.SERVERVERSION + "0", svrVersion);
}
}

RpcPacket respPacket = RpcPacket.constructRpcPacket(confirm, respMap, null);
Expand Down
Loading

0 comments on commit b439d94

Please sign in to comment.