package com.perforce.wvcm;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.util.AbstractList;
import java.util.Arrays;
import java.util.Collections;
import java.util.ConcurrentModificationException;
import java.util.Date;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.NoSuchElementException;
import java.util.Properties;
import javax.wvcm.*;
import com.perforce.client.api.ClientApi;
import com.perforce.client.api.ClientUser;
import com.perforce.client.api.P4ClientException;
/**
* P4.java
*
*
* Created: Mon Jan 05 17:04:41 2004
*
* @author <a href="mailto:paulkrause88@users.sf.net">Paul Krause</a>
* @version 1.0
*/
public class P4 implements Provider {
static final String E_NOSUB = "Perforce does not support subactivities.";
static final String E_NOTFILE = "Not a file";
static final String E_NOTFOLD = "Not a folder";
static final String E_NOTWS = "Not a workspace";
static final String E_UNKLOC = "Unknown location";
static final String E_UNSLOC = "Unsupported location";
static Integer retryCount = new Integer(0);
private final ReferenceQueue referenceQueue = new ReferenceQueue();
private ClientProxy clientProxy = new ClientProxy();
public P4(ProviderFactory.Callback pfc)
throws P4ClientException
{
login(pfc);
}
public P4(ProviderFactory.Callback pfc, Hashtable env)
throws P4ClientException
{
clientProxy.setClient(String.valueOf(env.get("P4CLIENT")));
clientProxy.setHost (String.valueOf(env.get("P4PORT")));
login(pfc);
}
private void login(ProviderFactory.Callback pfc)
throws P4ClientException
{
ProviderFactory.Callback.Authentication auth =
pfc.getAuthentication(clientProxy.getClient(), retryCount);
clientProxy.setUser(auth.loginName());
clientProxy.setPassword(auth.password());
clientProxy.init();
}
// Implementation of javax.wvcm.Provider
public Location location(String name) throws WvcmException {
throw new IllegalLocationException("Unsupported", name);
}
public List serverWorkspaceFolderList(PropertyNameList pnl)
throws WvcmException
{
return Collections.EMPTY_LIST;
}
public List clientWorkspaceFolderList(PropertyNameList pnl)
throws WvcmException
{
return Collections.EMPTY_LIST;
}
public List serverSharedWorkspaceList(PropertyNameList pnl)
throws WvcmException
{
return Collections.EMPTY_LIST;
}
public ResourceList resourceList() {
return new CachedList();
}
private abstract class BaseLocation {
public Activity activity() {
return null;
}
public Folder folder() {
return null;
}
public ControllableResource controllableResource() {
return null;
}
public Workspace workspace() {
return null;
}
}
private abstract class LocalLocation extends BaseLocation {
private String clientPath;
protected LocalLocation(String path) {
clientPath = path;
}
public String string() {
return clientPath;
}
}
class LocalFolderLocation extends LocalLocation implements Location {
private Folder folderResource;
LocalFolderLocation(String path, Folder f) {
super(path);
folderResource = f;
}
public Location parent() {
return null;
}
public Resource resource() {
return folderResource;
}
public Location child(String s) throws WvcmException {
return null; // TODO
}
}
class LocalFileLocation extends LocalLocation implements Location {
private Resource fileResource;
LocalFileLocation(String path, Resource file) {
super(path);
fileResource = file;
}
public Location parent() {
return null;
}
public Resource resource() {
return fileResource;
}
public Location child(String s) throws WvcmException {
throw new NoChildrenException(E_NOTFOLD, string());
}
}
private abstract class RemoteLocation extends BaseLocation {
private String depotPath;
protected RemoteLocation(String path) {
depotPath = path;
}
public String string() {
return depotPath;
}
protected RemoteFolderLocation lookupParent() {
return null;
}
}
class RemoteFolderLocation extends RemoteLocation implements Location {
private Folder folderResource;
private RemoteFolderLocation parentLocation;
RemoteFolderLocation(String path, Folder f) {
super(path);
folderResource = f;
}
public Location parent() {
return parentLocation;
}
public Resource resource() {
if (parentLocation == null) {
parentLocation = lookupParent();
}
return folderResource;
}
public Location child(String s) throws WvcmException {
//TODO: implement
return null;
}
public Folder folder() {
return folderResource;
}
}
class RemoteFileLocation extends RemoteLocation implements Location {
private ControllableResource fileResource;
private RemoteFolderLocation parentLocation;
RemoteFileLocation(String path, ControllableResource cr) {
super(path);
fileResource = cr;
}
public Location parent() {
if (parentLocation == null) {
parentLocation = lookupParent();
}
return parentLocation;
}
public Resource resource() {
return fileResource;
}
public Location child(String s) throws WvcmException {
throw new NoChildrenException(E_NOTFOLD, string());
}
public ControllableResource controllableResource() {
return fileResource;
}
}
class CachedList extends AbstractList implements ResourceList {
private double growthFactor = 1.5;
private SoftReference[] listItems = new SoftReference[1];
public Object get(int n) {
final int m = modCount;
if (n >= m) throw new IndexOutOfBoundsException(n + " >= " + m);
return listItems[n].get();
}
public int size() {
return modCount;
}
public synchronized void add(int n, Object obj) {
final int m = modCount;
if (n > m) throw new IndexOutOfBoundsException(n + " > " + m);
modCount++;
if (n > listItems.length) {
int cap = (int) Math.ceil(listItems.length * growthFactor);
SoftReference[] items = new SoftReference[cap];
System.arraycopy(listItems, 0, items, 0, listItems.length);
listItems = items;
}
listItems[n] = new SoftReference(obj, referenceQueue);
}
public boolean add(Object obj) {
add(modCount, obj);
return true;
}
public Object set(int n, Object obj) {
final int m = modCount;
if (n >= m) throw new IndexOutOfBoundsException(n + " >= " + m);
final Object old = listItems[n].get();
listItems[n] = new SoftReference(obj, referenceQueue);
return old;
}
public synchronized Object remove(int n) {
final int m = modCount;
if (n >= m) throw new IndexOutOfBoundsException(n + " >= " + m);
modCount--;
final Object old = listItems[n].get();
System.arraycopy(listItems, n, listItems, n - 1,
listItems.length - n);
return old;
}
protected synchronized void removeRange(int from, int to) {
if (from > to) {
final String args = "removeRange(" + from + ", " + to + ")";
throw new IllegalArgumentException(args);
}
final int m = modCount;
if (to >= m) throw new IndexOutOfBoundsException(to + " >= " + m);
final int n = to - from;
modCount -= n;
System.arraycopy(listItems, to, listItems, from,
listItems.length - from);
}
// Implementation of javax.wvcm.ResourceList
/**
* Locks all the resources on this list.
*
* @return a <code>ResourceList.ResponseIterator</code> value
*/
public ResponseIterator doControl() {
final Iterator cri = iterator();
return new ResponseIterator()
{
public boolean hasNext() {
return cri.hasNext();
}
public Object next() throws WvcmException {
try {
((ControllableResource) cri.next()).doControl();
return null;
} catch (ClassCastException e) {
throw new ControlFailureException(e);
} catch (ConcurrentModificationException e) {
throw new ControlFailureException(e);
} catch (NoSuchElementException e) {
throw new ControlFailureException(e);
}
}
};
}
/**
* Submit all the resources on this list to the depot.
*
* @param keep a <code>boolean</code> flag
* @param fork a <code>boolean</code> flag
* @return a <code>ResourceList.ResponseIterator</code> value
*/
public ResponseIterator doCheckin(final boolean keep,
final boolean fork)
{
final Iterator cri = iterator();
return new ResponseIterator()
{
public boolean hasNext() {
return cri.hasNext();
}
public Object next() throws WvcmException {
try {
final ControllableResource cr =
(ControllableResource) cri.next();
cr.doCheckin(keep, fork);
return null;
} catch (ClassCastException e) {
throw new CheckinFailureException(e);
} catch (ConcurrentModificationException e) {
throw new CheckinFailureException(e);
} catch (NoSuchElementException e) {
throw new CheckinFailureException(e);
}
}
};
}
/**
* Open or reopen all the resources on this list.
*
* @param fork a <code>boolean</code> flag
* @param acts a <code>List</code> of Activity objects
* @param create a <code>boolean</code> flag
* @param share a <code>boolean</code> flag
* @return a <code>ResourceList.ResponseIterator</code> value
*/
public ResponseIterator doCheckout(final boolean fork,
final List acts,
final boolean create,
final boolean share)
{
final Iterator cri = iterator();
return new ResponseIterator()
{
public boolean hasNext() {
return cri.hasNext();
}
public Object next() throws WvcmException {
try {
final ControllableResource cr =
(ControllableResource) cri.next();
cr.doCheckout(fork, acts, create, share);
return null;
} catch (ClassCastException e) {
throw new CheckoutFailureException(e);
} catch (ConcurrentModificationException e) {
throw new CheckoutFailureException(e);
} catch (NoSuchElementException e) {
throw new CheckoutFailureException(e);
}
}
};
}
/**
* Refresh all the resources on this list from the depot.
*
* @param want a <code>PropertyNameList</code> object
* @param force a <code>boolean</code> flag
* @return a <code>ResourceList.ResponseIterator</code> value
*/
public ResponseIterator doRefresh(final PropertyNameList want,
final boolean force)
{
final Iterator cri = iterator();
return new ResponseIterator()
{
public boolean hasNext() {
return cri.hasNext();
}
public Object next() throws WvcmException {
try {
final ControllableResource cr =
(ControllableResource) cri.next();
return cr.doRefresh(want, force);
} catch (ClassCastException e) {
throw new RefreshFailureException(e);
} catch (ConcurrentModificationException e) {
throw new RefreshFailureException(e);
} catch (NoSuchElementException e) {
throw new RefreshFailureException(e);
}
}
};
}
/**
* Revert all the resources on this list.
*
* @return a <code>ResourceList.ResponseIterator</code> value
*/
public ResponseIterator doUncheckout() {
final Iterator cri = iterator();
return new ResponseIterator()
{
public boolean hasNext() {
return cri.hasNext();
}
public Object next() throws WvcmException {
try {
final ControllableResource cr =
(ControllableResource) cri.next();
cr.doUncheckout();
return null;
} catch (ClassCastException e) {
throw new UncheckoutFailureException(e);
} catch (ConcurrentModificationException e) {
throw new UncheckoutFailureException(e);
} catch (NoSuchElementException e) {
throw new UncheckoutFailureException(e);
}
}
};
}
} // CachedList
class CachedObject implements Resource {
// Implementation of javax.wvcm.Resource
public String getDisplayName() throws WvcmException {
return null;
}
public String getComment() throws WvcmException {
return null;
}
public void setComment(String text) {
}
public long getContentLength() throws WvcmException {
return 0;
}
public Location location() {
return null;
}
public String getContentType() throws WvcmException {
return null;
}
public void setContentType(String ctype) {
}
public Date getLastModified() throws WvcmException {
return null;
}
public PropertyNameList getPropertyNameList(boolean atonly)
throws WvcmException
{
return null;
}
public Resource doReadProperties(PropertyNameList pnl)
throws WvcmException
{
return null;
}
public PropertyNameList getUpdatedPropertyList() throws WvcmException {
return null;
}
public void doWriteProperties() throws WvcmException {
}
public Resource doReadContent(PropertyNameList pnl, OutputStream out)
throws WvcmException
{
return null;
}
public void doWriteContent(InputStream in, String s)
throws WvcmException
{
}
public void doCopy(String dest, boolean overwrite)
throws WvcmException
{
}
public void doUnbind() throws WvcmException {
}
public void doRebind(Location dest, boolean overwrite)
throws WvcmException
{
}
public void doBind(Location dest, boolean overwrite)
throws WvcmException
{
}
public String getContentIdentifier() throws WvcmException {
return null;
}
public Locale getContentLanguage() throws WvcmException {
return null;
}
public void setContentLanguage(Locale lang) {
}
public String getContentCharacterSet() throws WvcmException {
return null;
}
public void setContentCharacterSet(String charset) {
}
public Date getCreationDate() throws WvcmException {
return null;
}
public String getCreatorDisplayName() throws WvcmException {
return null;
}
public void setCreatorDisplayName(String string) {
}
public void setDisplayName(String string) {
}
public List getWorkspaceFolderList() throws WvcmException {
throw new NotWorkspaceException(location());
}
public Object getAttribute(PropertyNameList.AttributeName att)
throws WvcmException
{
return null;
}
public void setAttribute(PropertyNameList.AttributeName att, Object x)
{
}
public void removeAttribute(PropertyNameList.AttributeName att) {
}
public List getProviderList() throws WvcmException {
return null;
}
public String getResourceIdentifier() throws WvcmException {
return null;
}
public List getParentBindingList() throws WvcmException {
return null;
}
} // CachedObject
class Change extends CachedObject implements Activity {
final int changeNumber;
private Workspace currentWorkspace;
public Change(Workspace ws) {
this("Created " + new Date(), ws);
}
public Change(String description, Workspace ws) {
currentWorkspace = ws;
ChangeUser ui = new ChangeUser();
ui.setDescription(description);
clientProxy.newChange(ui);
changeNumber = ui.getChangeNumber();
}
public Change(int id) {
ChangeUser ui = new ChangeUser();
clientProxy.fetchChange(id, ui);
changeNumber = ui.getChangeNumber();
//TODO: fetch the client (Workspace) holding this change
}
// Implementation of javax.wvcm.Activity
public void doCreateResource() throws WvcmException {
}
public void doCheckin(boolean keep, boolean fork)
throws WvcmException
{
}
public List getActivityCheckoutList() throws WvcmException {
return null;
}
public List getActivityVersionList() throws WvcmException {
return null;
}
public List getCurrentWorkspaceList() throws WvcmException {
return Arrays.asList(new Workspace[] {currentWorkspace});
}
public List getSubactivityList() throws WvcmException {
return Collections.EMPTY_LIST;
}
public void setSubactivityList(List list) {
throw new UnsupportedOperationException(E_NOSUB);
}
} // Change
class View extends CachedObject implements Workspace {
public View() {
}
// Implementation of javax.wvcm.ControllableFolder
public Iterator readMemberList(PropertyNameList pnl, boolean deep)
throws WvcmException
{
return null;
}
public void doBaselineControl(Baseline baseline) throws WvcmException {
}
public void doBaselineControl() throws WvcmException {
}
public List getEclipsedList() throws WvcmException {
return null;
}
public boolean getBaselineControllable() throws WvcmException {
return false;
}
// Implementation of javax.wvcm.Folder
public Iterator doReadMemberList(PropertyNameList pnl, boolean deep)
throws WvcmException
{
return null;
}
public List getBindingList() throws WvcmException {
return null;
}
// Implementation of javax.wvcm.ControllableResource
public ControllableResource doMerge(Version v, boolean manual, boolean restrict, boolean fork, boolean unreserved, List acts, boolean create, PropertyNameList pnl) throws WvcmException {
return null;
}
public MergePreviewReport doMergePreviewReport(Version v)
throws WvcmException
{
return null;
}
public void doCreateResource() throws WvcmException {
}
public Resource readProperties(PropertyNameList pnl)
throws WvcmException
{
return null;
}
public Resource readContent(PropertyNameList pnl, OutputStream out)
throws WvcmException
{
return null;
}
public Iterator doRefresh(PropertyNameList pnl, boolean force)
throws WvcmException
{
return null;
}
public void doControl() throws WvcmException {
}
public void doCheckout(boolean fork, List acts, boolean create, boolean unreserved)
throws WvcmException
{
}
public void doCheckout() throws WvcmException {
}
public void doCheckin(boolean keep, boolean fork)
throws WvcmException
{
}
public void doCheckin() throws WvcmException {
}
public Workspace getWorkspace() throws WvcmException {
return null;
}
public boolean getIsCheckedOut() throws WvcmException {
return false;
}
public ControllableResource getServerState() throws WvcmException {
return null;
}
public boolean getIsStaleContent() throws WvcmException {
return false;
}
public boolean getIsDirtyContent() throws WvcmException {
return false;
}
public PropertyNameList getStalePropertyList() throws WvcmException {
return null;
}
public PropertyNameList getDirtyPropertyList() throws WvcmException {
return null;
}
public void doCreateVersionControlledResource(Version v)
throws WvcmException
{
}
public void doUncheckout() throws WvcmException {
}
public Iterator doUpdate(Version v, PropertyNameList pnl)
throws WvcmException
{
return null;
}
public void doAddLabel(String s) throws WvcmException {
}
public void doRemoveLabel(String s) throws WvcmException {
}
public void doSetLabel(String s) throws WvcmException {
}
public Version doReadLabelledVersionProperties(String s, PropertyNameList pnl)
throws WvcmException
{
return null;
}
public boolean getVersionControllable() throws WvcmException {
return false;
}
public VersionHistory getVersionHistory() throws WvcmException {
return null;
}
public Configuration getControlledConfiguration()
throws WvcmException
{
return null;
}
public Version getCheckedIn() throws WvcmException {
return null;
}
public Version getCheckedOut() throws WvcmException {
return null;
}
public List getPredecessorList() throws WvcmException {
return null;
}
public void setPredecessorList(List pre) {
}
public List getActivityList() throws WvcmException {
return null;
}
public void setActivityList(List acts) {
}
public boolean getUnreserved() throws WvcmException {
return false;
}
public void setUnreserved(boolean flag) {
}
public List getMergeList() throws WvcmException {
return null;
}
public void setMergeList(List ml) {
}
public List getAutoMergeList() throws WvcmException {
return null;
}
public void setAutoMergeList(List aml) {
}
// Implementation of javax.wvcm.Workspace
public void setServerState(Workspace ws) {
}
public List getActivityFolderList() throws WvcmException {
return null;
}
public List getVersionHistoryFolderList() throws WvcmException {
return null;
}
public List getBaselineControlledFolderList() throws WvcmException {
return null;
}
public List getCurrentActivityList() throws WvcmException {
return null;
}
public void setCurrentActivityList(List acts) {
}
public List getWorkspaceCheckoutList() throws WvcmException {
return null;
}
public List doLocateByHistoryReport(List hists, PropertyNameList pnl)
throws WvcmException
{
return null;
}
public Iterator doMerge(List src, boolean inact, boolean manual, boolean restrict, boolean fork, boolean unreserved, List acts, boolean create, PropertyNameList pnl)
throws WvcmException
{
return null;
}
public Iterator doMergePreviewReport(List src) throws WvcmException {
return null;
}
} // View
} // P4
/**
* Extended API with command methods.
*
* Perforce client commands:
* <dl>
* <dt> add <dd> Open a new file to add it to the depot
* <dt> admin <dd> Perform administrative operations on the server
* <dt> annotate <dd> Print file lines along with their revisions
* <dt> branch <dd> Create or edit a branch specification
* <dt> branches <dd> Display list of branches
* <dt> change <dd> Create or edit a changelist description
* <dt> changes <dd> Display list of pending and submitted changelists
* <dt> client <dd> Create or edit a client specification and its view
* <dt> clients <dd> Display list of known clients
* <dt> counter <dd> Display, set, or delete a counter
* <dt> counters <dd> Display list of known counters
* <dt> delete <dd> Open an existing file to delete it from the depot
* <dt> depot <dd> Create or edit a depot specification
* <dt> depots <dd> Display list of depots
* <dt> describe <dd> Display a changelist description
* <dt> diff <dd> Display diff of client file with depot file
* <dt> diff2 <dd> Display diff of two depot files
* <dt> dirs <dd> List subdirectories of a given depot directory
* <dt> edit <dd> Open an existing file for edit
* <dt> filelog <dd> List revision history of files
* <dt> files <dd> List files in the depot
* <dt> fix <dd> Mark jobs as being fixed by named changelists
* <dt> fixes <dd> List what changelists fix what job
* <dt> flush <dd> Fake a 'p4 sync' by not moving files
* <dt> fstat <dd> Dump file info
* <dt> group <dd> Change members of a user group
* <dt> groups <dd> List groups (of users)
* <dt> have <dd> List revisions last synced
* <dt> help <dd> Print this help message
* <dt> info <dd> Print out client/server information
* <dt> integrate <dd> Schedule integration from one file to another
* <dt> integrated <dd> Show integrations that have been submitted
* <dt> job <dd> Create or edit a job (defect) specification
* <dt> jobs <dd> Display list of jobs
* <dt> jobspec <dd> Edit the job template
* <dt> label <dd> Create or edit a label specification and its view
* <dt> labels <dd> Display list of labels
* <dt> labelsync <dd> Synchronize label with the current client contents
* <dt> lock <dd> Lock an opened file against changelist submission
* <dt> logger <dd> Report what jobs and changelists have changed
* <dt> obliterate <dd> Remove files and their history from the depot
* <dt> opened <dd> Display list of files opened for pending changelist
* <dt> passwd <dd> Set the user's password on the server (and client)
* <dt> print <dd> Retrieve a depot file to the standard output
* <dt> protect <dd> Modify protections in the server namespace
* <dt> rename <dd> Explains how to rename files
* <dt> reopen <dd> Change the type or changelist number of an opened file
* <dt> resolve <dd> Merge open files with other revisions or files
* <dt> resolved <dd> Show files that have been merged but not submitted
* <dt> revert <dd> Discard changes from an opened file
* <dt> review <dd> List and track changelists (for the review daemon)
* <dt> reviews <dd> Show what users are subscribed to review files
* <dt> set <dd> Set variables in the registry (Windows only)
* <dt> submit <dd> Submit open files to the depot
* <dt> sync <dd> Synchronize the client with its view of the depot
* <dt> triggers <dd> Modify list of pre-submit triggers
* <dt> typemap <dd> Modify the file name-to-type mapping table
* <dt> unlock <dd> Release a locked file but leave it open
* <dt> user <dd> Create or edit a user specification
* <dt> users <dd> Display list of known users
* <dt> verify <dd> Verify that the server archives are intact
* <dt> where <dd> Show how file names map through the client view
* <dl>
*/
class ClientProxy extends ClientApi {
// add Open a new file to add it to the depot
void add(String file, ClientUser ui) {
setArgv(new String[] {file});
run("add", ui);
}
void add(String file, int change, ClientUser ui) {
setArgv(new String[] {file, "-c", String.valueOf(change)});
run("add", ui);
}
// admin Perform administrative operations on the server
void checkpoint(String prefix, ClientUser ui) {
setArgv(new String[] {"checkpoint", prefix});
run("admin", ui);
}
void checkpoint(ClientUser ui) {
setArgv(new String[] {"checkpoint"});
run("admin", ui);
}
void checkpointCompress(String prefix, ClientUser ui) {
setArgv(new String[] {"checkpoint", "-z", prefix});
run("admin", ui);
}
void checkpointCompress(ClientUser ui) {
setArgv(new String[] {"checkpoint", "-z"});
run("admin", ui);
}
void journal(String prefix, ClientUser ui) {
setArgv(new String[] {"journal", prefix});
run("admin", ui);
}
void journal(ClientUser ui) {
setArgv(new String[] {"journal"});
run("admin", ui);
}
void journalCompress(String prefix, ClientUser ui) {
setArgv(new String[] {"journal", "-z", prefix});
run("admin", ui);
}
void journalCompress(ClientUser ui) {
setArgv(new String[] {"journal", "-z"});
run("admin", ui);
}
void stop(ClientUser ui) {
setArgv(new String[] {"stop"});
run("admin", ui);
}
// annotate Print file lines along with their revisions
void annotate(String filerev, ClientUser ui) {
setArgv(new String[] {filerev});
run("annotate", ui);
}
void annotateAll(String filerev, ClientUser ui) {
setArgv(new String[] {"-a", filerev});
run("annotate", ui);
}
void annotateNoHeader(String filerev, ClientUser ui) {
setArgv(new String[] {"-q", filerev});
run("annotate", ui);
}
void annotateAllNoHeader(String filerev, ClientUser ui) {
setArgv(new String[] {"-aq", filerev});
run("annotate", ui);
}
// branch Create or edit a branch specification
// branches Display list of branches
// change Create or edit a changelist description
void newChange(ChangeUser ui) {
setArgv(new String[] {"-i"});
run("change", ui);
}
void fetchChange(int id, ChangeUser ui) {
setArgv(new String[] {"-o", String.valueOf(id)});
run("change", ui);
}
// changes Display list of pending and submitted changelists
void fetchChanges(ClientUser ui) {
setArgv(new String[] {});
run("changes", ui);
}
void fetchChanges(String filerev, ClientUser ui) {
setArgv(new String[] {filerev});
run("changes", ui);
}
// client Create or edit a client specification and its view
// clients Display list of known clients
// counter Display, set, or delete a counter
// counters Display list of known counters
// delete Open an existing file to delete it from the depot
// depot Create or edit a depot specification
// depots Display list of depots
// describe Display a changelist description
// diff Display diff of client file with depot file
// diff2 Display diff of two depot files
// dirs List subdirectories of a given depot directory
// edit Open an existing file for edit
// filelog List revision history of files
// files List files in the depot
// fix Mark jobs as being fixed by named changelists
// fixes List what changelists fix what job
// flush Fake a 'p4 sync' by not moving files
// fstat Dump file info
// group Change members of a user group
// groups List groups (of users)
// have List revisions last synced
// help Print this help message
// info Print out client/server information
// integrate Schedule integration from one file to another
// integrated Show integrations that have been submitted
// job Create or edit a job (defect) specification
// jobs Display list of jobs
// jobspec Edit the job template
// label Create or edit a label specification and its view
// labels Display list of labels
// labelsync Synchronize label with the current client contents
// lock Lock an opened file against changelist submission
// logger Report what jobs and changelists have changed
// obliterate Remove files and their history from the depot
// opened Display list of files opened for pending changelist
// passwd Set the user's password on the server (and Windows client)
// print Retrieve a depot file to the standard output
// protect Modify protections in the server namespace
// rename Explains how to rename files
// reopen Change the type or changelist number of an opened file
// resolve Merge open files with other revisions or files
// resolved Show files that have been merged but not submitted
// revert Discard changes from an opened file
// review List and track changelists (for the review daemon)
// reviews Show what users are subscribed to review files
// set Set variables in the registry (Windows only)
// submit Submit open files to the depot
// sync Synchronize the client with its view of the depot
// triggers Modify list of pre-submit triggers
// typemap Modify the file name-to-type mapping table
// unlock Release a locked file but leave it open
// user Create or edit a user specification
// users Display list of known users
// verify Verify that the server archives are intact
// where Show how file names map through the client view
} // ClientProxy
abstract class StatUser extends ClientUser {
Properties statusMap;
public void outputStat(Properties stats) {
statusMap = stats;
}
public String getProperty(String key) {
return statusMap.getProperty(key);
}
public String getProperty(String key, String dflt) {
return statusMap.getProperty(key, dflt);
}
void setProperty(String key, String val) {
statusMap.setProperty(key, val);
}
} // StatUser
class ChangeUser extends StatUser {
final static String KEY_CHANGE = "Change";
final static String KEY_DESCRIPTION = "Description";
final static String KEY_JOBS = "Jobs";
final static String KEY_FILES = "Files";
/**
* @return the changeNumber
* @exception NumberFormatException if changeNumber.equals("new")
*/
int getChangeNumber() throws NumberFormatException {
String change = getProperty(KEY_CHANGE);
return Integer.parseInt(change);
}
String getDescription() {
return getProperty(KEY_DESCRIPTION);
}
void setDescription(String desc) {
setProperty(KEY_DESCRIPTION, desc);
}
public String inputData() throws P4ClientException {
final StringBuffer buff = new StringBuffer(80);
buff.append(KEY_DESCRIPTION).append(':')
.append(Character.LINE_SEPARATOR).append('\t')
.append(getProperty(KEY_DESCRIPTION));
//TODO: add Files
//TODO: add Jobs
return buff.toString();
}
} // ChangeUser
class CheckinFailureException extends WvcmException {
CheckinFailureException(Exception e) {
super(e.getMessage(),
P4.E_UNKLOC,
ReasonCode.CANNOT_CHECK_IN,
new Exception[] {e});
}
}
class CheckoutFailureException extends WvcmException {
CheckoutFailureException(Exception e) {
super(e.getMessage(),
P4.E_UNKLOC,
ReasonCode.CANNOT_CHECK_OUT,
new Exception[] {e});
}
}
class ControlFailureException extends WvcmException {
ControlFailureException(Exception e) {
super(e.getMessage(),
P4.E_UNKLOC,
ReasonCode.CANNOT_PUT_UNDER_CONTROL,
new Exception[] {e});
}
}
class IllegalLocationException extends WvcmException {
IllegalLocationException(String reason, String location, Exception[] e) {
super(reason, location, ReasonCode.ILLEGAL_LOCATION_SYNTAX, e);
}
IllegalLocationException(String reason, String location) {
this(reason, location, null);
}
IllegalLocationException(String location) {
this(P4.E_UNSLOC, location);
}
IllegalLocationException(Location location) {
this(location.string());
}
}
class NoChildrenException extends WvcmException {
NoChildrenException(String reason, String location, Exception[] e) {
super(reason, location, ReasonCode.CANNOT_READ_MEMBERS, e);
}
NoChildrenException(String reason, String location) {
this(reason, location, null);
}
}
class NotWorkspaceException extends WvcmException {
NotWorkspaceException(String reason, String location, Exception[] e) {
super(reason, location, ReasonCode.PROPERTY_MISSING, e);
}
NotWorkspaceException(String reason, String location) {
this(reason, location, null);
}
NotWorkspaceException(String location) {
this(P4.E_NOTWS, location);
}
NotWorkspaceException(Location location) {
this(location.string());
}
}
class RefreshFailureException extends WvcmException {
RefreshFailureException(Exception e) {
super(e.getMessage(),
P4.E_UNKLOC,
ReasonCode.CANNOT_REFRESH_DIRTY_RESOURCE,
new Exception[] {e});
}
}
class UncheckoutFailureException extends WvcmException {
UncheckoutFailureException(Exception e) {
super(e.getMessage(),
P4.E_UNKLOC,
ReasonCode.CANNOT_CANCEL_CHECKED_OUT,
new Exception[] {e});
}
}