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 lablel. There are static class methods * that can be used to list <a href="#getLabels()">all P4 labels</a> or to get * <a href="#getLabel(java.lang.String)">a particular label</a>. * * @author <a href="mailto:david@markley.cc">David Markley</a> * @version $Date: 2002/08/05 $ $Revision: #2 $ */ public class Label extends Mapping { private static HashDecay labels = null; /** * Default no-argument constructor. */ public Label() { super(); getCache(); } /** * Constructor that is passed the label name. */ public Label(String name) { this(); setName(name); } private synchronized static HashDecay setCache() { if(null == labels) { labels = new HashDecay(1200000); labels.start(); } return labels; } public HashDecay getCache() { return setCache(); } /** * Returns a list of labels that begin with the specified prefix. * * @param prefix * Prefix for all labels to be returned * @return List of labels matching the prefix. * @deprecated Use * {@link #lookupLabels(Env, String) lookupLabels(Env, String)} * instead. */ public static Enumeration lookupLabels(String prefix) { return lookupMappings(labels, prefix); } /** * Returns a list of labels that begin with the specified prefix. * * @param prefix * Prefix for all labels to be returned * @return List of labels matching the prefix. */ public static Enumeration lookupLabels(Env env, String prefix) { loadLabels(env); return lookupMappings(labels, prefix); } /** * Loads the list of labels using the default environment. * * @deprecated Use {@link #loadLabels(Env) loadLabels(Env, String)} instead. */ public static void loadLabels() { loadLabels(null); } /** * Loads a list of all the labels into an internal class HashDecay. This * method will only be called by the class itself if the HashDecay is empty. * Users should call this method if they believe the p4 label information * needs to be brought up to date. * * @param env * Environment to use when working with P4 * @see HashDecay */ public static void loadLabels(Env env) { String l, name; String[] cmd = { "p4", "labels" }; StringTokenizer st; Label b; setCache(); try { P4Process p = new P4Process(env); p.exec(cmd); while(null != (l = p.readLine())) { if(!l.startsWith("Label")) { continue; } st = new StringTokenizer(l); if(6 > st.countTokens()) { continue; } st.nextToken(); name = st.nextToken(); synchronized(labels) { if(null == (b = (Label) labels.get(name))) { b = new Label(name); b.setEnv(env); } else { b.refreshUpdateTime(); continue; } } st.nextToken(); st.nextToken("'"); b.setDescription(st.nextToken()); labels.put(b.getName(), b); } } catch(Exception ex) { ex.printStackTrace(); } } /** * @param env * Environment to use when working with P4 * @return List of all label names (Enumeration of String instances). */ public static Enumeration getLabelNames(Env env) { loadLabels(env); return labels.keys(); } /** * @return List of all labels (Enumeration of Label instances). * @deprecated Use {@link #getLabels(Env) getLabels(Env)} instead. */ public static Enumeration getLabels() { return getLabels(null); } /** * @param env * Environment to use when working with P4 * @return Enumeration of all labels (set of Label instances). */ public static Enumeration getLabels(Env env) { return Utils.getEnumeration(getLabelIterator(env)); } /** * @param env * Environment to use when working with P4 * @return Iterator for all labels (set of Label instances). */ public static Iterator getLabelIterator(Env env) { loadLabels(env); Enumeration en = labels.elements(); TreeSet ts = new TreeSet(); while(en.hasMoreElements()) { ts.add(en.nextElement()); } return ts.iterator(); } /** * Returns a Label with the specified name, or null if not found. * * @param name * Name of the label to find. */ public static synchronized Label getLabel(String name) { return getLabel(null, name, true); } /** * Returns a Label with the specified name, or null if not found. * * @param env * Environment to use when working with P4. * @param name * Name of the label to find. * @param force * Indicates that the Label should be sync'd. */ public static synchronized Label getLabel(Env env, String name, boolean force) { Label b; if(null == name || name.trim().equals("")) return null; if(null == (b = (Label) setCache().get(name))) b = new Label(name); if(null != env) b.setEnv(env); b.sync(); labels.put(name, b); return b; } /** * Stores the label information back into p4, creating the label if it * didn't already exist. * * @deprecated Use {@link #commit() commit()} instea.d */ public void store() throws CommitException { this.commit(); } public void commit() throws CommitException { String[] cmd = { "p4", "label", "-i" }; String l; try { P4Process p = new P4Process(getEnv()); p.exec(cmd); while(null != (l = p.readLine())) { p.println("Label: " + getName()); p.println("Owner: " + getOwner()); if(null != getDescription()) p.println("Description:\n" + getDescription()); p.println("View:"); Enumeration en = getViews(); while(en.hasMoreElements()) p.println((String) en.nextElement()); p.println(""); 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 Label with the latest information from P4. This method * forces the Label to contain the latest, correct information if it didn't * already. * * @param name * Name of the Label to synchronize. */ public void sync(String name) { if(!outOfSync(300000)) return; setName(name); String description = ""; String l; String[] cmd = { "p4", "label", "-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("Label:")) { 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) { } } public String toXML() { StringBuffer sb = new StringBuffer("<label name=\""); sb.append(getName()); sb.append("\" owner=\""); sb.append(getOwner()); sb.append("\">"); sb.append(super.toXML()); sb.append("</label>"); return sb.toString(); } public static void main(String[] args) { String propfile = "/etc/p4.conf"; Env environ = null; Enumeration labels = null; Label lbl = null; Debug.setDebugLevel(Debug.VERBOSE); if(0 < args.length) propfile = args[0]; try { environ = new Env(propfile); } catch(PerforceException ex) { System.out.println("Could not load properties from " + propfile + ": " + ex); System.exit(-1); } System.out.println(environ); labels = getLabels(environ); while(labels.hasMoreElements()) { lbl = (Label) labels.nextElement(); System.out.println(lbl.getName()); } Utils.cleanUp(); } }