| 
What this is
 Other links
 The source code
/*
 *                 Sun Public License Notice
 * 
 * The contents of this file are subject to the Sun Public License
 * Version 1.0 (the "License"). You may not use this file except in
 * compliance with the License. A copy of the License is available at
 * http://www.sun.com/
 * 
 * The Original Code is NetBeans. The Initial Developer of the Original
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun
 * Microsystems, Inc. All Rights Reserved.
 */
package org.netbeans.modules.cvsclient.commands;
/**
 *
 * @author  Milos Kleint
 */
import org.netbeans.modules.vcscore.util.VcsUtilities;
import org.openide.ErrorManager;
import org.openide.nodes.Sheet;
import org.openide.nodes.PropertySupport;
import org.openide.util.actions.SystemAction;
import org.openide.util.RequestProcessor;
import org.openide.actions.PropertiesAction;
import org.netbeans.modules.javacvs.caching.RefreshCommand;
import org.netbeans.modules.javacvs.commands.FileSystemCommand;
import org.netbeans.modules.javacvs.commands.FsGlobalOptionsImpl;
import org.netbeans.modules.vcscore.runtime.*;
import org.netbeans.modules.javacvs.events.*;
import org.netbeans.modules.cvsclient.FsCommandFactory;
import org.netbeans.modules.cvsclient.IndependantClient;
import org.netbeans.modules.cvsclient.NbJavaCvsFileSystem;
import org.netbeans.modules.cvsclient.JavaCvsRuntimeCommandsProvider;
import org.netbeans.lib.cvsclient.event.*;
import org.netbeans.lib.cvsclient.command.*;
import java.io.*;
import java.util.*;
import java.beans.*;
import org.openide.nodes.*;
import java.lang.reflect.*;
import javax.swing.SwingUtilities;
public class JavaCvsRuntimeCommand extends RuntimeCommand 
                                   implements CommandDisplayerListener, 
                                              CommandErrorListener {
    
    private FileSystemCommand command;
    private JavaCvsRuntimeCommandsProvider provider;
    private boolean isError;
    private File outputTempFile;
    private PrintWriter writer;
    private boolean isRefresh;
    private LinkedList commandList;
    private int state;
    private boolean started;
                                       
    public JavaCvsRuntimeCommand(FileSystemCommand comm, JavaCvsRuntimeCommandsProvider provider) {
        command = comm;
        state = RuntimeCommand.STATE_DONE;
        this.provider = provider;
        isError = false;
        started = false;
        isRefresh = comm.getClass().equals(RefreshCommand.class);
    }
    public String getName() {
        return command.getName();
    }    
    public String getDisplayName() {
        return createDisplayName(command.getCVSCommand());
    }
    
    public int getExitStatus() {
        if (command.isStopped()) {
            return RuntimeCommand.INTERRUPTED;
        }
        if (isError) {
            return RuntimeCommand.FAILED;
        } else {
            return RuntimeCommand.SUCCEEDED;
        }
    }
    
    public void openCommandOutputDisplay(boolean gui) {
        if (outputTempFile != null && !command.isRunning()) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    showOutputPanel();
                }
            });
        }
//       pool.openCommandOutput(executor);
    }
    
    private void showOutputPanel() {
        final BufferedReader reader;
        try {
//            System.out.println("reading=" + outputTempFile.getAbsolutePath());
            reader = new BufferedReader(new FileReader(outputTempFile));
        } catch (FileNotFoundException fnfex) {
            ErrorManager.getDefault().notify(fnfex);
            return ;
        }
        final CommandLineInfoPanel panel = new CommandLineInfoPanel(command);
        panel.showStartCommand();
        RequestProcessor.getDefault().post(new Runnable() {
            public void run() {
                boolean finishedOK = true;
                try {
                    String line = reader.readLine();
                    while (line != null) {
                        if (line.startsWith("W")) {
                            finishedOK = false;
                            break;
                        }
                        boolean isKError = false;
                        if (line.length() < 2 || line.startsWith("C") // NOI18N
                             || line.startsWith("X")) { // NOI18N
                            line = reader.readLine();
                            continue;
                        }
                        if (line.startsWith("E")) { // NOI18N
                            isKError = true;
                        }
                        MessageEvent event = new MessageEvent(this, line.substring(2), isKError);
                        if (line.startsWith("T")) { // NOI18N
                            event.setTagged(true);
                        }
                        panel.messageGenerated(event);
                        line = reader.readLine();
                    }
                } catch (IOException exc) {
                    //TODO.. notify ??
                } finally {
                    if (reader != null) {
                        try {
                            reader.close();
                        } catch (Exception e) {}
                    }
                    if (panel != null) {
                        if (finishedOK) {
                            panel.showFinishedCommand();
                        } else {
                            panel.showExecutionFailed(new org.netbeans.modules.javacvs.events.ServerErrorException());
                        }
                    }
                }
            }
        });
    }
    
    public Sheet createSheet() {
        Sheet sheet = Sheet.createDefault();
	Sheet.Set set = Sheet.createPropertiesSet();
        sheet.put (set);
        set.setValue("helpID", JavaCvsRuntimeCommand.class.getName()+"_properties");
        Sheet.Set switchesSet =  Sheet.createPropertiesSet();
        switchesSet.setName(g("CTL_SwitchesSheet")); // NOI18N
        switchesSet.setDisplayName(g("CTL_SwitchesSheet")); // NOI18N
        switchesSet.setValue("helpID", JavaCvsRuntimeCommand.class.getName()+"_switches");
        Sheet.Set globalSet =  Sheet.createPropertiesSet(); 
        globalSet.setName(g("CTL_GlobalSwitchesSheet")); // NOI18N
        globalSet.setDisplayName(g("CTL_GlobalSwitchesSheet")); // NOI18N
        globalSet.setValue("helpID", JavaCvsRuntimeCommand.class.getName()+"_global");
        createSwitchProperties(command.getImpl(), switchesSet);
        createSwitchProperties(new FsGlobalOptionsImpl(command.getGlobalOptions()), globalSet);
        sheet.put(switchesSet);
        sheet.put(globalSet);
        createProperties(set);
        return sheet;
    }
    
    
    private void createProperties(final Sheet.Set set) {
        set.put(new PropertySupport.ReadOnly("name", String.class, g("CTL_Name"), "") { // NOI18N
                        public Object getValue() {
                            //System.out.println("getName: cmd = "+cmd);
                            return command.getName();
                        }
                });
        set.put(new PropertySupport.ReadOnly("files", String.class, g("CTL_Files"), "") { // NOI18N
                        public Object getValue() {
                            String localPath = command.getClientProvider().getLocalPath();
                            File[] flz = command.getFiles();
                            if (flz == null) {
                                return "";
                            }
                            String[] files = new String[flz.length];
                            for (int i = 0; i < files.length; i++) {
                                if (flz[i].length() == localPath.length()) { 
                                    files[i] = "."; //NOI18N
                                } else {
                                    files[i] = flz[i].getName();
                                }
                            }
                            return VcsUtilities.array2stringNl(files);
                        }
                });
        set.put(new PropertySupport.ReadOnly("status", String.class, g("CTL_Status"), "") { // NOI18N
                        public Object getValue() {
                            if (command.isRunning()) return g("CTL_Status_Running"); // NOI18N
                            if (isError) {
                                return g("CTL_Status_Error"); // NOI18N
                            } else {
                                return g("CTL_Status_Done"); // NOI18N
                            }
                        }
                });
                
    }
    
    private void createSwitchProperties(Object bean, Sheet.Set set) {
        java.beans.BeanInfo info = null;
        try {
            info = java.beans.Introspector.getBeanInfo(bean.getClass());
        } catch (IntrospectionException exc) {
            return;
        }
        PropertyDescriptor[] descs = info.getPropertyDescriptors();
        Node.Property[] props = new Node.Property[descs.length];
        for (int i = 0; i < descs.length; i++) {
            props[i] = new SwitchReadOnlyProperty(descs[i], bean);
        }
        set.put(props);
    }
    private String g(String name) {
        return org.openide.util.NbBundle.getBundle(JavaCvsRuntimeCommand.class).getString(name);
    }
    public SystemAction[] getActions() {
        if (started) {
            if (!isRefresh && !command.isRunning()) {
                return new SystemAction[] { CommandOutputViewAction.getInstance() ,
                DisplayerOutputViewAction.getInstance(),
                SystemAction.get(PropertiesAction.class) };
            }
            if (isRefresh && !command.isRunning()) {
                return new SystemAction[] {
                    CommandOutputViewAction.getInstance(),
                    SystemAction.get(PropertiesAction.class) };
            }
            if (command.isRunning() && !command.isStopped()) {
                return new SystemAction[] {
                    KillRunningCommandAction.getInstance(),
                    SystemAction.get(PropertiesAction.class)
                };
            }
        }
        return new SystemAction[] {SystemAction.get(PropertiesAction.class) };    
    }
    
    public SystemAction getDefaultAction() {
        return CommandOutputViewAction.getInstance();
    }
    
    public void killCommand() {
        command.hardCommandStop();
    }
    
    public String getId() {
        return Integer.toString(hashCode());
    }
    
    /**
     * this method is called before any of the library's commands
     * that is stored in the queue in FileSystemCommand, is run.
     * @param currentCommand shows the command that will be executed.
     */
    public void showBeforeEachExecute(org.netbeans.lib.cvsclient.command.Command currentCommand) {
        if (writer != null) {
            writer.println("C " + currentCommand.getCVSCommand()); // NOI18N
            commandList.add(currentCommand);
        }
    }
    
    /**
     * This is the last method to be called in the displayer.
     * Is called when the execution finishes. Any filan touchups can be made here.
     */
    public void showFinishedCommand() {
        finishCommand();
    }
    
    private void finishCommand() {
        setState(RuntimeCommand.STATE_DONE);
        provider.updateCommand(this);
        if (writer != null) {
            writer.flush();
            writer.close();
        }
    }
    
    /**
     * This method is the first one that is called during execution.
     * Here any initial setup of the displayer can be made.
     */
    public void showStartCommand() {
        started = true;
        setState(RuntimeCommand.STATE_RUNNING);
        provider.updateCommand(this);
//        if (!isRefresh) {
            try {
                outputTempFile = createTempFile();
                commandList = new LinkedList();
                writer = new PrintWriter(new FileOutputStream(outputTempFile));
            } catch (IOException exc) {
                writer = null;
                outputTempFile = null;
            }
//        }
    }
    
    /**
     * this method is called after library's commands execution
     */
    public void showAfterEachExecute() {
    }
    
    /**
     * When the server generates a line of output/error, the displayer is notified.
     * @param message - the string to be displayed, be it error/message (E/M response)
     */
    public void messageGenerated(MessageEvent message) {
        if (writer != null) {
            if (message.getClass().equals(EnhancedMessageEvent.class)) {
                EnhancedMessageEvent enhMessage = (EnhancedMessageEvent)message;
                if (enhMessage.getKey().equals(EnhancedMessageEvent.MERGED_PATH)) {
                    writer.println("X " + enhMessage.getValue().toString()); // NOI18N
                }
                return;
            }
            if (message.isTagged()) {
                writer.println("T " + message.getMessage()); // NOI18N
                return;
            }
            if (message.isError()) {
                writer.println("E " + message.getMessage()); // NOI18N
            } else {
                writer.println("M " + message.getMessage()); // NOI18N
            }
        }
    }
    
    /**
     * this one is called when the command's execution  fails for any reason.
     */
    public void showExecutionFailed(Exception exception) {
        isError = true;
        if (writer != null) {
            writer.println("W");
        }
        finishCommand();
        
    }
    
    public void errorGenerated(CommandErrorEvent event) {
        isError = event.endedWithError();
//        finishCommand();
    }    
    
    /**
     * When the library command's builder generates a FileInfoContainer object, the
     * Displayer is notified.
     * @param info - the generated information object
     */
    public void showFileInfoGenerated(org.netbeans.lib.cvsclient.command.FileInfoContainer info) {
    }
    
    private String createDisplayName(String newVal) {
        newVal = newVal.replace('\n', ' ');
        int firstOcc = newVal.indexOf('"'); // NOI18N
        int lastOcc = newVal.lastIndexOf('"'); // NOI18N
        if (lastOcc > firstOcc) {
            if ((lastOcc - firstOcc) > 10) {
                String fin = newVal.substring(0,firstOcc + 6);
                String fin2 = newVal.substring(lastOcc, newVal.length());
                newVal = fin + "..." + fin2;  //NOI18N
            }
        }
        return newVal;
    }
    
    class SwitchReadOnlyProperty extends PropertySupport.ReadOnly {
        
        private Object value;
        
        private Class editorClass;
        public SwitchReadOnlyProperty(PropertyDescriptor desc, Object obj) {
            super(desc.getName(), desc.getPropertyType(), desc.getDisplayName(), desc.getShortDescription());
            editorClass = desc.getPropertyEditorClass();
            try {
                Method meth = desc.getReadMethod();
                value = meth.invoke(obj, null);
            } catch (Exception exc) {
                value = null;
            }
            if (value == null && getValueType().isArray()) {
                // Create an empty array so that the property editors survive:
                value = java.lang.reflect.Array.newInstance(getValueType().getComponentType(), 0);
            }
        }
       
        public PropertyEditor getPropertyEditor() {
            if (editorClass != null) {
                try {
                    return (PropertyEditor) editorClass.newInstance();
                } catch (Exception exc) {}
            }
            return super.getPropertyEditor();
        }
        
        public java.lang.Object getValue() 
              throws java.lang.IllegalAccessException, java.lang.reflect.InvocationTargetException {
                  return value;
        }
        
    }
    
    private File createTempFile() {
        String TMP_ROOT=System.getProperty("netbeans.user")+File.separator+ // NOI18N
                 "system"+File.separator+"javacvs"+File.separator+"tmp"; // NOI18N
        File tmpDir = new File(TMP_ROOT);
        if (!tmpDir.exists()) {
            tmpDir.mkdirs();
        }
        long tmpId;
        do {
            tmpId = 10000 * (1 + Math.round (Math.random () * 8)) + Math.round (Math.random () * 1000);
        } while (new File(TMP_ROOT+File.separator+"tmp"+tmpId).exists()); // NOI18N
        String tempFileName = TMP_ROOT+File.separator+"tmp"+tmpId; // NOI18N
        File tempFile;
        try {
            tempFile = File.createTempFile("tmp" + tmpId, "", tmpDir); // NOI18N
        } catch (IOException exc) {
            tempFile = new File(tempFileName);
        }
        tempFile.deleteOnExit();
        return tempFile;
    }
    
    public void displayInGraphics() {
        CommandDisplayerListener disp = null;
        String methodName = command.getClass().getName();
        int ind = methodName.lastIndexOf('.');
        methodName = "add" + methodName.substring(ind + 1) + "Displayer"; // NOI18N
        IndependantClient client = (IndependantClient)command.getClientProvider();
        int dispType = client.getDisplayType();
        try {
            Method metoda = FsCommandFactory.class.getDeclaredMethod(methodName, new Class[] {command.getClass()});
            client.setDisplayType(NbJavaCvsFileSystem.DISP_TYPE_FORMATTED);
            disp = (CommandDisplayerListener)metoda.invoke(FsCommandFactory.class, new Object[] {command});
        } catch (Exception exc) {
            Thread.dumpStack();
            //TODO.. show exception..??
        } finally {
            client.setDisplayType(dispType);
        }
        if (disp != null) {
            if (disp instanceof RuntimeCommandDisplayer) {
                RuntimeCommandDisplayer rDisp = (RuntimeCommandDisplayer)disp;
                rDisp.setRunInRuntime(true);
            }
            BufferedReader reader = null;
            Iterator it = commandList.iterator();
            StringBuffer taggedBuffer = new StringBuffer();
//            System.out.println("start reading file" + outputTempFile.getName());
            final CommandDisplayerListener panel = disp;
            Builder build = null;
            try {
                //            System.out.println("reading=" + outputTempFile.getAbsolutePath());
                reader = new BufferedReader(new FileReader(outputTempFile));
                String line = reader.readLine();
                panel.showStartCommand();
                    
                EventManager eventManager = new EventManager();
                eventManager.addCVSListener(new CVSAdapter() {
                    public void fileInfoGenerated(FileInfoEvent e) {
                        panel.showFileInfoGenerated(e.getInfoContainer());
                    }
                });
                boolean starting = true;
                while (line != null) {
                    boolean isKError = false;
                    MessageEvent event;
                    if (line.length() < 2) {
                        line = reader.readLine();
                        continue;
                    }
                    if (line.startsWith("C")) { // NOI18N
                        if (!starting) {
                            build.outputDone();
                            disp.showAfterEachExecute();
                        }
                        if (it.hasNext()) {
                            BuildableCommand cm = (BuildableCommand)it.next();
                            disp.showBeforeEachExecute(cm);
                            build = cm.createBuilder(eventManager);
                        }
                        starting = false;
                    }
                    else if (line.startsWith("X")) { // NOI18N
                        if (build != null) {
                            build.parseEnhancedMessage(EnhancedMessageEvent.MERGED_PATH, line.substring(2));
                        }
                    }
                    else {
                        if (line.startsWith("E")) { // NOI18N
                            isKError = true;
                        }
                        event = new MessageEvent(this, line.substring(2), isKError);
                        String buildLine = null;
                        if (line.startsWith("T")) { // NOI18N
                            event.setTagged(true);
//                            System.out.println("tagged=" + event.getMessage());
                            buildLine = MessageEvent.parseTaggedMessage(taggedBuffer, line.substring(2));
//                            System.out.println("buildLine=" + buildLine);
                        } else if (line.startsWith("W")) {
                            //do nothing, interesting only for finding the error status for line output
                        } else {
                            buildLine = line.substring(2);
                        }
                        panel.messageGenerated(event);
                        if (buildLine != null) {
                            build.parseLine(buildLine, isKError);
                            taggedBuffer = new StringBuffer(""); // NOI18N
                        }
                    }
                    line = reader.readLine();
                }
            } catch (Exception exc) {
                //TODO.. notify ??
            } finally {
                if (reader != null) {
                    try {
                        reader.close();
                    } catch (Exception e) {}
                }
                if (panel != null) {
                    if (build != null) {
                        build.outputDone();
                    }
                    panel.showAfterEachExecute();
                    panel.showFinishedCommand();
                }
            }
        }
        
    }
    public int getState() {
        return state;
    }
    public void setState(int state) {
        this.state = state;
        firePropertyChange(PROP_STATE, null, null);
    }
    
}
 | 
| ... this post is sponsored by my books ... | |
         
           #1 New Release!  | 
      
         
           FP Best Seller  | 
  
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse 
URI on this website is
paid back to open source projects.