diff --git a/README.txt b/README.txt
deleted file mode 100644
index 331ac4d..0000000
--- a/README.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-P4Java is a java library for interacting with Perforce. It picked up where the official
-library from Perforce, P4J, left off. (It left, much, much to be desired. You couldn’t
-even use it with servers that required login via tickets) Among other projects, it is
-used in things like the Hudson Continuous Integration server. (http://hudson.dev.java.net)
-
-P4Java documentation is located here: http://tek42.com/p4java
-
-However, earlier this year (2010), Perforce came out with a new library that completely
-replaces the original one they wrote. In addition, it is completely native so you don’t
-need to install the p4 client. I believe, it is pretty close to a total feature complete
-client. So that is way cool.
-
-What isn’t way cool? That they ripped off the name, P4Java without even asking. They
-just up and announced “P4Java is here!” Hey thanks guys, I would have been happy to say
-go right ahead and use it. Maybe you could have even said thanks for saving your ass for
-years while there wasn’t a suitable library from your own company?
-
-Bitter? Yes. That’s just plain uncouth. So you won’t find a link to the new library
-here. Search for “perforce java library” on google. See which comes up. (not theirs)
\ No newline at end of file
diff --git a/checkstyle-suppressions.xml b/checkstyle-suppressions.xml
deleted file mode 100644
index 6964705..0000000
--- a/checkstyle-suppressions.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
+
+ P4Java + +P4Java is an open source Java library that allows you to interact with all Perforce SCM facilities. It provides additional support where the Perforce provided API leaves off. + +Why? + +The public API from Perforce doesn't support newer features of the server and doesn't allow you to extend upon the existing code base. And by newer, I mean features after 2001. Additionally, there is no active development against it. The last known change was in 2002. The API isn't even listed on Perforce's website. + +There are several goals for this new project to pick up where the public API leaves off. Among these are: + +Good documentation. Let's make sure you can get up and running as quickly as possible. After all, you probably aren't using this API as your core development project. +Extensible. In the event the API doesn't do something you need, it has a more open design that allows you to extend it. No final classes here! +Dependency Injection. The new API is designed with Dependancy Injection in mind so that you can easily integrate with your existing system. No static singletons! + +License + +P4Java is licensed under the LGPL. For people looking to contribute or submit patches, please send an email to info@tek42.com. While the code is hosted on a Perforce repository, we don't yet have an open source license for people to access it. +
If you are building P4Java from source, you'll need a Perforce server to run the tests against. If you don't care, there is always -Dmaven.test.skip=true
+LGPL
+Mike Wille (mike@tek42.com)
Mike Wille (mike.wille@flowz.com)
+ You can download this project in either + zip or + tar formats. +
+You can also clone the project with Git + by running: +
$ git clone git://github.com/digerata/P4Java+ + + + +
Enumeration of Strings containing
- * branch names.
- */
- public static Enumeration getBranchNames(Env env) {
- loadBranches(env);
- return branches.keys();
- }
-
- /**
- * Returns list of all branches.
- *
- * @return Enumeration of Branches.
- * @deprecated
- */
- public static Enumeration getBranches() {
- return getBranches(null);
- }
-
- /**
- * @param env
- * Source control environment.
- * @return Enumeration of Branches.
- */
- public static Enumeration getBranches(Env env) {
- return Utils.getEnumeration(getBranchIterator(env));
- }
-
- /**
- * @param env
- * Source control environment.
- * @return Iterator of Branches.
- */
- public static Iterator getBranchIterator(Env env) {
- loadBranches(env);
- Enumeration en = branches.elements();
- TreeSet ts = new TreeSet();
- while(en.hasMoreElements()) {
- ts.add(en.nextElement());
- }
- return ts.iterator();
- }
-
- /**
- * Returns a Branch with the specified name, or null if not found.
- *
- * @param name
- * Name of the branch to find.
- */
- public static synchronized Branch getBranch(String name) {
- return getBranch(null, name, true);
- }
-
- /**
- * Returns a Branch with the specified name, or null if not found.
- *
- * @param env
- * Environment to use when working with P4.
- * @param name
- * Name of the branch to find.
- * @param force
- * Indicates that the Branch should be sync'd.
- */
- public static synchronized Branch getBranch(Env env, String name, boolean force) {
- Branch b;
- if(null == name || name.trim().equals(""))
- return null;
- if(null == (b = (Branch) setCache().get(name)))
- b = new Branch(name);
- if(null != env)
- b.setEnv(env);
- b.sync();
- branches.put(name, b);
- return b;
- }
-
- /**
- * Integrate a set of files using the named branch. Creates a Change that
- * contains the integraed files. The change will be *PENDING* after this
- * completes.
- *
- * @param env
- * environment to use when working with P4.
- * @param fents
- * list of FileEntries to be integrated.
- * @param branch
- * name of the branch to integrate with.
- * @param sb
- * buffer that will contain a log of the integration.
- * @param description
- * description to be used for the Change created.
- * @return Change containing the files integrated.
- * @see Change
- */
- public static Change integrate(Env env, Vector fents, String branch, StringBuffer sb, String description)
- throws CommitException, PerforceException {
- Change c = new Change();
- c.setEnv(env);
- c.setDescription(description);
- c.setUser(User.getUser(env.getUser()));
- c.setClientName(env.getClient());
- c.commit();
- return integrate(env, fents, branch, sb, c);
- }
-
- /**
- * Integrate a set of files using the named branch. Uses the Change passed
- * in to contain the integraed files. The change will be *PENDING* after
- * this completes.
- *
- * @param env
- * environment to use when working with P4.
- * @param fents
- * list of FileEntries to be integrated.
- * @param branch
- * name of the branch to integrate with.
- * @param sb
- * buffer that will contain a log of the integration.
- * @param c
- * Change to be used to contain the integrated files.
- * @return Change containing the files integrated.
- * @see Change
- */
- public static Change integrate(Env env, Vector fents, String branch, StringBuffer sb, Change c)
- throws PerforceException {
- FileEntry fent;
-
- Enumeration en = fents.elements();
- while(en.hasMoreElements()) {
- fent = (FileEntry) en.nextElement();
- integrate(env, fent.getDepotPath() + "#" + fent.getHeadRev(), branch, sb, c);
- }
- return c;
- }
-
- /**
- * Class method for integrating using the instantiated Branch.
- *
- * @param source
- * source files to integrate from.
- * @param sb
- * buffer that will contain a log of the integration.
- * @param c
- * Change to be used to contain the integrated files.
- * @see Branch#integrate(Env,String,String,StringBuffer,Change)
- */
- public Change integrate(String source, StringBuffer sb, Change c) throws PerforceException {
- if(null == c) {
- c = new Change();
- c.setDescription("Automated Integration");
- c.commit();
- }
- return Branch.integrate(this.getEnv(), source, this.getName(), sb, c);
- }
-
- /**
- * Integrate a set of files using the named branch. Uses the Change passed
- * in to contain the integraed files. The change will be *PENDING* after
- * this completes.
- *
- * @param env
- * environment to use when working with P4.
- * @param source
- * source files to integrate from.
- * @param branch
- * name of the branch to integrate with.
- * @param sb
- * buffer that will contain a log of the integration.
- * @param c
- * Change to be used to contain the integrated files.
- * @return Change containing the files integrated.
- * @see Change
- */
- public static Change integrate(Env env, String source, String branch, StringBuffer sb, Change c)
- throws PerforceException {
- String[] intcmd = { "p4", "integrate", "-v", "-d", "-c", String.valueOf(c.getNumber()), "-b", branch, "-s",
- source };
- P4Process p;
- String l;
-
- intcmd[5] = String.valueOf(c.getNumber());
- for(int i = 0; i < 8; i++) {
- sb.append(intcmd[i]);
- sb.append(' ');
- }
- sb.append('\n');
- try {
- p = new P4Process(env);
- p.exec(intcmd);
- while(null != (l = p.readLine())) {
- if(null != sb) {
- sb.append(l);
- sb.append('\n');
- }
- }
- p.close();
- } catch(Exception ex) {
- throw new PerforceException(ex.getMessage());
- }
- return c;
- }
-
- /**
- * Stores the branch information back into p4, creating the branch if it
- * didn't already exist.
- *
- * @deprecated Use {@link #commit() commit()} instead.
- */
- public void store() throws CommitException {
- this.commit();
- }
-
- public void commit() throws CommitException {
- String[] cmd = { "p4", "branch", "-i" };
- String l;
- try {
- P4Process p = new P4Process(getEnv());
- p.exec(cmd);
- while(null != (l = p.readLine())) {
- p.println("Branch: " + getName());
- p.println("Owner: " + getOwner());
- p.println("View:");
- p.println(getView());
- p.flush();
- p.outClose();
- while(null != (l = p.readLine())) {
- }
- p.close();
- }
- } catch(Exception ex) {
- throw new CommitException(ex.getMessage());
- }
- }
-
- public void sync() {
- sync(getName());
- }
-
- /**
- * Synchronizes the Branch with the latest information from P4. This method
- * forces the Branch to contain the latest, correct information if it didn't
- * already.
- *
- * @param name
- * Name of the Branch to synchronize.
- */
- public void sync(String name) {
- if(!outOfSync(300000))
- return;
- setName(name);
- String description = "";
- String l;
- String[] cmd = { "p4", "branch", "-o", "name" };
- cmd[3] = name;
-
- try {
- P4Process p = new P4Process(getEnv());
- p.exec(cmd);
- while(null != (l = p.readLine())) {
- if(l.startsWith("#")) {
- continue;
- }
- if(l.startsWith("Branch:")) {
- setName(l.substring(8).trim());
- } else if(l.startsWith("Owner:")) {
- setOwner(l.substring(7).trim());
- } else if(l.startsWith("Description:")) {
- while(null != (l = p.readLine())) {
- if(!l.startsWith("\t"))
- break;
- description += l + "\n";
- }
- setDescription(description);
- } else if(l.startsWith("View:")) {
- while(null != (l = p.readLine())) {
- if(!(l.startsWith("\t") || l.startsWith(" ") || l.startsWith("//")))
- break;
- this.addView(l);
- }
- }
- }
- p.close();
- inSync();
- } catch(IOException ex) {
- Debug.out(Debug.ERROR, ex);
- }
- }
-
- public String toXML() {
- StringBuffer sb = new StringBuffer("HashDecay instance. Each instantiating class must create its
- * own HashDecay instance and return a reference to it through
- * the getCache method.
- *
- * The update time is what is used by the HasDecay to determine
- * when an object will decay and be discarded.
- *
- * @see HashDecay
- * @author David Markley
- * @version $Date: 2002/01/15 $ $Revision: #2 $
- */
-public interface Cacheable {
-
- /** Returns the time, in milliseconds, for this object's last update. */
- public long getUpdateTime();
-
- /** Sets the update time for this object to the current time. */
- public void refreshUpdateTime();
-
- /** Returns the time, in milliseconds, that this object was synchronized. */
- public long getSyncTime();
-
- /**
- * Tests this object to see if it is out of sync. Checks to see if the
- * expiration time is within the specified number of milliseconds.
- *
- * @param threshold
- * Number of milliseconds.
- * @return True if the object will be out of sync within the threshold.
- */
- public boolean outOfSync(long threshold);
-
- /** Invalidates this object. */
- public void invalidate();
-
- /** Marks this object as being in in sync or valid. */
- public void inSync();
-
- /** Removes any cached objects. */
- public void clearCache();
-
- /** Returns the HashDecay instance for this class */
- public HashDecay getCache();
-
- /**
- * Stores this object back into Perforce, creating it if it didn't already
- * exist.
- */
- public void commit() throws CommitException;
-
- /**
- * Brings this object back into sync with Perforce. This also sets the sets
- * the update and sync time for this object.
- */
- public void sync() throws PerforceException;
-}
diff --git a/src/main/java/com/perforce/api/Change.java b/src/main/java/com/perforce/api/Change.java
deleted file mode 100644
index ed95e94..0000000
--- a/src/main/java/com/perforce/api/Change.java
+++ /dev/null
@@ -1,810 +0,0 @@
-package com.perforce.api;
-
-import java.io.*;
-import java.util.*;
-
-/*
- * Copyright (c) 2001, Perforce Software, All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/**
- * Representation of a source control change. This class can be used to
- * determine information for a particular p4 change. It can be constructed using
- * the change number, but will not contain any additional change information
- * until the sync() method is called.
- *
- * @author David Markley
- * @version $Date: 2002/08/05 $ $Revision: #10 $
- */
-public final class Change extends SourceControlObject {
- private int number = -1;
-
- private User user = null;
-
- private String client_name = "";
-
- private String modtime_string = "";
-
- private String description = "";
-
- private int status = PENDING;
-
- private static HashDecay changes = null;
-
- /** Indicates that the Change is pending submission. */
- public final static int PENDING = 1;
-
- /** Indicates that the Change has been submitted. */
- public final static int SUBMITTED = 2;
-
- /**
- * Default no-argument constructor.
- */
- public Change() {
- super();
- getCache();
- }
-
- public Change(Env environ) {
- this();
- this.setEnv(environ);
- }
-
- /**
- * Constructor that accepts the change number. This change is not populated
- * with the correct information until the sync() method is called on it.
- *
- * @param number
- * Change number
- */
- public Change(int number) {
- this();
- this.number = number;
- }
-
- public Change(String number) {
- this();
- this.number = Integer.valueOf(number).intValue();
- }
-
- private static HashDecay setCache() {
- if(null == changes) {
- changes = new HashDecay(300000);
- changes.start();
- }
- return changes;
- }
-
- public HashDecay getCache() {
- return setCache();
- }
-
- public static Change getChange(String number) {
- return getChange(null, number, true);
- }
-
- public static Change getChange(String number, boolean force) {
- return getChange(null, number, force);
- }
-
- public static Change getChange(Env env, String number, boolean force) {
- return getChange(env, (Integer.valueOf(number)).intValue(), force);
- }
-
- public static Change getChange(int number) {
- return getChange(null, number, true);
- }
-
- public static Change getChange(int number, boolean force) {
- return getChange(null, number, force);
- }
-
- public static Change getChange(Env env, int number, boolean force) {
- Change c;
- if(null == (c = (Change) setCache().get(new Integer(number)))) {
- c = new Change(number);
- force = true;
- }
- if(null != env)
- c.setEnv(env);
- if(force)
- c.sync();
- changes.put(new Integer(number), c);
- return c;
- }
-
- public String getClientName() {
- return client_name;
- }
-
- public void setClientName(String name) {
- this.client_name = name;
- }
-
- public String getModtimeString() {
- return modtime_string;
- }
-
- public void setModtimeString(String modtime) {
- this.modtime_string = modtime;
- }
-
- /**
- * Sets the change number for the Change. This invalidates all the other
- * data for the Change.
- *
- * @param number
- * Change number
- */
- public void setNumber(int number) {
- this.number = number;
- user = null;
- description = "";
- status = PENDING;
- }
-
- /**
- * Returns the number of this Change.
- */
- public int getNumber() {
- return number;
- }
-
- /**
- * Sets the User that owns this Change.
- *
- * @param user
- * Owning user.
- */
- public void setUser(User user) {
- this.user = user;
- }
-
- /**
- * Returns the User that owns this Change.
- */
- public User getUser() {
- return user;
- }
-
- /**
- * Sets the description for the change.
- */
- public void setDescription(String description) {
- String l;
- try {
- StringBuffer sb = new StringBuffer();
- BufferedReader b = new BufferedReader(new StringReader(description));
- while(null != (l = b.readLine())) {
- sb.append('\t');
- sb.append(l.trim());
- sb.append('\n');
- }
- this.description = sb.toString();
- } catch(IOException ex) {
- this.description = description;
- }
- }
-
- /**
- * Returns the description for the Change. This description includes not
- * only the textual description provided by the user, but also the list of
- * affected files and how they were affected.
- *
- * The String returned includes newline characters.
- */
- public String getDescription() {
- return description;
- }
-
- public String getShortDescription() {
- return getShortDescription(false);
- }
-
- public String getShortDescription(boolean blurb) {
- StringBuffer sb = new StringBuffer();
- String l;
- try {
- BufferedReader b = new BufferedReader(new StringReader(getDescription()));
- while(null != (l = b.readLine())) {
- if(blurb && l.startsWith("Change"))
- continue;
- if(blurb && l.startsWith("Jobs fixed"))
- break;
- if(l.startsWith("Affected file")) {
- break;
- } else {
- sb.append(l);
- sb.append('\n');
- }
- }
- } catch(IOException ex) {
- }
- return sb.toString();
- }
-
- /**
- * Returns a Vector filled with the files (including revision numbers) that
- * were affected by this change. What was done to each file as a result of
- * this Change is stripped off.
- *
- * This method uses the value of the Change's description to determine the
- * files that are affected.
- *
- * @return Vector of Strings of files
- * affected.
- */
- public Vector getFiles() {
- Vector v = new Vector();
- try {
- BufferedReader b = new BufferedReader(new StringReader(getDescription()));
- String l, t;
- int pos;
- while(null != (l = b.readLine())) {
- t = l.trim();
-// if (t.startsWith("... ")) {
- if(t.startsWith("//")) {
- if(-1 != (pos = t.lastIndexOf(" "))) {
- v.addElement(t.substring(0, pos).trim());
- }
- }
- }
- } catch(IOException e) {
- }
- return v;
- }
-
- /**
- * Returns a Vector filled with the files (including revision numbers) that
- * were affected by this change. What was done to each file as a result of
- * this Change is stripped off.
- *
- * This method uses the value of the Change's description to determine the
- * files that are affected.
- *
- * @return Vector of FileEntry objects of
- * files affected.
- */
- public Vector getFileEntries() {
- if(PENDING == getStatus() && 0 < getNumber()) {
- return FileEntry.getOpened(getEnv(), false, false, getNumber(), null);
- }
- Vector v = new Vector();
- FileEntry fent;
- try {
- BufferedReader b = new BufferedReader(new StringReader(getDescription()));
- String l, t;
- int beg, end;
- while(null != (l = b.readLine())) {
- t = l.trim();
- if(t.startsWith("//")) {
- fent = new FileEntry();
- fent.setEnv(getEnv());
- beg = 0;
- end = 4;
- if(-1 != (end = t.indexOf('#', beg))) {
- fent.setDepotPath(t.substring(beg, end));
- beg = end + 1;
- if(-1 != (end = t.indexOf(' ', beg))) {
- fent.setHeadRev(Integer.valueOf(t.substring(beg, end).trim()).intValue());
- fent.setHeadAction(t.substring(end + 1));
- }
- } else {
- fent.setDepotPath(t);
- }
- v.addElement(fent);
- }
- }
- } catch(IOException e) {
- }
- return v;
- }
-
- /**
- * Adds the given FileEntry to the changelist. If the
- * changelist has not been committed to the server, that is done first.
- *
- * @param fent
- * file entry to be added.
- */
- public void addFile(FileEntry fent) throws PerforceException {
- if(-1 == number)
- commit();
- fent.reopen(null, this);
- }
-
- /**
- * Resolves this file. If the force flag is false, and auto-resolve is
- * attempted (p4 resolve -am). If the force flag is true, an "accept theirs"
- * resolve is completed (p4 resolve -at).
- *
- * @see FileEntry#resolve(boolean)
- * @param force
- * Indicates whether the resolve should be forced.
- */
- public String resolve(boolean force) throws PerforceException {
- StringBuffer sb = new StringBuffer();
- Enumeration en = getFileEntries().elements();
-
- try {
- while(en.hasMoreElements()) {
- sb.append(((FileEntry) en.nextElement()).resolve(force));
- }
- } catch(Exception ex) {
- throw new PerforceException(ex.getMessage());
- }
- return sb.toString();
- }
-
- /**
- * Sets status for the Change. This can be either PENDING or SUBMITTED.
- */
- public void setStatus(int status) {
- this.status = status;
- }
-
- /**
- * Returns the status for the Change. This can be either PENDING or
- * SUBMITTED.
- */
- public int getStatus() {
- return status;
- }
-
- /**
- * Submits the change, if it is pending.
- *
- * @throws SubmitException
- * If the submit fails.
- */
- public String submit() throws SubmitException {
- String l;
- StringBuffer sb = new StringBuffer();
- if(PENDING != status) {
- throw new SubmitException("Change already submitted.");
- }
- String[] cmd = { "p4", "submit", "-c", String.valueOf(getNumber()) };
- try {
- P4Process p = new P4Process(getEnv());
- p.exec(cmd);
- while(null != (l = p.readLine())) {
- sb.append(l);
- sb.append('\n');
- }
- p.close();
- } catch(Exception ex) {
- throw new SubmitException(ex.getMessage() + "\n\n" + sb.toString());
- }
- return sb.toString();
- }
-
- /**
- * Updates the change or creates a pending change.
- *
- * @deprecated Use {@link #commit() commit()} instead.
- */
- public void store() throws CommitException {
- this.commit();
- }
-
- public void commit() throws CommitException {
- Enumeration en;
- Vector fents = getFileEntries();
- StringBuffer sb = new StringBuffer();
- String[] cmd = { "p4", "change", "-i" };
- String l;
- int pos;
- boolean store_failed = false;
- try {
- P4Process p = new P4Process(getEnv());
- p.exec(cmd);
- try {
- Thread.sleep(1000);
- } catch(InterruptedException intex) { /* Ignoring Exception */
- }
- if(0 > number) {
- p.println("Change: new");
- } else {
- p.println("Change: " + getNumber());
- }
- p.println("Client: " + getClientName());
- if(null == getUser() && null != getEnv()) {
- p.println("User: " + getEnv().getUser());
- } else {
- p.println("User: " + user.getId());
- }
- p.println("Description: ");
- p.println(getDescription());
- if(null != fents && 0 < fents.size()) {
- FileEntry fent;
- p.println("Files: ");
- en = fents.elements();
- while(en.hasMoreElements()) {
- fent = (FileEntry) en.nextElement();
- p.println("\t" + fent.getDepotPath());
- }
- }
- if(Utils.isWindows()) {
- p.println("\032\n\032");
- }
- p.flush();
- p.outClose();
- Debug.notify("Change.store(): Wrote change info.");
- while(null != (l = p.readLine())) {
- Debug.notify("READ: " + l);
- if(l.startsWith("Change ") && (-1 != (pos = l.indexOf("created")))) {
- setNumber(Integer.valueOf(l.substring(7, pos - 1).trim()).intValue());
- }
- if(l.startsWith("Error"))
- store_failed = true;
- sb.append(l);
- sb.append('\n');
- }
- p.close();
- Debug.notify("Change.store(): All done reading.");
- } catch(Exception ex) {
- throw new CommitException(ex.getMessage());
- }
- if(store_failed || 0 > getNumber()) {
- throw new CommitException(sb.toString());
- }
- }
-
- /**
- * Synchronizes the Change with the correct information from P4, using
- * whatever change number has already been set in the Change. After this
- * method is called, all the information in the Change is valid.
- */
- public void sync() {
- sync(number);
- }
-
- /**
- * Sycnhronizes the Change with the correct information from P4. After this
- * method is called, all the information in the Change is valid.
- *
- * @param number
- * Change number
- */
- public void sync(int number) {
- if(SUBMITTED == status && !outOfSync(60000))
- return;
- this.number = number;
- String l, tstr;
- String[] cmd = { "p4", "describe", "-s", "number" };
- cmd[3] = String.valueOf(number);
- boolean wasFound = false;
- try {
- P4Process p = new P4Process(getEnv());
- p.exec(cmd);
- while(null != (l = p.readLine())) {
- if(!wasFound && l.startsWith("Change")) {
- tstr = l.substring(l.indexOf("by") + 3).trim();
- tstr = tstr.substring(0, tstr.indexOf("@"));
- user = User.getUser(getEnv(), tstr);
- modtime_string = l.substring(l.indexOf(" on ") + 4).trim();
- if(-1 == l.indexOf("pending")) {
- status = SUBMITTED;
- }
- description = l;
- wasFound = true;
- } else {
- description += l.trim() + "\n";
- }
- }
- p.close();
- inSync();
- } catch(IOException ex) {
- Debug.out(Debug.ERROR, ex);
- }
- }
-
- /**
- * Reverts all the files associated with a pending changelist.
- */
- public void revert() throws PerforceException {
- if(PENDING != status) {
- throw new PerforceException("Change already submitted.");
- }
- Enumeration en = getFileEntries().elements();
- try {
- while(en.hasMoreElements()) {
- ((FileEntry) en.nextElement()).revert();
- }
- } catch(Exception ex) {
- throw new PerforceException(ex.getMessage());
- }
- }
-
- /**
- * Delete the pending changelist. This method will revert any open files
- * associated with the changelist and then delete it.
- *
- * @return log of delete command.
- */
- public String delete() throws PerforceException {
- this.revert();
- return this.deleteEmptyChange();
- }
-
- /**
- * Deletes the Changelist if it is empty.
- *
- * @deprecated Use delete method instead.
- * @return String Contents of the information returned by P4 as a result of
- * the delete call.
- */
- public String deleteEmptyChange() throws PerforceException {
- String l;
- StringBuffer sb = new StringBuffer();
- if(PENDING != status) {
- throw new PerforceException("Change already submitted.");
- }
-
- String[] cmd = { "p4", "change", "-d", String.valueOf(getNumber()) };
- try {
- P4Process p = new P4Process(getEnv());
- p.exec(cmd);
- while(null != (l = p.readLine())) {
- sb.append(l);
- sb.append('\n');
- }
- p.close();
- } catch(Exception ex) {
- throw new PerforceException(ex.getMessage() + "\n\n" + sb.toString());
- }
- return sb.toString();
- }
-
- /**
- * Overrides the default toString() method.
- */
- public String toString() {
- StringBuffer sb = new StringBuffer("Change: ");
- sb.append(number);
- sb.append("\nUser: ");
- sb.append(user);
- sb.append("\nDescription:\n");
- sb.append(description);
- return sb.toString();
- }
-
- public static Change[] getChanges(Env env, String path) throws PerforceException {
- return getChanges(env, path, 100, null, null, false, null);
- }
-
- public static Change[] getChanges(String path) throws PerforceException {
- return getChanges(null, path, 100, null, null, false, null);
- }
-
- public static Change[] getChanges(Env env, String path, int max, String start, String end, boolean use_integs,
- String ufilter) throws PerforceException {
- int cmdlen = 8;
- String[] cmd;
- String tpath = path;
-
- if(use_integs)
- cmdlen++;
- if(null == tpath)
- tpath = "";
-
- if(null != start && !start.trim().equals("")) {
- tpath += "@" + start;
- if(null != end && !end.trim().equals("")) {
- tpath += "," + end;
- }
- }
-
- if(tpath.trim().equals(""))
- cmdlen--;
- cmd = new String[cmdlen];
- if(!tpath.trim().equals(""))
- cmd[cmdlen - 1] = tpath;
-
- cmd[0] = "p4";
- cmd[1] = "changes";
- cmd[2] = "-m";
- cmd[3] = String.valueOf(max);
- cmd[4] = "-l";
- cmd[5] = "-s";
- cmd[6] = "submitted";
- if(use_integs)
- cmd[7] = "-i";
- Vector v = new Vector();
- Change[] chngs;
- StringTokenizer st;
- int num;
- String l, id, description = "";
- User user;
- Change c = null;
- String modtime, client_name;
-
- try {
- P4Process p = new P4Process(env);
- p.setRawMode(true);
- p.exec(cmd);
- while(null != (l = p.readLine())) {
- if(l.startsWith("info: Change")) {
- l = l.substring(6).trim();
- st = new StringTokenizer(l);
- if(!st.nextToken().equals("Change"))
- continue;
- try {
- num = Integer.parseInt(st.nextToken());
- } catch(Exception ex) {
- throw new PerforceException("Could not parse change number from line: " + l);
- }
- if(!st.nextToken().equals("on"))
- continue;
- modtime = st.nextToken();
- if(!st.nextToken().equals("by"))
- continue;
- id = st.nextToken();
- int pos = id.indexOf("@");
- client_name = id.substring(pos + 1);
- id = id.substring(0, pos);
- user = User.getUser(env, id);
- if(null != c) {
- c.setDescription(description);
- }
- description = "";
- c = new Change(num);
- c.setEnv(env);
- c.setUser(user);
- c.setClientName(client_name);
- c.setModtimeString(modtime);
- if(null == ufilter || id.equals(ufilter)) {
- v.addElement(c);
- }
- } else {
- l = l.substring(5).trim();
- description += l + "\n";
- }
- }
- if(null != c) {
- c.setDescription(description);
- }
- p.close();
- } catch(IOException ex) {
- Debug.out(Debug.ERROR, ex);
- }
- chngs = new Change[v.size()];
- for(int i = 0; i < v.size(); i++) {
- chngs[i] = (Change) v.elementAt(i);
- changes.put(new Integer(chngs[i].getNumber()), chngs[i]);
- }
- return chngs;
- }
-
- public String toXML() {
- StringBuffer sb = new StringBuffer("true, the thread number is included in all
- * debugging output.
- */
- public static void setShowThread(boolean show) {
- show_thread = show;
- }
-
- /**
- * Returns the state of showing threads in degugging output.
- */
- public static boolean getShowThread() {
- return show_thread;
- }
-
- /**
- * Sets the EventLog that debugging output should be sent to.
- *
- * @param elog
- * EventLog to use.
- */
- public static void setEventLog(EventLog elog) {
- Debug.elog = elog;
- }
-
- /**
- * Returns the current EventLog in use.
- */
- public static EventLog getEventLog() {
- return elog;
- }
-
- /**
- * Sets the logging level. This determines where the debugging output will
- * be sent. Valid values are "none", "only", or "split". The default is
- * "only". The default value will be set, if the String does
- * not match.
- */
- public static void setLogLevel(String level) {
- if(level.equalsIgnoreCase("split")) {
- setLogLevel(Debug.LOG_SPLIT);
- } else if(level.equalsIgnoreCase("only")) {
- setLogLevel(Debug.LOG_ONLY);
- } else {
- setLogLevel(Debug.LOG_NONE);
- }
- }
-
- /**
- * Sets the logging level from the supplied Properties. This
- * looks for the "p4.log_level" property with the value of either "none",
- * "split", or "only".
- */
- public static void setProperties(Properties props) {
- String log = props.getProperty("p4.log_level", "none");
- if(log.equalsIgnoreCase("split")) {
- Debug.log_level = Debug.LOG_SPLIT;
- } else if(log.equalsIgnoreCase("only")) {
- Debug.log_level = Debug.LOG_ONLY;
- } else {
- Debug.log_level = Debug.LOG_NONE;
- }
- }
-
- /**
- * Sets the logging level. This determines where the debugging output will
- * be sent. Valid values are: {@link #LOG_SPLIT LOG_SPLIT},
- * {@link #LOG_ONLY LOG_ONLY}, and {@link #LOG_NONE LOG_NONE}. The default
- * is {@link #LOG_ONLY LOG_ONLY}.
- *
- * If the log level is set to {@link #LOG_NONE LOG_NONE}, then the debug
- * level is automatically set to {@link #NONE NONE}.
- */
- public static void setLogLevel(int log_level) {
- Debug.log_level = log_level;
- if(Debug.LOG_NONE == Debug.log_level)
- Debug.level = Debug.NONE;
- }
-
- /**
- * Returns the current logging level.
- */
- public static int getLogLevel() {
- return Debug.log_level;
- }
-
- /**
- * Sends the message to the EventLog
- *
- * @see EventLog
- */
- private static void errLog(String msg, String level) {
- if(null == elog)
- return;
- elog.log(getThreadName() + msg, level);
- }
-
- /**
- * @return The current Thread Name if show_thread is true
- */
- private static String getThreadName() {
- return show_thread ? Thread.currentThread().getName() + ": " : "";
- }
-
- /**
- * Displays an error message for debugging. If the debugging level is set
- * below ERROR, then no message is displayed.
- *
- * @param msg
- * The debugging error message.
- */
- public static void error(String msg) {
- if(ERROR > level)
- return;
- System.out.println(getThreadName() + "ERROR: " + msg);
- System.out.flush();
- if(LOG_SPLIT <= log_level) {
- errLog(msg, "ERROR");
- }
- }
-
- /**
- * Displays a warning message for debugging. If the debugging level is set
- * below WARNING, then no message is displayed.
- *
- * @param msg
- * The debugging warning message.
- */
- public static void warn(String msg) {
- if(WARNING > level)
- return;
- if(LOG_SPLIT >= log_level) {
- System.out.println(getThreadName() + "WARNING: " + msg);
- System.out.flush();
- }
- if(LOG_SPLIT <= log_level) {
- errLog(msg, "WARNING");
- }
- }
-
- /**
- * Displays a notice message for debugging. If the debugging level is set
- * below NOTICE, then no message is displayed.
- *
- * @param msg
- * The debugging notice message.
- */
- public static void notify(String msg) {
- if(NOTICE > level)
- return;
- if(LOG_SPLIT >= log_level) {
- System.out.println(getThreadName() + msg);
- System.out.flush();
- }
- if(LOG_SPLIT <= log_level) {
- errLog(msg, "NOTIFY");
- }
- }
-
- /**
- * Displays a notice message for debugging. If the debugging level is set
- * below NOTICE, then no message is displayed.
- *
- * @param msg
- * The debugging notice message.
- * @param arry
- * Array containing useful debug information.
- */
- public static void notify(String msg, String[] arry) {
- if(NOTICE > level)
- return;
- StringBuffer sb = new StringBuffer();
- for(int i = 0; i < arry.length; i++) {
- sb.append(arry[i]);
- sb.append(' ');
- }
- if(LOG_SPLIT >= log_level) {
- System.out.println(getThreadName() + msg + sb);
- System.out.flush();
- }
- if(LOG_SPLIT <= log_level) {
- errLog(msg + sb, "NOTIFY");
- }
- }
-
- /**
- * Displays a verbose message for debugging. If the debugging level is set
- * below VERBOSE, then no message is displayed.
- *
- * @param msg
- * The debugging notice message.
- */
- public static void verbose(String msg) {
- if(VERBOSE > level)
- return;
- if(LOG_SPLIT >= log_level) {
- System.out.println(getThreadName() + msg);
- System.out.flush();
- }
- if(LOG_SPLIT <= log_level) {
- errLog(msg, "VERBOSE");
- }
- }
-
- /**
- * Displays a verbose message for debugging. If the debugging level is set
- * below VERBOSE, then no message is displayed.
- *
- * @param msg
- * The debugging notice message.
- * @param arry
- * Array containing useful debug information.
- */
- public static void verbose(String msg, String[] arry) {
- if(VERBOSE > level)
- return;
- StringBuffer sb = new StringBuffer();
- for(int i = 0; i < arry.length; i++) {
- sb.append(arry[i]);
- sb.append(' ');
- }
- if(LOG_SPLIT >= log_level) {
- System.out.println(getThreadName() + msg + sb);
- System.out.flush();
- }
- if(LOG_SPLIT <= log_level) {
- errLog(msg + sb, "VERBOSE");
- }
- }
-
- /**
- * Writes the message associated with the Throwable to the
- * debugging output.
- *
- * @param level
- * Debugging level to associate with the message.
- * @param t
- * Throwable that contains the message.
- */
- public static void out(int level, Throwable t) {
- out("{0}", level, t);
- }
-
- /**
- * Writes the formatted message associated with the Throwable
- * to the debugging output. The message will be placed in the string
- * generated wherever the '{0}' attribute is placed.
- *
- * @see java.text.MessageFormat
- * @param format
- * Format to use for the debugging output.
- * @param level
- * Debugging level to associate with the message.
- * @param t
- * Throwable that contains the message.
- */
- public static void out(String format, int level, Throwable t) {
-
- if(level > Debug.level)
- return;
- try {
- StringWriter sw = new StringWriter();
- PrintWriter pw = new PrintWriter(sw);
- t.printStackTrace(pw);
- pw.close();
- Object[] args = { sw.toString() };
- String msg = MessageFormat.format(format, args);
- if(LOG_SPLIT >= log_level) {
- System.out.println(getThreadName() + msg);
- System.out.flush();
- }
- if(LOG_SPLIT <= log_level) {
- errLog(msg, Debug.getLevelName(level));
- }
- } catch(Exception ex) {
- System.err.println(t);
- System.err.flush();
- }
- }
-
- /**
- * Writes the message to the debugging output.
- *
- * @param level
- * Debugging level to associate with the message.
- * @param msg
- * Debugging message.
- */
- public static void out(int level, String msg) {
- if(level > Debug.level)
- return;
- if(LOG_SPLIT >= log_level) {
- System.out.println(getThreadName() + msg);
- System.out.flush();
- }
- if(LOG_SPLIT <= log_level) {
- errLog(msg, Debug.getLevelName(level));
- }
- }
-
- /**
- * Writes the message and associated array of Strings to the debugging
- * output. The message will be followed by all the elements in the
- * arry.
- *
- * @param level
- * Debugging level to associate with the message.
- * @param msg
- * Debugging message.
- * @param arry
- * Array of strings to be sent to the debugging output.
- */
- public static void out(int level, String msg, String[] arry) {
- if(level > Debug.level)
- return;
- StringBuffer sb = new StringBuffer();
- for(int i = 0; i < arry.length; i++) {
- sb.append(arry[i]);
- sb.append(' ');
- }
- if(LOG_SPLIT >= log_level) {
- System.out.println(getThreadName() + msg + sb);
- System.out.flush();
- }
- if(LOG_SPLIT <= log_level) {
- errLog(msg + sb, Debug.getLevelName(level));
- }
- }
-}
diff --git a/src/main/java/com/perforce/api/DirEntry.java b/src/main/java/com/perforce/api/DirEntry.java
deleted file mode 100644
index f44f7ac..0000000
--- a/src/main/java/com/perforce/api/DirEntry.java
+++ /dev/null
@@ -1,377 +0,0 @@
-package com.perforce.api;
-
-import java.io.*;
-import java.util.*;
-
-/*
- * Copyright (c) 2001, Perforce Software, All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/**
- * Representation of a source control directory.
- *
- * @author David Markley
- * @version $Date: 2001/11/05 $ $Revision: #1 $
- */
-public final class DirEntry extends SourceControlObject {
- private String path;
-
- private DirEntry parent;
-
- private boolean opened = false;
-
- private Vector subdirs = null;
-
- private Vector files = null;
-
- private static HashDecay dirs = null;
-
- /** Default, no-argument constructor. */
- public DirEntry() {
- super();
- subdirs = new Vector();
- files = new Vector();
- setCache();
- }
-
- /**
- * Constructs a directory entry.
- *
- * @param e
- * Source control environment to use.
- */
- public DirEntry(Env e) {
- this();
- setEnv(e);
- }
-
- /**
- * Constructs a directory entry.
- *
- * @param e
- * Source control environment to use.
- * @param path
- * The path for this directory.
- */
- public DirEntry(Env e, String path) {
- this(e);
- setPath(path);
- }
-
- /**
- * Constructs a directory entry.
- *
- * @param base
- * Another DirEntry used to set the environment.
- * @param path
- * The path for this directory.
- */
- public DirEntry(DirEntry base, String path) {
- this();
- setEnv(base.getEnv());
- setPath(path);
- }
-
- /**
- * Loads the directories and files for this directory.
- */
- public void sync() {
- try {
- loadDirs(getEnv());
- loadFiles(getEnv(), path);
- inSync();
- } catch(Exception ex) {
- }
- }
-
- /**
- * Does nothing. Doesn't do anything here, since directories are not really
- * stored in perforce.
- */
- public void commit() {
- }
-
- private static HashDecay setCache() {
- if(null == dirs) {
- dirs = new HashDecay(120000);
- dirs.start();
- }
- return dirs;
- }
-
- public HashDecay getCache() {
- return setCache();
- }
-
- /**
- * Returns a directory entry for the supplied path.
- *
- * @param env
- * Source control environment to use.
- * @param path
- * The path for this directory.
- * @param sync
- * Forces the directory information to be current.
- */
- public static DirEntry getDirEntry(Env env, String path, boolean sync) {
- DirEntry de;
- if(null == path || path.trim().equals(""))
- return null;
- if(null == (de = (DirEntry) setCache().get(path))) {
- de = new DirEntry(env, path);
- }
- if(null != env)
- de.setEnv(env);
- if(sync)
- de.sync();
- dirs.put(path, de);
- return de;
- }
-
- /**
- * Sets the path for this directory.
- *
- * @param path
- * New path for this directory.
- */
- public void setPath(String path) {
- if(null == path)
- return;
- path = path.trim();
- if(path.equals("") || !path.startsWith("//"))
- return;
- // TODO: Add checks for wildcards here!!!
- /*
- * if (null != alldirs) { synchronized (alldirs) { if (this ==
- * (DirEntry)(alldirs.get(this.path))) { alldirs.remove(this.path); }
- * alldirs.put(path, this); } }
- */
- this.path = path;
- }
-
- /**
- * Returns the path for this directory.
- */
- public String getPath() {
- return this.path;
- }
-
- /**
- * Returns the base path for this directory. This includes everything up to
- * the last path delimeter.
- */
- public String getBasePath() {
- int pos = path.lastIndexOf('/');
- if(-1 == pos) {
- return "//";
- }
- return path.substring(0, pos + 1);
- }
-
- /**
- * Returns the parent director. Constructs a new DirEntry
- * that represents the parent and returns it.
- */
- public DirEntry getParent() {
- DirEntry parent = null;
- int pos;
-
- if(-1 == (pos = path.lastIndexOf('/')))
- return null;
- String parent_path = path.substring(0, pos);
- if(parent_path.equals("/"))
- return null;
- /*
- * if (null != alldirs) { synchronized (alldirs) { parent =
- * (DirEntry)alldirs.get(parent_path); } }
- */
- if(null == parent) {
- parent = new DirEntry(this, parent_path);
- }
- return parent;
- }
-
- /**
- * Returns an array of directory names.
- */
- public String[] getDirNames() {
- return getDirNames(getEnv());
- }
-
- /**
- * Returns an array of directory names.
- *
- * @param env
- * Source control environment to use.
- */
- public String[] getDirNames(Env env) {
- String[] names;
- loadDirs(env);
- synchronized(subdirs) {
- names = v2a(subdirs);
- }
- return names;
- }
-
- /**
- * Loads the directories, using the default environment.
- */
- private void loadDirs() {
- loadDirs(getEnv());
- }
-
- /**
- * Loads the directories, using the specified environment.
- *
- * @param env
- * Source control environment to use.
- */
- private void loadDirs(Env env) {
- if(!outOfSync(60000))
- return;
- String[] cmd = { "p4", "dirs", path + "%1" };
- String l, dir;
- int pos;
-
- synchronized(subdirs) {
- subdirs.removeAllElements();
- }
-
- try {
- P4Process p = new P4Process(env);
- p.exec(cmd);
- while(null != (l = p.readLine())) {
- if((!l.startsWith("//")) || (-1 != l.indexOf(" - "))) {
- continue;
- }
- dir = l.trim();
- if(-1 != (pos = dir.lastIndexOf('/'))) {
- dir = dir.substring(pos + 1).trim();
- }
- synchronized(subdirs) {
- subdirs.addElement(dir);
- }
- }
- p.close();
- } catch(IOException ex) {
- Debug.out(Debug.ERROR, ex);
- }
- }
-
- /**
- * Converts a Vector to a String. This shows
- * how old this code is. Vector didn't always do this for us.
- */
- private String[] v2a(Vector v) {
- String[] tmp = new String[v.size()];
- for(int i = 0; i < v.size(); i++) {
- tmp[i] = (String) v.elementAt(i);
- }
- return tmp;
- }
-
- /**
- * Returns an array of file entries for this directory.
- */
- public FileEntry[] getFiles() {
- return getFiles(getEnv());
- }
-
- /**
- * Returns an array of file entries for this directory.
- *
- * @param env
- * Source control environment to use.
- */
- public FileEntry[] getFiles(Env env) {
- loadFiles(env, path);
- if(null == files)
- return null;
- FileEntry[] tmp;
- synchronized(files) {
- tmp = new FileEntry[files.size()];
- for(int i = 0; i < files.size(); i++) {
- tmp[i] = (FileEntry) files.elementAt(i);
- tmp[i].setEnv(env);
- }
- }
- return tmp;
- }
-
- /**
- * Returns an array of file names for this directory.
- */
- public String[] getFileNames() {
- return getFileNames(getEnv());
- }
-
- /**
- * Returns an array of file names for this directory.
- *
- * @param env
- * Source control environment to use.
- */
- public String[] getFileNames(Env env) {
- String[] names;
- loadFiles(env, path);
- if(null == files) {
- names = new String[1];
- names[0] = "";
- return names;
- }
- synchronized(files) {
- names = new String[files.size()];
- for(int i = 0; i < files.size(); i++) {
- names[i] = ((FileEntry) files.elementAt(i)).getName();
- }
- }
- return names;
- }
-
- /**
- * Loads the files in this directory.
- */
- private void loadFiles() {
- loadFiles(getEnv(), path);
- }
-
- /**
- * Loads the files in this directory.
- *
- * @param env
- * Source control environment to use.
- * @param path
- * Directory path to use, instead of this one.
- */
- private void loadFiles(Env env, String path) {
- if(!outOfSync(60000))
- return;
- files = FileEntry.getFiles(env, path);
- }
-
- public String toXML() {
- StringBuffer sb = new StringBuffer("
P4Process instance by the
- * SourceControlObject instances. It can also be set in the
- * {@link P4Process#getBase() base} P4Process instance. This will cause it to be
- * used as the default environment for all command execution.
- *
- * Values for the environment can be easily loaded from a
- * {@link java.util.Properties Properties} file. This makes configuration of the
- * environment much simpler.
- *
- * @see java.util.Properties
- * @author David Markley
- * @version $Date: 2002/05/16 $ $Revision: #5 $
- */
-public class Env {
- private boolean envp_valid = false;
-
- private String[] envp;
-
- private Hashtable environ;
-
- private Properties props;
-
- private String p4_exe; // Full path to the P4 executable.
-
- private String sep_path = null;
-
- private String sep_file = null;
-
- private long threshold = 10000;
-
- /** Default, no-argument constructor. */
- public Env() {
- super();
- environ = new Hashtable();
- environ.put("P4USER", "robot");
- environ.put("P4CLIENT", "robot-client");
- environ.put("P4PORT", "localhost:1666");
- environ.put("P4PASSWD", "");
- environ.put("PATH", "C:\\Program Files\\Perforce");
- environ.put("CLASSPATH", "/usr/share/java/p4.jar");
- environ.put("SystemDrive", "C:");
- environ.put("SystemRoot", "C:\\WINNT");
- environ.put("PATHEXT", ".COM;.EXE;.BAT;.CMD");
- setFromProperties(new Properties(System.getProperties()));
- }
-
- /**
- * Constructs an environment from a properties file.
- *
- * @param propfile
- * full path to a properties file.
- */
- public Env(String propfile) throws PerforceException {
- this();
-
- setFromProperties(propfile);
- }
-
- /**
- * Constructor that uses another environment as its basis. This is useful
- * for cloning environments and then changing a few attributes.
- *
- * @param base
- * Environment to be copied into the new environment.
- */
- public Env(Env base) {
- this();
- this.environ = (Hashtable) base.environ.clone();
- this.props = (Properties) base.props.clone();
- this.p4_exe = base.getExecutable();
- }
-
- /**
- * Constructor that uses a set of Properties to set up the
- * environment.
- *
- * @see #setFromProperties(Properties)
- * @param props
- * Used to construct the environment.
- */
- public Env(Properties props) {
- this();
- setFromProperties(props);
- }
-
- /**
- * Allows the user to set any environment variable. If the variable name
- * starts with 'P4', the value can not be set to null. It will instead be
- * set to the empty string. For all other variable, supplying a null value
- * will remove that variable form the environment.
- *
- * @param name
- * environment variable name
- * @param value
- * environment variable value
- */
- public void setenv(String name, String value) {
- if(null == name)
- return;
- synchronized(environ) {
- if(null == value) {
- if(name.startsWith("P4")) {
- environ.put(name, "");
- } else {
- environ.remove(name);
- }
- } else {
- environ.put(name, value);
- }
- }
- envp_valid = false;
- }
-
- /**
- * Returns the value for the named environment variable.
- *
- * @param name
- * environment variable name
- */
- public String getenv(String name) {
- synchronized(environ) {
- return (String) environ.get(name);
- }
- }
-
- /**
- * Returns the environment in a String array.
- */
- public String[] getEnvp() {
- String var;
- if(!envp_valid) {
- synchronized(environ) {
- envp = new String[environ.size()];
- Enumeration en = environ.keys();
- int i = 0;
- while(en.hasMoreElements()) {
- var = (String) en.nextElement();
- envp[i++] = var + "=" + environ.get(var);
- }
- }
- envp_valid = true;
- }
- return envp;
- }
-
- /**
- * Checks the environment to see if it is valid. To check the validity of
- * the environment, the user information is accessed. This ensures that the
- * server can be contacted and that the password is set properly.
- *
- * If the environment is valid, this method will return quietly. Otherwise,
- * it will throw a PerforceException with a message regarding
- * the failure.
- */
- public void checkValidity() throws PerforceException {
- String[] msg = { "Connect to server failed; check $P4PORT", "Perforce password (P4PASSWD) invalid or unset.",
- "Can't create a new user - over license quota." };
- int msgndx = -1, i, cnt = 0;
-
- P4Process p = null;
- String l;
- String[] cmd = { "p4", "user", "-o" };
-
- try {
- p = new P4Process(this);
- p.exec(cmd);
- while(null != (l = p.readLine())) {
- cnt++;
- for(i = 0; i < msg.length; i++) {
- if(-1 != l.indexOf(msg[i]))
- msgndx = i;
- }
- }
- p.close();
- } catch(IOException ex) {
- if(null != p) {
- try {
- p.close();
- } catch(Exception ignex) { /* Ignored Exception */
- }
- }
- }
- if(-1 != msgndx)
- throw new PerforceException(msg[msgndx]);
- if(0 == cnt)
- throw new PerforceException("No output from p4 user -o");
- }
-
- /**
- * Returns a Vector containing the property value list, as
- * split up by the commas. This is used to get the values for a property in
- * the form of:
- *
- * some.property.key=val1,val2,val3 - *
- * Will always return a Vector, even if it is empty.
- *
- * @param key
- * the property key
- * @param defaultValue
- * a default value
- */
- public Vector getPropertyList(String key, String defaultValue) {
- return getPropertyList(key, defaultValue, ",");
- }
-
- /**
- * Returns a Vector containing the property value list, as
- * split up by the specified delimeter. This is used to get the values for a
- * property in the form of:
- *
- * some.property.key=val1,val2,val3 - *
- * Will always return a Vector, even if it is empty.
- *
- * @param key
- * the property key
- * @param defaultValue
- * a default value
- * @param delimeter
- * string that seperates the values
- */
- public Vector getPropertyList(String key, String defaultValue, String delimeter) {
- Vector v = new Vector();
- String val, tok;
- StringTokenizer st;
-
- val = getProperty(key, defaultValue);
- st = new StringTokenizer(val, delimeter);
- while(st.hasMoreTokens()) {
- v.addElement(st.nextToken());
- }
- return v;
- }
-
- /**
- * Returns a new Properties instance that is set using the
- * environments properties as its default.
- */
- public Properties getProperties() {
- return new Properties(props);
- }
-
- /**
- * Searches for the property with the specified key in this property list.
- * If the key is not found in this property list, the default property list,
- * and its defaults, recursively, are then checked. The method returns the
- * default value argument if the property is not found.
- *
- * @param key
- * the property key
- * @param defaultValue
- * a default value
- * @return the value in this property list with the specified key value
- * @see java.util.Properties
- */
- public String getProperty(String key, String defaultValue) {
- if(null == props)
- return defaultValue;
- return props.getProperty(key, defaultValue);
- }
-
- /**
- * Searches for the property with the specified key in this property list.
- * If the key is not found in this property list, the default property list,
- * and its defaults, recursively, are then checked. The method returns null
- * if the property is not found.
- *
- * @param key
- * the property key
- * @return the value in this property list with the specified key value
- * @see java.util.Properties
- */
- public String getProperty(String key) {
- return getProperty(key, null);
- }
-
- /**
- * Calls the hashtable method put. Provided for parallelism with the
- * getProperty method. Enforces use of strings for property keys and values.
- *
- * @param key
- * the key to be placed into this property list.
- * @param value
- * the value corresponding to key.
- * @see java.util.Properties#setProperty(String,String)
- */
- public String setProperty(String key, String value) {
- String val = (String) props.setProperty(key, value);
- if(!key.startsWith("p4.")) {
- return val;
- }
- if(key.equals("p4.user")) {
- setUser(value);
- } else if(key.equals("p4.client")) {
- setClient(value);
- } else if(key.equals("p4.port")) {
- setPort(value);
- } else if(key.equals("p4.password")) {
- setPassword(value);
- } else if(key.equals("p4.executable")) {
- setExecutable(value);
- } else if(key.equals("p4.sysdrive")) {
- setSystemDrive(value);
- } else if(key.equals("p4.sysroot")) {
- setSystemRoot(value);
- } else if(key.equals("p4.threshold")) {
- try {
- setServerTimeout(Integer.valueOf(value).intValue());
- } catch(Exception ex) { /* Ignored Exception */
- }
- }
- return val;
- }
-
- /**
- * Sets the environment using the specified properties file.
- *
- * @see #setFromProperties(Properties)
- * @param propfile
- * Path to a properties file.
- */
- public void setFromProperties(String propfile) throws PerforceException {
- Properties props = new Properties(System.getProperties());
- if(null != propfile) {
- try {
- props.load(new BufferedInputStream(new FileInputStream(propfile)));
- System.setProperties(props);
- } catch(Exception e) {
- System.err.println("Unable to load properties.");
- e.printStackTrace(System.err);
- throw new PerforceException("Unable to load properties from " + propfile);
- }
- }
- setFromProperties(props);
- }
-
- /**
- * Uses a set of Properties to set up the environment. The
- * properties that are used used by this method are:
- *
- *
| Property | - *Value Set | - *
|---|---|
| p4.user | - *P4USER | - *
| p4.client | - *P4CLIENT | - *
| p4.port | - *P4PORT | - *
| p4.password | - *P4PASSWORD | - *
| p4.executable | - *Executable | - *
| p4.sysdrive | - *SystemDrive | - *
| p4.sysroot | - *SystemRoot | - *
| p4.threshold | - *Server Timeout Threshold | - *
- * p4.executable=/usr/bin/p4 # This will work - * p4.executable=/usr/bin/ # This will work - * <font color=Red>p4.executable=/usr/bin # This won't work</font> - *- * - * @param exe - * Full path to the p4 executable. - */ - public void setExecutable(String exe) { - int pos; - if(null == exe) - return; - p4_exe = exe; - if(null == sep_file) { - sep_file = System.getProperties().getProperty("file.separator", "\\"); - } - if(-1 == (pos = exe.lastIndexOf(sep_file))) - return; - if(null == sep_path) { - sep_path = System.getProperties().getProperty("path.separator", ";"); - } - appendPath(exe.substring(0, pos)); - props.setProperty("p4.executable", p4_exe); - envp_valid = false; - } - - /** Returns the path to the executable. */ - public String getExecutable() { - return p4_exe; - } - - /** Set the server timeout threshold. */ - public void setServerTimeout(long threshold) { - this.threshold = threshold; - props.setProperty("p4.threshold", String.valueOf(threshold)); - } - - /** Return the server timeout threshold. */ - public long getServerTimeout() { - return threshold; - } - - public String toString() { - String[] envp = getEnvp(); - StringBuffer sb = new StringBuffer(); - for(int i = 0; i < envp.length; i++) { - sb.append(envp[i]); - sb.append("\n"); - } - return sb.toString(); - } - - /** - * Returns an XML representation of the environment. - */ - public String toXML() { - StringBuffer sb = new StringBuffer("
EventLog to print.
- * @param out
- * Print output.
- * @param format
- * Format to use.
- * @see java.text.MessageFormat
- */
- public static void printLog(EventLog elog, PrintWriter out, String format) {
- Object[] args = { "foo" };
- synchronized(elog) {
- Enumeration en = elog.events.elements();
- while(en.hasMoreElements()) {
- args[0] = ((String) en.nextElement());
- out.println(MessageFormat.format(format, args));
- }
- }
- }
-
- /**
- * Sets the title for this log.
- *
- * @param title
- * The title of the log.
- */
- public synchronized void setTitle(String title) {
- this.title = title;
- }
-
- /**
- * Gets the title of the log.
- */
- public synchronized String getTitle() {
- return title;
- }
-}
diff --git a/src/main/java/com/perforce/api/FileEntry.java b/src/main/java/com/perforce/api/FileEntry.java
deleted file mode 100644
index 0bad41a..0000000
--- a/src/main/java/com/perforce/api/FileEntry.java
+++ /dev/null
@@ -1,1264 +0,0 @@
-package com.perforce.api;
-
-import java.io.*;
-import java.util.*;
-import java.text.*;
-
-/*
- * Copyright (c) 2001, Perforce Software, All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/**
- * Representation of a source control file.
- *
- * @see Hashtable
- * @author David Markley
- * @version $Date: 2002/06/05 $ $Revision: #8 $
- */
-public final class FileEntry extends SourceControlObject {
- private String depot_path = null;
-
- private String client_path = null;
-
- private String description = "";
-
- private String owner = "";
-
- private FileEntry source = null;
-
- private int head_change = -1;
-
- private int head_rev = 0;
-
- private String head_type = "unknown";
-
- private long head_time = 0;
-
- private int have_rev = 0;
-
- private int other_cnt = 0;
-
- private String head_action = "";
-
- private Vector others;
-
- private static HashDecay fentries;
-
- private String file_content = "";
-
- private DateFormat fmt = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM);
-
- /** Default no-argument constructor. */
- public FileEntry() {
- this((Env) null);
- }
-
- /**
- * Constructs a file entry using the environment.
- *
- * @param env
- * Source control environement to use.
- */
- public FileEntry(Env env) {
- super(env);
- if(null == others) {
- others = new Vector();
- }
- }
-
- /**
- * Constructs a file entry using the environment and path.
- *
- * @param env
- * Source control environement to use.
- * @param p
- * Path to the file.
- */
- public FileEntry(Env env, String p) {
- this(env);
- if(p.startsWith("//")) {
- depot_path = p;
- } else {
- client_path = p;
- }
- }
-
- /**
- * Constructs a file entry using the path.
- *
- * @param p
- * Path to the file.
- */
- public FileEntry(String p) {
- this(null, p);
- }
-
- private static HashDecay setCache() {
- if(null == fentries) {
- fentries = new HashDecay(120000);
- fentries.start();
- }
- return fentries;
- }
-
- public HashDecay getCache() {
- return setCache();
- }
-
- /** Sets the decription for this file */
- public void setDescription(String d) {
- description = d;
- }
-
- /** Returns the decription for this file */
- public String getDescription() {
- return description;
- }
-
- /** Sets the owner for this file */
- public void setOwner(String o) {
- int pos;
- owner = o;
- if(-1 != (pos = owner.indexOf('@'))) {
- owner = owner.substring(0, pos);
- }
- }
-
- /** Returns the owner for this file */
- public String getOwner() {
- return owner;
- }
-
- /** Sets the source file entry associated with this file. */
- public void setSource(FileEntry fent) {
- source = fent;
- }
-
- /** Returns the source file entry associated with this file. */
- public FileEntry getSource() {
- return source;
- }
-
- /** Sets the head revision type for this file. */
- public void setHeadType(String type) {
- this.head_type = type;
- }
-
- /** Returns the head revision type for this file. */
- public String getHeadType() {
- return this.head_type;
- }
-
- /**
- * Sets the head date for this file. The expected format for the date is
- * yyyy/MM/dd. The time will default to 12:00:00 AM.
- */
- public void setHeadDate(String date) {
- // Format the current time.
- SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd");
- // Parse the previous string back into a Date.
- ParsePosition pos = new ParsePosition(0);
- Date hDate = formatter.parse(date, pos);
- this.head_time = hDate.getTime() / 1000;
- }
-
- /**
- * Returns a String representation of date for the head revsision of the
- * file. The format is yyyy/MM/dd.
- */
- public String getHeadDate() {
- // Format the current time.
- SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd");
- return formatter.format(new Date(this.head_time * 1000));
- }
-
- /** Sets the head revision time for this file. */
- public void setHeadTime(long time) {
- this.head_time = time;
- }
-
- /** Returns the head revision time for this file. */
- public long getHeadTime() {
- return this.head_time;
- }
-
- /**
- * Sets the format used by the getHeadTimeString method. The format of this
- * string is that of the SimpleDateFormat class.
- *
- * An example format would be setTimeFormat("MM/dd HH:mm:ss");
- *
- * @see SimpleDateFormat
- */
- public void setTimeFormat(String format) {
- if(null == format)
- return;
- fmt = new SimpleDateFormat(format);
- }
-
- /** Returns the head revision time as a String for this file. */
- public String getHeadTimeString() {
- Date d = new Date(this.head_time * 1000);
-
- if(null == fmt) {
- fmt = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM);
- fmt.setTimeZone(TimeZone.getTimeZone("EST"));
- }
- return fmt.format(d);
- }
-
- /** Sets the head revision action for this file. */
- public void setHeadAction(String action) {
- this.head_action = action;
- }
-
- /** Returns the head revision action for this file. */
- public String getHeadAction() {
- return this.head_action;
- }
-
- /** Sets the head revision change number for this file. */
- public void setHeadChange(int change) {
- this.head_change = change;
- }
-
- /** Returns the head revision change number for this file. */
- public int getHeadChange() {
- return this.head_change;
- }
-
- /** Sets the head revision number for this file. */
- public void setHeadRev(int rev) {
- this.head_rev = rev;
- }
-
- /** Returns the head revision number for this file. */
- public int getHeadRev() {
- return this.head_rev;
- }
-
- /** Sets the revision number the client has for this file. */
- public void setHaveRev(int rev) {
- this.have_rev = rev;
- }
-
- /** Returns the revision number the client has for this file. */
- public int getHaveRev() {
- return this.have_rev;
- }
-
- /**
- * Sets the depot path for this file.
- *
- * @param p
- * path for this file in the depot.
- */
- public void setDepotPath(String p) {
- this.depot_path = p;
- }
-
- /** Returns the depot path for this file. */
- public String getDepotPath() {
- return depot_path;
- }
-
- /** Returns the path in local format. Uses the local path delimeter. */
- public static String localizePath(String path) {
- return customizePath(path, '/', File.separatorChar);
- }
-
- /** Returns the path in depot format. Uses the depot delimeter: '/'. */
- public static String depotizePath(String path) {
- return customizePath(path, File.separatorChar, '/');
- }
-
- /**
- * Returns the path after converting characters.
- *
- * @param str
- * String to convert.
- * @param from_char
- * Character to be changed from.
- * @param to_char
- * Character to be changed to.
- */
- public static String customizePath(String str, char from_char, char to_char) {
- StringBuffer strbuf = new StringBuffer();
- int beg = 0, end = 0;
- while(-1 != (end = str.indexOf(from_char, beg))) {
- strbuf.append(str.substring(beg, end));
- strbuf.append(to_char);
- beg = end + 1;
- }
- strbuf.append(str.substring(beg));
- return strbuf.toString();
- }
-
- /**
- * Resolves this file. If the force flag is false, and auto-resolve is
- * attempted (p4 resolve -am). If the force flag is true, an "accept theirs"
- * resolve is completed (p4 resolve -at).
- *
- * @param force
- * Indicates whether the resolve should be forced.
- */
- public String resolve(boolean force) throws IOException {
- StringBuffer sb = new StringBuffer();
- String l;
- String[] rescmd = { "p4", "resolve", "-am", "fileRev" };
- if(force || -1 != (getHeadType().indexOf("binary")) || -1 != (getHeadType().indexOf("link"))) {
- rescmd[2] = "-at";
- } else {
- rescmd[2] = "-am";
- }
- rescmd[3] = getDepotPath();
- P4Process p = new P4Process(getEnv());
- p.exec(rescmd);
- while(null != (l = p.readLine())) {
- if(null != sb) {
- sb.append(l);
- sb.append('\n');
- }
- }
- p.close();
- return sb.toString();
- }
-
- /**
- * Forces a resolve on a set of files. The Enumeration
- * contains the set of FileEntry objects that need resolved.
- *
- * @param env
- * Source control environment to use.
- * @param en
- * Enumeration of FileEntry.
- */
- public static String resolveAT(Env env, Enumeration en) throws IOException {
- StringBuffer sb = new StringBuffer();
- FileEntry fent;
- String l;
- String[] rescmd = { "p4", "-x", "-", "resolve", "-at" };
- P4Process p = new P4Process(env);
- p.exec(rescmd);
- while(en.hasMoreElements()) {
- fent = (FileEntry) en.nextElement();
- p.println(fent.getDepotPath());
- Debug.notify("resolveAT(): " + fent.getDepotPath());
- }
- p.println("\032\n\032");
- p.flush();
- p.outClose();
- Debug.notify("FileEntry.resolveAT(): Reading more lines.");
- while(null != (l = p.readLine())) {
- if(null != sb) {
- sb.append(l);
- sb.append('\n');
- }
- }
- p.close();
- return sb.toString();
- }
-
- /**
- * Resolves all the files in the path. The flags are used by the 'p4
- * resolve' command to resolve any files in the path. This is just a simple
- * way to execute the 'p4 resolve' command.
- *
- * @param env
- * Source control environment to use.
- * @param flags
- * 'p4 resolve' command flags.
- * @param path
- * Path over which to resolve. May include wildcards.
- */
- public static String resolveAll(Env env, String flags, String path) throws IOException {
- StringBuffer sb = new StringBuffer();
- FileEntry fent;
- String l;
- String[] rescmd = { "p4", "resolve", flags, path };
- P4Process p = new P4Process(env);
- p.exec(rescmd);
- Debug.notify("FileEntry.resolveAll(): Reading more lines.");
- while(null != (l = p.readLine())) {
- if(null != sb) {
- sb.append(l);
- sb.append('\n');
- }
- }
- p.close();
- return sb.toString();
- }
-
- /**
- * @deprecated Don't use this anymore.
- */
- public static String HTMLEncode(String str) {
- if(null == str)
- return null;
- StringBuffer strbuf = new StringBuffer(str.length());
- char tmp;
- for(int i = 0; i < str.length(); i++) {
- tmp = str.charAt(i);
- if('<' == tmp) {
- strbuf.append("<");
- } else if('>' == tmp) {
- strbuf.append(">");
- } else {
- strbuf.append(tmp);
- }
- }
- return strbuf.toString();
- }
-
- /** Returns the file name. */
- public String getName() {
- int pos;
- String path = getDepotPath();
- if(null == path) {
- path = getClientPath();
- }
- if(null == path) {
- return "";
- }
- if(-1 == (pos = path.lastIndexOf('/'))) {
- return path;
- }
- return path.substring(pos + 1);
- }
-
- /**
- * Sets the client path for this file.
- *
- * @param p
- * path for this file on the client system.
- */
- public void setClientPath(String p) {
- this.client_path = p;
- }
-
- /** Returns the client path for this file. */
- public String getClientPath() {
- return client_path;
- }
-
- /**
- * Gets the file information for the specified path.
- *
- * @param p
- * Path of the file to gather information about.
- */
- public static synchronized FileEntry getFile(String p) {
- FileEntry f = new FileEntry(p);
- f.sync();
- return f;
- }
-
- /**
- * Returns the list of files for the path. The path may include wildcards.
- *
- * @param env
- * Source control environment to use.
- * @param path
- * Path for set of files.
- */
- public static Vector getFiles(Env env, String path) {
- Vector v = null;
- String[] cmd = { "p4", "fstat", path + "%1" };
- if(null == path)
- return null;
-
- try {
- P4Process p = new P4Process(env);
- p.exec(cmd);
- v = parseFstat(null, p, true);
- p.close();
- } catch(IOException ex) {
- Debug.out(Debug.ERROR, ex);
- }
- return v;
- }
-
- /**
- * Returns a list of FileEntry objects that represent the
- * history of the specified file.
- *
- * @param env
- * Source control environment to use.
- * @param path
- * Path to the file. Must be specific. No wildcards.
- */
- public static Vector getFileLog(Env env, String path) {
- String[] cmd = { "p4", "filelog", path };
- String l, tmp;
- StringTokenizer st;
- P4Process p;
- FileEntry fent = null, tmpent = null;
- Vector v = new Vector();
- int beg, end;
-
- if(null == path)
- return v;
- try {
- p = new P4Process(env);
- p.setRawMode(true);
- p.exec(cmd);
- while(null != (l = p.readLine())) {
- l = l.trim();
- if(l.startsWith("info2: ") && null != fent) {
- tmpent = new FileEntry(env);
- beg = 8;
- if(-1 == (end = l.indexOf(' ', beg))) {
- continue;
- }
- tmpent.setHeadAction(l.substring(beg, end));
- beg = end;
- if(-1 == (end = l.indexOf("from "))) {
- tmpent.setDepotPath(path);
- } else {
- beg = end + 5;
- if(-1 == (end = l.indexOf('#', beg))) {
- tmpent.setDepotPath(l.substring(beg));
- } else {
- tmpent.setDepotPath(l.substring(beg, end));
- }
- }
- if(-1 != (end = l.lastIndexOf('#'))) {
- if(-1 != (beg = l.lastIndexOf('#', end - 1))) {
- tmpent.setHaveRev(Integer.parseInt(l.substring(beg + 1, end - 1)));
- }
- tmpent.setHeadRev(Integer.parseInt(l.substring(end + 1)));
- }
- fent.setSource(tmpent);
- } else if(l.startsWith("info1: ")) {
- if(null != fent) {
- v.addElement(fent);
- }
- fent = new FileEntry(env);
- fent.setDepotPath(path);
- st = new StringTokenizer(l.substring(8));
- fent.setHeadRev(Integer.parseInt(st.nextToken()));
- st.nextToken(); // change
- fent.setHeadChange(Integer.parseInt(st.nextToken()));
- fent.setHeadAction(st.nextToken());
- st.nextToken(); // on
- fent.setHeadDate(st.nextToken());
- st.nextToken(); // by
- fent.setOwner(st.nextToken());
- tmp = st.nextToken();
- fent.setHeadType(tmp.substring(1, tmp.length() - 1));
- if(1 < (end = l.lastIndexOf('\''))) {
- if(-1 < (beg = l.lastIndexOf('\'', end - 1))) {
- if(end - beg - 1 > 0) {
- fent.setDescription(l.substring(beg + 1, end - 1));
- }
- }
- }
- }
- }
- p.close();
- } catch(IOException ex) {
- Debug.out(Debug.ERROR, ex);
- }
- if(null != fent && null != fent.getDepotPath()) {
- v.addElement(fent);
- }
- return v;
- }
-
- /**
- * Opens the file on the path for edit under the change. If the change is
- * null, the file is opened under the default changelist.
- *
- * @param env
- * P4 Environment
- * @param path
- * Depot or client path to the file being opened for edit.
- * @param sync
- * If true, the file will be sync'd before opened for edit.
- * @param force
- * If true, the file will be opened for edit even if it isn't the
- * most recent version.
- * @param lock
- * If true, the file will be locked once opened.
- * @param chng
- * The change that the file will be opened for edit in.
- */
- public static FileEntry openForEdit(Env env, String path, boolean sync, boolean force, boolean lock, Change chng)
- throws Exception {
- if(sync) {
- FileEntry.syncWorkspace(env, path);
- }
- FileEntry fent = new FileEntry(env, path);
- fent.openForEdit(force, lock, chng);
- return fent;
- }
-
- /**
- * Opens this file for edit.
- *
- * @see #openForEdit(Env, String, boolean, boolean, boolean, Change)
- */
- public void openForEdit() throws Exception {
- openForEdit(true, false, null);
- }
-
- /**
- * Opens this file for edit.
- *
- * @see #openForEdit(Env, String, boolean, boolean, boolean, Change)
- */
- public void openForEdit(boolean force, boolean lock) throws Exception {
- openForEdit(force, lock, null);
- }
-
- /**
- * Opens this file for edit.
- *
- * @see #openForEdit(Env, String, boolean, boolean, boolean, Change)
- */
- public void openForEdit(boolean force, boolean lock, Change chng) throws Exception {
- String[] cmd1;
- String[] cmd2;
- String l;
- P4Process p;
- int i = 0;
- sync();
- if(force) {
- cmd1 = new String[4];
- cmd1[2] = "-f";
- } else {
- cmd1 = new String[3];
- }
- cmd1[0] = "p4";
- cmd1[1] = "sync";
- cmd1[cmd1.length - 1] = getDepotPath();
-
- cmd2 = new String[(null == chng) ? 3 : 5];
- cmd2[i++] = "p4";
- cmd2[i++] = "edit";
- if(null != chng) {
- cmd2[i++] = "-c";
- cmd2[i++] = String.valueOf(chng.getNumber());
- }
- cmd2[i++] = getClientPath();
-
- p = new P4Process(getEnv());
- p.exec(cmd1);
- while(null != (l = p.readLine())) {
- }
- p.close();
- p = new P4Process(getEnv());
- p.exec(cmd2);
- while(null != (l = p.readLine())) {
- }
- p.close();
- if(lock)
- obtainLock();
- }
-
- /**
- * Obtains the lock for this file. The file must have been opened for edit
- * prior to this method being called.
- */
- public void obtainLock() throws Exception {
- String[] cmd = { "p4", "lock", getDepotPath() };
- String l;
- P4Process p;
-
- p = new P4Process(getEnv());
- p.exec(cmd);
- while(null != (l = p.readLine())) {
- }
- p.close();
- }
-
- /**
- * Opens the file on the path for add under the change. If the change is
- * null, the file is opened under the default changelist.
- *
- * @param env
- * P4 Environment
- * @param path
- * Depot or client path to the file being opened for add.
- * @param chng
- * The change that the file will be opened for add in.
- */
- public static FileEntry openForAdd(Env env, String path, Change chng) throws Exception {
- FileEntry fent = new FileEntry(env, path);
- fent.openForAdd(chng);
- return fent;
- }
-
- /**
- * Opens this file for addition.
- *
- * @see #openForAdd(Env, String, Change)
- */
- public void openForAdd() throws Exception {
- openForAdd(null);
- }
-
- /**
- * Opens this file for addition.
- *
- * @see #openForAdd(Env, String, Change)
- */
- public void openForAdd(Change chng) throws Exception {
- String[] cmd;
- int i = 0;
- cmd = new String[(null == chng) ? 3 : 5];
- cmd[i++] = "p4";
- cmd[i++] = "add";
- if(null != chng) {
- cmd[i++] = "-c";
- cmd[i++] = String.valueOf(chng.getNumber());
- }
- cmd[i++] = getClientPath();
- String l;
- P4Process p;
-
- if(null == getClientPath()) {
- throw new Exception("No Client Path");
- }
-
- p = new P4Process(getEnv());
- p.exec(cmd);
- while(null != (l = p.readLine())) {
- }
- p.close();
- }
-
- /**
- * Checks in a file that has already been opened on the client using the
- * description given. A new changelist is created and used for this
- * submission. The returned FileEntry contains the latest
- * information for the checked-in file.
- */
- public static FileEntry checkIn(Env env, String path, String description) throws PerforceException {
- FileEntry fent = new FileEntry(env, path);
- Change chng = new Change(env);
- chng.setDescription(description);
- chng.addFile(fent);
- chng.submit();
- fent.sync();
- return fent;
- }
-
- /**
- * Reopens the file with the new type or in the new change list.
- */
- public void reopen(String type, Change chng) throws PerforceException {
- String[] cmd;
- int i = 0;
- String l;
- P4Process p = null;
-
- if(null == getClientPath()) {
- try {
- sync();
- } catch(Exception ex) { /* Ignored Exception */
- }
- if(null == getClientPath()) {
- throw new PerforceException("No Client Path");
- }
- }
-
- if(null == type && null == chng)
- return;
- cmd = new String[(null == type || null == chng) ? 5 : 7];
- cmd[i++] = "p4";
- cmd[i++] = "reopen";
- if(null != type) {
- cmd[i++] = "-t";
- cmd[i++] = type;
- }
- if(null != chng) {
- cmd[i++] = "-c";
- cmd[i++] = String.valueOf(chng.getNumber());
- }
- cmd[i++] = getClientPath();
-
- try {
- p = new P4Process(getEnv());
- p.exec(cmd);
- while(null != (l = p.readLine())) {
- if((-1 != l.indexOf("not opened on this client")) || (-1 != l.indexOf("Invalid file type"))
- || (-1 != l.indexOf("unknown"))) {
- throw new PerforceException(l);
- }
- }
- } catch(Exception ex) {
- throw new PerforceException(ex.getMessage());
- } finally {
- if(null != p) {
- try {
- p.close();
- } catch(IOException ioex) { /* Ignored Exception */
- }
- }
- }
- }
-
- /**
- * Reverts this file.
- */
- public boolean revert() {
- String[] cmd1 = { "p4", "revert", getDepotPath() };
- String[] cmd2 = { "p4", "sync", getDepotPath() + "#none" };
- String l;
- P4Process p;
-
- try {
- p = new P4Process(getEnv());
- p.exec(cmd1);
- while(null != (l = p.readLine())) {
- }
- p.close();
- p = new P4Process(getEnv());
- p.exec(cmd2);
- while(null != (l = p.readLine())) {
- }
- p.close();
- } catch(IOException ex) {
- Debug.out(Debug.ERROR, ex);
- return false;
- }
- return true;
- }
-
- /**
- * Returns a list of files that are open for edit or add. The list is a
- * Vectore of FileEntry objects. The only
- * information that is valid for the object will be the path, until the
- * {@link #sync() sync} method is called.
- */
- public static Vector getOpened() {
- return getOpened(null, true, false, -1, null);
- }
-
- /**
- * Returns a list of files that are open for edit or add. The list is a
- * Vectore of FileEntry objects.
- *
- * Getting the stats for each FileEntry is a more expensive
- * operation. By default, this is not done. What this means is that the only
- * information that is valid for the object will be the path, until the
- * {@link #sync() sync} method is called.
- *
- * @param env
- * Source control environment to use.
- * @param stat
- * Indicates that file statistics should be gathered.
- */
- public static Vector getOpened(Env env, boolean stat) {
- return getOpened(env, stat, false, -1, null);
- }
-
- /**
- * Returns a list of files that are open for edit or add. The list is a
- * Vector of FileEntry objects.
- *
- * Getting the stats for each FileEntry is a more expensive
- * operation. By default, this is not done. What this means is that the only
- * information that is valid for the object will be the path, until the
- * {@link #sync() sync} method is called.
- *
- * If changelist is 0, all the changes in the default changelist are
- * returned. If it is less than 0, all opened files are returned.
- *
- * @param env
- * Source control environment to use.
- * @param stat
- * Indicates that file statistics should be gathered.
- * @param all
- * Indicates that all open files should be returned.
- * @param changelist
- * If non-zero, show files open in this changelist.
- * @param files
- * If non-null, show files open in this Vector of
- * FileEntry objects.
- */
- public static Vector getOpened(Env env, boolean stat, boolean all, int changelist, Vector files) {
- Vector v = new Vector();
- String l, str;
- StringTokenizer st;
- int i = 0, cnt = 2;
- String[] cmd;
- FileEntry fent;
- if(all)
- cnt++;
- if(0 <= changelist)
- cnt += 2;
- if(null != files)
- cnt += files.size();
- cmd = new String[cnt];
- cmd[i++] = "p4";
- cmd[i++] = "opened";
- if(all)
- cmd[i++] = "-a";
- if(0 <= changelist) {
- cmd[i++] = "-c";
- cmd[i++] = (0 == changelist) ? "default" : String.valueOf(changelist);
- }
- if(null != files) {
- Enumeration en = files.elements();
- while(en.hasMoreElements()) {
- cmd[i++] = (String) en.nextElement();
- }
- }
- try {
- P4Process p = new P4Process(env);
- p.exec(cmd);
- while(null != (l = p.readLine())) {
- if(!l.startsWith("//")) {
- continue;
- }
- st = new StringTokenizer(l, "#");
- if(null == (str = st.nextToken())) {
- continue;
- }
- fent = new FileEntry(env, str);
- if(null == (str = st.nextToken("# \t"))) {
- continue;
- }
- fent.setHeadRev(Integer.valueOf(str).intValue());
- st.nextToken(" \t"); // Should be the dash here.
- if(null == (str = st.nextToken())) {
- continue;
- }
- fent.setHeadAction(str);
- if(null == (str = st.nextToken())) {
- continue;
- }
- if(str.equals("default")) {
- fent.setHeadChange(-1);
- st.nextToken(); // Change here.
- } else if(str.equals("change")) {
- if(null == (str = st.nextToken())) {
- continue;
- } // Change number
- fent.setHeadChange(Integer.valueOf(str).intValue());
- }
- if(null == (str = st.nextToken(" \t()"))) {
- continue;
- }
- fent.setHeadType(str);
- // Insertion sort...slow but effective.
- for(i = 0; i < v.size(); i++) {
- if(((FileEntry) v.elementAt(i)).getHeadChange() > fent.getHeadChange())
- break;
- }
- v.insertElementAt(fent, i);
- }
- p.close();
- } catch(IOException ex) {
- Debug.out(Debug.ERROR, ex);
- }
- if(stat) {
- Enumeration en = v.elements();
- while(en.hasMoreElements()) {
- fent = (FileEntry) en.nextElement();
- fent.setEnv(env);
- fent.sync();
- }
- }
- return v;
- }
-
- /**
- * No-op. This makes no sense for a FileEntry.
- */
- public void commit() {
- }
-
- /**
- * @deprecated
- * @see #syncWorkspace(Env, String)
- */
- public String syncMySpace(Env env, String path) throws IOException {
- return FileEntry.syncWorkspace(env, path);
- }
-
- /**
- * Returns a Vector of FileEntry objects that
- * reflect what files were changed by the sync process. If path is null, the
- * entire workspace is synchronized to the head revision. The path may
- * contain wildcard characters, as with the command line 'p4 sync' command.
- *
- * @param env
- * Source control environment.
- * @param path
- * Path to synchronize. May include wildcards.
- */
- public static Vector synchronizeWorkspace(Env env, String path) throws IOException {
- String[] cmd;
- if(null == path || path.trim().equals("")) {
- cmd = new String[2];
- } else {
- cmd = new String[3];
- cmd[2] = path;
- }
- cmd[0] = "p4";
- cmd[1] = "sync";
-
- String l;
- int pos1, pos2;
- Vector v = new Vector();
- FileEntry fent = null;
- try {
- P4Process p = new P4Process(env);
- p.exec(cmd);
- while(null != (l = p.readLine())) {
- fent = null;
- if(!l.startsWith("//")) {
- continue;
- }
- pos1 = 0;
- if(-1 == (pos2 = l.indexOf('#')))
- continue;
- fent = new FileEntry(env, l.substring(pos1, pos2));
- pos1 = pos2 + 1;
- if(-1 == (pos2 = l.indexOf(' ', pos1)))
- continue;
- try {
- fent.setHeadRev(Integer.parseInt(l.substring(pos1, pos2)));
- } catch(Exception ex) {
- fent = null;
- continue;
- }
- pos1 = pos2 + 1;
- if(-1 != (pos2 = l.indexOf("updating ")) || -1 != (pos2 = l.indexOf("added as "))) {
- fent.setClientPath(l.substring(pos2 + 9).trim());
- }
- if(null != fent) {
- v.addElement(fent);
- fent = null;
- }
- }
- p.close();
- } catch(IOException ex) {
- Debug.out(Debug.ERROR, ex);
- throw ex;
- }
- return v;
- }
-
- /**
- * Synchronizes the workspace.
- *
- * @param env
- * Source control environment.
- * @param path
- * Path to synchronize. May include wildcards.
- */
- public static String syncWorkspace(Env env, String path) throws IOException {
- String[] cmd;
- if(null == path || path.trim().equals("")) {
- cmd = new String[3];
- cmd[2] = path;
- } else {
- cmd = new String[2];
- }
- cmd[0] = "p4";
- cmd[1] = "sync";
-
- String l, str = "";
- try {
- P4Process p = new P4Process(env);
- p.exec(cmd);
- while(null != (l = p.readLine())) {
- str += l + "\n";
- }
- p.close();
- } catch(IOException ex) {
- Debug.out(Debug.ERROR, ex);
- throw ex;
- }
- return str;
- }
-
- /**
- * Returns a String that contains this file's contents. This
- * only works well for text files.
- */
- public String getFileContents() {
- return getFileContents(getEnv(), getDepotPath());
- }
-
- /**
- * Returns a String that contains this file's contents. This
- * only works well for text files.
- *
- * @param env
- * Source control environment.
- * @param path
- * Path to the file. Must be specific. No wildcards.
- */
- public String getFileContents(Env env, String path) {
- String l;
- StringBuffer ret = null;
- String[] cmd = { "p4", "print", path };
- try {
- P4Process p = new P4Process(env);
- p.setRawMode(true);
- p.exec(cmd);
- while(null != (l = p.readLine())) {
- if(null == ret) {
- ret = new StringBuffer();
- } else if(l.startsWith("text: ")) {
- ret.append(l.substring(6));
- if(!l.endsWith("\n"))
- ret.append('\n');
- }
- }
- if(null == ret) {
- ret = new StringBuffer();
- }
-
- if(0 != p.close()) {
- throw new IOException("P4 exited with and error:" + p.getExitCode());
- }
- } catch(IOException ex) {
- Debug.out(Debug.ERROR, ex);
- }
- file_content = ret.toString();
- return file_content;
- }
-
- public void sync() {
- String l;
- String[] cmd = { "p4", "fstat", "path" };
- if(null != depot_path) {
- cmd[2] = depot_path;
- } else if(null != client_path) {
- cmd[2] = client_path;
- } else {
- return;
- }
- if(0 != head_rev) {
- cmd[2] += "#" + head_rev;
- }
- try {
- P4Process p = new P4Process(getEnv());
- p.exec(cmd);
- parseFstat(this, p, false);
- if(0 != p.close()) {
- throw new IOException("P4 exited with an error:" + p.getExitCode());
- }
- } catch(IOException ex) {
- Debug.out(Debug.ERROR, ex);
- }
- }
-
- /**
- * Useful method for parsing that lovely fstat format information.
- */
- private static Vector parseFstat(FileEntry fe, P4Process p, boolean igndel) {
- FileEntry nfe;
- String l;
- Vector v = new Vector();
- String dataname, datavalue;
- boolean multiple = false;
-
- if(null == p)
- return null;
- if(null == (nfe = fe))
- nfe = new FileEntry(p.getEnv());
-
- while(null != (l = p.readLine())) {
- StringTokenizer tokes = new StringTokenizer(l, " ");
-
- dataname = (String) (tokes.hasMoreElements() ? tokes.nextElement() : null);
- datavalue = (String) (tokes.hasMoreElements() ? tokes.nextElement() : null);
- if(dataname.equals("clientFile")) {
- nfe.setClientPath(datavalue);
- } else if(dataname.equals("depotFile")) {
- if(multiple)
- nfe = new FileEntry(p.getEnv());
- nfe.setDepotPath(datavalue);
- v.add(nfe);
- multiple = true;
- } else if(dataname.equals("headAction")) {
- nfe.setHeadAction(datavalue);
- } else if(dataname.equals("headChange")) {
- nfe.setHeadChange(new Integer(datavalue).intValue());
- } else if(dataname.equals("headRev")) {
- nfe.setHeadRev(new Integer(datavalue).intValue());
- } else if(dataname.equals("headType")) {
- nfe.setHeadType(datavalue);
- } else if(dataname.equals("headTime")) {
- nfe.setHeadTime(new Long(datavalue).longValue());
- } else if(dataname.equals("haveRev")) {
- nfe.setHaveRev(new Integer(datavalue).intValue());
- } else if(dataname.equals("action")) {
-
- } else if(dataname.equals("change")) {
-
- } else if(dataname.equals("unresolved")) {
-
- } else if(dataname.equals("otherOpen")) {
-
- } else if(dataname.equals("otherLock")) {
-
- } else if(dataname.equals("ourLock")) {
-
- }
- }
- return v;
- }
-
- public String toString() {
- return depot_path + "\n" + client_path + "\nothers: " + other_cnt;
- }
-
- public String toXML() {
- StringBuffer sb = new StringBuffer("String) to lookup jobs
- * for.
- * @param files
- * array of files (including wildcards) used to limit to lookup.
- * @return array of jobs that fix the specified change.
- */
- public static Job[] getJobFixes(Env env, String change, String[] files) {
- Vector[] fixes = getFixes(env, null, change, files);
- Vector vj = fixes[1];
- Job[] jobs = new Job[vj.size()];
- for(int i = 0; i < vj.size(); i++) {
- jobs[i] = (Job) vj.elementAt(i);
- }
- return jobs;
- }
-
- /**
- * Returns an array of two Vectors. The first
- * Vector in the array is filled with the changes fixed. The
- * second Vector contains the jobs that fix those changes.
- *
- * @param env
- * Perforce environment to use.
- * @param jobname
- * Named job to get fixes for.
- * @param change
- * Change number (as a String) to lookup jobs
- * for.
- * @param files
- * array of files (including wildcards) used to limit to lookup.
- * @return an array of two Vectors that contains changes and
- * jobs fixed.
- */
- private static Vector[] getFixes(Env env, String jobname, String change, String[] files) {
- int args = 2, pos = 0;
- if(null != jobname) {
- args += 2;
- jobname = jobname.trim();
- }
- if(null != change) {
- args += 2;
- change = change.trim();
- }
- if(null != files)
- args += files.length;
- String[] cmd = new String[args];
- cmd[pos++] = "p4";
- cmd[pos++] = "fixes";
- if(null != jobname) {
- cmd[pos++] = "-j";
- cmd[pos++] = jobname;
- }
- if(null != change) {
- cmd[pos++] = "-c";
- cmd[pos++] = change;
- }
- if(null != files) {
- for(int i = 0; i < files.length; i++) {
- cmd[pos++] = files[i];
- }
- }
- Vector vc = new Vector();
- Vector vj = new Vector();
- Change c = null;
- Job jb = null;
- StringTokenizer st;
- String l, jbname, number, user, tmpdesc = "", modtime, state;
-
- try {
- P4Process p = new P4Process(env);
- p.exec(cmd);
- while(null != (l = p.readLine())) {
- st = new StringTokenizer(l);
- jbname = st.nextToken();
- jb = new Job(env, jbname);
- vj.addElement(jb);
- if(!st.nextToken().equals("fixed"))
- continue;
- if(!st.nextToken().equals("by"))
- continue;
- if(!st.nextToken().equals("change"))
- continue;
- c = new Change(st.nextToken());
- c.setEnv(env);
- if(!st.nextToken().equals("on"))
- continue;
- c.setModtimeString(st.nextToken());
- if(!st.nextToken().equals("by"))
- continue;
- c.setClientName(st.nextToken());
- if(null != c) {
- vc.addElement(c);
- c = null;
- }
- }
- p.close();
- } catch(IOException ex) {
- Debug.out(Debug.ERROR, ex);
- }
- Vector[] fixes = new Vector[2];
- fixes[0] = vc;
- fixes[1] = vj;
- return fixes;
- }
-
- public String toXML() {
- StringBuffer sb = new StringBuffer("
- * TBD: This class is not really used anywhere else. It is intended to be used
- * for more interaction with the jobs interface.
- *
- * @author David Markley
- * @version $Date: 2002/08/05 $ $Revision: #2 $
- */
-public final class JobField {
- private int code = 0;
-
- private String name = "";
-
- private int data_type = 0;
-
- private int len = 0;
-
- private int field_type = 0;
-
- private Vector values;
-
- private String preset;
-
- private static Hashtable fields;
-
- private JobField[] fieldarray;
-
- private final static int BASECODE = 101;
-
- private final static int MAXCODE = 199;
-
- /** Data type is a single word (any value) */
- public final static int WORD = 1;
-
- /** Data type is a date/time field */
- public final static int DATE = 2;
-
- /** Data type is one of a set of words */
- public final static int SELECT = 3;
-
- /** Data type is a one-liner */
- public final static int LINE = 4;
-
- /** Data type is a block of text */
- public final static int TEXT = 5;
-
- /** Field type has no default, not required to be present */
- public final static int OPTIONAL = 6;
-
- /** Field type has default provided, still not required */
- public final static int DEFAULT = 7;
-
- /** Field type has default provided, value must be present */
- public final static int REQUIRED = 8;
-
- /** Field type has set once to the default and never changed */
- public final static int ONCE = 9;
-
- /** Field type has always reset to the default upon saving */
- public final static int ALWAYS = 10;
-
- public JobField() {
- super();
- if(null == fields) {
- fields = new Hashtable();
- }
- if(null == fieldarray) {
- fieldarray = new JobField[MAXCODE - BASECODE + 1];
- }
- values = new Vector();
- }
-
- public JobField(int code, String name, int dtype, int len, int ftype) {
- this();
- setDataType(dtype);
- setLength(len);
- setFieldType(ftype);
- setName(name);
- setCode(code);
- }
-
- public JobField(int code, String name, String dtype, int len, String ftype) {
- this();
- setDataType(dtype);
- setLength(len);
- setFieldType(ftype);
- setName(name);
- setCode(code);
- }
-
- private static JobField parseField(String def) {
- StringTokenizer st = new StringTokenizer(def);
- int code, len;
- String name, dtype, ftype;
- JobField jf;
-
- try {
- st.nextToken(); /* Skip 'info:' */
- code = Integer.valueOf(st.nextToken()).intValue();
- name = st.nextToken();
- dtype = st.nextToken();
- len = Integer.valueOf(st.nextToken()).intValue();
- ftype = st.nextToken();
- jf = new JobField(code, name, dtype, len, ftype);
- } catch(Exception ex) {
- ex.printStackTrace(System.out);
- return null;
- }
- return jf;
- }
-
- public static void loadFields(Env env, boolean redo) {
- if(!redo && null != fields) {
- return;
- }
- fields = new Hashtable();
- String cmd[] = { "p4", "jobspec", "-o" };
- String l;
- JobField jf = null;
- try {
- P4Process p = new P4Process(env);
- p.setRawMode(true);
- p.exec(cmd);
- while(null != (l = p.readLine())) {
- if(l.startsWith("#"))
- continue;
- if(l.startsWith("info: Fields:")) {
- while(null != (l = p.readLine()) && l.startsWith("info: \t")) {
- jf = JobField.parseField(l);
- }
- }
- if(l.startsWith("Preset:")) {
- }
- if(l.startsWith("Values:")) {
- }
- }
- p.close();
- } catch(IOException ex) {
- }
- }
-
- public static JobField getField(String name) {
- if(null == fields) {
- fields = new Hashtable();
- }
- return (JobField) fields.get(name);
- }
-
- public int getCode() {
- return code;
- }
-
- public void setCode(int code) {
- this.code = code;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- if(name.trim().equals(""))
- return;
- if(!this.name.trim().equals("")) {
- fields.remove(this.name);
- }
- this.name = name;
- fields.put(this.name, this);
- }
-
- public int getDataType() {
- return data_type;
- }
-
- public void setDataType(int dtype) {
- this.data_type = dtype;
- }
-
- public void setDataType(String dtype) {
- if(dtype.equals("word")) {
- this.data_type = JobField.WORD;
- } else if(dtype.equals("date")) {
- this.data_type = JobField.DATE;
- } else if(dtype.equals("select")) {
- this.data_type = JobField.SELECT;
- } else if(dtype.equals("line")) {
- this.data_type = JobField.LINE;
- } else {
- this.data_type = JobField.TEXT;
- }
- }
-
- public int getLength() {
- return len;
- }
-
- public void setLength(int len) {
- this.len = len;
- }
-
- public int getFieldType() {
- return field_type;
- }
-
- public void setFieldType(int ftype) {
- this.field_type = ftype;
- }
-
- public void setFieldType(String ftype) {
- if(ftype.equals("optional")) {
- this.field_type = JobField.OPTIONAL;
- } else if(ftype.equals("always")) {
- this.field_type = JobField.ALWAYS;
- } else if(ftype.equals("required")) {
- this.field_type = JobField.REQUIRED;
- } else if(ftype.equals("once")) {
- this.field_type = JobField.ONCE;
- } else {
- this.field_type = JobField.DEFAULT;
- }
- }
-
- public void setPreset(String value) {
- this.preset = value;
- }
-
- public String getPreset() {
- return this.preset;
- }
-
- public void addValue(String value) {
- values.addElement(value);
- }
-
- public Enumeration getValues() {
- return values.elements();
- }
-
- public String toXML() {
- StringBuffer sb = new StringBuffer("
- * Example Usage: - * - *
- * String l;
- * Env env = new Env();
- * String[] cmd = { "p4", "branches" };
- * try {
- * P4Process p = new P4Process(env);
- * p.exec(cmd);
- * while(null != (l = p.readLine())) {
- * // Parse the output.
- * }
- * p.close();
- * } catch(Exception ex) {
- * throw new PerforceException(ex.getMessage());
- * }
- *
- *
- * @author David Markley
- * @version $Date: 2002/01/15 $ $Revision: #3 $
- * @see Env
- * @see SourceControlObject
- * @see Thread
- */
-public class P4Process {
- private static P4Process base = null;
-
- private P4JNI jni_proc = null;
-
- private boolean using_native = false;
-
- private Env environ = null;
-
- private Runtime rt = Runtime.getRuntime();
-
- private Process p;
-
- private BufferedReader in, err;
-
- private Writer out;
-
- private int exit_code = 0;
-
- private EventLog log;
-
- private String P4_ERROR = null;
-
- private String[] new_cmd;
-
- private long threshold = 10000; // The default is 10 seconds;
-
- private boolean raw = false;
-
- /**
- * Default no-argument constructor. If the runtime has not been established,
- * this constructor will set it up. No environment is specified, so the base
- * environment will be used if it exists.
- *
- * @see #getBase()
- */
- public P4Process() {
- this(null);
- }
-
- /**
- * Constructor that specifies the source control environment.
- *
- * @param e
- * Source control environment to use.
- */
- public P4Process(Env e) {
- super();
- if(null == rt) {
- rt = Runtime.getRuntime();
- }
- if(null == e) {
- if(null == base) {
- base = this;
- this.environ = new Env();
- } else {
- this.environ = new Env(base.getEnv());
- }
- } else {
- this.environ = e;
- }
- if(null != environ)
- this.threshold = environ.getServerTimeout();
- }
-
- /**
- * Sets the environment to use.
- *
- * @param e
- * Source control environment.
- */
- public void setEnv(Env e) {
- this.environ = e;
- if(null != environ)
- this.threshold = environ.getServerTimeout();
- }
-
- /**
- * Returns the environment in use by this process.
- *
- * @return Source control environment.
- */
- public Env getEnv() {
- return this.environ;
- }
-
- /**
- * Returns the base process for this class. The base process is set when
- * this class is first instantiated. The base process is used when other
- * P4Process are instantiated to share settings, including
- * the {@link com.perforce.api.Env source control environment}.
- *
- * @see Env
- * @return Source control environment.
- */
- public static P4Process getBase() {
- if(null != base) {
- return base;
- } else {
- return new P4Process();
- }
- }
-
- /**
- * Sets the base process to be used when new processes are instantiated.
- *
- * @see #getBase()
- */
- public static void setBase(P4Process b) {
- if(null != b) {
- base = b;
- }
- }
-
- public Writer getWriter() {
- return out;
- }
-
- /**
- * Returns the exit code returned when the underlying process exits.
- *
- * @return Typical UNIX style return code.
- */
- public int getExitCode() {
- return exit_code;
- }
-
- /**
- * In raw mode, the process will return the prefix added by the "-s" command
- * line option. The default is false.
- */
- public void setRawMode(boolean raw) {
- this.raw = raw;
- }
-
- /**
- * Returns the status of raw mode for this process.
- */
- public boolean getRawMode() {
- return this.raw;
- }
-
- /**
- * Executes a p4 command. This uses the class environment information to
- * execute the p4 command specified in the String array. This array contains
- * all the command line arguments that will be specified for execution,
- * including "p4" in the first position.
- *
- * @param cmd
- * Array of command line arguments ("p4" must be first).
- */
- public synchronized void exec(String[] cmd) throws IOException {
- String[] pre_cmds = new String[12];
- int i = 0;
- pre_cmds[i++] = cmd[0];
- pre_cmds[i++] = "-s";// Forces all commands to use stdout for message
- // reporting, no longer read stderr
- if(!getEnv().getPort().trim().equals("")) {
- pre_cmds[i++] = "-p";
- pre_cmds[i++] = getEnv().getPort();
- }
- if(!getEnv().getUser().trim().equals("")) {
- pre_cmds[i++] = "-u";
- pre_cmds[i++] = getEnv().getUser();
- }
- if(!getEnv().getClient().trim().equals("")) {
- pre_cmds[i++] = "-c";
- pre_cmds[i++] = getEnv().getClient();
- }
- if(!getEnv().getPassword().trim().equals("")) {
- pre_cmds[i++] = "-P";
- pre_cmds[i++] = getEnv().getPassword();
- }
- if(cmd[1].equals("-x")) {
- pre_cmds[i++] = "-x";
- pre_cmds[i++] = cmd[2];
- }
- new_cmd = new String[(i + cmd.length) - 1];
- for(int j = 0; j < (i + cmd.length) - 1; j++) {
- if(j < i) {
- new_cmd[j] = pre_cmds[j];
- } else {
- new_cmd[j] = cmd[(j - i) + 1];
- }
- }
- Debug.verbose("P4Process.exec: ", new_cmd);
- if(P4JNI.isValid()) {
- native_exec(new_cmd);
- using_native = true;
- } else {
- pure_exec(new_cmd);
- using_native = false;
- }
- }
-
- /**
- * Executes the command utilizing the P4API. This method will be used only
- * if the supporting Java Native Interface library could be loaded.
- */
- private synchronized void native_exec(String[] cmd) throws IOException {
- jni_proc = new P4JNI();
- // P4JNI tmp = new P4JNI();
- jni_proc.runCommand(jni_proc, cmd, environ);
- in = jni_proc.getReader();
- err = in;
- out = jni_proc.getWriter();
- }
-
- /**
- * Executes the command through a system 'exec'. This method will be used
- * only if the supporting Java Native Interface library could not be loaded.
- */
- private synchronized void pure_exec(String[] cmd) throws IOException {
- if(null != this.environ.getExecutable()) {
- cmd[0] = this.environ.getExecutable();
- }
- p = rt.exec(cmd, this.environ.getEnvp());
- InputStream is = p.getInputStream();
- Debug.verbose("P4Process.exec().is: " + is);
- InputStreamReader isr = new InputStreamReader(is);
- Debug.verbose("P4Process.exec().isr: " + isr);
- in = new BufferedReader(isr);
- InputStream es = p.getErrorStream();
- Debug.verbose("P4Process.exec().es: " + es);
- InputStreamReader esr = new InputStreamReader(es);
- Debug.verbose("P4Process.exec().esr: " + esr);
- err = new BufferedReader(esr);
-
- OutputStream os = p.getOutputStream();
- Debug.verbose("P4Process.exec().os: " + os);
- OutputStreamWriter osw = new OutputStreamWriter(os);
- Debug.verbose("P4Process.exec().osw: " + osw);
- out = new FilterWriter(new BufferedWriter(osw)) {
- public void write(String str) throws IOException {
- super.write(str);
- System.out.print("P4DebugOutput: " + str);
- }
-
- };
- }
-
- /**
- * Sets the event log. Any events that should be logged will be logged
- * through the EventLog specified here.
- *
- * @param log
- * Log for all events.
- */
- public synchronized void setEventLog(EventLog log) {
- this.log = log;
- }
-
- /**
- * Logs the event message to the output stream.
- *
- * @param out
- * Stream to which the message is logged.
- * @param event
- * Message to be logged.
- */
- private void log(PrintStream out, String event) {
- if(null == log) {
- out.println(event);
- out.flush();
- } else {
- log.log(event);
- }
- }
-
- /**
- * Writes line to the standard input of the process.
- *
- * @param line
- * Line to be written.
- */
- public synchronized void print(String line) throws IOException {
- out.write(line);
- }
-
- /**
- * Writes line to the standard input of the process. A
- * newline is appended to the output.
- *
- * @param line
- * Line to be written.
- */
- public synchronized void println(String line) throws IOException {
- out.write(line + "\n");
- }
-
- /**
- * Flushes the output stream to the process.
- */
- public synchronized void flush() throws IOException {
- out.flush();
- }
-
- /**
- * Flushes and closes the output stream to the process.
- */
- public synchronized void outClose() throws IOException {
- out.flush();
- out.close();
- }
-
- /**
- * Returns the next line from the process, or null if the command has
- * completed its execution.
- */
- public synchronized String readLine() {
- if(using_native && null != jni_proc && jni_proc.isPiped()) {
- return native_readLine();
- } else {
- return pure_readLine();
- }
- }
-
- /**
- * Reads the next line from the process. This method will be used only if
- * the supporting Java Native Interface library could be loaded.
- */
- private synchronized String native_readLine() {
- try {
- return in.readLine();
- } catch(IOException ex) {
- return null;
- }
- }
-
- /**
- * Reads the next line from the process. This method will be used only if
- * the supporting Java Native Interface library could not be loaded.
- */
- private synchronized String pure_readLine() {
- String line;
- long current, timeout = ((new Date()).getTime()) + threshold;
-
- if(null == p || null == in || null == err)
- return null;
- // Debug.verbose("P4Process.readLine()");
- try {
- for(;;) {
- if(null == p || null == in || null == err) {
- Debug.error("P4Process.readLine(): Something went null");
- return null;
- }
-
- current = (new Date()).getTime();
- if(current >= timeout) {
- Debug.error("P4Process.readLine(): Timeout");
- // If this was generating a new object from stdin, return an
- // empty string. Otherwise, return null.
- for(int i = 0; i < new_cmd.length; i++) {
- if(new_cmd[i].equals("-i"))
- return "";
- }
- return null;
- }
-
- // Debug.verbose("P4Process.readLine().in: "+in);
- try {
- /**
- * If there's something coming in from stdin, return it. We
- * assume that the p4 command was called with -s which sends
- * all messages to standard out pre-pended with a string
- * that indicates what kind of messsage it is error warning
- * text info exit
- */
- // Some errors still come in on Standard error
- while(err.ready()) {
- line = err.readLine();
- if(null != line) {
- addP4Error(line + "\n");
- }
- }
-
- if(in.ready()) {
- line = in.readLine();
- Debug.verbose("From P4:" + line);
- if(line.startsWith("error")) {
- if(!line.trim().equals("") && (-1 == line.indexOf("up-to-date"))
- && (-1 == line.indexOf("no file(s) to resolve"))) {
- addP4Error(line);
- }
- } else if(line.startsWith("warning")) {
- } else if(line.startsWith("text")) {
- } else if(line.startsWith("info")) {
- } else if(line.startsWith("exit")) {
- int exit_code = new Integer(line.substring(line.indexOf(" ") + 1, line.length()))
- .intValue();
- if(0 == exit_code) {
- Debug.verbose("P4 Exec Complete.");
- } else {
- Debug.error("P4 exited with an Error!");
- }
- return null;
- }
- if(!raw)
- line = line.substring(line.indexOf(":") + 1).trim();
- Debug.verbose("P4Process.readLine(): " + line);
- return line;
- }
- } catch(NullPointerException ne) {
- }
- // If there's nothing on stdin or stderr, check to see if the
- // process has exited. If it has, return null.
- try {
- exit_code = p.exitValue();
- return null;
- } catch(IllegalThreadStateException ie) {
- Debug.verbose("P4Process: Thread is not done yet.");
- }
- // Sleep for a second, so this thread can't become a CPU hog.
- try {
- Debug.verbose("P4Process: Sleeping...");
- Thread.sleep(100); // Sleep for 1/10th of a second.
- } catch(InterruptedException ie) {
- }
- }
- } catch(IOException ex) {
- return null;
- }
- }
-
- /**
- * Waits for the process to exit and closes out the process. This method
- * should be called after the {@link #exec(java.lang.String[]) exec} method
- * in order to close things down properly.
- *
- * @param out
- * The stream to which any errors should be sent.
- * @return The exit value of the underlying process.
- */
- public synchronized int close(PrintStream out) throws IOException {
- if(using_native && null != jni_proc && jni_proc.isPiped()) {
- native_close(out);
- } else {
- pure_close(out);
- }
- /*
- * if (0 != exit_code) { throw new IOException("P4Process ERROR: p4 sync
- * exited with error ("+ exit_code+")"); }
- */
- if(null != P4_ERROR) {
- throw new IOException(P4_ERROR);
- }
- return exit_code;
- }
-
- /**
- * Closes down connections to the underlying process. This method will be
- * used only if the supporting Java Native Interface library could be
- * loaded.
- */
- private synchronized void native_close(PrintStream out) {
- try {
- in.close();
- out.flush();
- out.close();
- } catch(IOException ioe) {
- }
- }
-
- /**
- * Closes down connections to the underlying process. This method will be
- * used only if the supporting Java Native Interface library could not be
- * loaded.
- */
- private synchronized void pure_close(PrintStream out) {
- /*
- * Try to close this process for at least 30 seconds.
- */
- for(int i = 0; i < 30; i++) {
- try {
- in.close();
- err.close();
- out.flush();
- out.close();
- } catch(IOException ioe) {
- }
- try {
- exit_code = p.waitFor();
- p.destroy();
- break;
- } catch(InterruptedException ie) {
- }
- try {
- Thread.sleep(1000);
- } catch(InterruptedException ie) {
- }
- }
- }
-
- /**
- * Waits for the underlying process to exit and closes it down. This method
- * should be called after the {@link #exec(java.lang.String[]) exec} method
- * in order to close things out properly. Errors are sent to System.err.
- *
- * @see System
- * @return The exit value of the underlying process.
- */
- public int close() throws IOException {
- return close(System.err);
- }
-
- /** Set the server timeout threshold. */
- public void setServerTimeout(long threshold) {
- this.threshold = threshold;
- }
-
- /** Return the server timeout threshold. */
- public long getServerTimeout() {
- return threshold;
- }
-
- public String toString() {
- return this.environ.toString();
- }
-
- private void addP4Error(String message) {
- if(null == P4_ERROR) {
- P4_ERROR = message;
- } else {
- P4_ERROR += message;
- }
- }
-}
diff --git a/src/main/java/com/perforce/api/PerforceException.java b/src/main/java/com/perforce/api/PerforceException.java
deleted file mode 100644
index 0f37915..0000000
--- a/src/main/java/com/perforce/api/PerforceException.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package com.perforce.api;
-
-/*
- * Copyright (c) 2001, Perforce Software, All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/**
- * Signals that a general exception occurred when working with Perforce.
- *
- * @author David Markley
- * @version $Date: 2001/11/05 $ $Revision: #1 $
- */
-public class PerforceException extends Exception {
-
- public PerforceException(String msg) {
- super(msg);
- }
-}
diff --git a/src/main/java/com/perforce/api/RobotMessage.java b/src/main/java/com/perforce/api/RobotMessage.java
deleted file mode 100644
index f44883f..0000000
--- a/src/main/java/com/perforce/api/RobotMessage.java
+++ /dev/null
@@ -1,157 +0,0 @@
-package com.perforce.api;
-
-import java.io.*;
-import java.util.*;
-
-/*
- * Copyright (c) 2001, Perforce Software, All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/**
- * Container class for messages to and from the P4Robot. This message is sent to
- * the robot by the P4ReviewerService and any other application that wants to
- * instruct the P4Robot to synchronize with the P4 depot in a particular way.
- * - * The key to this is the views that are a part of this. Each view will be used - * in executing "p4 sync" on the P4Robot. If the SYNC_FORCE flag is specified, - * then the views are all executed with "p4 sync -f". If the SYNC_ALL flag is - * specified, the views are ignored and one "p4 sync //..." is executed (with - * the -f flag, if that is also specified). - * - * @author David Markley - * @version $Date: 2001/11/05 $ $Revision: #1 $ - * @deprecated This shoud be a part of the P4WebPublisher package. - */ -public class RobotMessage implements Serializable { - /** Indicates that the "p4 sync" should be run with the -f option */ - public final static int SYNC_FORCE = 1; - - /** Indicates that the views should be ignored and "p4 sync //..." is run */ - public final static int SYNC_ALL = 2; - - /** @serial */ - private Vector views = new Vector(); - - /** @serial */ - private String label = ""; - - /** @serial */ - private int change = -1; - - /** @serial */ - private int flags = 0; - - /** - * Default no-argument constructor. - */ - public RobotMessage() { - } - - /** - * Constructs a RobotMessage using the specified Change. What this does is - * load the views for this with the files that were affected by the Change. - * This allows for a more focused sync on the robot side. - * - * @param change - * Change to be used in constructing this. - */ - public RobotMessage(Change change) { - this(); - - views = change.getFiles(); - } - - /** - * Add a view. The view will be appended to a "p4 sync" executed by the - * robot. Thus, any valid file specification that is valid with "p4 sync" - * can be used: file[revRange] - * - * @param view - * Single view to be added. - */ - public void addView(String view) { - views.addElement(view); - } - - /** - * Clear all view information. This is useful, if the RobotMessage instance - * is to be reused in another send to a robot. - */ - public void clearViews() { - views.removeAllElements(); - } - - /** - * Returns the number of views in this. - */ - public int getViewCount() { - return views.size(); - } - - /** - * Returns an enumeration of the views. This is most useful on the robot end - * of things. - */ - public Enumeration getViews() { - return views.elements(); - } - - /** - * Sets the flags. - * - * @see #SYNC_FORCE - * @see #SYNC_ALL - * @param flags - * New value for the flags - */ - public void setFlags(int flags) { - this.flags = flags; - } - - /** - * Returns the flags that are set. - * - * @see #SYNC_FORCE - * @see #SYNC_ALL - */ - public int getFlags() { - return flags; - } - - private void writeObject(ObjectOutputStream out) throws IOException { - if(null == views) { - views = new Vector(); - } - out.writeObject(views); - out.writeObject(label); - out.writeInt(change); - out.writeInt(flags); - } - - private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { - views = (Vector) in.readObject(); - label = (String) in.readObject(); - change = in.readInt(); - flags = in.readInt(); - } - -} diff --git a/src/main/java/com/perforce/api/SourceControlObject.java b/src/main/java/com/perforce/api/SourceControlObject.java deleted file mode 100644 index 66cf735..0000000 --- a/src/main/java/com/perforce/api/SourceControlObject.java +++ /dev/null @@ -1,143 +0,0 @@ -package com.perforce.api; - -import java.io.*; -import java.util.*; - -/* - * Copyright (c) 2001, Perforce Software, All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/** - * An abstract base class for all source control objects. - * - * @author David Markley - * @version $Date: 2002/01/15 $ $Revision: #2 $ - */ -public abstract class SourceControlObject implements Cacheable { - private long update_time = 0; - - private long sync_time = 0; - - private Env environ; - - /** Default, no-argument constructor. */ - public SourceControlObject() { - update_time = 0; - sync_time = 0; - } - - /** - * Constructor that takes an environment for this object to use. - * - * @param env - * source control environement to use. - */ - public SourceControlObject(Env env) { - this(); - setEnv(env); - } - - /** - * Sets the P4 environment to be used when working with this object. This - * environment is required to store, sync, or otherwise work with the P4 - * depot. It is passed to the P4Process used in each of these transactions. - * - * @see Env - * @see P4Process - * @param env - * user environment to use. - */ - public void setEnv(Env env) { - this.environ = env; - } - - /** - * Returns the P4 environment associated with this instance. - * - * @return P4 environment. - */ - public Env getEnv() { - return this.environ; - } - - /** Returns the time, in milliseconds, for this object's last update. */ - public synchronized long getUpdateTime() { - return update_time; - } - - /** Sets the update time for this object to the current time. */ - public synchronized void refreshUpdateTime() { - update_time = (new Date()).getTime(); - } - - /** Returns the time, in milliseconds, that this object was synchronized. */ - public synchronized long getSyncTime() { - return sync_time; - } - - /** - * Tests this object to see if it is out of sync. Checks to see if the - * expiration time is within the specified number of milliseconds. - * - * @param threshold - * Number of milliseconds. - * @return True if the object will be out of sync within the threshold. - */ - public synchronized boolean outOfSync(long threshold) { - return (threshold < ((new Date()).getTime() - sync_time)); - } - - /** Invalidates this object. */ - public synchronized void invalidate() { - sync_time = 0; - } - - /** Marks this object as being in in sync or valid. */ - public synchronized void inSync() { - sync_time = (new Date()).getTime(); - } - - /** Removes any cached objects. */ - public void clearCache() { - getCache().clear(); - } - - /** Returns the HashDecay instance for this class */ - public abstract HashDecay getCache(); - - /** - * Stores this object back into Perforce, creating it if it didn't already - * exist. - */ - public abstract void commit() throws CommitException; - - /** - * Brings this object back into sync with Perforce. This also sets the sets - * the update and sync time for this object. - */ - public abstract void sync() throws PerforceException; - - /** - * Returns a string containing the object in XML form. - */ - public abstract String toXML(); -} diff --git a/src/main/java/com/perforce/api/SubmitException.java b/src/main/java/com/perforce/api/SubmitException.java deleted file mode 100644 index 762e3c4..0000000 --- a/src/main/java/com/perforce/api/SubmitException.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.perforce.api; - -import java.io.*; - -/* - * Copyright (c) 2001, Perforce Software, All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/** - * Signals that an exception occurred during a submit to Perforce. - * - * @author David Markley - * @version $Date: 2001/11/05 $ $Revision: #1 $ - */ -public final class SubmitException extends PerforceException { - - public SubmitException(String msg) { - super(msg); - } -} diff --git a/src/main/java/com/perforce/api/User.java b/src/main/java/com/perforce/api/User.java deleted file mode 100644 index f318bc7..0000000 --- a/src/main/java/com/perforce/api/User.java +++ /dev/null @@ -1,336 +0,0 @@ -package com.perforce.api; - -import java.io.*; -import java.util.*; - -/* - * Copyright (c) 2001, Perforce Software, All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/** - * Representation of a source control user. Each instance can store one p4 - * user's information. The class methods can be used to get a particular user. If that user - * has been gotten before, their user information will not be reloaded from P4. - * It is instead loaded from an internal HashDecay. - *
- * If the user information must be up to date, then the sync() - * method must be called. - *
- * TBD: The current implementation does NOT handle the "reviews" information for
- * each user. Should User extend Mapping?
- *
- * @see HashDecay
- * @author David Markley
- * @version $Date: 2002/05/16 $ $Revision: #2 $
- */
-public final class User extends SourceControlObject {
- private String id = "";
-
- private String email = "";
-
- private String fullname = "";
-
- private static HashDecay users = null;
-
- /**
- * Default no-argument constructor.
- */
- public User() {
- super();
- getCache();
- }
-
- /**
- * Constructor that accepts the id of the user. This simply creates an
- * instance that has the id set. No other information in the class will be
- * present until the sync() method is called.
- *
- * @param id
- * Id for the user.
- */
- public User(String id) {
- this();
- this.id = id;
- }
-
- private static HashDecay setCache() {
- if(null == users) {
- users = new HashDecay(600000);
- users.start();
- }
- return users;
- }
-
- public HashDecay getCache() {
- return setCache();
- }
-
- /**
- * Sets the id for this user.
- *
- * @param id
- * Id for the user.
- */
- public void setId(String id) {
- this.id = id;
- }
-
- /**
- * Returns an
- * If the user information must be up to date, then the sync() method must be called.
- *
- * @deprecated Use method with Env parameter.
- * @param uid
- * User id that is requested.
- */
- public static synchronized User getUser(String uid) {
- return getUser(null, uid);
- }
-
- /**
- * Gets the user information for the specified user. If that user has been
- * gotten before, their user information will not be reloaded from P4. It is
- * instead loaded from an internal HashDecay.
- *
- * If the user information must be up to date, then the sync() method must be called.
- *
- * @param env
- * Source control environment to use.
- * @param uid
- * The user id of the user information to get from p4.
- */
- public static synchronized User getUser(Env env, String uid) {
- if(null == uid) {
- return null;
- }
- if(uid.trim().equals("")) {
- return null;
- }
-
- String tid;
- int i, left = 0;
- uid = uid.trim();
- if(-1 == (left = uid.indexOf("<"))) {
- tid = uid;
- } else {
- tid = uid.substring(0, left - 1).trim();
- }
- User u = (User) setCache().get(uid);
- if(null != u) {
- return u;
- } else {
- u = new User(tid);
- }
- u.setEmail(tid);
- u.setFullName(tid);
- if(-1 != left) {
- uid = uid.substring(left + 1);
- char[] ch = uid.toCharArray();
- left = 0;
- for(i = 0; i < ch.length; i++) {
- switch(ch[i]) {
- case '>':
- u.setEmail(new String(ch, left, i - left));
- break;
- case '(':
- left = i + 1;
- break;
- case ')':
- u.setFullName(new String(ch, left, i - left));
- break;
- }
- }
- }
- u.setEnv(env);
- users.put(tid, u);
- return u;
- }
-
- /**
- * Returns the id for this user.
- *
- * @return Id for the user.
- */
- public String getId() {
- return id;
- }
-
- /**
- * Sets the e-mail address for this user.
- *
- * @param email
- * Email address for the user.
- */
- public void setEmail(String email) {
- this.email = email;
- }
-
- /**
- * Returns the e-mail address for this user.
- *
- * @return Email address for the user.
- */
- public String getEmail() {
- return email;
- }
-
- /**
- * Sets the full name of this user.
- *
- * @param fullname
- * The full name for the user.
- */
- public void setFullName(String fullname) {
- this.fullname = fullname;
- }
-
- /**
- * Returns the full name of this user.
- *
- * @return The full name for the user.
- */
- public String getFullName() {
- return fullname;
- }
-
- /**
- * TBD: The > becomes > and < becomes <
- */
- public static String HTMLEncode(String str) {
- if(null == str)
- return "null";
- StringBuffer strbuf = new StringBuffer(str.length());
- char tmp;
- for(int i = 0; i < str.length(); i++) {
- tmp = str.charAt(i);
- if('<' == tmp) {
- strbuf.append("<");
- } else if('>' == tmp) {
- strbuf.append(">");
- } else {
- strbuf.append(tmp);
- }
- }
- return strbuf.toString();
- }
-
- /**
- * Returns common prefix for a Vector of strings. This is very useful for
- * determining a commong prefix for a set of paths.
- */
- public static String commonPrefix(Vector v) {
- return commonPrefix(v.elements());
- }
-
- /**
- * Returns common prefix for an Enumeration of strings.
- */
- public static String commonPrefix(Enumeration en) {
- if(null == en || !en.hasMoreElements())
- return "";
- String common = (String) en.nextElement();
- String str = null;
- int i, len;
- char[] ar1, ar2;
-
- ar1 = common.toCharArray();
- while(en.hasMoreElements()) {
- str = (String) en.nextElement();
- ar2 = str.toCharArray();
- if(str.startsWith(common))
- continue;
- len = common.length();
- if(len > str.length())
- len = str.length();
- for(i = 0; i < len; i++) {
- if(ar1[i] != ar2[i])
- break;
- }
- if(0 == i)
- return "";
- common = common.substring(0, i);
- ar1 = common.toCharArray();
- }
- if(-1 != (i = common.indexOf('#')))
- common = common.substring(0, i);
- if(-1 != (i = common.indexOf('@')))
- common = common.substring(0, i);
- return common;
- }
-
- /**
- * Returns the change number portion of a depot path, if there is a valid
- * one found. Otherwise, it returns -1.
- */
- public final static int getChangeFromPath(String path) {
- int i = path.indexOf('@');
- if(0 > i)
- return -1;
- try {
- return Integer.valueOf(path.substring(i + 1)).intValue();
- } catch(NumberFormatException ex) {
- return -1;
- }
- }
-
- /**
- * Cleans up after the package has been used. This stops any running threads
- * and releases any objects for garbage collection.
- */
- public static void cleanUp() {
- HashDecay.stopAll();
- System.gc();
- }
-
- /**
- * Breaks up a depot path and formats each level. Each format string takes
- * two arguments. The first is set to the full path to a particular element.
- * The second is set to the short name for the element.
- *
- * This is extremely useful for setting up links from each component of a
- * path.
- *
- * @param path
- * The path to be formatted.
- * @param pathfmt
- * The format to be used for path elements.
- * @param filefmt
- * The format to be used for the file element.
- * @param revfmt
- * The format to be used for the rev component.
- * @param urlencode
- * Determines if paths are encoded.
- * @see URLEncoder
- */
- public static StringBuffer formatDepotPath(String path, String pathfmt, String filefmt, String revfmt,
- boolean urlencode) throws PerforceException {
- StringBuffer sb = new StringBuffer("//");
- Object[] args = { "path", "part" };
- int p1 = 1, p2 = 0;
-
- if(null == path || (!path.startsWith("//"))) {
- throw new PerforceException(path + " is not a depot path.");
- }
-
- // Don't bother parsing anything if all the formats are null.
- if(null == pathfmt && null == filefmt && null == revfmt) {
- return new StringBuffer(path);
- }
-
- if(null == pathfmt) {
- p1 = path.lastIndexOf("/");
- sb.append(path.substring(2, p1 + 1));
- } else {
- while(-1 != (p2 = path.indexOf("/", p1 + 1))) {
- args[0] = path.substring(0, p2);
- if(urlencode)
- args[0] = URLEncoder.encode((String) args[0]);
- args[1] = path.substring(p1 + 1, p2);
- sb.append(MessageFormat.format(pathfmt, args));
- sb.append('/');
- p1 = p2;
- }
- }
-
- String rev = null;
- if(-1 == (p2 = path.indexOf("#", p1 + 1))) {
- p2 = path.length();
- } else {
- rev = path.substring(p2 + 1);
- }
- args[0] = path.substring(0, p2);
- if(urlencode)
- args[0] = URLEncoder.encode((String) args[0]);
- String fname = path.substring(p1 + 1, p2);
- args[1] = fname;
- if(null == filefmt) {
- sb.append(args[1]);
- } else {
- sb.append(MessageFormat.format(filefmt, args));
- }
-
- if(null != rev) {
- sb.append('#');
- args[0] = path;
- if(urlencode)
- args[0] = URLEncoder.encode((String) args[0]);
- args[1] = rev;
- if(null == revfmt) {
- sb.append(args[1]);
- } else {
- sb.append(MessageFormat.format(revfmt, args));
- }
- }
- return sb;
- }
-
- public static Enumeration getEnumeration(Iterator i) {
- Vector v = new Vector();
- while(i.hasNext())
- v.addElement(i.next());
- return v.elements();
- }
-
- /**
- * @deprecated Useful for testing, but should not be documented.
- */
- public static void main(String[] argv) {
- Vector v = new Vector(argv.length);
- for(int i = 0; i < argv.length; i++) {
- v.addElement(argv[i]);
- System.out.println(argv[i] + ": " + getChangeFromPath(argv[i]));
- }
- System.out.println("Common: " + commonPrefix(v));
- }
-}
diff --git a/src/main/java/com/perforce/api/package.html b/src/main/java/com/perforce/api/package.html
deleted file mode 100644
index e7ea559..0000000
--- a/src/main/java/com/perforce/api/package.html
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-Provides legacy perforce.com API classes. These classes can be used as a backup if
-the new API does not provide a particular need for you. The new API contains the
-Depot object which has support for generating a legacy Env object. You can use this
-for all legacy API calls that require an Env parameter.
-
- * As an example of usage:
- * E.g., depot.getStatus().isValid() for checking if the settings are correct.
- *
- * @return Status object
- */
- public Status getStatus() {
- if(status == null)
- status = new Status(this);
- return status;
- }
-
- /**
- * Returns the output created by "p4 info"
- *
- * @return The string output of p4 info
- */
- public String info() throws Exception {
- Executor p4 = getExecFactory().newExecutor();
- String cmd[] = { "p4", "info" };
- p4.exec(cmd);
- StringBuilder sb = new StringBuilder();
- String line;
- while((line = p4.getReader().readLine()) != null) {
- sb.append(line + "\n");
- }
- return sb.toString();
- }
-
- /**
- * Gets a property specified by key
- *
- * @param key
- * @return
- */
- public String getProperty(String key) {
- return settings.get(key);
- }
-
- /**
- * Gets a value specified by key. If the value is empty, it will return the specified default.
- *
- * @param key
- * @param def
- * @return
- */
- public String getProperty(String key, String def) {
- String value = getProperty(key);
- if(value == null || value.equals(""))
- return def;
- return value;
- }
-
- /**
- * Sets the P4USER in the class information.
- *
- * @param user
- * P4USER value.
- */
- public void setUser(String user) {
- if(null == user)
- return;
- settings.put("P4USER", user);
- validEnvp = false;
- }
-
- /**
- * Returns the P4USER.
- *
- * @return
- */
- public String getUser() {
- return settings.get("P4USER");
- }
-
- /**
- * Sets the P4CLIENT in the class information.
- *
- * @param user
- * P4CLIENT value.
- */
- public void setClient(String client) {
- if(null == client)
- return;
- settings.put("P4CLIENT", client);
- validEnvp = false;
- }
-
- /**
- * Returns the P4CLIENT.
- *
- * @return
- */
- public String getClient() {
- return settings.get("P4CLIENT");
- }
-
- /**
- * Sets the P4PORT in the class information.
- *
- * @param user
- * P4PORT value.
- */
- public void setPort(String port) {
- if(null == port)
- return;
- settings.put("P4PORT", port);
- validEnvp = false;
- }
-
- /**
- * Returns the P4PORT.
- *
- * @return
- */
- public String getPort() {
- return settings.get("P4PORT");
- }
-
- /**
- * Sets the P4PASSWD in the class information.
- *
- * @param user
- * P4PASSWD value.
- */
- public void setPassword(String password) {
- if(null == password)
- return;
- settings.put("P4PASSWD", password);
- validEnvp = false;
- }
-
- /**
- * Returns the P4PASSWORD.
- *
- * @return
- */
- public String getPassword() {
- return settings.get("P4PASSWD");
- }
-
- /**
- * Sets the PATH in the class information.
- *
- * @param path
- * PATH value.
- */
- public void setPath(String path) {
- if(null == path)
- return;
- settings.put("PATH", path);
- validEnvp = false;
- }
-
- /**
- * Append the path element to the existing path. If the path element given is already in the path, no change is
- * made.
- *
- * @param path
- * the path element to be appended.
- */
- public void appendPath(String path) {
- String tok;
- if(null == path)
- return;
- String origPath = getProperty("PATH");
- if(null == pathSep || null == origPath) {
- setPath(path);
- return;
- }
- StringTokenizer st = new StringTokenizer(origPath, pathSep);
- StringBuffer sb = new StringBuffer();
- while(st.hasMoreTokens()) {
- tok = st.nextToken();
- if(tok.equals(path))
- return;
- sb.append(tok);
- sb.append(pathSep);
- }
- sb.append(path);
- setPath(path);
- }
-
- /**
- * Returns the path
- *
- * @return
- */
- public String getPath() {
- return settings.get("PATH");
- }
-
- /**
- * Sets the SystemDrive in the class information. This is only meaningful under Windows.
- *
- * @param user
- * SystemDrive value.
- */
- public void setSystemDrive(String drive) {
- if(null == drive)
- return;
- settings.put("SystemDrive", drive);
- validEnvp = false;
- }
-
- /**
- * Returns the system drive
- *
- * @return
- */
- public String getSystemDrive() {
- return settings.get("SystemDrive");
- }
-
- /**
- * Sets the SystemRoot in the class information. This is only meaningful under Windows.
- *
- * @param user
- * SystemRoot value.
- */
- public void setSystemRoot(String root) {
- if(null == root)
- return;
- settings.put("SystemRoot", root);
- validEnvp = false;
- }
-
- /**
- * Returns the system root.
- *
- * @return
- */
- public String getSystemRoot() {
- return settings.get("SystemRoot");
- }
-
- /**
- * Sets up the path to reach the p4 executable. The full path passed in must contain the executable or at least end
- * in the system's file separator character. This gotten from the file.separator property. For example:
- *
- *
- * Again Perforce fails us with an imcomplete API. Their change object does not contain a record of files or jobs
- * attached to the change. Grr... I'm forced to create one that is more complete.
- *
- * This class maps the output of p4 describe [ChangeNumber]. However, it does not contain the diffs ouput by that
- * command. If you want those, get them yourself.
- *
- * @author Mike Wille
- */
-public class Changelist implements java.io.Serializable {
- int changeNumber;
- String workspace;
- Date date;
- String user;
- String description;
- List
- * This is necessary because the Client class that Perforce provides in their API is not complete. It is missing several
- * fields and we cannot extend that class because its final.
- *
- * @author Mike Wille
- */
-public class Workspace extends AbstractViewsSupport implements java.io.Serializable {
- String name;
- String owner;
- String host;
- String description;
- String root;
- String altRoots;
- String options;
- String lineEnd;
- String submitOptions;
- String update;
- String access;
-
- public Workspace() {
- super();
- this.name = "";
- this.owner = "";
- this.host = "";
- this.description = "";
- this.root = "";
- this.altRoots = "";
- this.options = "";
- this.lineEnd = "";
- this.submitOptions = "";
- this.update = "";
- this.access = "";
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append("[Client]\n");
- sb.append("Name: " + getName() + "\n");
- sb.append("Update: " + getUpdate() + "\n");
- sb.append("Access: " + getAccess() + "\n");
- sb.append("Owner: " + getOwner() + "\n");
- sb.append("Host: " + getHost() + "\n");
- sb.append("Description: " + getDescription() + "\n");
- sb.append("Root: " + getRoot() + "\n");
- sb.append("AltRoot: " + getAltRoots() + "\n");
- sb.append("Options: " + getOptions() + "\n");
- sb.append("SubmitOptions: " + getSubmitOptions() + "\n");
- sb.append("LineEnd: " + getLineEnd() + "\n");
- sb.append("Views: \n");
- for(String view : views) {
- sb.append("\t" + view + "\n");
- }
-
- return sb.toString();
- }
-
- /**
- * @return the name
- */
- public String getName() {
- return name;
- }
-
- /**
- * @param name
- * the name to set
- */
- public void setName(String name) {
- this.name = name;
- }
-
- /**
- * @return the owner
- */
- public String getOwner() {
- return owner;
- }
-
- /**
- * @param owner
- * the owner to set
- */
- public void setOwner(String owner) {
- this.owner = owner;
- }
-
- /**
- * @return the host
- */
- public String getHost() {
- return host;
- }
-
- /**
- * @param host
- * the host to set
- */
- public void setHost(String host) {
- this.host = host;
- }
-
- /**
- * @return the description
- */
- public String getDescription() {
- return description;
- }
-
- /**
- * @param description
- * the description to set
- */
- public void setDescription(String description) {
- this.description = description;
- }
-
- /**
- * @return the root
- */
- public String getRoot() {
- return root;
- }
-
- /**
- * @param root
- * the root to set
- */
- public void setRoot(String root) {
- this.root = root;
- }
-
- /**
- * @return the altRoots
- */
- public String getAltRoots() {
- return altRoots;
- }
-
- /**
- * @param altRoots
- * the altRoots to set
- */
- public void setAltRoots(String altRoots) {
- this.altRoots = altRoots;
- }
-
- /**
- * @return the options
- */
- public String getOptions() {
- return options;
- }
-
- /**
- * @param options
- * the options to set
- */
- public void setOptions(String options) {
- this.options = options;
- }
-
- /**
- * @return the lineEnd
- */
- public String getLineEnd() {
- return lineEnd;
- }
-
- /**
- * @param lineEnd
- * the lineEnd to set
- */
- public void setLineEnd(String lineEnd) {
- this.lineEnd = lineEnd;
- }
-
- /**
- * @return the submitOptions
- */
- public String getSubmitOptions() {
- return submitOptions;
- }
-
- /**
- * @param submitOptions
- * the submitOptions to set
- */
- public void setSubmitOptions(String submitOptions) {
- this.submitOptions = submitOptions;
- }
-
- /**
- * @return the update
- */
- public String getUpdate() {
- return update;
- }
-
- /**
- * @param update
- * the update to set
- */
- public void setUpdate(String update) {
- this.update = update;
- }
-
- /**
- * @return the access
- */
- public String getAccess() {
- return access;
- }
-
- /**
- * @param access
- * the access to set
- */
- public void setAccess(String access) {
- this.access = access;
- }
-
-}
diff --git a/src/main/java/com/tek42/perforce/model/package.html b/src/main/java/com/tek42/perforce/model/package.html
deleted file mode 100644
index 171532b..0000000
--- a/src/main/java/com/tek42/perforce/model/package.html
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-Provides models of perforce objects.
-
-All first class objects of perforce are provided here.
-
-Provides a java API for interacting with Perforce SCM.
-
-Example Usage:
- * Useful for all perforce objects that are editable via forms. i.e., User, Workspace, Jobspec, etc.
- *
- * @author Mike Wille
- */
-public abstract class AbstractFormBuilder
- * Unfortunately, this likely doesn't work on windows.
- *
- * @throws PerforceException If perforce throws any errors
- */
- protected void login() throws PerforceException {
- // Unfortunately, the simple way of doing this: echo password | p4 login
- // Doesn't work on windows! So we have to try and write directly, but
- // that doesn't seem to work either. The code is left here, but probably is
- // not going to work. If you are facing this problem, use depot.setTicket() with a ticket
- // that has an expiration significantly far ahead in time to work as a permanent login.
- String sep = System.getProperty("file.separator");
- if(sep.equals("\\")) {
- Executor login = depot.getExecFactory().newExecutor();
- login.exec(new String[] { "p4", "login" });
- try {
- Thread.sleep(250);
- } catch(InterruptedException e) {
- // nothing to do
- }
- try {
- login.getWriter().write(depot.getPassword() + "\n");
- } catch(IOException e) {
- throw new PerforceException("Failed to communicate with p4 when logging in to server.");
- }
- login.close();
- } else { // for everything not windows...
- Executor login = depot.getExecFactory().newExecutor();
- // The -p parameter outputs the ticket to stdout.
- final String[] args = {"/bin/sh", "-c", depot.getExecutable() + " login -p"};
- logger.info("Running " + Arrays.toString(args));
- login.exec(null, args);
- String ticket = null;
- try {
- login.getWriter().write(depot.getPassword()==null ? "" : depot.getPassword());
- login.getWriter().newLine();
- login.getWriter().flush();
- BufferedReader reader = login.getReader();
- String line;
-
- // The last line output from p4 login will be the ticket
- while((line = reader.readLine()) != null) {
- ticket = line;
- }
-
- } catch(IOException e) {
- throw new PerforceException("Unable to login via p4 login due to IOException: " + e.getMessage());
- }
- // if we obtained a ticket, save it for later use. Our environment setup by Depot can't usually
- // see the .p4tickets file.
- if(ticket != null) {
- ticket = ticket.trim();
- if(ticket.contains(" ")) {
- throw new PerforceException("Failed to login: " + ticket);
- }
- logger.warn("Using p4 issued ticket.");
- depot.setP4Ticket(ticket);
- }
-
- login.close();
- }
- }
-}
diff --git a/src/main/java/com/tek42/perforce/parse/Builder.java b/src/main/java/com/tek42/perforce/parse/Builder.java
deleted file mode 100644
index 2adafc1..0000000
--- a/src/main/java/com/tek42/perforce/parse/Builder.java
+++ /dev/null
@@ -1 +0,0 @@
-/*
* P4Java - java integration with Perforce SCM
* Copyright (C) 2007-, Mike Wille, Tek42
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* You can contact the author at:
*
* Web: http://tek42.com
* Email: mike@tek42.com
* Mail: 755 W Big Beaver Road
* Suite 1110
* Troy, MI 48084
*/
package com.tek42.perforce.parse;
import java.io.Writer;
import com.tek42.perforce.PerforceException;
/**
* Interface for parsing perforce output into a concrete object and also for saving the object back to perforce.
*
* The pattern for using this template to build an object is:
* And conversely for saving:
*
* Note, although the object being saved is passed to this method, this method does not need to do anything with it.
*
* @return A 1D string array of tokens to execute
* @param obj The object that is being saved, useful if propert(ies) are needed for the save command to be generated.
*/
public String[] getSaveCmd(T obj);
/**
* Tells the AbstractPerforceTemplate whether or not this builder will write data on Standard Input to the perforce
* command specified in getSaveCmd(). Currently, this only applies to saving as their is no writing required for
* building.
*
* @return True if standard input should be opened and this builder's save() method called. False otherwise.
*/
public boolean requiresStandardInput();
/**
* The converse of {@link #build(StringBuilder)} this should take an object and disassemble it for writing to the
* Perforce server. The specification of what is written to the Writer is dependant on the object being saved.
*
* @param obj
* The object to be saved
* @param writer
* The Writer to write the string representation to
* @throws PerforceException
* If the object is invalid or there is an issue with writing
*/
public void save(T obj, Writer writer) throws PerforceException;
}
\ No newline at end of file
diff --git a/src/main/java/com/tek42/perforce/parse/ChangelistBuilder.java b/src/main/java/com/tek42/perforce/parse/ChangelistBuilder.java
deleted file mode 100644
index 622a558..0000000
--- a/src/main/java/com/tek42/perforce/parse/ChangelistBuilder.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * P4Java - java integration with Perforce SCM
- * Copyright (C) 2007-, Mike Wille, Tek42
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * You can contact the author at:
- *
- * Web: http://tek42.com
- * Email: mike@tek42.com
- * Mail: 755 W Big Beaver Road
- * Suite 1110
- * Troy, MI 48084
- */
-package com.tek42.perforce.parse;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.GregorianCalendar;
-import java.util.List;
-import java.util.Locale;
-import java.util.StringTokenizer;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.tek42.perforce.PerforceException;
-import com.tek42.perforce.model.Changelist;
-
-/**
- * Responsible for building and saving changelists.
- *
- * @author Mike Wille
- */
-public class ChangelistBuilder implements Builder
- * To get the latest change in the depot for the project, you can use:
- *
- *
- * Note: this method follows perforce in that it starts at the highest number and works backwards. So this might not
- * be what you want. (It certainly isn't for Hudson)
- *
- * @param path
- * Path to filter on
- * @param start
- * The number of the change to start from
- * @param limit
- * The number of changes to return
- * @return
- * @throws PerforceException
- */
- public ListEnumeration of all User objects.
- */
- public static synchronized Enumeration getUsers() {
- return getUsers(null);
- }
-
- /**
- * Returns an Enumeration of all User objects.
- */
- public static synchronized Enumeration getUsers(Env env) {
- String l;
- User u;
- String[] cmd = { "p4", "users" };
-
- try {
- P4Process p = new P4Process(env);
- p.exec(cmd);
- while(null != (l = p.readLine())) {
- if(l.startsWith("#")) {
- continue;
- }
- u = getUser(l);
- u.setEnv(env);
- }
- p.close();
- } catch(IOException ex) {
- }
-
- return setCache().elements();
- }
-
- /**
- * Gets the user information for the specified user. If that user has been
- * gotten before, their user information will not be reloaded from P4. It is
- * instead loaded from an internal HashDecay.
- * commit method is not working yet.
- */
- public void commit() {
- }
-
- /**
- * Synchronizes the user information with P4. This method must be called to
- * ensure that this contains the latest information from p4. This form of
- * the method can be used to change the user Id in at the same time.
- *
- * @param id
- * The user id for this to synchronize from p4.
- */
- public void sync(String id) {
- this.id = id;
- sync();
- }
-
- /**
- * Synchronizes the user information with P4. This method must be called to
- * ensure that this contains the latest information from p4.
- */
- public void sync() {
- if(!outOfSync(300000))
- return;
- String l;
- String[] cmd = { "p4", "user", "-o", "id" };
- cmd[3] = id;
-
- try {
- P4Process p = new P4Process(getEnv());
- p.exec(cmd);
- while(null != (l = p.readLine())) {
- if(l.startsWith("#")) {
- continue;
- }
- if(l.startsWith("User:")) {
- id = l.substring(6).trim();
- } else if(l.startsWith("Email:")) {
- email = l.substring(7).trim();
- } else if(l.startsWith("FullName:")) {
- fullname = l.substring(10).trim();
- }
- }
- p.close();
- inSync();
- } catch(IOException ex) {
- }
- }
-
- public String toString() {
- return id;
- }
-
- public String toXML() {
- StringBuffer sb = new StringBuffer("path matches the wildpath.
- * Only perforce wildcards are considered in the wildpath.
- */
- public static boolean wildPathMatch(String wildpath, String path) {
- // System.out.println("Matching: "+wildpath+" to "+path);
- wildpath = wildpath.trim();
- path = path.trim();
- boolean match = true;
- boolean in_dots = false;
- int i, j, plen = path.length(), wplen = wildpath.length();
- char wc, pc;
- for(j = 0, i = 0; i < wplen && j < plen; i++) {
- if('%' == (wc = wildpath.charAt(i))) {
- wc = wildpath.charAt(++i);
- if('0' > wc || '9' < wc) {
- match = false;
- break;
- }
- while('/' != path.charAt(j) && j < plen) {
- j++;
- }
- continue;
- } else if('*' == wc) {
- while('/' != path.charAt(j) && j < plen) {
- j++;
- }
- continue;
- }
- if('.' == wc && wildpath.regionMatches(i, "...", 0, 3)) {
- i += 2;
- in_dots = true;
- continue;
- }
- if(path.charAt(j++) != wc) {
- if(!in_dots) {
- match = false;
- break;
- } else {
- i--;
- }
- } else if(in_dots) {
- String wpath2 = wildpath.substring(i);
- String path2 = path.substring(j - 1);
- if(wildPathMatch(wpath2, path2)) {
- return true;
- } else {
- i--;
- }
- }
- }
- if(j < plen)
- return in_dots;
- if(i < wplen)
- return false;
- return match;
- }
-
- /**
- * Returns the string encoded for HTML use.
- *
- *
- *
- *
- * // Setup
- * Depot depot = new Depot();
- * depot.setPort("perforce.com:1666");
- * depot.setUser("username");
- * depot.setPassword("password");
- * depot.setWorkspace("workspace");
- *
- * // Test
- * depot.isValid() // returns true if so
- *
- * // Look at the last change for a project...
- * List<Changelist> changes = depot.getChanges().getChangelists("//depot/ProjectName/...", -1, 1);
- * System.out.println(Last Change is: " + changes.get(0));
- *
- *
- * @author Mike Wille
- */
-public class Depot {
- private static Depot depot;
- private final Logger logger = LoggerFactory.getLogger("perforce");
- private HashMap
- * p4.executable=/usr/bin/p4 # This will work
- * p4.executable=/usr/bin/ # This will work
- * <font color=Red>p4.executable=/usr/bin # This won't work</font>
- *
- *
- * @param exe
- * Full path to the p4 executable.
- */
- public void setExecutable(String exe) {
- int pos;
- if(null == exe)
- return;
- p4exe = exe;
- if(null == fileSep) {
- fileSep = System.getProperties().getProperty("file.separator", "\\");
- }
- if(-1 == (pos = exe.lastIndexOf(fileSep)))
- return;
- if(null == pathSep) {
- pathSep = System.getProperties().getProperty("path.separator", ";");
- }
- appendPath(exe.substring(0, pos));
- validEnvp = false;
- }
-
- /**
- * Returns the path to the executable.
- *
- * @return
- */
- public String getExecutable() {
- return p4exe;
- }
-
- /**
- * Set the server timeout threshold.
- *
- * @param threshold
- */
- public void setServerTimeout(long threshold) {
- this.threshold = threshold;
- }
-
- /**
- * Return the server timeout threshold.
- *
- * @return
- */
- public long getServerTimeout() {
- return threshold;
- }
-
- /**
- * Returns the ticket value for this depot's user.
- *
- * @return the p4Ticket
- */
- public String getP4Ticket() {
- return p4Ticket;
- }
-
- /**
- * If using tickets, set the value of the ticket for this depot's user. Example value would be:
- * 875477B92937E4AF7B20C5234C8905E2
- *
- * @param ticket
- * the p4Ticket to set
- */
- public void setP4Ticket(String ticket) {
- p4Ticket = ticket;
- }
-
-}
diff --git a/src/main/java/com/tek42/perforce/PerforceException.java b/src/main/java/com/tek42/perforce/PerforceException.java
deleted file mode 100644
index 80b3373..0000000
--- a/src/main/java/com/tek42/perforce/PerforceException.java
+++ /dev/null
@@ -1 +0,0 @@
-package com.tek42.perforce;
/*
* Copyright (c) 2001, Perforce Software, All rights reserved. Permission is hereby granted, free of charge, to any
* person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* Signals that a general exception occurred when working with Perforce.
*
* @author David Markley
* @version $Date: 2001/11/05 $ $Revision: #1 $
*/
public class PerforceException extends Exception {
private static final long serialVersionUID = 1L;
public PerforceException(String mesg) {
super(mesg);
}
public PerforceException(String mesg, Throwable cause) {
super(mesg, cause);
}
}
\ No newline at end of file
diff --git a/src/main/java/com/tek42/perforce/model/AbstractViewsSupport.java b/src/main/java/com/tek42/perforce/model/AbstractViewsSupport.java
deleted file mode 100644
index d27b2af..0000000
--- a/src/main/java/com/tek42/perforce/model/AbstractViewsSupport.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * P4Java - java integration with Perforce SCM
- * Copyright (C) 2007-, Mike Wille, Tek42
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * You can contact the author at:
- *
- * Web: http://tek42.com
- * Email: mike@tek42.com
- * Mail: 755 W Big Beaver Road
- * Suite 1110
- * Troy, MI 48084
- */
-
-package com.tek42.perforce.model;
-
-import java.util.List;
-import java.util.ArrayList;
-
-/**
- * Provide base support for views.
- *
- * @author Mike Wille
- */
-public abstract class AbstractViewsSupport implements java.io.Serializable {
- protected Listtrue if this is a pending changelist
- */
- public boolean isPending() {
- return pending;
- }
-
- /**
- * @param pending
- */
- public void setPending(boolean pending) {
- this.pending = pending;
- }
-}
diff --git a/src/main/java/com/tek42/perforce/model/Counter.java b/src/main/java/com/tek42/perforce/model/Counter.java
deleted file mode 100644
index 2bec619..0000000
--- a/src/main/java/com/tek42/perforce/model/Counter.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package com.tek42.perforce.model;
-
-/**
- * Represents a Perforce counter.
- *
- * @author Kamlesh Sangani
- */
-public class Counter {
-
- private String name;
- private int value = 0;
-
- /**
- * Returns counter name
- *
- * @return counter name
- */
- public String getName() {
- return name;
- }
-
- /**
- * Sets counter name
- *
- * @param name
- * counter name
- */
- public void setName(String name) {
- this.name = name;
- }
-
- /**
- * Returns counter value
- *
- * @return counter value
- */
- public int getValue() {
- return value;
- }
-
- /**
- * Sets counter value
- *
- * @param value
- * counter value
- */
- public void setValue(int value) {
- this.value = value;
- }
-
- @Override
- public String toString() {
- return String.format("[Name=%s, Value=%d]", name, value);
- }
-}
diff --git a/src/main/java/com/tek42/perforce/model/Group.java b/src/main/java/com/tek42/perforce/model/Group.java
deleted file mode 100644
index 6369e41..0000000
--- a/src/main/java/com/tek42/perforce/model/Group.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * P4Java - java integration with Perforce SCM
- * Copyright (C) 2007-, Mike Wille, Tek42
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * You can contact the author at:
- *
- * Web: http://tek42.com
- * Email: mike@tek42.com
- * Mail: 755 W Big Beaver Road
- * Suite 1110
- * Troy, MI 48084
- */
-
-package com.tek42.perforce.model;
-
-import java.util.List;
-import java.util.ArrayList;
-
-/**
- * Represents a group in perforce.
- *
- * @author Mike
- * Date: Jul 21, 2008 2:42:09 PM
- */
-public class Group {
- String name;
- String maxResults;
- String maxScanRows;
- String maxLockTime;
- Long timeout;
- List
-
- // Setup
- Depot depot = new Depot();
- depot.setPort("perforce.com:1666");
- depot.setUser("username");
- depot.setPassword("password");
- depot.setWorkspace("workspace");
-
- // Test
- depot.getStatus().isValid() // returns true if so
-
- // Look at the last change for a project...
- List changes = depot.getChanges().getChangelists("//depot/ProjectName/...", -1, 1);
- System.out.println(Last Change is: " + changes.get(0));
-
-
*
*
*
*
* @author Mike Wille
*/
public interface Builder
- * depot.getChangeNumbers("//project/...", -1, 1)
- *
- *