All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.fife.ui.rtextarea.Macro Maven / Gradle / Ivy

Go to download

RSyntaxTextArea is the syntax highlighting text editor for Swing applications. Features include syntax highlighting for 40+ languages, code folding, code completion, regex find and replace, macros, code templates, undo/redo, line numbering and bracket matching.

There is a newer version: 3.5.1
Show newest version
/*
 * 09/16/2004
 *
 * Macro.java - A macro as recorded/played back by an RTextArea.
 * Copyright (C) 2004 Robert Futrell
 * robert_futrell at users.sourceforge.net
 * http://fifesoft.com/rsyntaxtextarea
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA.
 */
package org.fife.ui.rtextarea;

import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
import org.w3c.dom.*;
import org.xml.sax.InputSource;

import org.fife.io.UnicodeReader;


/**
 * A macro as recorded/played back by an RTextArea.
 *
 * @author Robert Futrell
 * @version 0.1
 */
public class Macro {

	private String name;
	private ArrayList macroRecords;

	private static final String ROOT_ELEMENT			= "macro";
	private static final String MACRO_NAME				= "macroName";
	private static final String ACTION					= "action";
	private static final String ID					= "id";

	private static final String UNTITLED_MACRO_NAME		= "";

	private static final String FILE_ENCODING			= "UTF-8";


	/**
	 * Constructor.
	 */
	public Macro() {
		this(UNTITLED_MACRO_NAME);
	}


	/**
	 * Loads a macro from a file on disk.
	 *
	 * @param file The file from which to load the macro.
	 * @throws java.io.EOFException If an EOF is reached unexpectedly (i.e.,
	 *         the file is corrupt).
	 * @throws FileNotFoundException If the specified file does not exist, is
	 *         a directory instead of a regular file, or otherwise cannot be
	 *         opened.
	 * @throws IOException If an I/O exception occurs while reading the file.
	 * @see #saveToFile
	 */
	public Macro(File file) throws EOFException, FileNotFoundException,
								IOException {

		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		DocumentBuilder db = null;
		Document doc = null;
		try {
			db = dbf.newDocumentBuilder();
			//InputSource is = new InputSource(new FileReader(file));
			InputSource is = new InputSource(new UnicodeReader(
								new FileInputStream(file), FILE_ENCODING));
			is.setEncoding(FILE_ENCODING);
			doc = db.parse(is);//db.parse(file);
		} catch (Exception e) {
			e.printStackTrace();
			String desc = e.getMessage();
			if (desc==null) {
				desc = e.toString();
			}
			throw new IOException("Error parsing XML: " + desc);
		}

		macroRecords = new ArrayList();

		// Traverse the XML tree.
		boolean parsedOK = initializeFromXMLFile(doc.getDocumentElement());
		if (parsedOK==false) {
			name = null;
			macroRecords.clear();
			macroRecords = null;
			throw new IOException("Error parsing XML!");
		}

	}


	/**
	 * Constructor.
	 *
	 * @param name The name of the macro.
	 */
	public Macro(String name) {
		this(name, null);
	}


	/**
	 * Constructor.
	 *
	 * @param name The name of the macro.
	 * @param records The initial records of the macro.
	 */
	public Macro(String name, List records) {
		
		this.name = name;

		if (records!=null) {
			macroRecords = new ArrayList(records.size());
			Iterator i = records.iterator();
			while (i.hasNext()) {
				MacroRecord record = (MacroRecord)i.next();
				macroRecords.add(record);
			}
		}
		else {
			macroRecords = new ArrayList(10);
		}
	
	}


	/**
	 * Adds a macro record to this macro.
	 *
	 * @param record The record to add.  If null, nothing happens.
	 * @see #getMacroRecords
	 */
	public void addMacroRecord(MacroRecord record) {
		if (record!=null)
			macroRecords.add(record);
	}


	/**
	 * Returns the macro records that make up this macro.
	 *
	 * @return The macro records.
	 * @see #addMacroRecord
	 */
	public List getMacroRecords() {
		return macroRecords;
	}


	/**
	 * Returns the name of this macro.
	 *
	 * @return The macro's name.
	 * @see #setName
	 */
	public String getName() {
		return name;
	}


	/**
	 * Used in parsing an XML document containing a macro.  This method
	 * initializes this macro with the data contained in the passed-in node.
	 *
	 * @param node The root node of the parsed XML document.
	 * @return true if the macro initialization went okay;
	 *         false if an error occurred.
	 */
	private boolean initializeFromXMLFile(Element root) {

		/*
		 * This method expects the XML document to be in the following format:
		 *
		 * 
		 * 
		 *    test
		 *    abcdefg
		 *    [...]
		 *    ...
		 * 
		 *
		 */

		NodeList childNodes = root.getChildNodes();
		int count = childNodes.getLength();

		for (int i=0; i0) {
							node = childNodes2.item(0);
							int type2 = node.getNodeType();
							if (type2!=Node.CDATA_SECTION_NODE &&
									type2!=Node.TEXT_NODE) {
								return false;
							}
							name = node.getNodeValue().trim();
						}
						//System.err.println("Macro name==" + name);
					}

					else if (nodeName.equals(ACTION)) {
						NamedNodeMap attributes = node.getAttributes();
						if (attributes==null || attributes.getLength()!=1)
							return false;
						Node node2 = attributes.item(0);
						MacroRecord macroRecord = new MacroRecord();
						if (!node2.getNodeName().equals(ID)) {
							return false;
						}
						macroRecord.id = node2.getNodeValue();
						NodeList childNodes2 = node.getChildNodes();
						int length = childNodes2.getLength();
						if (length==0) { // Could be empty "" command.
							//System.err.println("... empty actionCommand");
							macroRecord.actionCommand = "";
							//System.err.println("... adding action: " + macroRecord);
							macroRecords.add(macroRecord);
							break;
						}
						else {
							node = childNodes2.item(0);
							int type2 = node.getNodeType();
							if (type2!=Node.CDATA_SECTION_NODE &&
									type2!=Node.TEXT_NODE) {
								return false;
							}
							macroRecord.actionCommand = node.getNodeValue();
							macroRecords.add(macroRecord);
						}

					}
					break;

				default:
					break; // Skip whitespace nodes, etc.

			}

		}

		// Everything went okay.
		return true;

	}


	/**
	 * Saves this macro to a text file.  This file can later be read in by
	 * the constructor taking a File parameter; this is the
	 * mechanism for saving macros.
	 *
	 * @param fileName The name of the file in which to save the macro.
	 * @throws IOException If an error occurs while generating the XML for
	 *         the output file.
	 */
	public void saveToFile(String fileName) throws IOException {

		/*
		 * This method writes the XML document in the following format:
		 *
		 * 
		 * 
		 *    test
		 *    abcdefg
		 *    [...]
		 *    ...
		 * 
		 *
		 */

		try {

			DocumentBuilder db = DocumentBuilderFactory.newInstance().
											newDocumentBuilder();
			DOMImplementation impl = db.getDOMImplementation();

			Document doc = impl.createDocument(null, ROOT_ELEMENT, null);
			Element rootElement = doc.getDocumentElement();

			// Write the name of the macro.
			Element nameElement = doc.createElement(MACRO_NAME);
			rootElement.appendChild(nameElement);

			// Write all actions (the meat) in the macro.
			int numActions = macroRecords.size();
			for (int i=0; i0) {
					// Remove illegal characters.  I'm no XML expert, but
					// I'm not sure what I'm doing wrong.  If we don't
					// strip out chars with Unicode value < 32, our
					// generator will insert '&#', which will cause
					// our parser to barf when reading the macro back in
					// (it says "Invalid XML character").  But why doesn't
					// our generator tell us the character is invalid too?
					String command = record.actionCommand;
					for (int j=0; j




© 2015 - 2024 Weber Informatics LLC | Privacy Policy