001: /*
002: * Gruntspud
003: *
004: * Copyright (C) 2002 Brett Smith.
005: *
006: * Written by: Brett Smith <t_magicthize@users.sourceforge.net>
007: *
008: * This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public
009: * License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
010: * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details.
012: *
013: * You should have received a copy of the GNU Library General Public License along with this program; if not, write to the Free
014: * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
015: */
016:
017: package gruntspud.actions;
018:
019: import gruntspud.CVSFileNode;
020: import gruntspud.Constants;
021: import gruntspud.GruntspudContext;
022: import gruntspud.event.GruntspudCVSListener;
023: import gruntspud.style.TextStyle;
024:
025: import java.awt.Component;
026: import java.awt.event.ActionEvent;
027: import java.awt.event.KeyEvent;
028: import java.io.File;
029: import java.util.ArrayList;
030: import java.util.Iterator;
031: import java.util.ResourceBundle;
032:
033: import org.netbeans.lib.cvsclient.command.Command;
034: import org.netbeans.lib.cvsclient.event.FileAddedEvent;
035: import org.netbeans.lib.cvsclient.event.FileInfoEvent;
036: import org.netbeans.lib.cvsclient.event.FileRemovedEvent;
037: import org.netbeans.lib.cvsclient.event.FileUpdatedEvent;
038: import org.netbeans.lib.cvsclient.event.MessageEvent;
039: import org.netbeans.lib.cvsclient.event.ModuleExpansionEvent;
040: import org.netbeans.lib.cvsclient.event.TerminationEvent;
041:
042: /**
043: * Default implementation for a <code>GruntspudAction</code> that should be
044: * extended by actions that perform some action on a CVS repository. Other
045: * actions used in Gruntspud UI should exted <code>AbstractGruntspudAction</code>
046: * instead as this class provides methods they should not need.
047: *
048: * @author magicthize
049: */
050: public abstract class DefaultGruntspudAction extends
051: AbstractGruntspudAction implements GruntspudCVSListener {
052: static ResourceBundle res = ResourceBundle
053: .getBundle("gruntspud.actions.ResourceBundle");
054:
055: // Private instance variables
056: private GruntspudContext context;
057: private Component parent;
058: private Command currentCommand;
059: private boolean outputToConsole;
060: protected StringBuffer taggedLine;
061: protected boolean updatesFiles;
062: protected java.util.List updatedFiles;
063: protected GruntspudCVSListener[] enabledOptionalListeners;
064:
065: /**
066: * Constructor for the DefaultGruntspudAction object
067: *
068: * @param context context
069: */
070: public DefaultGruntspudAction(GruntspudContext context) {
071: init(context);
072: }
073:
074: /**
075: * Constructor that allows action to be built from a resource bundle
076: *
077: * @param res resource bundle
078: * @param actionPrefix prefix in resource bundle for actions properties
079: * @param context context
080: */
081: public DefaultGruntspudAction(ResourceBundle res,
082: String actionPrefix, GruntspudContext context) {
083: super (res, actionPrefix);
084: init(context);
085: }
086:
087: private void init(GruntspudContext context) {
088: this .context = context;
089: taggedLine = new StringBuffer();
090: outputToConsole = context.getHost().getBooleanProperty(
091: Constants.OPTIONS_OUTPUT_TO_CONSOLE);
092: }
093:
094: /**
095: * An action may set which of the optional listeners are able to receive CVS events.
096: * Most CVS actions have an option to specify where the output of the CVS command
097: * should be sent to, the 'Report Dialog', 'Console' etc.
098: *
099: * @param listeners listeners to receive events
100: */
101: public void setEnabledOptionalListeners(
102: GruntspudCVSListener[] listeners) {
103: enabledOptionalListeners = listeners;
104: }
105:
106: /**
107: * An action may set which of the optional listeners are able to receive CVS events.
108: * Most CVS actions have an option to specify where the output of the CVS command
109: * should be sent to, the 'Report Dialog', 'Console' etc.
110: *
111: * @return enabled listeners
112: */
113: public GruntspudCVSListener[] getEnabledOptionalListeners() {
114: return enabledOptionalListeners;
115: }
116:
117: /**
118: * Returns true if the event modifiers match those configured by the user
119: * to bypass the cvs commands option dialogue
120: *
121: * @param modifiers
122: * @return <code>true</code> if action should not show its options dialog
123: */
124: public boolean isBypassOptions(int modifiers) {
125: int i = getContext().getHost().getIntegerProperty(
126: Constants.OPTIONS_DISPLAY_COMMAND_OPTIONS_BYPASS_MASK,
127: KeyEvent.CTRL_MASK + KeyEvent.SHIFT_MASK);
128: return (modifiers & i) == i;
129: }
130:
131: public String getShortName() {
132: return "Default";
133: }
134:
135: public boolean isOptionalListener() {
136: return false;
137: }
138:
139: /**
140: * Return the component that this event originated from. <code>null</code> will
141: * be returned if the event did not come from a component
142: *
143: * @param evt event
144: * @return component where the event originated
145: */
146: public Component getParentComponentForEvent(ActionEvent evt) {
147: return (evt.getSource() instanceof Component) ? ((Component) evt
148: .getSource())
149: : getContext().getHost().getMainComponent();
150: }
151:
152: /**
153: * Return <code>true</code> if this action changes any files in the local
154: * workspace
155: *
156: * @return <code>true</code> if action will change local files
157: */
158: public boolean isUpdatesFiles() {
159: return updatesFiles;
160: }
161:
162: /**
163: * Set if this action will change any files in the local workspace
164: *
165: * @param updatesFiles <code>true</code> if action changes files in local workspace
166: */
167: public void setUpdatesFiles(boolean updatesFiles) {
168: this .updatesFiles = updatesFiles;
169: }
170:
171: /**
172: * Invoked when a set of commands are about to be run
173: *
174: * @param parent parent component
175: */
176: public void init(Component parent) {
177: this .parent = parent;
178: }
179:
180: /**
181: * Invoked when a group of commands is start
182: *
183: * @param cmd an array containing all of the commands that will be run in this group
184: * @param parent parent component
185: */
186: public void commandGroupStarted(Command[] cmd) {
187: taggedLine.setLength(0);
188: updatedFiles = null;
189: }
190:
191: /**
192: * Return the parent component for this action
193: *
194: * @return component
195: */
196: public Component getParent() {
197: return parent;
198: }
199:
200: /**
201: * Return the currently executing command, or <code>null</code>
202: * if no command is currently executing
203: *
204: * @return currently executing command
205: */
206: public Command getCurrentCommand() {
207: return currentCommand;
208: }
209:
210: /**
211: * Invoked when the current group of commands finished
212: */
213: public void commandGroupFinished() {
214: if (isUpdatesFiles() && updatedFiles != null
215: && updatedFiles.size() > 0) {
216: for (Iterator i = updatedFiles.iterator(); i.hasNext();) {
217: File f = (File) i.next();
218: CVSFileNode n = null;
219: while (n == null && f != null) {
220: n = getContext().getViewManager()
221: .findNodeForPath(
222: getContext().getViewManager()
223: .getRootNode(), f, true);
224: if (n == null) {
225: f = f.getParentFile();
226: }
227: }
228: if (n != null) {
229: getContext().getViewManager().nodeUpdated(n);
230: }
231: }
232: getContext().getViewManager().updateNodes();
233: }
234: currentCommand = null;
235: updatedFiles = null;
236: }
237:
238: /**
239: * Invoked when a single command starts
240: *
241: * @param cmd command just started
242: */
243: public void commandUnitStarted(Command cmd) {
244: currentCommand = cmd;
245: }
246:
247: /**
248: * Invoked when a single command finishes
249: */
250: public void commandUnitFinished() {
251: currentCommand = null;
252: }
253:
254: /**
255: * Invoked when an execption occurs when executing the CVS command
256: *
257: * @param t exception
258: */
259: public void commandException(Throwable t) {
260: }
261:
262: /**
263: * Return the context
264: *
265: * @return context
266: */
267: public GruntspudContext getContext() {
268: return context;
269: }
270:
271: /**
272: * Invoked whenever the state changes in some way.
273: * Each action must determine whether or not it should
274: * be enabled or not
275: *
276: * @return <code>true</code> if the action should be enabled
277: */
278: public boolean checkAvailable() {
279: return true;
280: }
281:
282: /**
283: * Return a style to use for a given console message
284: *
285: * @param mesg message
286: * @return style
287: */
288: public TextStyle getStyleForMessage(String mesg) {
289: return null;
290: }
291:
292: /**
293: * Return if this action will output to the console
294: *
295: * @return action will output to the console
296: */
297: public boolean isOutputToConsole() {
298: return outputToConsole;
299: }
300:
301: /**
302: * Set whether this action will output to the console
303: *
304: * @param outputToConsole action will output to console
305: */
306: public void setOutputToConsole(boolean outputToConsole) {
307: this .outputToConsole = outputToConsole;
308: }
309:
310: /* (non-Javadoc)
311: * @see org.netbeans.lib.cvsclient.event.CVSListener#messageSent(org.netbeans.lib.cvsclient.event.MessageEvent)
312: */
313: public void messageSent(MessageEvent evt) {
314: // System.err.println(">>"+ evt);
315: String line = evt.getMessage();
316: TextStyle c = evt.isError() ? context.getTextStyleModel()
317: .getStyle(Constants.OPTIONS_STYLE_GRUNTSPUD) : context
318: .getTextStyleModel().getStyle(
319: Constants.OPTIONS_STYLE_CVS);
320: String mesg = evt.isTagged() ? evt.parseTaggedMessage(
321: taggedLine, evt.getMessage()) : line;
322: if ((mesg != null) && (mesg.length() > 0)) {
323: if (outputToConsole || evt.isError()) {
324: if (!evt.isError()) {
325: TextStyle z = getStyleForMessage(mesg);
326: if (z != null)
327: c = z;
328: }
329: getContext().getHost().writeToConsole(c, mesg);
330: }
331: }
332: }
333:
334: /* (non-Javadoc)
335: * @see org.netbeans.lib.cvsclient.event.CVSListener#fileAdded(org.netbeans.lib.cvsclient.event.FileAddedEvent)
336: */
337: public void fileAdded(FileAddedEvent e) {
338: }
339:
340: /* (non-Javadoc)
341: * @see org.netbeans.lib.cvsclient.event.CVSListener#fileRemoved(org.netbeans.lib.cvsclient.event.FileRemovedEvent)
342: */
343: public void fileRemoved(FileRemovedEvent e) {
344:
345: }
346:
347: /* (non-Javadoc)
348: * @see org.netbeans.lib.cvsclient.event.CVSListener#fileUpdated(org.netbeans.lib.cvsclient.event.FileUpdatedEvent)
349: */
350: public void fileUpdated(FileUpdatedEvent e) {
351: }
352:
353: /* (non-Javadoc)
354: * @see org.netbeans.lib.cvsclient.event.CVSListener#commandTerminated(org.netbeans.lib.cvsclient.event.TerminationEvent)
355: */
356: public void commandTerminated(TerminationEvent e) {
357: }
358:
359: /* (non-Javadoc)
360: * @see org.netbeans.lib.cvsclient.event.CVSListener#fileInfoGenerated(org.netbeans.lib.cvsclient.event.FileInfoEvent)
361: */
362: public void fileInfoGenerated(FileInfoEvent e) {
363: if (isUpdatesFiles()) {
364: File f = e.getInfoContainer().getFile();
365: if (f != null) {
366: if (updatedFiles == null)
367: updatedFiles = new ArrayList();
368: updatedFiles.add(f);
369: }
370: }
371: }
372:
373: /* (non-Javadoc)
374: * @see org.netbeans.lib.cvsclient.event.CVSListener#moduleExpanded(org.netbeans.lib.cvsclient.event.ModuleExpansionEvent)
375: */
376: public void moduleExpanded(ModuleExpansionEvent e) {
377: }
378:
379: /* (non-Javadoc)
380: * @see gruntspud.event.GruntspudCVSListener#isSelectedByDefault()
381: */
382: public boolean isSelectedByDefault() {
383: return true;
384: }
385: }
|