alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

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

 

new blog posts

 

Copyright 1998-2021 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.