/** * */ package com.perforce.p4java.impl.mapbased.client; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import com.perforce.p4java.Log; import com.perforce.p4java.PropertyDefs; import com.perforce.p4java.impl.generic.client.ClientView; import com.perforce.p4java.impl.generic.core.InputMapper; import com.perforce.p4java.impl.generic.core.MapEntry; import com.perforce.p4java.impl.mapbased.server.Parameters; import com.perforce.p4java.impl.mapbased.server.Server; import com.perforce.p4java.client.IClient; import com.perforce.p4java.client.IClientSummary; import com.perforce.p4java.client.IClientViewMapping; import com.perforce.p4java.core.IChangelist; import com.perforce.p4java.core.file.IFileSpec; import com.perforce.p4java.core.file.IntegrationOptions; import com.perforce.p4java.exception.AccessException; import com.perforce.p4java.exception.ConnectionException; import com.perforce.p4java.exception.P4JavaError; import com.perforce.p4java.exception.NullPointerError; import com.perforce.p4java.exception.P4JavaException; import com.perforce.p4java.exception.RequestException; import com.perforce.p4java.option.client.AddFilesOptions; import com.perforce.p4java.option.client.CopyFilesOptions; import com.perforce.p4java.option.client.DeleteFilesOptions; import com.perforce.p4java.option.client.EditFilesOptions; import com.perforce.p4java.option.client.GetDiffFilesOptions; import com.perforce.p4java.option.client.IntegrateFilesOptions; import com.perforce.p4java.option.client.LabelSyncOptions; import com.perforce.p4java.option.client.LockFilesOptions; import com.perforce.p4java.option.client.MergeFilesOptions; import com.perforce.p4java.option.client.PopulateFilesOptions; import com.perforce.p4java.option.client.ReconcileFilesOptions; import com.perforce.p4java.option.client.ReopenFilesOptions; import com.perforce.p4java.option.client.ResolveFilesAutoOptions; import com.perforce.p4java.option.client.ResolvedFilesOptions; 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.UnshelveFilesOptions; import com.perforce.p4java.option.client.UnlockFilesOptions; import com.perforce.p4java.option.server.OpenedFilesOptions; import com.perforce.p4java.server.CmdSpec; import com.perforce.p4java.server.IOptionsServer; import com.perforce.p4java.server.IServer; import com.perforce.p4java.server.callback.IStreamingCallback; /** * Default implementation of the generic parts of an IClient interface.<p> * * 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.<p> */ 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; /** * Convenience method to return a new Client object with certain default values * filled in.<p> * * 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).<p> * * 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).<p> * * 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(); client.setName(name); client.setServer(server); client.setDescription(description == null ? DEFAULT_DESCRIPTION : description); client.setOwnerName(userName); client.setRoot(rootDir); ClientView clientView = new ClientView(); clientView.setClient(client); List<IClientViewMapping> viewMappings = new ArrayList<IClientViewMapping>(); 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.<p> * * ClientSummary fields are set as noted in the ClientSummary default constructor * comments. */ 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.<p> * * 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; this.serverImpl = (Server) server; } /** * Construct a new Client object from explicit fields.<p> * * Note that any IServer object returned by the ServerFactory will work for the serverImpl * parameter; if not, a suitable cast exception will be thrown.<p> */ public Client(String name, Date accessed, Date updated, String description, String hostName, String ownerName, String root, ClientLineEnd lineEnd, IClientOptions options, IClientSubmitOptions submitOptions, List<String> alternateRoots, IServer serverImpl, ClientView clientView) { super(name, accessed, updated, description, hostName, ownerName, root, lineEnd, options, submitOptions, alternateRoots); this.serverImpl = (Server) serverImpl; this.clientView = clientView; } /** * Construct a new Client object from explicit fields.<p> * * Note that any IServer object returned by the ServerFactory will work for the serverImpl * parameter; if not, a suitable cast exception will be thrown.<p> */ public Client(String name, Date accessed, Date updated, String description, String hostName, String ownerName, String root, ClientLineEnd lineEnd, IClientOptions options, IClientSubmitOptions submitOptions, List<String> alternateRoots, IServer serverImpl, ClientView clientView, String stream) { super(name, accessed, updated, description, hostName, ownerName, root, lineEnd, options, submitOptions, alternateRoots, stream); this.serverImpl = (Server) 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.<p> * * Note that any IServer object returned by the ServerFactory will work for the serverImpl * parameter; if not, a suitable cast exception will be thrown.<p> */ public Client(IServer serverImpl, Map<String, Object> map) { super(map, false); super.refreshable = true; super.updateable = true; this.serverImpl = (Server) serverImpl; // 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<IClientViewMapping> mappingList = new ArrayList<IClientViewMapping>(); 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])); } // 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); } } /** * 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.<p> * * 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.<p> * * Note that any IServer object returned by the ServerFactory will work for the serverImpl * parameter; if not, a suitable cast exception will be thrown.<p> * * 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); this.serverImpl = (Server) 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(); } } } /** * @see com.perforce.p4java.client.IClient#getServer() */ public IServer getServer() { return this.serverImpl; } /** * Completing a client calls {@link #refresh()} and updates the * {@link #isComplete()} flag. A no op for the new IClient object. * * @see #refresh() * @see com.perforce.p4java.impl.generic.core.ServerResource#complete() */ 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() */ 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()); 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()); } } } /** * @see com.perforce.p4java.impl.generic.core.ServerResource#update() */ 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) */ 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() */ public ClientView getClientView() { return this.clientView; } /** * @see com.perforce.p4java.client.IClient#setClientView(com.perforce.p4java.impl.generic.client.ClientView) */ public void setClientView(ClientView clientView) { this.clientView = clientView; } /** * 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. */ public void setServer(IServer server) { this.serverImpl = (Server) server; } /** * @see com.perforce.p4java.client.IClient#sync(java.util.List, boolean, boolean, boolean, boolean) */ public List<IFileSpec> sync(List<IFileSpec> 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) */ public List<IFileSpec> sync(List<IFileSpec> fileSpecs, SyncOptions syncOpts) throws P4JavaException { List<IFileSpec> specList = new ArrayList<IFileSpec>(); 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<Map<String, Object>> resultMaps = this.serverImpl.execMapCmdList(CmdSpec.SYNC, Parameters.processParameters( syncOpts, fileSpecs, this.server), null); if (resultMaps != null) { for (Map<String, Object> map : resultMaps) { specList.add(this.serverImpl.handleFileReturn(map, this)); } } 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) */ public void sync(List<IFileSpec> 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#labelSync(java.util.List, java.lang.String, boolean, boolean, boolean) */ public List<IFileSpec> labelSync(List<IFileSpec> 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) */ public List<IFileSpec> labelSync(List<IFileSpec> fileSpecs, String labelName, LabelSyncOptions opts) throws P4JavaException { List<IFileSpec> specList = new ArrayList<IFileSpec>(); if (labelName == null) { throw new NullPointerError( "null label name passed to Client.labelSync()"); } List<Map<String, Object>> resultMaps = this.serverImpl.execMapCmdList(CmdSpec.LABELSYNC, Parameters.processParameters( opts, fileSpecs, "-l" + labelName, this.server), null); if (resultMaps != null) { for (Map<String, Object> map : resultMaps) { specList.add(this.serverImpl.handleFileReturn(map, this)); } } return specList; } /** * @see com.perforce.p4java.client.IClient#createChangelist(com.perforce.p4java.core.IChangelist) */ 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<Map<String, Object>> resultMaps = this.serverImpl.execMapCmdList(CmdSpec.CHANGE, new String[] { "-i" }, InputMapper.map(newChangelist)); if (resultMaps != null) { int id = IChangelist.UNKNOWN; for (Map<String, Object> 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) */ public List<IFileSpec> addFiles(List<IFileSpec> 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<IFileSpec>(); } } /** * @see com.perforce.p4java.client.IClient#addFiles(java.util.List, com.perforce.p4java.option.client.AddFilesOptions) */ public List<IFileSpec> addFiles(List<IFileSpec> fileSpecs, AddFilesOptions opts) throws P4JavaException { List<IFileSpec> resultList = new ArrayList<IFileSpec>(); List<Map<String, Object>> resultMaps = this.serverImpl.execMapCmdList( CmdSpec.ADD, Parameters.processParameters( opts, fileSpecs, this.serverImpl), null); if (resultMaps != null) { for (Map<String, Object> map : resultMaps) { resultList.add(this.serverImpl.handleFileReturn(map, this)); } } return resultList; } /** * @see com.perforce.p4java.client.IClient#deleteFiles(java.util.List, int, boolean) */ public List<IFileSpec> deleteFiles(List<IFileSpec> 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<IFileSpec>(); } } /** * @see com.perforce.p4java.client.IClient#deleteFiles(java.util.List, com.perforce.p4java.option.client.DeleteFilesOptions) */ public List<IFileSpec> deleteFiles(List<IFileSpec> fileSpecs, DeleteFilesOptions opts) throws P4JavaException { List<IFileSpec> resultList = new ArrayList<IFileSpec>(); List<Map<String, Object>> resultMaps = this.serverImpl.execMapCmdList( CmdSpec.DELETE, Parameters.processParameters( opts, fileSpecs, this.serverImpl), null); if (resultMaps != null) { for (Map<String, Object> map : resultMaps) { resultList.add(this.serverImpl.handleFileReturn(map, this)); } } return resultList; } /** * @see com.perforce.p4java.client.IClient#editFiles(java.util.List, boolean, boolean, int, java.lang.String) */ public List<IFileSpec> editFiles(List<IFileSpec> 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) */ public List<IFileSpec> editFiles(List<IFileSpec> fileSpecs, EditFilesOptions opts) throws P4JavaException { List<IFileSpec> resultList = new ArrayList<IFileSpec>(); List<Map<String, Object>> resultMaps = this.serverImpl.execMapCmdList( CmdSpec.EDIT, Parameters.processParameters( opts, fileSpecs, this.serverImpl), null); if (resultMaps != null) { for (Map<String, Object> map : resultMaps) { resultList.add(this.serverImpl.handleFileReturn(map, this)); } } return resultList; } /** * @see com.perforce.p4java.client.IClient#revertFiles(java.util.List, boolean, int, boolean, boolean) */ public List<IFileSpec> revertFiles(List<IFileSpec> 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<IFileSpec>(); } } /** * @see com.perforce.p4java.client.IClient#revertFiles(java.util.List, com.perforce.p4java.option.client.RevertFilesOptions) */ public List<IFileSpec> revertFiles(List<IFileSpec> fileSpecs, RevertFilesOptions opts) throws P4JavaException { List<IFileSpec> resultList = new ArrayList<IFileSpec>(); List<Map<String, Object>> resultMaps = this.serverImpl.execMapCmdList( CmdSpec.REVERT, Parameters.processParameters( opts, fileSpecs, null, false, this.serverImpl), null); if (resultMaps != null) { for (Map<String, Object> map : resultMaps) { resultList.add(this.serverImpl.handleFileReturn(map, this)); } } return resultList; } /** * @see com.perforce.p4java.client.IClient#haveList(java.util.List) */ public List<IFileSpec> haveList(List<IFileSpec> fileSpecs) throws ConnectionException, AccessException { List<IFileSpec> haveList = new ArrayList<IFileSpec>(); if ((this.serverImpl.getCurrentClient() == null) || !this.serverImpl.getCurrentClient().getName().equalsIgnoreCase(this.getName())) { return haveList; } List<Map<String, Object>> resultMaps = this.serverImpl.execMapCmdList( CmdSpec.HAVE, Server.getPreferredPathArray(null, fileSpecs), null); if (resultMaps != null) { for (Map<String, Object> result : resultMaps) { haveList.add(this.serverImpl.handleFileReturn(result, this)); } } return haveList; } /** * @see com.perforce.p4java.client.IClient#reopenFiles(java.util.List, int, java.lang.String) */ public List<IFileSpec> reopenFiles(List<IFileSpec> 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<IFileSpec>(); } } /** * @see com.perforce.p4java.client.IClient#reopenFiles(java.util.List, com.perforce.p4java.option.client.ReopenFilesOptions) */ public List<IFileSpec> reopenFiles(List<IFileSpec> fileSpecs, ReopenFilesOptions opts) throws P4JavaException { List<IFileSpec> reopenList = new ArrayList<IFileSpec>(); List<Map<String, Object>> resultMaps = this.serverImpl.execMapCmdList( CmdSpec.REOPEN, Parameters.processParameters( opts, fileSpecs, null, false, this.serverImpl), null); if (resultMaps != null) { for (Map<String, Object> map : resultMaps) { reopenList.add(this.serverImpl.handleFileReturn(map, this)); } } return reopenList; } /** * @see com.perforce.p4java.client.IClient#where(java.util.List) */ public List<IFileSpec> where(List<IFileSpec> fileSpecs) throws ConnectionException, AccessException { List<IFileSpec> resultList = new ArrayList<IFileSpec>(); if ((this.serverImpl.getCurrentClient() == null) || !this.serverImpl.getCurrentClient().getName().equalsIgnoreCase(this.getName())) { return resultList; } List<Map<String, Object>> resultMaps = this.serverImpl.execMapCmdList( CmdSpec.WHERE, Server.getPreferredPathArray(null, fileSpecs), null); if (resultMaps != null) { for (Map<String, Object> result : resultMaps) { resultList.add(this.serverImpl.handleFileReturn(result, this)); } } return resultList; } /** * @see com.perforce.p4java.client.IClient#openedFiles(java.util.List, int, int) */ public List<IFileSpec> openedFiles(List<IFileSpec> 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<IFileSpec>(); } } /** * @see com.perforce.p4java.client.IClient#openedFiles(java.util.List, com.perforce.p4java.option.server.OpenedFilesOptions) */ public List<IFileSpec> openedFiles(List<IFileSpec> 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<String> 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) */ public List<IFileSpec> 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<IFileSpec>(); } } /** * @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) */ public List<IFileSpec> integrateFiles(IFileSpec fromFile, IFileSpec toFile, String branchSpec, IntegrateFilesOptions opts) throws P4JavaException { List<Map<String, Object>> resultMaps = this.serverImpl.execMapCmdList( CmdSpec.INTEG, Parameters.processParameters( opts, fromFile, toFile, branchSpec, this.serverImpl), null); 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) */ public List<IFileSpec> integrateFiles(IFileSpec fromFile, List<IFileSpec> toFiles, IntegrateFilesOptions opts) throws P4JavaException { List<Map<String, Object>> resultMaps = this.serverImpl.execMapCmdList( CmdSpec.INTEG, Parameters.processParameters( opts, fromFile, toFiles, null, this.serverImpl), null); return getIntegrationFilesFromReturn(resultMaps); } /** * @see com.perforce.p4java.client.IClient#resolveFilesAuto(java.util.List, boolean, boolean, boolean, boolean, boolean) */ public List<IFileSpec> resolveFilesAuto(List<IFileSpec> 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<IFileSpec>(); } } /** * @see com.perforce.p4java.client.IClient#resolveFilesAuto(java.util.List, com.perforce.p4java.option.client.ResolveFilesAutoOptions) */ public List<IFileSpec> resolveFilesAuto(List<IFileSpec> fileSpecs, ResolveFilesAutoOptions opts) throws P4JavaException { String amFlag = null; if ((opts == null) || (!opts.isAcceptTheirs() && !opts.isAcceptYours() && !opts.isForceResolve() && !opts.isSafeMerge())) { amFlag = "-am"; } List<Map<String, Object>> resultMaps = this.serverImpl.execMapCmdList( CmdSpec.RESOLVE, Parameters.processParameters( opts, fileSpecs, amFlag, serverImpl), null); return getIntegrationFilesFromReturn(resultMaps); } /** * @see com.perforce.p4java.client.IClient#resolveFile(com.perforce.p4java.core.file.IFileSpec, java.io.InputStream) */ 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) */ public IFileSpec resolveFile(IFileSpec targetFile, InputStream sourceStream, boolean useTextualMerge, int startFromRev, int endFromRev) throws ConnectionException, RequestException, AccessException { if (targetFile == 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<String, Object> resolveMap = new HashMap<String, Object>(); IFileSpec fileSpec = null; if (serverImpl != null) { // Copy the source stream to a tmp file: File tmpFile = null; try { File tmpDir = new File(serverImpl.getProperties().getProperty( PropertyDefs.P4JAVA_TMP_DIR_KEY, System.getProperty("java.io.tmpdir"))); tmpFile = File.createTempFile("p4java", ".tmp", tmpDir); if (tmpFile != null) { FileOutputStream outStream = new FileOutputStream(tmpFile); byte[] bytes = new byte[1024]; int bytesRead = 0; 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<String> args = new ArrayList<String>(); 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(targetFile.getAnnotatedPreferredPathString()); List<Map<String, Object>> 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 this.serverImpl.handleIntegrationFileReturn(resultMaps.get(1), true); } else { return this.serverImpl.handleIntegrationFileReturn(resultMaps.get(0), false); } } } 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) */ public List<IFileSpec> resolvedFiles(List<IFileSpec> 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<IFileSpec>(); } } /** * @see com.perforce.p4java.client.IClient#resolvedFiles(java.util.List, com.perforce.p4java.option.client.ResolvedFilesOptions) */ public List<IFileSpec> resolvedFiles(List<IFileSpec> fileSpecs, ResolvedFilesOptions opts) throws P4JavaException { List<Map<String, Object>> 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) */ public List<IFileSpec> lockFiles(List<IFileSpec> 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<IFileSpec>(); } } /** * @see com.perforce.p4java.client.IClient#lockFiles(java.util.List, com.perforce.p4java.option.client.LockFilesOptions) */ public List<IFileSpec> lockFiles(List<IFileSpec> fileSpecs, LockFilesOptions opts) throws P4JavaException { List<IFileSpec> lockedList = new ArrayList<IFileSpec>(); List<Map<String, Object>> resultMaps = this.serverImpl.execMapCmdList( CmdSpec.LOCK, Parameters.processParameters(opts, fileSpecs, serverImpl), null); if (resultMaps != null) { for (Map<String, Object> result : resultMaps) { lockedList.add(this.serverImpl.handleFileReturn(result, this)); } } return lockedList; } /** * @see com.perforce.p4java.client.IClient#unlockFiles(java.util.List, int, boolean) */ public List<IFileSpec> unlockFiles(List<IFileSpec> 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<IFileSpec>(); } } /** * @see com.perforce.p4java.client.IClient#unlockFiles(java.util.List, com.perforce.p4java.option.client.UnlockFilesOptions) */ public List<IFileSpec> unlockFiles(List<IFileSpec> fileSpecs, UnlockFilesOptions opts) throws P4JavaException { List<IFileSpec> unlockedList = new ArrayList<IFileSpec>(); List<Map<String, Object>> resultMaps = this.serverImpl.execMapCmdList( CmdSpec.UNLOCK, Parameters.processParameters(opts, fileSpecs, serverImpl), null); if (resultMaps != null) { for (Map<String, Object> result : resultMaps) { unlockedList.add(this.serverImpl.handleFileReturn(result, this)); } } return unlockedList; } /** * @see com.perforce.p4java.client.IClient#getDiffFiles(java.util.List, int, boolean, boolean, boolean, boolean, boolean, boolean, boolean) */ public List<IFileSpec> getDiffFiles(List<IFileSpec> 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<IFileSpec>(); } } /** * @see com.perforce.p4java.client.IClient#getDiffFiles(java.util.List, com.perforce.p4java.option.client.GetDiffFilesOptions) */ public List<IFileSpec> getDiffFiles(List<IFileSpec> fileSpecs, GetDiffFilesOptions opts) throws P4JavaException { List<IFileSpec> diffList = new ArrayList<IFileSpec>(); List<Map<String, Object>> resultMaps = this.serverImpl.execMapCmdList( CmdSpec.DIFF, Parameters.processParameters(opts, fileSpecs, serverImpl), null); if (resultMaps != null) { for (Map<String, Object> result : resultMaps) { diffList.add(this.serverImpl.handleFileReturn(result, this)); } } return diffList; } /** * @see com.perforce.p4java.client.IClient#shelveFiles(java.util.List, int, com.perforce.p4java.option.client.ShelveFilesOptions) */ public List<IFileSpec> shelveFiles(List<IFileSpec> fileSpecs, int changelistId, ShelveFilesOptions opts) throws P4JavaException { List<IFileSpec> resultList = new ArrayList<IFileSpec>(); String changelistString = null; if (changelistId == IChangelist.DEFAULT) { changelistString = "-cdefault"; } else if (changelistId > 0) { changelistString = "-c" + changelistId; } List<Map<String, Object>> resultMaps = this.serverImpl.execMapCmdList( CmdSpec.SHELVE, Parameters.processParameters( opts, fileSpecs, changelistString, serverImpl), null); if (resultMaps != null) { for (Map<String, Object> result : resultMaps) { resultList.add(this.serverImpl.handleFileReturn(result, this)); } } return resultList; } /** * @see com.perforce.p4java.client.IClient#unshelveFiles(java.util.List, int, int, com.perforce.p4java.option.client.UnshelveFilesOptions) */ public List<IFileSpec> unshelveFiles(List<IFileSpec> fileSpecs, int sourceChangelistId, int targetChangelistId, UnshelveFilesOptions opts) throws P4JavaException { List<IFileSpec> resultList = new ArrayList<IFileSpec>(); 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<Map<String, Object>> resultMaps = this.serverImpl.execMapCmdList( CmdSpec.UNSHELVE, Parameters.processParameters( opts, fileSpecs, new String[] { sourceChangelistString, targetChangelistString}, serverImpl), null); if (resultMaps != null) { for (Map<String, Object> result : resultMaps) { resultList.add(this.serverImpl.handleFileReturn(result, this)); } } return resultList; } /** * @see com.perforce.p4java.client.IClient#shelveChangelist(int, * java.util.List, boolean, boolean, boolean) */ public List<IFileSpec> shelveChangelist(int changelistId, List<IFileSpec> 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<IFileSpec>(); } } /** * @see com.perforce.p4java.client.IClient#shelveChangelist(com.perforce.p4java.core.IChangelist) */ public List<IFileSpec> shelveChangelist(IChangelist list) throws ConnectionException, RequestException, AccessException { if (list == null) { throw new NullPointerError("Null changelist specification in shelveChangelist method call"); } List<Map<String, Object>> resultMaps = this.serverImpl.execMapCmdList(CmdSpec.SHELVE, new String[] { "-i" }, InputMapper.map(list,true)); List<IFileSpec> resultList = new ArrayList<IFileSpec>(); if (resultMaps != null) { for (Map<String, Object> result : resultMaps) { resultList.add(this.serverImpl.handleFileReturn(result, this)); } } return resultList; } /** * @see com.perforce.p4java.client.IClient#unshelveChangelist(int, * java.util.List, int, boolean, boolean) */ public List<IFileSpec> unshelveChangelist(int shelveChangelistId, List<IFileSpec> 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<IFileSpec>(); } } /** * @see com.perforce.p4java.client.IClient#submitShelvedChangelist(int) */ public List<IFileSpec> submitShelvedChangelist(int shelvedChangelistId) throws P4JavaException { if (shelvedChangelistId <= 0) { throw new RequestException( "Shelved changelist ID must be greater than zero"); } List<Map<String, Object>> resultMaps = this.serverImpl.execMapCmdList(CmdSpec.SUBMIT, new String[] { "-e", "" + shelvedChangelistId }, null); List<IFileSpec> resultList = new ArrayList<IFileSpec>(); if (resultMaps != null) { for (Map<String, Object> result : resultMaps) { resultList.add(this.serverImpl.handleFileReturn(result, this)); } } 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) */ public List<IFileSpec> copyFiles(IFileSpec fromFile, IFileSpec toFile, String branchSpec, CopyFilesOptions opts) throws P4JavaException { List<Map<String, Object>> 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) */ public List<IFileSpec> copyFiles(IFileSpec fromFile, List<IFileSpec> toFiles, CopyFilesOptions opts) throws P4JavaException { List<Map<String, Object>> 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) */ public List<IFileSpec> mergeFiles(IFileSpec fromFile, List<IFileSpec> toFiles, MergeFilesOptions opts) throws P4JavaException { List<Map<String, Object>> 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<IFileSpec> getIntegrationFilesFromReturn(List<Map<String, Object>> maps) throws P4JavaException { List<IFileSpec> integList = new ArrayList<IFileSpec>(); if (maps != null) { for (Map<String, Object> result : maps) { integList.add(this.serverImpl.handleIntegrationFileReturn(result, this)); } } return integList; } /** * @see com.perforce.p4java.client.IClient#reconcileFiles(java.util.List, com.perforce.p4java.option.client.ReconcileFilesOptions) */ public List<IFileSpec> reconcileFiles(List<IFileSpec> fileSpecs, ReconcileFilesOptions opts) throws P4JavaException { List<IFileSpec> resultList = new ArrayList<IFileSpec>(); List<Map<String, Object>> resultMaps = this.serverImpl.execMapCmdList( CmdSpec.RECONCILE, Parameters.processParameters( opts, fileSpecs, this.serverImpl), null); if (resultMaps != null) { for (Map<String, Object> map : resultMaps) { resultList.add(this.serverImpl.handleFileReturn(map, this)); } } return resultList; } /** * @see com.perforce.p4java.client.IClient#populateFiles(com.perforce.p4java.core.file.IFileSpec, java.util.List, com.perforce.p4java.option.client.PopulateFilesOptions) */ public List<IFileSpec> populateFiles(IFileSpec fromFile, List<IFileSpec> toFiles, PopulateFilesOptions opts) throws P4JavaException { List<Map<String, Object>> resultMaps = this.serverImpl.execMapCmdList( CmdSpec.POPULATE, Parameters.processParameters( opts, fromFile, toFiles, null, this.serverImpl), null); return getIntegrationFilesFromReturn(resultMaps); } }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 19903 | stuartrowe |
Branching //guest/perforce_software/p4java/... to //guest/stuartrowe/p4java/... |
||
//guest/perforce_software/p4java/r14.1/src/main/java/com/perforce/p4java/impl/mapbased/client/Client.java | |||||
#1 | 12541 | Matt Attaway | Initial add of the 14.1 p4java source code |