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.Date;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Properties;
import javax.wvcm.Activity;
import javax.wvcm.Baseline;
import javax.wvcm.Configuration;
import javax.wvcm.ControllableFolder;
import javax.wvcm.ControllableResource;
import javax.wvcm.Folder;
import javax.wvcm.Location;
import javax.wvcm.PropertyNameList;
import javax.wvcm.Provider;
import javax.wvcm.ProviderFactory;
import javax.wvcm.Resource;
import javax.wvcm.ResourceList;
import javax.wvcm.Version;
import javax.wvcm.VersionHistory;
import javax.wvcm.Workspace;
import javax.wvcm.WvcmException;
import com.perforce.client.api.ClientApi;
import com.perforce.client.api.ClientUser;
import com.perforce.client.api.P4ClientException;
/**
* P4Provider.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 P4Provider implements Provider {
static final String E_NOSUB = "Perforce does not support subactivities.";
static final String E_NOTWS = "Not a workspace";
static final String E_UNLOC = "Unsupported location";
static Integer retryCount = new Integer(0);
private final ReferenceQueue referenceQueue = new ReferenceQueue();
private ClientProxy clientProxy = new ClientProxy();
public P4Provider(ProviderFactory.Callback pfc)
throws P4ClientException
{
login(pfc);
}
public P4Provider(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 null;
}
public List clientWorkspaceFolderList(PropertyNameList pnl)
throws WvcmException
{
return null;
}
public List serverSharedWorkspaceList(PropertyNameList pnl)
throws WvcmException
{
return null;
}
public ResourceList resourceList() {
return new CachedList();
}
public class CachedList extends AbstractList implements ResourceList {
private double growthFactor = 1.5;
private SoftReference[] listItems = new SoftReference[1];
public Object get(int n) {
if (n >= modCount) throw new IndexOutOfBoundsException(n + " >= " + modCount);
return listItems[n].get();
}
public int size() {
return modCount;
}
public void add(int n, Object obj) {
if (n > modCount) throw new IndexOutOfBoundsException(n + " > " + modCount);
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) {
if (n >= modCount) throw new IndexOutOfBoundsException(n + " >= " + modCount);
final Object old = listItems[n].get();
listItems[n] = new SoftReference(obj, referenceQueue);
return old;
}
public Object remove(int n) {
if (n >= modCount) throw new IndexOutOfBoundsException(n + " >= " + modCount);
modCount--;
final Object old = listItems[n].get();
System.arraycopy(listItems, n, listItems, n - 1, listItems.length - n);
return old;
}
protected void removeRange(int from, int to) {
if (from > to) throw new IllegalArgumentException("removeRange(" + from + ", " + to + ")");
if (to >= modCount) throw new IndexOutOfBoundsException(to + " >= " + modCount);
final int n = to - from;
modCount -= n;
System.arraycopy(listItems, to, listItems, from, listItems.length - n);
}
// Implementation of javax.wvcm.ResourceList
/**
* Locks all the resources on this list.
*
* @return a <code>ResourceList.ResponseIterator</code> value
*/
public ResourceList.ResponseIterator doControl() {
return null;
}
/**
* 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 ResourceList.ResponseIterator doCheckin(boolean keep, boolean fork)
{
return null;
}
/**
* 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 ResourceList.ResponseIterator doCheckout(boolean fork, List acts, boolean create, boolean share)
{
return null;
}
/**
* Refresh all the resources on this list from the depot.
*
* @param pnl a <code>PropertyNameList</code> object
* @param force a <code>boolean</code> flag
* @return a <code>ResourceList.ResponseIterator</code> value
*/
public ResourceList.ResponseIterator doRefresh(PropertyNameList pnl, boolean force) {
return null;
}
/**
* Revert all the resources on this list.
*
* @return a <code>ResourceList.ResponseIterator</code> value
*/
public ResourceList.ResponseIterator doUncheckout() {
return null;
}
} // 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 Client extends CachedObject implements Workspace {
public Client() {
}
// 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;
}
} // Client
} // P4Provider
class ClientProxy extends ClientApi {
void newChange(ChangeUser ui) {
run("change -i", ui);
}
void fetchChange(int id, ChangeUser ui) {
run("change -o " + id, ui);
}
} // 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 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(P4Provider.E_UNLOC, location);
}
IllegalLocationException(Location location) {
this(location.string());
}
}
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(P4Provider.E_NOTWS, location);
}
NotWorkspaceException(Location location) {
this(location.string());
}
}