View Javadoc

1   /*
2   Karma core - Core of the Karma application
3   Copyright (C) 2004  Toolforge <www.toolforge.nl>
4   
5   This library is free software; you can redistribute it and/or
6   modify it under the terms of the GNU Lesser General Public
7   License as published by the Free Software Foundation; either
8   version 2.1 of the License, or (at your option) any later version.
9   
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  Lesser General Public License for more details.
14  
15  You should have received a copy of the GNU Lesser General Public
16  License along with this library; if not, write to the Free Software
17  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19  package nl.toolforge.karma.core.vc.cvsimpl;
20  
21  import nl.toolforge.karma.core.cmd.CommandResponse;
22  import nl.toolforge.karma.core.vc.VersionControlException;
23  import org.apache.commons.logging.Log;
24  import org.apache.commons.logging.LogFactory;
25  import org.netbeans.lib.cvsclient.command.FileInfoContainer;
26  import org.netbeans.lib.cvsclient.command.log.LogInformation;
27  import org.netbeans.lib.cvsclient.event.CVSListener;
28  import org.netbeans.lib.cvsclient.event.FileAddedEvent;
29  import org.netbeans.lib.cvsclient.event.FileInfoEvent;
30  import org.netbeans.lib.cvsclient.event.FileRemovedEvent;
31  import org.netbeans.lib.cvsclient.event.FileUpdatedEvent;
32  import org.netbeans.lib.cvsclient.event.MessageEvent;
33  import org.netbeans.lib.cvsclient.event.ModuleExpansionEvent;
34  import org.netbeans.lib.cvsclient.event.TerminationEvent;
35  
36  import java.util.ArrayList;
37  import java.util.Iterator;
38  import java.util.List;
39  import java.util.Map;
40  import java.util.StringTokenizer;
41  
42  /***
43   * Adapts a response from CVS to Karma specific messages. This class listens to CVS responses as per the Netbeans API.
44   * Success messages are sent to the <code>CommandResponse</code> instance (which can optionally be registered with this
45   * instance). Errors are thrown as CVSRuntimeExceptions
46   *
47   * @author D.A. Smedes
48   * @version $Id: CVSResponseAdapter.java,v 1.3 2004/11/16 22:31:57 asmedes Exp $
49   */
50  public final class CVSResponseAdapter implements CVSListener {
51  
52    private FileInfoContainer logInformation = null;
53    private CommandResponse response = null;
54  
55    private static Log logger = LogFactory.getLog(CVSResponseAdapter.class);
56    private Map arguments = null;
57  
58    public CVSResponseAdapter() {}
59  
60    /***
61     * This class can use a <code>CommandResponseListener</code> to send cvs events to. For example, user interfaces can
62     * register a listener to receive events from underlying code, thus creating interactivity.
63     *
64     * @param response
65     */
66    public CVSResponseAdapter(CommandResponse response) {
67      this.response = response;
68    }
69  
70    public void setArguments(Map arguments) {
71      this.arguments = arguments;
72    }
73  
74    public Object[] getArguments(String args) {
75  
76      if (arguments == null) {
77        return null;
78      }
79  
80      List argList = new ArrayList();
81      StringTokenizer tokenizer = new StringTokenizer(args, ",");
82      while (tokenizer.hasMoreTokens()) {
83        argList.add(((String) tokenizer.nextElement()).trim());
84      }
85  
86      // First pass ... count actual available parameters; is there a value for each requested key ?
87      //
88  
89      int j = 0;
90      for (Iterator i = argList.iterator(); i.hasNext();) {
91        String value = (String) arguments.get((String) i.next());
92        j = (value == null ? j : (j += 1));
93      }
94  
95      // Second pass ... assign values
96      //
97  
98      Object[] argArray = new Object[j];
99      j = 0;  // Reset
100     for (Iterator i = argList.iterator(); i.hasNext();) {
101       String value = (String) arguments.get((String) i.next());
102       if (value != null) {
103         argArray[j] = value;
104         j++;
105       }
106     }
107 
108     arguments = null; // Reset this session ...
109 
110     return argArray;
111   }
112 
113   /***
114    * <p>Copied from the Netbeans API documentation : Called when a file is removed.
115    *
116    * @param event The event from CVS.
117    */
118   public void fileRemoved(FileRemovedEvent event) {}
119 
120   /***
121    * <p>Copied from the Netbeans API documentation : Fire a module expansion event. This is called when the servers has
122    * responded to an expand-modules request.
123    * <p/>
124    * <p>Copied from the Netbeans API documentation : This event is really intended only for the use in the Checkout command. During a checkout command, the client
125    * must ask the server to expand modules to determine whether there are aliases defined for a particular module. The
126    * client must then use the expansion to determine if a local directory exists and if so, send appropriate Modified
127    * requests etc.
128    *
129    * @param event The event from CVS.
130    */
131   public void moduleExpanded(ModuleExpansionEvent event) {}
132 
133   /***
134    * <p>Copied from the Netbeans API documentation : Called when a file has been added.
135    *
136    * @param event The event from CVS.
137    */
138   public void fileAdded(FileAddedEvent event) {}
139 
140   /***
141    * <p>Copied from the Netbeans API documentation : Called when file information has been received.
142    * <p/>
143    * <p>This method constructs the <code>LogInformation</code> object that contains the log for a specific file as
144    * a result of the <code>cvs log</code> command.
145    *
146    * @param event The event from CVS.
147    */
148   public void fileInfoGenerated(FileInfoEvent event) {
149     logInformation = event.getInfoContainer();
150   }
151 
152   /***
153    * Gets the log that is the result of the <code>cvs log</code> command.
154    *
155    * @return A <code>LogInformation</code> that can be queried by classes for all information on a (set of) file(s).
156    */
157   public LogInformation getLogInformation() {
158     return (LogInformation) logInformation;
159   }
160 
161   /***
162    * <p>Copied from the Netbeans API documentation : Called when server responses with "ok" or "error", (when the command finishes)
163    *
164    * @param event The event from CVS.
165    */
166   public void commandTerminated(TerminationEvent event) { }
167 
168   /***
169    * <p>Copied from the Netbeans API documentation : Called when a file has been updated.
170    *
171    * @param event The event from CVS.
172    */
173   public void fileUpdated(FileUpdatedEvent event) { }
174 
175   /***
176    * <p>Copied from the Netbeans API documentation : Called when the server wants to send a message to be displayed to
177    * the user. This method is called whenever
178    *
179    * @param event The event from CVS.
180    */
181   public void messageSent(MessageEvent event) {
182 
183     // Get the message from CVS and parse it into something usefull.
184     //
185     String message = event.getMessage();
186 
187 //    if (message.length() > 0) {
188 //      System.out.println(message);
189 //    }
190 
191     if (message.startsWith("Checking in")) {
192 
193       // TODO Localize message
194       //
195       if (response != null) {
196         //response.addMessage(new SuccessMessage("File has been added to the CVS repository."));
197       } else {
198         logger.debug("'SuccessMessage' not routed to CommandResponseHandler : " + event.getMessage());
199       }
200 
201     } else if (message.startsWith("cvs server: cannot find module")) {
202 
203       throw new CVSRuntimeException(VersionControlException.MODULE_NOT_IN_REPOSITORY, getArguments("MODULE, REPOSITORY"));
204 
205     } else if (message.startsWith("cvs add:") && message.indexOf("already exists") >= 0) {
206 
207       throw new CVSRuntimeException(CVSException.FILE_EXISTS_IN_REPOSITORY, getArguments("FILE, MODULE, REPOSITORY"));
208 
209     } else if (message.startsWith("cvs") && message.indexOf("no such tag") >= 0) {
210 
211       throw new CVSRuntimeException(CVSException.VERSION_NOT_FOUND, getArguments("MODULE, VERSION"));
212 
213     } else if (message.indexOf("contains characters other than digits") >= 0) {
214 
215       throw new CVSRuntimeException(CVSException.INVALID_SYMBOLIC_NAME, getArguments("MODULE, SYMBOLIC_NAME"));
216 
217     } else if (message.indexOf("permission denied") >= 0) {
218 
219       // todo does this work ??
220       // should be tested properly ...
221 
222       throw new CVSRuntimeException(CVSException.SECURITY_VIOLATION);
223 
224     }
225   }
226 
227 }