├── .project ├── ChangeRecorder ├── .classpath ├── .gitignore ├── .project ├── .settings │ └── org.eclipse.jdt.core.prefs ├── META-INF │ └── MANIFEST.MF ├── build.properties ├── icons │ └── jcu_obj.gif ├── lib │ └── commons-io-2.4.jar ├── plugin.xml └── src │ └── org │ └── jtool │ └── changerecorder │ ├── Activator.java │ ├── diff │ ├── CodeDelta.java │ ├── DiffOperationGenerator.java │ └── diff_match_patch.java │ ├── editor │ ├── ConsoleOperationListener.java │ ├── HistoryManager.java │ └── JCompilationUnitEditor.java │ ├── event │ ├── OperationEvent.java │ ├── OperationEventListener.java │ └── OperationEventSource.java │ ├── history │ ├── CodeRestorer.java │ ├── Operation2Xml.java │ ├── OperationHistory.java │ ├── Xml2Operation.java │ └── XmlConstantStrings.java │ ├── operation │ ├── AbstractOperation.java │ ├── CompoundOperation.java │ ├── CopyOperation.java │ ├── FileOperation.java │ ├── IOperation.java │ ├── MenuOperation.java │ ├── NormalOperation.java │ ├── NullOperation.java │ ├── ResourceOperation.java │ └── TextOperation.java │ └── util │ ├── FileStream.java │ ├── StringComparator.java │ ├── Time.java │ ├── Whoami.java │ └── XmlFileStream.java ├── LICENSE ├── MacroRecorder ├── .classpath ├── .gitignore ├── .project ├── .settings │ └── org.eclipse.jdt.core.prefs ├── META-INF │ └── MANIFEST.MF ├── build.properties └── src │ └── org │ └── jtool │ └── macrorecorder │ ├── Activator.java │ ├── internal │ ├── diff │ │ ├── CodeDelta.java │ │ ├── DiffMacroGenerator.java │ │ └── diff_match_patch.java │ └── recorder │ │ ├── CommandExecutionManager.java │ │ ├── DocMacroRecorder.java │ │ ├── DocMacroRecorderOffEdit.java │ │ ├── DocMacroRecorderOnEdit.java │ │ ├── DocumentManager.java │ │ ├── MenuMacroRecorder.java │ │ ├── RefactoringExecutionManager.java │ │ ├── ResourceChangedManager.java │ │ └── Time.java │ ├── macro │ ├── CancelMacro.java │ ├── CompoundMacro.java │ ├── CopyMacro.java │ ├── DiffMacro.java │ ├── DocumentMacro.java │ ├── ExecutionMacro.java │ ├── Macro.java │ ├── ResourceMacro.java │ └── TriggerMacro.java │ ├── recorder │ ├── MacroCompressor.java │ ├── MacroEvent.java │ ├── MacroListener.java │ └── Recorder.java │ └── util │ ├── EditorUtilities.java │ └── WorkspaceUtilities.java ├── README.md ├── RemoteSystemsTempFiles └── .project ├── compare.png ├── jp.ac.ritsumei.cs.fse.contentassist ├── .classpath ├── .project ├── .settings │ └── org.eclipse.jdt.core.prefs ├── META-INF │ └── MANIFEST.MF ├── bin │ ├── .gitignore │ └── jp │ │ └── ac │ │ └── ritsumei │ │ └── cs │ │ └── fse │ │ └── contentassist │ │ ├── Activator.class │ │ ├── DataAnalyser │ │ ├── ConsoleOperationListener2.class │ │ ├── DataManager.class │ │ ├── HistoryRecorder.class │ │ └── getProposalResult.class │ │ ├── View │ │ └── JavaCompletionProposalComputer1.class │ │ └── entity │ │ └── ApplyOperation.class ├── build.properties ├── plugin.xml └── src │ └── jp │ └── ac │ └── ritsumei │ └── cs │ └── fse │ └── contentassist │ ├── Activator.java │ ├── DataAnalyser │ ├── ConsoleOperationListener2.java │ ├── DataManager.java │ ├── HistoryRecorder.java │ └── getProposalResult.java │ ├── View │ └── JavaCompletionProposalComputer1.java │ └── entity │ └── ApplyOperation.java ├── structure.png └── 編集履歴から算出した開発者の関心度に基づくコード補完.pdf /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | ContentAssist 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /ChangeRecorder/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /ChangeRecorder/.gitignore: -------------------------------------------------------------------------------- 1 | /bin 2 | -------------------------------------------------------------------------------- /ChangeRecorder/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | ChangeRecorder 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.pde.ManifestBuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.pde.SchemaBuilder 20 | 21 | 22 | 23 | 24 | 25 | org.eclipse.pde.PluginNature 26 | org.eclipse.jdt.core.javanature 27 | 28 | 29 | -------------------------------------------------------------------------------- /ChangeRecorder/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 4 | org.eclipse.jdt.core.compiler.compliance=1.7 5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 7 | org.eclipse.jdt.core.compiler.source=1.7 8 | -------------------------------------------------------------------------------- /ChangeRecorder/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Bundle-ManifestVersion: 2 3 | Bundle-Name: ChangeRecorder 4 | Bundle-SymbolicName: ChangeRecorder;singleton:=true 5 | Bundle-Version: 1.0.0.qualifier 6 | Bundle-Activator: org.jtool.changerecorder.Activator 7 | Require-Bundle: org.eclipse.ui;bundle-version="3.106.0", 8 | org.eclipse.core.runtime;bundle-version="3.10.0", 9 | org.eclipse.core.resources;bundle-version="3.9.1", 10 | org.eclipse.ui.ide;bundle-version="3.10.1", 11 | org.eclipse.ui.editors;bundle-version="3.8.200", 12 | org.eclipse.jface.text;bundle-version="3.9.1", 13 | org.eclipse.jdt.ui;bundle-version="3.10.1", 14 | org.eclipse.jdt.core;bundle-version="3.10.0", 15 | org.eclipse.ltk.core.refactoring;bundle-version="3.6.101", 16 | MacroRecorder;bundle-version="1.0.0" 17 | Bundle-RequiredExecutionEnvironment: JavaSE-1.8 18 | Bundle-ActivationPolicy: lazy 19 | Bundle-ClassPath: ., 20 | lib/commons-io-2.4.jar 21 | Export-Package: org.jtool.changerecorder.diff, 22 | org.jtool.changerecorder.editor, 23 | org.jtool.changerecorder.event, 24 | org.jtool.changerecorder.history, 25 | org.jtool.changerecorder.operation, 26 | org.jtool.changerecorder.util 27 | -------------------------------------------------------------------------------- /ChangeRecorder/build.properties: -------------------------------------------------------------------------------- 1 | output.. = bin/ 2 | bin.includes = META-INF/,\ 3 | plugin.xml,\ 4 | .,\ 5 | lib/commons-io-2.4.jar 6 | source.. = src/ 7 | jre.compilation.profile = JavaSE-1.7 8 | 9 | -------------------------------------------------------------------------------- /ChangeRecorder/icons/jcu_obj.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liaoziyang/ContentAssist/9f1c42158ddc765438b5e488ccf699372850fb2e/ChangeRecorder/icons/jcu_obj.gif -------------------------------------------------------------------------------- /ChangeRecorder/lib/commons-io-2.4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liaoziyang/ContentAssist/9f1c42158ddc765438b5e488ccf699372850fb2e/ChangeRecorder/lib/commons-io-2.4.jar -------------------------------------------------------------------------------- /ChangeRecorder/plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 8 | 9 | 10 | 12 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /ChangeRecorder/src/org/jtool/changerecorder/Activator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.changerecorder; 8 | 9 | import org.jtool.changerecorder.editor.HistoryManager; 10 | import org.eclipse.core.resources.IWorkspace; 11 | import org.eclipse.core.resources.IWorkspaceRoot; 12 | import org.eclipse.core.resources.ResourcesPlugin; 13 | import org.eclipse.core.runtime.IPath; 14 | import org.eclipse.ui.IStartup; 15 | import org.eclipse.ui.plugin.AbstractUIPlugin; 16 | import org.osgi.framework.BundleContext; 17 | 18 | import java.io.File; 19 | 20 | /** 21 | * The activator class that manages plug-in information. 22 | * @author Katsuhisa Maruyama 23 | */ 24 | public class Activator extends AbstractUIPlugin implements IStartup { 25 | 26 | /** 27 | * The plug-in ID. 28 | */ 29 | public static final String PLUGIN_ID = "ChangeRecorder"; 30 | 31 | /** 32 | * The plug-in instance. 33 | */ 34 | private static Activator plugin; 35 | 36 | /** 37 | * The top directory that stores history files. 38 | */ 39 | public static String DEFAULT_HISTORY_TOPDIR = File.separator + "#history"; 40 | 41 | /** 42 | * Creates a plug-in instance. 43 | */ 44 | public Activator() { 45 | 46 | } 47 | 48 | /** 49 | * Performs actions when the plug-in is activated. 50 | * @param context the bundle context for this plug-in 51 | * @throws Exception if this plug-in did not start up properly 52 | */ 53 | @Override 54 | public void start(BundleContext context) throws Exception { 55 | super.start(context); 56 | plugin = this; 57 | 58 | HistoryManager.getInstance().start(); 59 | 60 | System.out.println(PLUGIN_ID + " activated."); 61 | } 62 | 63 | /** 64 | * Performs actions when when the plug-in is shut down. 65 | * @param context the bundle context for this plug-in 66 | * @throws Exception if this this plug-in fails to stop 67 | */ 68 | @Override 69 | public void stop(BundleContext context) throws Exception { 70 | HistoryManager.getInstance().stop(); 71 | 72 | super.stop(context); 73 | plugin = null; 74 | } 75 | 76 | /** 77 | * Will be called in a separate thread after the workbench initializes. 78 | */ 79 | @Override 80 | public void earlyStartup() { 81 | } 82 | 83 | /** 84 | * Returns the default plug-in instance. 85 | * @return the default plug-in instance 86 | */ 87 | public static Activator getPlugin() { 88 | return plugin; 89 | } 90 | 91 | /** 92 | * Obtains the workspace. 93 | * @return the workspace information 94 | */ 95 | public IWorkspace getWorkspace() { 96 | return ResourcesPlugin.getWorkspace(); 97 | } 98 | 99 | /** 100 | * Returns the directory path of the plug-in's workspace, which contains operation history. 101 | * @return the the directory into which the operation history is stored 102 | */ 103 | public String getOperationHistoryDirPath() { 104 | IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); 105 | IPath workspaceDir = workspaceRoot.getLocation(); 106 | return workspaceDir.append(Activator.DEFAULT_HISTORY_TOPDIR).toString(); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /ChangeRecorder/src/org/jtool/changerecorder/diff/CodeDelta.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.changerecorder.diff; 8 | 9 | /** 10 | * Manages the delta of code (the difference between two source files). 11 | * @author Katsuhisa Maruyama 12 | */ 13 | class CodeDelta { 14 | 15 | /** 16 | * The type of code change operation. 17 | */ 18 | enum Type { 19 | DELETE, INSERT, NULL 20 | } 21 | 22 | /** 23 | * The offset value of the text that contains this code delta. 24 | */ 25 | private int offset; 26 | 27 | /** 28 | * The type of this code delta. 29 | */ 30 | private Type type; 31 | 32 | /** 33 | * The text of the code delta. 34 | */ 35 | private String text; 36 | 37 | /** 38 | * Creates an instance that stores information on change. 39 | * @param offset the offset value of the location where the change was applied 40 | * @param type the type of the change 41 | * @param text 42 | */ 43 | CodeDelta(int offset, Type type, String text) { 44 | this.offset = offset; 45 | this.type = type; 46 | this.text = text; 47 | } 48 | 49 | /** 50 | * Returns the offset value of the text that indicates the start point of the change. 51 | * @return the offset value for the change 52 | */ 53 | int getOffset() { 54 | return offset; 55 | } 56 | 57 | /** 58 | * Returns the type of the change. 59 | * @return the code change type 60 | */ 61 | Type getType() { 62 | return type; 63 | } 64 | 65 | /** 66 | * Returns the text that was inserted or deleted by the change. 67 | * @return the changed text 68 | */ 69 | String getText() { 70 | return text; 71 | } 72 | 73 | /** 74 | * Returns the string for printing 75 | * @return the string information 76 | */ 77 | public String toString() { 78 | return "-- Delta [" + String.valueOf(offset) + "] "+ type + " (" + text + ")"; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /ChangeRecorder/src/org/jtool/changerecorder/diff/DiffOperationGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.changerecorder.diff; 8 | 9 | import org.jtool.changerecorder.diff.diff_match_patch.Diff; 10 | import org.jtool.changerecorder.diff.diff_match_patch.Operation; 11 | import org.jtool.changerecorder.operation.NormalOperation; 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | import java.util.LinkedList; 15 | import java.util.ListIterator; 16 | 17 | /** 18 | * Generates diff operations from differences between the contents of two the source files. 19 | * @author Katsuhisa Maruyama 20 | */ 21 | public class DiffOperationGenerator { 22 | 23 | /** 24 | * The cost of an empty edit operation in terms of edit characters. 25 | */ 26 | private static short editCost = 4; 27 | 28 | /** 29 | * Sets the edit costs for finding difference. 30 | * @param cost the edit cost to be set 31 | */ 32 | public static void setEditCost(short cost) { 33 | editCost = cost; 34 | } 35 | 36 | /** 37 | * Generates diff operations from the differences between two textual contents. 38 | * @param time the time when this operation was inserted 39 | * @param path the name of the file path on which this operation was performed 40 | * @param otext the old contents of the file 41 | * @param ntext the new contents of the file 42 | * @return the collection of the generated diff operations 43 | */ 44 | public static List generate(long time, String path, String otext, String ntext) { 45 | List ops = new ArrayList(); 46 | List deltas = findDiff(otext, ntext); 47 | 48 | int offsetGap = 0; 49 | for (int idx = 0; idx < deltas.size(); idx++) { 50 | CodeDelta delta = deltas.get(idx); 51 | 52 | String itext = ""; 53 | String dtext = ""; 54 | if (delta.getType() == CodeDelta.Type.DELETE) { 55 | dtext = delta.getText(); 56 | 57 | } else if (delta.getType() == CodeDelta.Type.INSERT) { 58 | itext = delta.getText(); 59 | } 60 | 61 | int start = delta.getOffset() + offsetGap; 62 | NormalOperation op = new NormalOperation(time, idx, path, start, itext, dtext, NormalOperation.Type.DIFF); 63 | offsetGap = offsetGap - dtext.length(); 64 | 65 | ops.add(op); 66 | } 67 | 68 | return ops; 69 | } 70 | 71 | /** 72 | * Finds differences between the contents of two the source code files. 73 | * @param otext the contents of the source code file to be diffed 74 | * @param ntext the contents of the source code file to be diffed 75 | * @return the collection of the code deltas 76 | */ 77 | private static List findDiff(String otext, String ntext) { 78 | diff_match_patch dmp = new diff_match_patch(); 79 | dmp.Diff_EditCost = editCost; 80 | 81 | LinkedList diffs = dmp.diff_main(otext, ntext); 82 | dmp.diff_cleanupEfficiency(diffs); 83 | List deltas = getDeltas(diffs); 84 | 85 | return deltas; 86 | } 87 | 88 | /** 89 | * Obtains the deltas from a given difference information. 90 | * @param diffs the collection of difference information of the diff utility. 91 | * @return the collection of the code deltas 92 | */ 93 | private static List getDeltas(LinkedList diffs) { 94 | ArrayList deltas = new ArrayList(); 95 | int offset = 0; 96 | 97 | for (ListIterator pointer = diffs.listIterator(); pointer.hasNext(); ) { 98 | Diff diff = pointer.next(); 99 | 100 | if (diff.operation == Operation.INSERT) { 101 | deltas.add(new CodeDelta(offset, CodeDelta.Type.INSERT, diff.text)); 102 | 103 | } else if (diff.operation == Operation.DELETE) { 104 | deltas.add(new CodeDelta(offset, CodeDelta.Type.DELETE, diff.text)); 105 | } 106 | 107 | offset = offset + diff.text.length(); 108 | } 109 | 110 | return deltas; 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /ChangeRecorder/src/org/jtool/changerecorder/editor/ConsoleOperationListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.changerecorder.editor; 8 | 9 | import org.jtool.changerecorder.event.OperationEvent; 10 | import org.jtool.changerecorder.event.OperationEventListener; 11 | 12 | /** 13 | * Displays operations recorded on editors. 14 | * @author Katsuhisa Maruyama 15 | */ 16 | public class ConsoleOperationListener implements OperationEventListener { 17 | 18 | /** 19 | * Receives an operation event when operation history was updated. 20 | * @param evt the received event 21 | */ 22 | @Override 23 | public void historyNotification(OperationEvent evt) { 24 | System.out.println(evt.getOperation().toString()); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /ChangeRecorder/src/org/jtool/changerecorder/editor/JCompilationUnitEditor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.changerecorder.editor; 8 | 9 | import org.jtool.changerecorder.operation.FileOperation; 10 | import org.jtool.changerecorder.operation.IOperation; 11 | import org.jtool.macrorecorder.recorder.MacroEvent; 12 | import org.jtool.macrorecorder.util.EditorUtilities; 13 | import org.eclipse.core.resources.IFile; 14 | import org.eclipse.core.runtime.CoreException; 15 | import org.eclipse.core.runtime.IProgressMonitor; 16 | import org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor; 17 | import org.eclipse.jface.text.IDocument; 18 | import org.eclipse.ui.IEditorInput; 19 | import org.eclipse.ui.IEditorSite; 20 | import org.eclipse.ui.PartInitException; 21 | 22 | /** 23 | * Provides a Java-specific text editor on which editing operations are recorded. 24 | */ 25 | @SuppressWarnings("restriction") 26 | public class JCompilationUnitEditor extends CompilationUnitEditor { 27 | 28 | /** 29 | * A manager that manages the operation history. 30 | */ 31 | private HistoryManager historyManager = null; 32 | 33 | /** 34 | * Creates an instance of this editor. 35 | */ 36 | public JCompilationUnitEditor() { 37 | super(); 38 | } 39 | 40 | /** 41 | * Records the file open operation when the editor is instantiated. 42 | * @param site the editor site 43 | * @param input the editor input 44 | * @exception PartInitException if this editor was not initialized successfully 45 | */ 46 | @Override 47 | public void init(IEditorSite site, IEditorInput input) throws PartInitException { 48 | super.init(site, input); 49 | 50 | if (historyManager == null) { 51 | historyManager = HistoryManager.getInstance(); 52 | historyManager.start(this); 53 | 54 | historyManager.recordFileOpenOperation(getInputFile(), getSourceCode()); 55 | } 56 | } 57 | 58 | /** 59 | * Records the file activation operation when the editor is activated. 60 | */ 61 | @Override 62 | public void setFocus() { 63 | super.setFocus(); 64 | 65 | if (historyManager != null) { 66 | IOperation op = historyManager.getLastOperation(); 67 | if (op != null && op.getOperationType() == IOperation.Type.FILE) { 68 | FileOperation fop = (FileOperation)op; 69 | if (fop.getActionType() == FileOperation.Type.ACT && fop.getFilePath().compareTo(getInputFilePath()) == 0) { 70 | return; 71 | } 72 | } 73 | 74 | historyManager.recordFileOperation(getInputFile(), getSourceCode(), FileOperation.Type.ACT, false); 75 | } 76 | } 77 | 78 | /** 79 | * Records the file save operation and stores the operation history into the output file when the contents of the editor is saved. 80 | * @param progressMonitor the progress monitor for communicating result state, or null if not needed 81 | */ 82 | @Override 83 | public void doSave(IProgressMonitor progressMonitor) { 84 | super.doSave(progressMonitor); 85 | 86 | if (historyManager != null) { 87 | historyManager.recordFileOperation(getInputFile(), getSourceCode(), FileOperation.Type.SAVE, true); 88 | historyManager.writeHistory(getInputFile()); 89 | } 90 | } 91 | 92 | /** 93 | * Stores the operation history into the output file when the setting of the editor input is changed. 94 | * @param input the changed editor input 95 | */ 96 | @Override 97 | protected void doSetInput(IEditorInput input) throws CoreException { 98 | super.doSetInput(input); 99 | } 100 | 101 | /** 102 | * Records the file close operation and stores the operation history into the output file when the editor is closed. 103 | */ 104 | @Override 105 | public void dispose() { 106 | if (historyManager != null) { 107 | historyManager.stop(this); 108 | 109 | historyManager.recordFileCloseOperation(getInputFile(), getSourceCode()); 110 | historyManager.writeHistory(getInputFile()); 111 | historyManager = null; 112 | } 113 | 114 | super.dispose(); 115 | } 116 | 117 | /** 118 | * Returns the path of a file existing on this editor. 119 | * @return the file path, which is relative to the path of the path of the workspace 120 | */ 121 | public String getInputFilePath() { 122 | return EditorUtilities.getInputFilePath(this); 123 | } 124 | 125 | /** 126 | * Returns a file existing on this editor. 127 | * @return the IFile instance corresponding to the file, or null if none 128 | */ 129 | public IFile getInputFile() { 130 | return EditorUtilities.getInputFile(this); 131 | } 132 | 133 | /** 134 | * Obtains a document related to this editor. 135 | * @return the related document, or null if none 136 | */ 137 | public IDocument getDocument() { 138 | return EditorUtilities.getDocument(this); 139 | } 140 | 141 | /** 142 | * Obtains the contents of source code related to this editor. 143 | * @return the contents of the source code, or null if the source code is not valid 144 | */ 145 | public String getSourceCode() { 146 | return EditorUtilities.getSourceCode(this); 147 | } 148 | 149 | /** 150 | * Receives a macro event when a new macro is added. 151 | * @param evt the macro event 152 | */ 153 | public void macroAdded(MacroEvent evt) { 154 | /* 155 | Macro macro = evt.getMacro(); 156 | System.out.println(macro.toString()); 157 | if (macro instanceof CompoundMacro) { 158 | CompoundMacro cmacro = (CompoundMacro)macro; 159 | for (Macro m : cmacro.getMacros()) { 160 | System.out.println(" " + m.toString()); 161 | } 162 | } 163 | */ 164 | } 165 | 166 | /** 167 | * Receives a macro event when a document is changed. 168 | * @param evt the raw macro event 169 | */ 170 | public void documentChanged(MacroEvent evt) { 171 | // System.out.println("!MACRO: " + evt.getMacro()); 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /ChangeRecorder/src/org/jtool/changerecorder/event/OperationEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.changerecorder.event; 8 | 9 | import org.jtool.changerecorder.operation.IOperation; 10 | 11 | /** 12 | * Manages an event indicating that the operation has performed. 13 | * @author Katsuhisa Maruyama 14 | */ 15 | public class OperationEvent { 16 | 17 | /** 18 | * Defines the type of this event. 19 | */ 20 | public enum Type { 21 | OPERATION_ADDED, DEFAULT; 22 | } 23 | 24 | /** 25 | * The type of this event. 26 | */ 27 | private OperationEvent.Type type = OperationEvent.Type.DEFAULT; 28 | 29 | /** 30 | * The operation sent by this operation event. 31 | */ 32 | private IOperation operation; 33 | 34 | /** 35 | * Creates an instance containing information on this operation event. 36 | * @param type the type of this operation event 37 | * @param operation the operation sent by this operation event 38 | */ 39 | public OperationEvent(OperationEvent.Type type, IOperation operation) { 40 | this.type = type; 41 | this.operation = operation; 42 | } 43 | 44 | /** 45 | * Creates an instance containing information on this operation event. 46 | * @param operation the operation sent by this operation event 47 | */ 48 | public OperationEvent(IOperation operation) { 49 | this.operation = operation; 50 | } 51 | 52 | /** 53 | * Returns the type of this operation event. 54 | * @return the event type 55 | */ 56 | public OperationEvent.Type getType() { 57 | return type; 58 | } 59 | 60 | /** 61 | * Returns the operation sent by this operation event. 62 | * @return the operation related to this operation event 63 | */ 64 | public IOperation getOperation() { 65 | return operation; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /ChangeRecorder/src/org/jtool/changerecorder/event/OperationEventListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.changerecorder.event; 8 | 9 | /** 10 | * Defines the listener interface for receiving an operation event. 11 | * @author Katsuhisa Maruyama 12 | */ 13 | public interface OperationEventListener { 14 | 15 | /** 16 | * Receives an operation event when operation history was updated. 17 | * @param evt the received event 18 | */ 19 | public void historyNotification(OperationEvent evt); 20 | } 21 | -------------------------------------------------------------------------------- /ChangeRecorder/src/org/jtool/changerecorder/event/OperationEventSource.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.changerecorder.event; 8 | 9 | import org.jtool.changerecorder.operation.IOperation; 10 | import java.util.List; 11 | import java.util.ArrayList; 12 | 13 | /** 14 | * Manages a source that send an operation event. 15 | * @author Katsuhisa Maruyama 16 | */ 17 | public class OperationEventSource { 18 | 19 | /** 20 | * The collection of listeners that receives operation events. 21 | */ 22 | private List listeners = new ArrayList(); 23 | 24 | /** 25 | * Creates an object that performs as an event source. 26 | */ 27 | public OperationEventSource() { 28 | } 29 | 30 | /** 31 | * Adds a listener in order to receive an operation event from this source. 32 | * @param listener the event listener to be added 33 | */ 34 | public void addOperationEventListener(OperationEventListener listener) { 35 | listeners.add(listener); 36 | } 37 | 38 | /** 39 | * Removes a listener which no longer receives an operation event from this source. 40 | * @param listener the event listener to be removed 41 | */ 42 | public void removeOperationEventListener(OperationEventListener listener) { 43 | listeners.remove(listener); 44 | } 45 | 46 | /** 47 | * Sends an operation event to all the listeners. 48 | * @param evt the operation event. 49 | */ 50 | protected void notify(IOperation op) { 51 | OperationEvent evt = new OperationEvent(OperationEvent.Type.OPERATION_ADDED, op); 52 | for (OperationEventListener listener : listeners) { 53 | listener.historyNotification(evt); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /ChangeRecorder/src/org/jtool/changerecorder/history/CodeRestorer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.changerecorder.history; 8 | 9 | import org.jtool.changerecorder.operation.CompoundOperation; 10 | import org.jtool.changerecorder.operation.IOperation; 11 | import org.jtool.changerecorder.operation.NormalOperation; 12 | 13 | /** 14 | * Applies an operation into code. 15 | * @author Katsuhisa Maruyama 16 | */ 17 | public class CodeRestorer { 18 | 19 | /** 20 | * Obtains the code after the application of a given operation into given code. 21 | * @param preCode the code before the application 22 | * @param op the operation to be applied 23 | * @return the resulting code after the application 24 | */ 25 | public static String applyOperation(String preCode, IOperation op) { 26 | if (op instanceof NormalOperation) { 27 | return applyOperation(preCode, (NormalOperation)op); 28 | 29 | } else if (op instanceof CompoundOperation) { 30 | return applyOperation(preCode, (CompoundOperation)op); 31 | } 32 | return preCode; 33 | } 34 | 35 | /** 36 | * Applies a specified normal operation into given code. 37 | * @param preCode the code before the application 38 | * @param op the operation to be applied 39 | * @return the resulting code after the application 40 | */ 41 | public static String applyOperation(String preCode, NormalOperation op) { 42 | StringBuilder postCode = new StringBuilder(preCode); 43 | 44 | if (hasDeletionMismatch(postCode, op)) { 45 | return null; 46 | } 47 | 48 | int start = op.getStart(); 49 | int end = start + op.getDeletedText().length(); 50 | String itext = op.getInsertedText(); 51 | postCode.replace(start, end, itext); 52 | return postCode.toString(); 53 | } 54 | 55 | /** 56 | * Applies a given compound operation into given code. 57 | * @param preCode the code before the application 58 | * @param cop the operation to be applied 59 | * @return the resulting code after the application 60 | */ 61 | public static String applyOperation(String preCode, CompoundOperation cop) { 62 | String postCode = null; 63 | 64 | for (IOperation op : cop.getLeaves()) { 65 | if (op instanceof CompoundOperation) { 66 | applyOperation(preCode, (CompoundOperation)op); 67 | 68 | } else if (op instanceof NormalOperation) { 69 | postCode = applyOperation(preCode, (NormalOperation)op); 70 | if (postCode == null) { 71 | return null; 72 | } 73 | preCode = postCode; 74 | } 75 | } 76 | return postCode; 77 | } 78 | 79 | /** 80 | * Obtains the code after the application of a given operation into given code reversely. 81 | * @param preCode the code before the application 82 | * @param op the operation to be applied 83 | * @return the resulting code after the application 84 | */ 85 | public static String applyOperationReversely(String preCode, IOperation op) { 86 | if (op instanceof NormalOperation) { 87 | return applyOperationReversely(preCode, (NormalOperation)op); 88 | 89 | } else if (op instanceof CompoundOperation) { 90 | return applyOperationReversely(preCode, (CompoundOperation)op); 91 | 92 | } 93 | return preCode; 94 | } 95 | 96 | /** 97 | * Applies a specified normal operation into given code reversely. 98 | * @param preCode the code before the application 99 | * @param op the operation to be applied 100 | * @return the resulting code after the application 101 | */ 102 | public static String applyOperationReversely(String preCode, NormalOperation op) { 103 | StringBuilder postCode = new StringBuilder(preCode); 104 | 105 | if (hasInsertionMismatch(postCode, op)) { 106 | return null; 107 | } 108 | 109 | int start = op.getStart(); 110 | int end = start + op.getDeletedText().length(); 111 | String dtext = op.getDeletedText(); 112 | postCode.replace(start, end, dtext); 113 | return postCode.toString(); 114 | } 115 | 116 | /** 117 | * Applies a given compound operation into given code reversely. 118 | * @param preCode the code before the application 119 | * @param cop the operation to be applied 120 | * @return the resulting code after the application 121 | */ 122 | public static String applyOperationReversely(String preCode, CompoundOperation cop) { 123 | String postCode = null; 124 | 125 | for (IOperation op : cop.getLeaves()) { 126 | if (op instanceof CompoundOperation) { 127 | applyOperationReversely(preCode, (CompoundOperation)op); 128 | 129 | } else if (op instanceof NormalOperation) { 130 | postCode = applyOperationReversely(preCode, (NormalOperation)op); 131 | if (postCode == null) { 132 | return null; 133 | } 134 | preCode = postCode; 135 | } 136 | } 137 | return postCode; 138 | } 139 | 140 | /** 141 | * Tests if the deletion derives any mismatch. 142 | * @param code the code before the application 143 | * @param op the operation to be applied 144 | * @return true if a mismatch exists, otherwise false 145 | */ 146 | private static boolean hasDeletionMismatch(StringBuilder code, NormalOperation op) { 147 | String dtext = op.getDeletedText(); 148 | int start = op.getStart(); 149 | int end = start + dtext.length(); 150 | 151 | if (dtext.length() > 0) { 152 | String rtext = code.substring(start, end); 153 | if (rtext != null && rtext.compareTo(dtext) != 0) { 154 | 155 | for (int i = 0; i < rtext.length(); i++) { 156 | if (rtext.charAt(i) == dtext.charAt(i)) { 157 | System.out.println(((int)rtext.charAt(i)) + " == " + ((int)dtext.charAt(i))); 158 | } else { 159 | System.out.println(((int)rtext.charAt(i)) + " != " + ((int)dtext.charAt(i))); 160 | } 161 | } 162 | return true; 163 | } 164 | } 165 | return false; 166 | } 167 | 168 | /** 169 | * Tests if the deletion derives any mismatch. 170 | * @param code the code before the application 171 | * @param op the operation to be applied 172 | * @return true if a mismatch exists, otherwise false 173 | */ 174 | private static boolean hasInsertionMismatch(StringBuilder code, NormalOperation op) { 175 | String itext = op.getDeletedText(); 176 | int start = op.getStart(); 177 | int end = start + itext.length(); 178 | 179 | if (itext.length() > 0) { 180 | String rtext = code.substring(start, end); 181 | if (rtext != null && rtext.compareTo(itext) != 0) { 182 | 183 | for (int i = 0; i < rtext.length(); i++) { 184 | if (rtext.charAt(i) == itext.charAt(i)) { 185 | System.out.println(((int)rtext.charAt(i)) + " == " + ((int)itext.charAt(i))); 186 | } else { 187 | System.out.println(((int)rtext.charAt(i)) + " != " + ((int)itext.charAt(i))); 188 | } 189 | } 190 | return true; 191 | } 192 | } 193 | return false; 194 | } 195 | } 196 | -------------------------------------------------------------------------------- /ChangeRecorder/src/org/jtool/changerecorder/history/XmlConstantStrings.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.changerecorder.history; 8 | 9 | /** 10 | * The elements, attributes, and values of the attributes appearing in XML documents 11 | * that store information on the operation history. 12 | * @author Katsuhisa Maruyama 13 | */ 14 | public interface XmlConstantStrings { 15 | 16 | static final String OperationHistoryElem = "OperationHistory"; 17 | static final String OperationHistoryVersion = "1.0a"; 18 | static final String OperationsElem = "operations"; 19 | 20 | static final String NormalOperationElem = "normalOperation"; 21 | static final String CompoundOperationElem = "compoundOperation"; 22 | static final String CopyOperationElem = "copyOperation"; 23 | static final String FileOperationElem = "fileOperation"; 24 | static final String MenuOperationElem = "menuOperation"; 25 | static final String ResourceOperationElem = "resourceOperation"; 26 | 27 | static final String InsertedElem = "inserted"; 28 | static final String DeletedElem = "deleted"; 29 | static final String CopiedElem = "copied"; 30 | static final String CodeElem = "code"; 31 | 32 | static final String VersionAttr = "version"; 33 | static final String TimeAttr = "time"; 34 | static final String SeqAttr = "seq"; 35 | static final String OffsetAttr = "offset"; 36 | static final String FileAttr = "file"; 37 | static final String ActionAttr = "action"; 38 | static final String LabelAttr = "label"; 39 | static final String AuthorAttr = "author"; 40 | 41 | static final String TargetAttr = "target"; 42 | static final String APathAttr = "apath"; 43 | 44 | static final String Yes = "yes"; 45 | static final String No = "no"; 46 | static final String None = "None"; 47 | } 48 | -------------------------------------------------------------------------------- /ChangeRecorder/src/org/jtool/changerecorder/operation/AbstractOperation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.changerecorder.operation; 8 | 9 | import org.jtool.changerecorder.util.StringComparator; 10 | import org.jtool.changerecorder.util.Whoami; 11 | 12 | /** 13 | * Defines the abstract class used for accessing information on the all kinds of operations. 14 | * @author Katsuhisa Maruyama 15 | */ 16 | public abstract class AbstractOperation implements IOperation { 17 | 18 | /** 19 | * The time when this operation was performed. 20 | */ 21 | protected long time; 22 | 23 | /** 24 | * The sequence number that indicates the order of change operations in the same time. 25 | */ 26 | private int sequenceNumber = 0; 27 | 28 | /** 29 | * The path name of the file on which this operation was performed. 30 | */ 31 | protected String path; 32 | 33 | /** 34 | * The name of a developer who performed this operation. 35 | */ 36 | protected String author; 37 | 38 | /** 39 | * Creates an instance storing information on this operation. 40 | * @param time the time when this operation was performed 41 | * @param seq the sequence number of this operation 42 | * @param path the name of the file on which this operation was performed 43 | * @param author the author's name 44 | */ 45 | protected AbstractOperation(long time, int seq, String path, String author) { 46 | this.time = time; 47 | this.sequenceNumber = seq; 48 | this.path = path; 49 | this.author = author; 50 | } 51 | 52 | /** 53 | * Creates an instance storing information on this operation. 54 | * @param time the time when this operation was performed 55 | * @param seq the sequence number of this operation 56 | * @param path the name of the file on which this operation was performed 57 | */ 58 | protected AbstractOperation(long time, int seq, String path) { 59 | this(time, seq, path, getUserName()); 60 | } 61 | 62 | /** 63 | * Creates an instance storing information on this operation. 64 | * @param time the time when this operation was performed 65 | * @param path the name of the file on which this operation was performed 66 | * @param author the author's name 67 | */ 68 | protected AbstractOperation(long time, String path, String author) { 69 | this(time, 0, path, author); 70 | } 71 | 72 | /** 73 | * Creates an instance storing information on this operation. 74 | * @param time the time when this operation was performed 75 | * @param path the name of the file on which this operation was performed 76 | */ 77 | protected AbstractOperation(long time, String path) { 78 | this(time, 0, path); 79 | } 80 | 81 | /** 82 | * Obtains the user name by executing whoamitrue if the operation is a text edit operation 135 | */ 136 | public boolean isTextEditOperation() { 137 | IOperation.Type type = getOperationType(); 138 | return type == IOperation.Type.NORMAL || type == IOperation.Type.COMPOUND || type == IOperation.Type.COPY; 139 | } 140 | 141 | /** 142 | * Tests if a given operation changes any text. 143 | * @return true if the operation is a text change operation 144 | */ 145 | public boolean isTextChangedOperation() { 146 | IOperation.Type type = getOperationType(); 147 | return type == IOperation.Type.NORMAL || type == IOperation.Type.COMPOUND; 148 | } 149 | 150 | /** 151 | * Converts a text into its pretty one. 152 | * @param text the original text 153 | * @return the text consists of the first four characters not including the new line 154 | */ 155 | public String getText(String text) { 156 | final int LESS_LEN = 9; 157 | 158 | String text2; 159 | if (text.length() < LESS_LEN + 1) { 160 | text2 = text; 161 | } else { 162 | text2 = text.substring(0, LESS_LEN + 1) + "..."; 163 | } 164 | 165 | return text2.replace('\n', '~'); 166 | } 167 | 168 | /** 169 | * Tests if this operation is the same as a given one. 170 | * @param op the given operation 171 | * @return true if the two operations are the same, otherwise false 172 | */ 173 | public boolean equals(IOperation op) { 174 | if (!(op instanceof AbstractOperation)) { 175 | return false; 176 | } 177 | 178 | return time == op.getTime() && sequenceNumber == getSequenceNumber() && 179 | StringComparator.isSame(path, op.getFilePath()) && 180 | StringComparator.isSame(author, op.getAuthor()); 181 | } 182 | } 183 | -------------------------------------------------------------------------------- /ChangeRecorder/src/org/jtool/changerecorder/operation/CompoundOperation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.changerecorder.operation; 8 | 9 | import org.jtool.changerecorder.util.StringComparator; 10 | import org.jtool.changerecorder.util.Time; 11 | import java.util.List; 12 | import java.util.ArrayList; 13 | 14 | /** 15 | * Stores information on a compound operation enclosing multiple operations. 16 | * @author Katsuhisa Maruyama 17 | */ 18 | public class CompoundOperation extends AbstractOperation { 19 | 20 | /** 21 | * The array list of operations contained in this operation. 22 | */ 23 | private List operations = new ArrayList(); 24 | 25 | /** 26 | * The label indicating the name of this operation. 27 | */ 28 | protected String label; 29 | 30 | /** 31 | * Creates an instance storing information on this compound operation. 32 | * @param time the time when this operation was performed 33 | * @param author the author's name 34 | * @param ops the operations contained in this operation 35 | * @param label the label indicating the name of the undo operation 36 | */ 37 | public CompoundOperation(long time, String author, List ops, String label) { 38 | super(time, "", author); 39 | this.operations = ops; 40 | this.label = label; 41 | } 42 | 43 | /** 44 | * Creates an instance storing information on this compound operation. 45 | * @param time the time when this operation was performed 46 | * @param ops the operations contained in this operation 47 | * @param label the label indicating the name of the undo operation 48 | */ 49 | public CompoundOperation(long time, List ops, String label) { 50 | this(time, AbstractOperation.getUserName(), ops, label); 51 | } 52 | 53 | /** 54 | * Returns the array of operations contained in this operation. 55 | * @return the contained operations 56 | */ 57 | public List getOperations() { 58 | return operations; 59 | } 60 | 61 | /** 62 | * Returns the label indicating the name of the undo operation. 63 | * @return the label string 64 | */ 65 | public String getLabel() { 66 | return label; 67 | } 68 | 69 | /** 70 | * Returns the array list of operations dangling on this operation. 71 | * @return the dangling editing operations 72 | */ 73 | public List getLeaves() { 74 | List leaves = new ArrayList(); 75 | for (IOperation op : operations) { 76 | if (op.getOperationType() == IOperation.Type.COMPOUND) { 77 | CompoundOperation cop = (CompoundOperation)op; 78 | leaves.addAll(cop.getLeaves()); 79 | } else { 80 | leaves.add(op); 81 | } 82 | } 83 | return leaves; 84 | } 85 | 86 | /** 87 | * Returns the sort of this operation. 88 | * @return the string indicating the operation sort 89 | */ 90 | @Override 91 | public IOperation.Type getOperationType() { 92 | return IOperation.Type.COMPOUND; 93 | } 94 | 95 | /** 96 | * Tests if this operation is the same as a given one. 97 | * @param op the given operation 98 | * @return true if the two operations are the same, otherwise false 99 | */ 100 | @Override 101 | public boolean equals(IOperation op) { 102 | if (!(op instanceof CompoundOperation)) { 103 | return false; 104 | } 105 | 106 | CompoundOperation cop = (CompoundOperation)op; 107 | if (!super.equals(cop) || !StringComparator.isSame(label, cop.getLabel()) || 108 | operations.size() != cop.getOperations().size()) { 109 | return false; 110 | } 111 | 112 | for (int idx = 0; idx < operations.size(); idx++) { 113 | if (!operations.get(idx).equals(cop.getOperations().get(idx))) { 114 | return false; 115 | } 116 | } 117 | 118 | return true; 119 | } 120 | 121 | /** 122 | * Returns the string for printing, which does not contain a new line character at its end. 123 | * @return the string for printing 124 | */ 125 | @Override 126 | public String toString() { 127 | StringBuilder buf = new StringBuilder(); 128 | buf.append("{"); 129 | buf.append(Time.toUsefulFormat(time)); 130 | buf.append(" label=[" + label + "]\n"); 131 | 132 | for (IOperation op : operations) { 133 | buf.append(" " + op.toString()); 134 | buf.append("\n"); 135 | } 136 | buf.append("}"); 137 | 138 | return buf.toString(); 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /ChangeRecorder/src/org/jtool/changerecorder/operation/CopyOperation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.changerecorder.operation; 8 | 9 | import org.jtool.changerecorder.util.StringComparator; 10 | import org.jtool.changerecorder.util.Time; 11 | 12 | /** 13 | * Stores information on a copy operation. 14 | * @author Katsuhisa Maruyama 15 | */ 16 | public class CopyOperation extends AbstractOperation { 17 | 18 | /** 19 | * The leftmost offset of the text modified by this editing operation. 20 | */ 21 | protected int start; 22 | 23 | /** 24 | * The content of the text copied by this editing operation. 25 | */ 26 | protected String copiedText; 27 | 28 | /** 29 | * Creates an instance storing information on this copy operation. 30 | * @param time the time when this operation was performed 31 | * @param path the name of the file path on which this operation was performed 32 | * @param author the author's name 33 | * @param start the leftmost offset of the text modified by this operation 34 | * @param ctext the content of the text copied by this operation 35 | */ 36 | public CopyOperation(long time, String path, String author, int start, String ctext) { 37 | super(time, path, author); 38 | this.start = start; 39 | this.copiedText = ctext; 40 | } 41 | 42 | /** 43 | * Creates an instance storing information on this copy operation. 44 | * @param time the time when this operation was performed 45 | * @param path the name of the file path on which this operation was performed 46 | * @param start the leftmost offset of the text modified by this operation 47 | * @param ctext the content of the text copied by this operation 48 | */ 49 | public CopyOperation(long time, String path, int start, String ctext) { 50 | this(time, path, AbstractOperation.getUserName(), start, ctext); 51 | } 52 | 53 | /** 54 | * Returns the leftmost offset of the text copied by this operation. 55 | * @return the leftmost offset value of the modified text 56 | */ 57 | public int getStart() { 58 | return start; 59 | } 60 | 61 | /** 62 | * Returns the content of the text copied by this operation. 63 | * @return the content of the copied text, or the empty string 64 | */ 65 | public String getCopiedText() { 66 | return copiedText; 67 | } 68 | 69 | /** 70 | * Returns the sort of this operation. 71 | * @return the string indicating the operation sort 72 | */ 73 | @Override 74 | public IOperation.Type getOperationType() { 75 | return IOperation.Type.COPY; 76 | } 77 | 78 | /** 79 | * Tests if this operation is the same as a given one. 80 | * @param op the given operation 81 | * @return true if the two operations are the same, otherwise false 82 | */ 83 | @Override 84 | public boolean equals(IOperation op) { 85 | if (!(op instanceof CopyOperation)) { 86 | return false; 87 | } 88 | 89 | CopyOperation cop = (CopyOperation)op; 90 | return super.equals(cop) && 91 | start == cop.getStart() && StringComparator.isSame(copiedText, cop.getCopiedText()); 92 | } 93 | 94 | /** 95 | * Returns the string for printing, which does not contain a new line character at its end. 96 | * @return the string for printing 97 | */ 98 | @Override 99 | public String toString() { 100 | StringBuilder buf = new StringBuilder(); 101 | buf.append(Time.toUsefulFormat(time)); 102 | buf.append(" author=[" + author + "]"); 103 | buf.append(" path=" + path + "]"); 104 | buf.append(" offset=" + start); 105 | buf.append(" copied=[" + getText(copiedText) + "]\n"); 106 | 107 | return buf.toString(); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /ChangeRecorder/src/org/jtool/changerecorder/operation/FileOperation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.changerecorder.operation; 8 | 9 | import org.jtool.changerecorder.util.StringComparator; 10 | import org.jtool.changerecorder.util.Time; 11 | 12 | /** 13 | * Stores information on a file operation. 14 | * @author Katsuhisa Maruyama 15 | */ 16 | public class FileOperation extends AbstractOperation { 17 | 18 | /** 19 | * Defines the type of a file action. 20 | */ 21 | public enum Type { 22 | NEW, OPEN, CLOSE, SAVE, DELETE, ACT, INSTANT, NONE; 23 | 24 | /** 25 | * Checks the type of the file action 26 | * @param str the string indicating the action 27 | * @return the type of the file action, or NONE if none 28 | */ 29 | public static Type parseType(String str) { 30 | if (StringComparator.isSameIgnoreCase(str, "new")) { 31 | return NEW; 32 | } else if (StringComparator.isSameIgnoreCase(str, "open")) { 33 | return OPEN; 34 | } else if (StringComparator.isSameIgnoreCase(str, "close")) { 35 | return CLOSE; 36 | } else if (StringComparator.isSameIgnoreCase(str, "save")) { 37 | return SAVE; 38 | } else if (StringComparator.isSameIgnoreCase(str, "delete")) { 39 | return DELETE; 40 | } else if (StringComparator.isSameIgnoreCase(str, "act")) { 41 | return ACT; 42 | } else if (StringComparator.isSameIgnoreCase(str, "instant")) { 43 | return INSTANT; 44 | } 45 | return NONE; 46 | } 47 | } 48 | 49 | /** 50 | * The sort of the file action for this operation. 51 | */ 52 | protected Type actionType; 53 | 54 | /** 55 | * The contents of the source code when this file operation was performed. 56 | */ 57 | protected String code; 58 | 59 | /** 60 | * Creates an instance storing information on this file operation. 61 | * @param time the time when this operation was performed 62 | * @param path the path name of the file on which this operation was performed 63 | * @param author the author's name 64 | * @param atype the type of the operation 65 | * @param code the contents of the source code when this file operation was performed 66 | */ 67 | public FileOperation(long time, String path, String author, Type atype, String code) { 68 | super(time, path, author); 69 | this.actionType = atype; 70 | this.code = code; 71 | } 72 | 73 | /** 74 | * Creates an instance storing information on this file operation. 75 | * @param time the time when this operation was performed 76 | * @param path the path name of the file on which this operation was performed 77 | * @param atype the type of the operation 78 | * @param code the contents of the source code when this file operation was performed 79 | */ 80 | public FileOperation(long time, String path, Type atype, String code) { 81 | this(time, path, AbstractOperation.getUserName(), atype, code); 82 | } 83 | 84 | /** 85 | * Returns the sort of the file action for this operation. 86 | * @return the sort of the file action for this operation 87 | */ 88 | public Type getActionType() { 89 | return actionType; 90 | } 91 | 92 | /** 93 | * Returns the contents of the source code when this file operation was performed 94 | * @return the contents of the source code 95 | */ 96 | public String getCode() { 97 | return code; 98 | } 99 | 100 | /** 101 | * Sets the contents of the source code when this file operation was performed 102 | * @param code the contents of the source code 103 | */ 104 | public void setCode(String code) { 105 | this.code = code; 106 | } 107 | 108 | /** 109 | * Returns the sort of this operation. 110 | * @return the string indicating the operation sort 111 | */ 112 | @Override 113 | public IOperation.Type getOperationType() { 114 | return IOperation.Type.FILE; 115 | } 116 | 117 | /** 118 | * Tests if this operation is the same as a given one. 119 | * @param op the given operation 120 | * @return true if the two operations are the same, otherwise false 121 | */ 122 | @Override 123 | public boolean equals(IOperation op) { 124 | if (!(op instanceof FileOperation)) { 125 | return false; 126 | } 127 | 128 | FileOperation fop = (FileOperation)op; 129 | return super.equals(fop) && 130 | actionType == fop.getActionType() && StringComparator.isSame(code, fop.getCode()); 131 | } 132 | 133 | /** 134 | * Returns the string for printing, which does not contain a new line character at its end. 135 | * @return the string for printing 136 | */ 137 | @Override 138 | public String toString() { 139 | StringBuilder buf = new StringBuilder(); 140 | buf.append(Time.toUsefulFormat(time)); 141 | buf.append(" " + actionType.toString()); 142 | buf.append(" author=[" + author + "]"); 143 | buf.append(" path=" + path); 144 | if (code != null) { 145 | buf.append(" code=[" + getText(code) + "]"); 146 | } 147 | 148 | return buf.toString(); 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /ChangeRecorder/src/org/jtool/changerecorder/operation/IOperation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.changerecorder.operation; 8 | 9 | /** 10 | * Defines the interface used for accessing information on the all kinds of operations. 11 | * @author Katsuhisa Maruyama 12 | */ 13 | public interface IOperation { 14 | 15 | /** 16 | * Defines the type of an operation. 17 | */ 18 | public enum Type { 19 | 20 | /** 21 | * The string indicating if this is a normal operation. 22 | */ 23 | NORMAL, 24 | 25 | /** 26 | * The string indicating if this is a compounded operation. 27 | */ 28 | COMPOUND, 29 | 30 | /** 31 | * The string indicating if this is a copy operation. 32 | */ 33 | COPY, 34 | 35 | /** 36 | * The string indicating if this is a file operation. 37 | */ 38 | FILE, 39 | 40 | /** 41 | * The string indicating if this is a menu operation. 42 | */ 43 | MENU, 44 | 45 | /** 46 | * The string indicating if this is a resource change operation. 47 | */ 48 | RESOURCE, 49 | 50 | /** 51 | * The string indicating if this is a null operation. 52 | */ 53 | NULL; 54 | } 55 | 56 | /** 57 | * Returns the time when this operation was performed. 58 | * @return the time of the operation 59 | */ 60 | public long getTime(); 61 | 62 | /** 63 | * Returns the sequence number indicating the order of operations whose times are the same. 64 | * @return the sequence number of this operation 65 | */ 66 | public int getSequenceNumber(); 67 | 68 | /** 69 | * Returns the path name of the file on which this operation was performed. 70 | * @return the path name of the file 71 | */ 72 | public String getFilePath(); 73 | 74 | /** 75 | * Returns the name of a author who performs this operation. 76 | * @return the suthor's name 77 | */ 78 | public String getAuthor(); 79 | 80 | /** 81 | * Returns the sort of this operation. 82 | * @return the string indicating the operation sort 83 | */ 84 | public IOperation.Type getOperationType(); 85 | 86 | /** 87 | * Tests if a given operation edits any text. 88 | * @return true if the operation is a text edit operation 89 | */ 90 | public boolean isTextEditOperation(); 91 | 92 | /** 93 | * Tests if a given operation changes any text. 94 | * @return true if the operation is a text change operation 95 | */ 96 | public boolean isTextChangedOperation(); 97 | 98 | /** 99 | * Tests if this operation is the same as a given one. 100 | * @param op the given operation 101 | * @return true if the two operations are the same, otherwise false 102 | */ 103 | public boolean equals(IOperation op); 104 | 105 | /** 106 | * Returns the string for printing, which does not contain a new line character at its end. 107 | * @return the string for printing 108 | */ 109 | public String toString(); 110 | } 111 | -------------------------------------------------------------------------------- /ChangeRecorder/src/org/jtool/changerecorder/operation/MenuOperation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.changerecorder.operation; 8 | 9 | import org.jtool.changerecorder.util.StringComparator; 10 | import org.jtool.changerecorder.util.Time; 11 | 12 | /** 13 | * Stores information on a menu operation. 14 | * @author Katsuhisa Maruyama 15 | */ 16 | public class MenuOperation extends AbstractOperation { 17 | 18 | /** 19 | * The label indicating the contents of this operation. 20 | */ 21 | protected String label; 22 | 23 | /** 24 | * Provides the constructor for creating an instance storing information on this operation. 25 | * @param time the time when this operation was performed 26 | * @param path the name of the file on which this operation was performed 27 | * @param author the author's name 28 | * @param the label indicating the name of the menu operation 29 | */ 30 | public MenuOperation(long time, String path, String author, String label) { 31 | super(time, path, author); 32 | this.label = label; 33 | } 34 | 35 | /** 36 | * Provides the constructor for creating an instance storing information on this operation. 37 | * @param time the time when this operation was performed 38 | * @param path the name of the file on which this operation was performed 39 | * @param the label indicating the name of the menu operation 40 | */ 41 | public MenuOperation(long time, String path, String label) { 42 | this(time, path, AbstractOperation.getUserName(), label); 43 | } 44 | 45 | /** 46 | * Returns the label indicating the name of the menu operation. 47 | * @return the label string 48 | */ 49 | public String getLabel() { 50 | return label; 51 | } 52 | 53 | /** 54 | * Returns the sort of this operation. 55 | * @return the string indicating the operation sort 56 | */ 57 | @Override 58 | public IOperation.Type getOperationType() { 59 | return IOperation.Type.MENU; 60 | } 61 | 62 | /** 63 | * Tests if this operation is the same as a given one. 64 | * @param op the given operation 65 | * @return true if the two operations are the same, otherwise false 66 | */ 67 | @Override 68 | public boolean equals(IOperation op) { 69 | if (!(op instanceof MenuOperation)) { 70 | return false; 71 | } 72 | 73 | MenuOperation mop = (MenuOperation)op; 74 | return super.equals(mop) && StringComparator.isSame(label, mop.getLabel()); 75 | } 76 | 77 | /** 78 | * Returns the string for printing, which does not contain a new line character at its end. 79 | * @return the string for printing 80 | */ 81 | @Override 82 | public String toString() { 83 | StringBuilder buf = new StringBuilder(); 84 | buf.append(Time.toUsefulFormat(time)); 85 | buf.append(" MENU "); 86 | buf.append(" label=[" + label + "]"); 87 | buf.append(" autor=[" + author + "]"); 88 | buf.append(" path=" + path); 89 | 90 | return buf.toString(); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /ChangeRecorder/src/org/jtool/changerecorder/operation/NullOperation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.changerecorder.operation; 8 | 9 | /** 10 | * Stores information on a null operation. 11 | * This operation does not usually appear. 12 | * @author Katsuhisa Maruyama 13 | */ 14 | public class NullOperation extends AbstractOperation { 15 | 16 | /** 17 | * The cache that stores the original operation. 18 | */ 19 | private IOperation originalOperation = null; 20 | 21 | /** 22 | * Creates an instance storing information on this null operation. 23 | */ 24 | public NullOperation() { 25 | super(-1, null, null); 26 | } 27 | 28 | /** 29 | * Creates an instance storing information on this null operation. 30 | * @param original the original operation to be stored 31 | */ 32 | public NullOperation(IOperation original) { 33 | super(-1, null, null); 34 | originalOperation = original; 35 | } 36 | 37 | /** 38 | * Returns the stored original operation 39 | * @return the original operation 40 | */ 41 | public IOperation getOriginalOperation() { 42 | return originalOperation; 43 | } 44 | 45 | /** 46 | * Returns the sort of this operation. 47 | * @return the string indicating the operation sort 48 | */ 49 | @Override 50 | public IOperation.Type getOperationType() { 51 | return IOperation.Type.NULL; 52 | } 53 | 54 | /** 55 | * Tests if this operation is the same as a given one. 56 | * @param op the given operation 57 | * @return always false 58 | */ 59 | @Override 60 | public boolean equals(IOperation op) { 61 | return false; 62 | } 63 | 64 | /** 65 | * Returns the string for printing, which does not contain a new line character at its end. 66 | * @return the string for printing 67 | */ 68 | @Override 69 | public String toString() { 70 | return "NULL"; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /ChangeRecorder/src/org/jtool/changerecorder/operation/ResourceOperation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.changerecorder.operation; 8 | 9 | import org.jtool.changerecorder.util.StringComparator; 10 | import org.jtool.changerecorder.util.Time; 11 | 12 | /** 13 | * Stores information on an operation related to the resource (project and package) changes. 14 | * @author Katsuhisa Maruyama 15 | */ 16 | public class ResourceOperation extends AbstractOperation { 17 | 18 | /** 19 | * Defines the type of a resource change. 20 | */ 21 | public enum Type { 22 | 23 | /** 24 | * The type of the resource change performed by this operation. 25 | */ 26 | ADDED, REMOVED, MOVED_FROM, MOVED_TO, RENAMED_FROM, RENAMED_TO, OTHERS; 27 | 28 | /** 29 | * Obtains the type of the resource change performed by this operation. 30 | * @param str the type string indicating the resource change 31 | * @return the type of the resource change 32 | */ 33 | public static ResourceOperation.Type parseType(String str) { 34 | if (StringComparator.isSameIgnoreCase(str, "added")) { 35 | return ADDED; 36 | } else if (StringComparator.isSameIgnoreCase(str, "removed")) { 37 | return REMOVED; 38 | } else if (StringComparator.isSameIgnoreCase(str, "moved_from")) { 39 | return MOVED_FROM; 40 | } else if (StringComparator.isSameIgnoreCase(str, "moved_to")) { 41 | return MOVED_TO; 42 | } else if (StringComparator.isSameIgnoreCase(str, "renamed_from")) { 43 | return RENAMED_FROM; 44 | } else if (StringComparator.isSameIgnoreCase(str, "renamed_to")) { 45 | return RENAMED_TO; 46 | } 47 | 48 | return OTHERS; 49 | } 50 | } 51 | 52 | /** 53 | * Defines the target of a resource change. 54 | */ 55 | public enum Target { 56 | 57 | /** 58 | * The target of the resource change performed by this operation. 59 | */ 60 | JPROJECT, JPACKAGE, JFILE, OTHERS; 61 | 62 | /** 63 | * Obtains the target of the resource change performed by this operation. 64 | * @param str the target string indicating the resource change 65 | * @return the target of the resource change 66 | */ 67 | public static ResourceOperation.Target parseType(String str) { 68 | if (StringComparator.isSameIgnoreCase(str, "jproject")) { 69 | return JPROJECT; 70 | } else if (StringComparator.isSameIgnoreCase(str, "jpackage")) { 71 | return JPACKAGE; 72 | } else if (StringComparator.isSameIgnoreCase(str, "jfile")) { 73 | return JFILE; 74 | } 75 | 76 | return OTHERS; 77 | } 78 | } 79 | 80 | /** 81 | * The type of the resource change performed by this operation. 82 | */ 83 | protected Type actionType; 84 | 85 | /** 86 | * The target of the resource change performed by this operation. 87 | */ 88 | protected Target target; 89 | 90 | /** 91 | * The path of a resource identical to the resource changed by this macro. 92 | */ 93 | private String ipath; 94 | 95 | /** 96 | * Creates an instance that stores an operation related to resource change. 97 | * @param time the time when the operation was performed 98 | * @param path the file related to the changed resource 99 | * @param author the author's name 100 | * @param atype the type of the resource change 101 | * @param target the target of the resource change 102 | * @param ipath the path of a resource identical to the changed resource 103 | */ 104 | public ResourceOperation(long time, String path, String author, Type atype, Target target, String ipath) { 105 | super(time, path, author); 106 | this.actionType = atype; 107 | this.target = target; 108 | this.ipath = ipath; 109 | } 110 | 111 | /** 112 | * Creates an instance that stores an operation related to resource change. 113 | * @param time the time when the operation was performed 114 | * @param path the file related to the changed resource, which is usually null 115 | * @param ctype the type of the resource change 116 | * @param target the target of the resource change 117 | * @param ipath the path of a resource identical to the changed resource 118 | */ 119 | public ResourceOperation(long time, String path, Type ctype, Target target, String ipath) { 120 | this(time, path, AbstractOperation.getUserName(), ctype, target, ipath); 121 | } 122 | 123 | /** 124 | * Returns the type of the resource change performed by this operation 125 | * @return the type of the resource change 126 | */ 127 | public Type getActionType() { 128 | return actionType; 129 | } 130 | 131 | /** 132 | * Returns the target of the resource change performed by this operation 133 | * @return the target of the resource change 134 | */ 135 | public Target getTarget() { 136 | return target; 137 | } 138 | 139 | /** 140 | * Returns the path of a resource moved/renamed from or to. 141 | * @return the path of the identical resource 142 | */ 143 | public String getIdenticalPath() { 144 | return ipath; 145 | } 146 | 147 | /** 148 | * Returns the sort of this operation. 149 | * @return the string indicating the operation sort 150 | */ 151 | @Override 152 | public IOperation.Type getOperationType() { 153 | return IOperation.Type.RESOURCE; 154 | } 155 | 156 | /** 157 | * Tests if this operation is the same as a given one. 158 | * @param op the given operation 159 | * @return true if the two operations are the same, otherwise false 160 | */ 161 | @Override 162 | public boolean equals(IOperation op) { 163 | if (!(op instanceof ResourceOperation)) { 164 | return false; 165 | } 166 | 167 | ResourceOperation rop = (ResourceOperation)op; 168 | return super.equals(rop) && 169 | actionType == rop.getActionType() && target == rop.getTarget() && 170 | StringComparator.isSame(ipath, rop.getIdenticalPath()); 171 | } 172 | 173 | /** 174 | * Obtains information on this operation. 175 | * @return the string storing the information on this operation 176 | */ 177 | @Override 178 | public String toString() { 179 | StringBuilder buf = new StringBuilder(); 180 | buf.append(Time.toUsefulFormat(time)); 181 | buf.append(" " + actionType.name()); 182 | buf.append(" author=[" + author + "]"); 183 | buf.append(" target=" + target.name()); 184 | buf.append(" path=" + path); 185 | buf.append(" ipath=" + ipath); 186 | 187 | return buf.toString(); 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /ChangeRecorder/src/org/jtool/changerecorder/operation/TextOperation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.changerecorder.operation; 8 | 9 | import org.jtool.changerecorder.util.StringComparator; 10 | 11 | /** 12 | * Stores information on a text operation. 13 | * @author Katsuhisa Maruyama 14 | */ 15 | public abstract class TextOperation extends AbstractOperation { 16 | 17 | /** 18 | * The leftmost offset of the text modified by this operation. 19 | */ 20 | protected int start; 21 | 22 | /** 23 | * The contents of the text inserted by this operation. 24 | */ 25 | protected String insertedText = ""; 26 | 27 | /** 28 | * The contents of the text deleted by this operation. 29 | */ 30 | protected String deletedText = ""; 31 | 32 | /** 33 | * Creates an instance storing information on this operation. 34 | * @param time the time when this operation was performed 35 | * @param seq the sequence number of this operation 36 | * @param path the name of the file path on which this operation was performed 37 | * @param author the author's name 38 | * @param start the leftmost offset of the text modified by this operation 39 | * @param itext the contents of the text inserted by this operation 40 | * @param dtext the contents of the text deleted by this operation 41 | */ 42 | public TextOperation(long time, int seq, String path, String author, int start, String itext, String dtext) { 43 | super(time, seq, path, author); 44 | this.start = start; 45 | if (itext != null) { 46 | this.insertedText = itext; 47 | } 48 | if (dtext != null) { 49 | this.deletedText = dtext; 50 | } 51 | } 52 | 53 | /** 54 | * Creates an instance storing information on this operation. 55 | * @param time the time when this operation was performed 56 | * @param seq the sequence number of this operation 57 | * @param path the name of the file path on which this operation was performed 58 | * @param start the leftmost offset of the text modified by this operation 59 | * @param itext the contents of the text inserted by this operation 60 | * @param dtext the contents of the text deleted by this operation 61 | */ 62 | public TextOperation(long time, int seq, String path, int start, String itext, String dtext) { 63 | this(time, seq, path, AbstractOperation.getUserName(), start, itext, dtext); 64 | } 65 | 66 | /** 67 | * Creates an instance storing information on this editing operation. 68 | * This constructor is called when the instance is created from the undo history of Eclipse. 69 | * @param time the time when this operation was performed 70 | * @param path the name of the file path on which this operation was performed 71 | * @param author the author's name 72 | * @param start the leftmost offset of the text modified by this operation 73 | * @param itext the contents of the text inserted by this operation 74 | * @param dtext the contents of the text deleted by this operation 75 | */ 76 | public TextOperation(long time, String path, String author, int start, String itext, String dtext) { 77 | this(time, 0, path, author, start, itext, dtext); 78 | } 79 | 80 | /** 81 | * Creates an instance storing information on this editing operation. 82 | * This constructor is called when the instance is created from the undo history of Eclipse. 83 | * @param time the time when this operation was performed 84 | * @param path the name of the file path on which this operation was performed 85 | * @param start the leftmost offset of the text modified by this operation 86 | * @param itext the contents of the text inserted by this operation 87 | * @param dtext the contents of the text deleted by this operation 88 | */ 89 | public TextOperation(long time, String path, int start, String itext, String dtext) { 90 | this(time, path, AbstractOperation.getUserName(), start, itext, dtext); 91 | } 92 | 93 | /** 94 | * Returns the leftmost offset of the text modified by this operation. 95 | * @return the leftmost offset value of the modified text 96 | */ 97 | public int getStart() { 98 | return start; 99 | } 100 | 101 | /** 102 | * Returns the contents of the text inserted by this operation. 103 | * @return the contents of the inserted text, or the empty string 104 | */ 105 | public String getInsertedText() { 106 | return insertedText; 107 | } 108 | 109 | /** 110 | * Sets the contents of the text inserted by this operation. 111 | * @param text the contents of the inserted text 112 | */ 113 | public void setInsertedText(String text) { 114 | insertedText = text; 115 | } 116 | 117 | /** 118 | * Returns the content of the text deleted by this operation. 119 | * @return the contents of the deleted text, or the empty string 120 | */ 121 | public String getDeletedText() { 122 | return deletedText; 123 | } 124 | 125 | /** 126 | * Sets the contents of the text deleted by this operation. 127 | * @param text the contents of the deleted text 128 | */ 129 | public void setDeletedText(String text) { 130 | deletedText = text; 131 | } 132 | 133 | /** 134 | * Tests if this operation did not any change of the text. 135 | * @return true if both the inserted and deleted texts are empty, otherwise false 136 | */ 137 | public boolean isEmpty() { 138 | return insertedText.length() == 0 && deletedText.length() == 0; 139 | } 140 | 141 | /** 142 | * Tests if this operation inserted any text. 143 | * @return true if the inserted text is not empty but the deleted text is empty, otherwise false 144 | */ 145 | public boolean isInsertion() { 146 | return insertedText.length() != 0 && deletedText.length() == 0; 147 | } 148 | 149 | /** 150 | * Tests if this operation inserted any text. 151 | * @return true if the deleted text is not empty but the inserted text is empty, otherwise false 152 | */ 153 | public boolean isDeletion() { 154 | return insertedText.length() == 0 && deletedText.length() != 0; 155 | } 156 | 157 | /** 158 | * Tests if this operation inserted any text. 159 | * @return true if the inserted and deleted texts are not empty, otherwise false 160 | */ 161 | public boolean isReplace() { 162 | return insertedText.length() != 0 && deletedText.length() != 0; 163 | } 164 | 165 | /** 166 | * Tests if this operation is the same as a given one. 167 | * @param op the given operation 168 | * @return true if the two operations are the same, otherwise false 169 | */ 170 | @Override 171 | public boolean equals(IOperation op) { 172 | if (!(op instanceof TextOperation)) { 173 | return false; 174 | } 175 | 176 | TextOperation top = (TextOperation)op; 177 | return super.equals(top) && start == top.getStart() && 178 | StringComparator.isSame(insertedText, top.getInsertedText()) && 179 | StringComparator.isSame(deletedText, top.getDeletedText()); 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /ChangeRecorder/src/org/jtool/changerecorder/util/FileStream.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.changerecorder.util; 8 | 9 | import org.apache.commons.io.FileUtils; 10 | import java.io.File; 11 | import java.io.IOException; 12 | 13 | /** 14 | * Manages the file stream. 15 | * @author Katsuhisa Maruyama 16 | */ 17 | public class FileStream { 18 | 19 | /** 20 | * Reads and returns the contents of a file. 21 | * @param path the full path indicating the file to be read 22 | * @return the contents of the file 23 | */ 24 | public static String read(String path) { 25 | File file = new File(path); 26 | try { 27 | return FileUtils.readFileToString(file); 28 | } catch (IOException e) { 29 | System.err.println(e.getMessage()); 30 | } 31 | return ""; 32 | } 33 | 34 | /** 35 | * Writes the content into a file. 36 | * @param path the full path indicating the file which the contents are written into 37 | * @param contents the contents to be written 38 | */ 39 | public static void write(String path, String contents) { 40 | makeDir(path); 41 | 42 | File file = new File(path); 43 | try { 44 | FileUtils.writeStringToFile(file, contents); 45 | } catch (final IOException e) { 46 | System.err.println(e.getMessage()); 47 | } 48 | } 49 | 50 | /** 51 | * Creates a directory containing a file. 52 | * @param path the path name of the file 53 | */ 54 | public static void makeDir(String path) { 55 | try { 56 | FileUtils.forceMkdir(new File(path).getParentFile()); 57 | } catch (final IOException e) { 58 | System.err.println(e.getMessage()); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /ChangeRecorder/src/org/jtool/changerecorder/util/StringComparator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.changerecorder.util; 8 | 9 | /** 10 | * Compares two strings. 11 | * @author Katsuhisa Maruyama 12 | */ 13 | public class StringComparator { 14 | 15 | /** 16 | * Tests if two texts are the same. 17 | * @param text1 the first text to be compared to the second text 18 | * @param text2 the second text to be compare to the first text 19 | * @return true if both the texts are the same, otherwise false 20 | */ 21 | public static boolean isSame(String text1, String text2) { 22 | if (text1 == null && text2 == null) { 23 | return true; 24 | } 25 | 26 | if (text1 == null || text2 == null) { 27 | return false; 28 | } 29 | 30 | return text1.compareTo(text2) == 0; 31 | } 32 | 33 | /** 34 | * Tests if two texts are the same, ignoring case differences. 35 | * @param text1 the first text to be compared to the second text 36 | * @param text2 the second text to be compare to the first text 37 | * @return true if the texts are the same, otherwise false 38 | */ 39 | public static boolean isSameIgnoreCase(String text1, String text2) { 40 | if (text1 == null && text2 == null) { 41 | return true; 42 | } 43 | 44 | if (text1 == null || text2 == null) { 45 | return false; 46 | } 47 | 48 | return text1.compareToIgnoreCase(text2) == 0; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /ChangeRecorder/src/org/jtool/changerecorder/util/Time.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.changerecorder.util; 8 | 9 | import java.util.Calendar; 10 | 11 | /** 12 | * Manages and formats time information. 13 | * @author Katsuhisa Maruyama 14 | */ 15 | public class Time { 16 | 17 | /** 18 | * Obtains the current time. 19 | * @return the current time 20 | */ 21 | public static long getCurrentTime() { 22 | Calendar cal = Calendar.getInstance(); 23 | return cal.getTimeInMillis(); 24 | } 25 | 26 | /** 27 | * Obtains the formated time information. 28 | * @param time the time information 29 | * @return the formatted string of the time 30 | */ 31 | public static String toUsefulFormat(long time) { 32 | Calendar cal = Calendar.getInstance(); 33 | cal.setTimeInMillis(time); 34 | 35 | return String.format("%1$tY/%1$tm/%1$td %1$tT", cal); 36 | } 37 | 38 | /** 39 | * Obtains time from the string format. 40 | * @param str the string representing the time 41 | * @return the time 42 | */ 43 | public static long parseTime(String str) { 44 | str = str.trim(); 45 | str = str.replace('/', ' '); 46 | str = str.replace(':', ' '); 47 | String[] strs = str.split(" "); 48 | if (strs.length < 3 || 6 < strs.length) { 49 | return -1; 50 | } 51 | 52 | int year, month, day, hour, min, sec; 53 | try { 54 | year = Integer.parseInt(strs[0]); 55 | month = Integer.parseInt(strs[1]); 56 | day = Integer.parseInt(strs[2]); 57 | hour = Integer.parseInt(strs[3]); 58 | min = Integer.parseInt(strs[4]); 59 | sec = Integer.parseInt(strs[5]); 60 | } catch (Exception e) { 61 | return -1; 62 | } 63 | 64 | Calendar cal = Calendar.getInstance(); 65 | cal.set(year, month - 1, day, hour, min, sec); 66 | return cal.getTimeInMillis(); 67 | } 68 | 69 | /** 70 | * Obtains the year information. 71 | * @param time the time information 72 | * @return the year information 73 | */ 74 | public static int getYear(long time) { 75 | Calendar cal = Calendar.getInstance(); 76 | cal.setTimeInMillis(time); 77 | return cal.get(Calendar.YEAR); 78 | } 79 | 80 | /** 81 | * Obtains the month information. 82 | * @param time the time information 83 | * @return the month information 84 | */ 85 | public static int getMonth(long time) { 86 | Calendar cal = Calendar.getInstance(); 87 | cal.setTimeInMillis(time); 88 | return cal.get(Calendar.MONTH) + 1; 89 | } 90 | 91 | /** 92 | * Obtains the day information. 93 | * @param time the time information 94 | * @return the day information 95 | */ 96 | public static int getDay(long time) { 97 | Calendar cal = Calendar.getInstance(); 98 | cal.setTimeInMillis(time); 99 | return cal.get(Calendar.DAY_OF_MONTH); 100 | } 101 | 102 | /** 103 | * Obtains time information with the YYYYMMDD format. 104 | * @param time the time information 105 | * @return the formated string of the time 106 | */ 107 | public static String YYYYMMDD(long time) { 108 | return String.format("%04d%02d%02d", getYear(time), getMonth(time), getDay(time)); 109 | } 110 | 111 | /** 112 | * Tests if the time information is valid. 113 | * @param time the time information 114 | * @return true if the time information is valid, otherwise false 115 | */ 116 | public static boolean isValid(long time) { 117 | return 0 <= time && time <= Long.MAX_VALUE; 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /ChangeRecorder/src/org/jtool/changerecorder/util/Whoami.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Software Science and Technology Lab. 3 | * Department of Computer Science, Ritsumeikan University 4 | */ 5 | 6 | package org.jtool.changerecorder.util; 7 | 8 | import java.io.BufferedReader; 9 | import java.io.IOException; 10 | import java.io.InputStreamReader; 11 | 12 | /** 13 | * Obtains the name of a user editing source code. 14 | * @author Katsuhisa Maruyama 15 | */ 16 | public class Whoami { 17 | 18 | /** 19 | * The name of a command for obtaining developer's name. 20 | */ 21 | private static final String whoamiCmd = "whoami"; 22 | 23 | /** 24 | * The user name. 25 | */ 26 | private static String userName = null; 27 | 28 | /** 29 | * Obtains the user name by using the whoami command. 30 | * @return the user name 31 | */ 32 | public static String getUserName() { 33 | if (userName != null) { 34 | return userName; 35 | } 36 | 37 | userName = "Unknown"; 38 | 39 | BufferedReader reader = null; 40 | Process process = null; 41 | try { 42 | Runtime runtime = Runtime.getRuntime(); 43 | process = runtime.exec(whoamiCmd); 44 | reader = new BufferedReader(new InputStreamReader(process.getInputStream())); 45 | 46 | userName = reader.readLine(); 47 | if (userName.indexOf("\\") >= 0) { // for Windows format (host_name + "\" + user_name) 48 | userName = userName.substring(userName.indexOf("\\") + 1); 49 | } 50 | } catch (IOException e) { 51 | /* empty */ 52 | } finally { 53 | if (process != null) { 54 | process.destroy(); 55 | } 56 | if (reader != null) { 57 | try { 58 | reader.close(); 59 | } catch (IOException e) { 60 | /* empty */ 61 | } 62 | } 63 | } 64 | 65 | return userName; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /ChangeRecorder/src/org/jtool/changerecorder/util/XmlFileStream.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.changerecorder.util; 8 | 9 | import org.eclipse.core.resources.IFile; 10 | import org.eclipse.core.runtime.CoreException; 11 | import org.xml.sax.ErrorHandler; 12 | import org.xml.sax.SAXException; 13 | import org.xml.sax.SAXParseException; 14 | import org.w3c.dom.Document; 15 | import javax.xml.parsers.DocumentBuilder; 16 | import javax.xml.parsers.DocumentBuilderFactory; 17 | import javax.xml.transform.OutputKeys; 18 | import javax.xml.transform.Transformer; 19 | import javax.xml.transform.TransformerException; 20 | import javax.xml.transform.TransformerFactory; 21 | import javax.xml.transform.dom.DOMSource; 22 | import javax.xml.transform.stream.StreamResult; 23 | import java.io.File; 24 | import java.io.StringWriter; 25 | import java.nio.charset.Charset; 26 | 27 | /** 28 | * Manages the XML file stream. 29 | * @author Katsuhisa Maruyama 30 | */ 31 | public class XmlFileStream { 32 | 33 | /** 34 | * Reads and returns the DOM instance created from the contents of an XML file. 35 | * @param path the full path indicating the XML file to be read 36 | * @return the DOM instance 37 | */ 38 | public static Document read(final String path) { 39 | try { 40 | DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 41 | factory.setIgnoringElementContentWhitespace(true); 42 | DocumentBuilder builder = factory.newDocumentBuilder(); 43 | 44 | builder.setErrorHandler(new ErrorHandler() { 45 | 46 | public void error(SAXParseException e) throws SAXException { 47 | printException(path, e); 48 | } 49 | 50 | public void fatalError(SAXParseException e) throws SAXException { 51 | printException(path, e); 52 | } 53 | 54 | public void warning(SAXParseException e) throws SAXException { 55 | printException(path, e); 56 | } 57 | }); 58 | 59 | File file = new File(path); 60 | return builder.parse(file); 61 | 62 | } catch (Exception e) { 63 | System.err.println("DOM: Parse error occurred: " + e.getMessage() + "."); 64 | } 65 | return null; 66 | } 67 | 68 | /** 69 | * Prints errors during paring the contents of the XML file. 70 | * @param path the full path indicating the XML file to be read 71 | * @param e the occurred exception 72 | */ 73 | private static void printException(String path, SAXParseException e) { 74 | System.err.println("[FATAL]file:" + path + "line:" + e.getLineNumber() + ", " + 75 | "column:" + e.getColumnNumber() + ", " + e.getMessage()); 76 | } 77 | 78 | /** 79 | * 80 | * Writes the content of the DOM instance into an XML file. 81 | * @param doc the content of the DOM instance to be written 82 | * @param path the full path indicating the file which the contents are written into 83 | * @param file the input file 84 | */ 85 | public static void write(Document doc, String path, IFile file) { 86 | try { 87 | String encoding; 88 | if (file == null) { 89 | encoding = Charset.defaultCharset().name(); 90 | } else { 91 | encoding = file.getCharset(); 92 | } 93 | 94 | write(doc, path, encoding); 95 | } catch (CoreException e) { 96 | e.printStackTrace(); 97 | } 98 | } 99 | 100 | /** 101 | * 102 | * Writes the content of the DOM instance into an XML file. 103 | * @param doc the content of the DOM instance to be written 104 | * @param path the full path indicating the file which the contents are written into 105 | * @param the encoding of texts in the DOM instance 106 | */ 107 | public static void write(Document doc, String path, String encoding) { 108 | path.replace('/', File.separatorChar); 109 | 110 | try { 111 | TransformerFactory factory = TransformerFactory.newInstance(); 112 | Transformer transformer = factory.newTransformer(); 113 | transformer.setOutputProperty(OutputKeys.ENCODING, encoding); 114 | // transformer.setOutputProperty(OutputKeys.ENCODING, "Shift_JIS"); 115 | // transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); 116 | transformer.setOutputProperty(OutputKeys.INDENT, "yes"); 117 | DOMSource src = new DOMSource(doc); 118 | 119 | StringWriter writer = new StringWriter(); 120 | transformer.transform(src, new StreamResult(writer)); 121 | 122 | FileStream.write(path, writer.toString()); 123 | } catch (TransformerException e) { 124 | System.out.println("DOM: Write error occurred: " + e.getMessage() + "."); 125 | } 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Ziyang Liao 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MacroRecorder/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /MacroRecorder/.gitignore: -------------------------------------------------------------------------------- 1 | /bin 2 | -------------------------------------------------------------------------------- /MacroRecorder/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | MacroRecorder 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.pde.ManifestBuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.pde.SchemaBuilder 20 | 21 | 22 | 23 | 24 | 25 | org.eclipse.pde.PluginNature 26 | org.eclipse.jdt.core.javanature 27 | 28 | 29 | -------------------------------------------------------------------------------- /MacroRecorder/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 4 | org.eclipse.jdt.core.compiler.compliance=1.7 5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 7 | org.eclipse.jdt.core.compiler.source=1.7 8 | -------------------------------------------------------------------------------- /MacroRecorder/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Bundle-ManifestVersion: 2 3 | Bundle-Name: MacroRecorder 4 | Bundle-SymbolicName: MacroRecorder;singleton:=true 5 | Bundle-Version: 1.0.0.qualifier 6 | Bundle-Activator: org.jtool.macrorecorder.Activator 7 | Require-Bundle: org.eclipse.ui;bundle-version="3.106.0", 8 | org.eclipse.core.runtime;bundle-version="3.10.0", 9 | org.eclipse.core.resources;bundle-version="3.9.1", 10 | org.eclipse.ui.ide;bundle-version="3.10.1", 11 | org.eclipse.ui.editors;bundle-version="3.8.200", 12 | org.eclipse.jface.text;bundle-version="3.9.1", 13 | org.eclipse.jdt.ui;bundle-version="3.10.1", 14 | org.eclipse.jdt.core;bundle-version="3.10.0", 15 | org.eclipse.ltk.core.refactoring;bundle-version="3.6.101" 16 | Bundle-RequiredExecutionEnvironment: JavaSE-1.8 17 | Bundle-ActivationPolicy: lazy 18 | Export-Package: org.jtool.macrorecorder.macro, 19 | org.jtool.macrorecorder.recorder, 20 | org.jtool.macrorecorder.util 21 | -------------------------------------------------------------------------------- /MacroRecorder/build.properties: -------------------------------------------------------------------------------- 1 | source.. = src/ 2 | output.. = bin/ 3 | bin.includes = .,\ 4 | META-INF/ 5 | jre.compilation.profile = JavaSE-1.7 6 | 7 | -------------------------------------------------------------------------------- /MacroRecorder/src/org/jtool/macrorecorder/Activator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.macrorecorder; 8 | 9 | import org.eclipse.ui.plugin.AbstractUIPlugin; 10 | import org.osgi.framework.BundleContext; 11 | import org.eclipse.ui.IWorkbenchWindow; 12 | import org.eclipse.ui.PlatformUI; 13 | import org.jtool.macrorecorder.recorder.Recorder; 14 | 15 | /** 16 | * The activator class controls the plug-in life cycle. 17 | * @author Katsuhisa Maruyama 18 | */ 19 | public class Activator extends AbstractUIPlugin { 20 | 21 | /** 22 | * The plug-in ID. 23 | */ 24 | public static final String PLUGIN_ID = "MacroRecorder"; 25 | 26 | /** 27 | * The plug-in instance. 28 | */ 29 | private static Activator plugin; 30 | 31 | /** 32 | * Creates a plug-in instance. 33 | */ 34 | public Activator() { 35 | } 36 | 37 | /** 38 | * Performs actions when the plug-in is activated. 39 | * @param context the bundle context for this plug-in 40 | * @throws Exception if this plug-in did not start up properly 41 | */ 42 | @Override 43 | public void start(BundleContext context) throws Exception { 44 | super.start(context); 45 | plugin = this; 46 | 47 | Recorder.getInstance().start(); 48 | 49 | System.out.println(PLUGIN_ID + " activated."); 50 | } 51 | 52 | /** 53 | * Performs actions when when the plug-in is shut down. 54 | * @param context the bundle context for this plug-in 55 | * @throws Exception if this this plug-in fails to stop 56 | */ 57 | @Override 58 | public void stop(BundleContext context) throws Exception { 59 | Recorder.getInstance().stop(); 60 | 61 | super.stop(context); 62 | 63 | plugin = null; 64 | } 65 | 66 | /** 67 | * Returns the default plug-in instance. 68 | * @return the default plug-in instance 69 | */ 70 | public static Activator getPlugin() { 71 | return plugin; 72 | } 73 | 74 | /** 75 | * Obtains the workbench window. 76 | * @return the workbench window 77 | */ 78 | public static IWorkbenchWindow getWorkbenchWindow() { 79 | return PlatformUI.getWorkbench().getActiveWorkbenchWindow(); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /MacroRecorder/src/org/jtool/macrorecorder/internal/diff/CodeDelta.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.macrorecorder.internal.diff; 8 | 9 | /** 10 | * Manages the delta of code (the difference between two source files). 11 | * @author Katsuhisa Maruyama 12 | */ 13 | public class CodeDelta { 14 | 15 | /** 16 | * The type of code change operation. 17 | */ 18 | enum Type { 19 | DELETE, INSERT, NULL 20 | } 21 | 22 | /** 23 | * The offset value of the text that contains this code delta. 24 | */ 25 | private int offset; 26 | 27 | /** 28 | * The type of this code delta. 29 | */ 30 | private Type type; 31 | 32 | /** 33 | * The text of the code delta. 34 | */ 35 | private String text; 36 | 37 | /** 38 | * Creates an instance that stores information on change. 39 | * @param offset the offset value of the location where the change was applied 40 | * @param type the type of the change 41 | * @param text 42 | */ 43 | public CodeDelta(int offset, Type type, String text) { 44 | this.offset = offset; 45 | this.type = type; 46 | this.text = text; 47 | } 48 | 49 | /** 50 | * Returns the offset value of the text that indicates the start point of the change. 51 | * @return the offset value for the change 52 | */ 53 | int getOffset() { 54 | return offset; 55 | } 56 | 57 | /** 58 | * Returns the type of the change. 59 | * @return the code change type 60 | */ 61 | Type getType() { 62 | return type; 63 | } 64 | 65 | /** 66 | * Returns the text that was inserted or deleted by the change. 67 | * @return the changed text 68 | */ 69 | String getText() { 70 | return text; 71 | } 72 | 73 | /** 74 | * Returns the string for printing 75 | * @return the string information 76 | */ 77 | public String toString() { 78 | return "-- Delta [" + String.valueOf(offset) + "] "+ type + " (" + text + ")"; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /MacroRecorder/src/org/jtool/macrorecorder/internal/diff/DiffMacroGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.macrorecorder.internal.diff; 8 | 9 | import org.jtool.macrorecorder.internal.diff.diff_match_patch.Diff; 10 | import org.jtool.macrorecorder.internal.diff.diff_match_patch.Operation; 11 | import org.jtool.macrorecorder.macro.DiffMacro; 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | import java.util.LinkedList; 15 | import java.util.ListIterator; 16 | 17 | /** 18 | * Generates diff macros from differences between the contents of two the source files. 19 | * @author Katsuhisa Maruyama 20 | */ 21 | public class DiffMacroGenerator { 22 | 23 | /** 24 | * The cost of an empty edit operation in terms of edit characters. 25 | */ 26 | private static short editCost = 4; 27 | 28 | /** 29 | * Sets the edit costs for finding difference. 30 | * @param cost the edit cost to be set 31 | */ 32 | public static void setEditCost(short cost) { 33 | editCost = cost; 34 | } 35 | 36 | /** 37 | * Generates diff macros from the differences between two textual contents. 38 | * @param time the time when this operation was inserted 39 | * @param path the name of the file path on which this operation was performed 40 | * @param otext the old contents of the file 41 | * @param ntext the new contents of the file 42 | * @return the collection of the generated diff macros 43 | */ 44 | public static List generate(long time, String path, String otext, String ntext) { 45 | List macros = new ArrayList(); 46 | List deltas = findDiff(otext, ntext); 47 | 48 | int offsetGap = 0; 49 | for (int idx = 0; idx < deltas.size(); idx++) { 50 | CodeDelta delta = deltas.get(idx); 51 | 52 | String itext = ""; 53 | String dtext = ""; 54 | if (delta.getType() == CodeDelta.Type.DELETE) { 55 | dtext = delta.getText(); 56 | 57 | } else if (delta.getType() == CodeDelta.Type.INSERT) { 58 | itext = delta.getText(); 59 | } 60 | 61 | int start = delta.getOffset() + offsetGap; 62 | DiffMacro macro = new DiffMacro(time, "Diff", path, start, itext, dtext); 63 | offsetGap = offsetGap - dtext.length(); 64 | 65 | macros.add(macro); 66 | } 67 | 68 | return macros; 69 | } 70 | 71 | /** 72 | * Finds differences between the contents of two the source code files. 73 | * @param otext the contents of the source code file to be diffed 74 | * @param ntext the contents of the source code file to be diffed 75 | * @return the collection of the code deltas 76 | */ 77 | private static List findDiff(String otext, String ntext) { 78 | diff_match_patch dmp = new diff_match_patch(); 79 | dmp.Diff_EditCost = editCost; 80 | 81 | LinkedList diffs = dmp.diff_main(otext, ntext); 82 | dmp.diff_cleanupEfficiency(diffs); 83 | List deltas = getDeltas(diffs); 84 | 85 | return deltas; 86 | } 87 | 88 | /** 89 | * Obtains the deltas from a given difference information. 90 | * @param diffs the collection of difference information of the diff utility. 91 | * @return the collection of the code deltas 92 | */ 93 | private static List getDeltas(LinkedList diffs) { 94 | ArrayList deltas = new ArrayList(); 95 | int offset = 0; 96 | 97 | for (ListIterator pointer = diffs.listIterator(); pointer.hasNext(); ) { 98 | Diff diff = pointer.next(); 99 | 100 | if (diff.operation == Operation.INSERT) { 101 | deltas.add(new CodeDelta(offset, CodeDelta.Type.INSERT, diff.text)); 102 | 103 | } else if (diff.operation == Operation.DELETE) { 104 | deltas.add(new CodeDelta(offset, CodeDelta.Type.DELETE, diff.text)); 105 | } 106 | 107 | offset = offset + diff.text.length(); 108 | } 109 | 110 | return deltas; 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /MacroRecorder/src/org/jtool/macrorecorder/internal/recorder/CommandExecutionManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.macrorecorder.internal.recorder; 8 | 9 | import org.jtool.macrorecorder.macro.ExecutionMacro; 10 | import org.jtool.macrorecorder.macro.TriggerMacro; 11 | import org.eclipse.core.commands.ExecutionEvent; 12 | import org.eclipse.core.commands.ExecutionException; 13 | import org.eclipse.core.commands.IExecutionListener; 14 | import org.eclipse.core.commands.NotHandledException; 15 | import org.eclipse.core.commands.common.NotDefinedException; 16 | import org.eclipse.ui.commands.ICommandService; 17 | import org.eclipse.ui.PlatformUI; 18 | 19 | /** 20 | * Manages command events (menu etc.). 21 | * @author Katsuhisa Maruyama 22 | */ 23 | public class CommandExecutionManager implements IExecutionListener { 24 | 25 | /** 26 | * A recorder that records menu actions. 27 | */ 28 | private MenuMacroRecorder recorder; 29 | 30 | /** 31 | * Creates an object that records command execution events. 32 | * @param recorder a recorder that records menu actions 33 | */ 34 | public CommandExecutionManager(MenuMacroRecorder recorder) { 35 | this.recorder = recorder; 36 | } 37 | 38 | /** 39 | * Registers a command manager with the command service of the workbench. 40 | * @param cm the command manager 41 | */ 42 | public static void register(CommandExecutionManager cm) { 43 | ICommandService cs = (ICommandService)PlatformUI.getWorkbench().getService(ICommandService.class); 44 | if (cs != null) { 45 | cs.addExecutionListener(cm); 46 | } 47 | } 48 | 49 | /** 50 | * Unregisters a command manager with the command service of the workbench. 51 | * @param cm the command manager 52 | */ 53 | public static void unregister(CommandExecutionManager cm) { 54 | ICommandService cs = (ICommandService)PlatformUI.getWorkbench().getService(ICommandService.class); 55 | if (cs != null) { 56 | cs.removeExecutionListener(cm); 57 | } 58 | } 59 | 60 | /** 61 | * Receives a command that is about to execute. 62 | * @param commandId the identifier of the command that is about to execute 63 | * @param event the event that will be passed to the execute method 64 | */ 65 | @Override 66 | public void preExecute(String commandId, ExecutionEvent event) { 67 | long time = Time.getCurrentTime(); 68 | String path = recorder.getActiveInputFilePath(); 69 | 70 | ExecutionMacro macro = new ExecutionMacro(time, "Exec", path, commandId); 71 | recorder.recordExecutionMacro(macro); 72 | 73 | try { 74 | String id = event.getCommand().getCategory().getId(); 75 | if (id.endsWith("category.refactoring")) { 76 | recorder.setParentMacro(macro); 77 | 78 | TriggerMacro trigger = new TriggerMacro(time, "Refactoring", path, TriggerMacro.Kind.BEGIN); 79 | recorder.recordTriggerMacro(trigger); 80 | } 81 | } catch (NotDefinedException e) { 82 | e.printStackTrace(); 83 | } 84 | } 85 | 86 | /** 87 | * Receives a command that has failed to complete execution. 88 | * @param commandId the identifier of the command that has executed 89 | * @param returnValue the return value from the command; may be null. 90 | */ 91 | @Override 92 | public void postExecuteSuccess(String commandId, Object returnValue) { 93 | } 94 | 95 | /** 96 | * Receives a command with no handler. 97 | * @param commandId the identifier of command that is not handled 98 | * @param exception the exception that occurred 99 | */ 100 | @Override 101 | public void notHandled(String commandId, NotHandledException exception) { 102 | } 103 | 104 | /** 105 | * Receives a command that has completed execution successfully. 106 | * @param commandId the identifier of the command that has executed 107 | * @param returnValue the return value from the command 108 | */ 109 | @Override 110 | public void postExecuteFailure(String commandId, ExecutionException exception) { 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /MacroRecorder/src/org/jtool/macrorecorder/internal/recorder/DocMacroRecorderOffEdit.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.macrorecorder.internal.recorder; 8 | 9 | import org.jtool.macrorecorder.recorder.Recorder; 10 | import org.jtool.macrorecorder.util.EditorUtilities; 11 | import org.jtool.macrorecorder.macro.DocumentMacro; 12 | import org.jtool.macrorecorder.macro.ExecutionMacro; 13 | import org.jtool.macrorecorder.macro.TriggerMacro; 14 | import org.jtool.macrorecorder.macro.ResourceMacro; 15 | import org.eclipse.core.resources.IFile; 16 | import org.eclipse.jface.text.IDocument; 17 | 18 | /** 19 | * Records document macros related to a file. 20 | * @author Katsuhisa Maruyama 21 | */ 22 | public class DocMacroRecorderOffEdit extends DocMacroRecorder { 23 | 24 | /** 25 | * A file related to recorded macros. 26 | */ 27 | private IFile file; 28 | 29 | /** 30 | * The document of a file. 31 | */ 32 | private IDocument doc; 33 | 34 | /** 35 | * Creates an object that records document macros related to a file. 36 | * @param file the file 37 | * @param recorder a recorder that sends macro events 38 | */ 39 | public DocMacroRecorderOffEdit(IFile file, Recorder recorder) { 40 | super(EditorUtilities.getInputFilePath(file), recorder); 41 | 42 | this.file = file; 43 | this.doc = EditorUtilities.getDocument(file); 44 | } 45 | 46 | /** 47 | * Starts the recording of document macros. 48 | */ 49 | public void start() { 50 | if (file == null) { 51 | return; 52 | } 53 | 54 | DocumentManager.register(doc, null, documentManager); 55 | 56 | preCode = doc.get(); 57 | 58 | super.start(); 59 | } 60 | 61 | /** 62 | * Stops the recording of macros. 63 | */ 64 | public void stop() { 65 | if (file == null) { 66 | return; 67 | } 68 | 69 | DocumentManager.unregister(doc, null, documentManager); 70 | 71 | super.stop(); 72 | } 73 | 74 | /** 75 | * Records a document macro and its compressed macro. 76 | * @param macro the document macro 77 | */ 78 | protected void recordDocumentMacro(DocumentMacro macro) { 79 | super.recordDocumentMacro(macro); 80 | } 81 | 82 | /** 83 | * Records a command execution macro. 84 | * @param macro the command execution macro 85 | */ 86 | protected void recordExecutionMacro(ExecutionMacro macro) { 87 | super.recordExecutionMacro(macro); 88 | recordRawMacro(macro); 89 | } 90 | 91 | /** 92 | * Records a trigger macro. 93 | * @param macro the trigger macro 94 | */ 95 | protected void recordTriggerMacro(TriggerMacro macro) { 96 | super.recordTriggerMacro(macro); 97 | } 98 | 99 | /** 100 | * Records a resource change macro. 101 | * @param macro the resource change macro 102 | */ 103 | protected void recordResourceMacro(ResourceMacro macro) { 104 | super.recordResourceMacro(macro); 105 | } 106 | 107 | /** 108 | * Records a compressed macro into the operation history and its original one in . 109 | * @param macro a document macro 110 | */ 111 | protected void recordUndoRedoMacro(DocumentMacro macro) { 112 | super.recordUndoRedoMacro(macro); 113 | } 114 | 115 | /** 116 | * Obtains the current contents of a file under recording. 117 | * @return the contents of source code, or null if source code does not exist 118 | */ 119 | protected String getCurrentCode() { 120 | IDocument doc = EditorUtilities.getDocument(file); 121 | if (doc != null) { 122 | return doc.get(); 123 | } 124 | return null; 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /MacroRecorder/src/org/jtool/macrorecorder/internal/recorder/DocMacroRecorderOnEdit.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.macrorecorder.internal.recorder; 8 | 9 | import org.jtool.macrorecorder.recorder.MacroCompressor; 10 | import org.jtool.macrorecorder.recorder.Recorder; 11 | import org.jtool.macrorecorder.util.EditorUtilities; 12 | import org.jtool.macrorecorder.macro.DocumentMacro; 13 | import org.jtool.macrorecorder.macro.ExecutionMacro; 14 | import org.jtool.macrorecorder.macro.TriggerMacro; 15 | import org.jtool.macrorecorder.macro.ResourceMacro; 16 | import org.jtool.macrorecorder.macro.CopyMacro; 17 | import org.eclipse.swt.custom.StyledText; 18 | import org.eclipse.ui.IEditorPart; 19 | import org.eclipse.jface.text.IDocument; 20 | 21 | /** 22 | * Records document macros performed on the editor. 23 | * @author Katsuhisa Maruyama 24 | */ 25 | public class DocMacroRecorderOnEdit extends DocMacroRecorder { 26 | 27 | /** 28 | * An editor on which document macros are recorded. 29 | */ 30 | private IEditorPart editor; 31 | 32 | /** 33 | * The document of a file. 34 | */ 35 | private IDocument doc; 36 | 37 | /** 38 | * A compressor that compresses macros. 39 | */ 40 | private MacroCompressor compressor; 41 | 42 | /** 43 | * The styled text of an editor. 44 | */ 45 | private StyledText styledText; 46 | 47 | /** 48 | * Creates an object that records document macros performed on an editor. 49 | * @param editor the editor 50 | * @param recorder a recorder that sends macro events 51 | * @param compressor a compressor that compresses macros 52 | */ 53 | public DocMacroRecorderOnEdit(IEditorPart editor, Recorder recorder, MacroCompressor compressor) { 54 | super(EditorUtilities.getInputFilePath(editor), recorder); 55 | 56 | this.editor = editor; 57 | this.doc = EditorUtilities.getDocument(editor); 58 | this.compressor = compressor; 59 | this.styledText = EditorUtilities.getStyledText(editor); 60 | } 61 | 62 | /** 63 | * Starts the recording of document macros. 64 | */ 65 | public void start() { 66 | if (editor == null) { 67 | return; 68 | } 69 | 70 | DocumentManager.register(doc, styledText, documentManager); 71 | 72 | preCode = doc.get(); 73 | 74 | super.start(); 75 | } 76 | 77 | /** 78 | * Stops the recording of macros. 79 | */ 80 | public void stop() { 81 | if (editor == null) { 82 | return; 83 | } 84 | 85 | DocumentManager.unregister(doc, styledText, documentManager); 86 | 87 | super.stop(); 88 | } 89 | 90 | /** 91 | * Records a document macro and its compressed macro. 92 | * @param macro the document macro 93 | */ 94 | protected void recordDocumentMacro(DocumentMacro macro) { 95 | boolean isCutPaste = setCutPasteMacro(macro); 96 | recordRawMacro(macro); 97 | // System.out.println("MACRO = " + macro); 98 | 99 | if (isCutPaste) { 100 | dumpMacros(macro); 101 | return; 102 | } 103 | 104 | if (compressor.canCombine(macro)) { 105 | DocumentMacro newMacro = compressor.combine(lastDocumentMacro, macro); 106 | if (newMacro != null) { 107 | lastDocumentMacro = newMacro; 108 | } else { 109 | dumpLastDocumentMacro(); 110 | lastDocumentMacro = macro; 111 | } 112 | } else { 113 | dumpMacros(macro); 114 | } 115 | } 116 | 117 | /** 118 | * Tests if a macro indicates the cut or paste and sets its type according to its result. 119 | * @param macro a macro that might be a cut or paste one 120 | * @return true if a macro indicates the cut or paste, otherwise false 121 | */ 122 | boolean setCutPasteMacro(DocumentMacro macro) { 123 | if (lastRawMacro == null) { 124 | return false; 125 | } 126 | 127 | if (lastRawMacro instanceof ExecutionMacro) { 128 | ExecutionMacro emacro = (ExecutionMacro)lastRawMacro; 129 | if (emacro.getCommandId().compareTo("org.eclipse.ui.edit.cut") == 0) { 130 | macro.setType("Cut"); 131 | return true; 132 | } else if (emacro.getCommandId().compareTo("org.eclipse.ui.edit.paste") == 0) { 133 | macro.setType("Paste"); 134 | return true; 135 | } 136 | } 137 | return false; 138 | } 139 | 140 | /** 141 | * Records a command execution macro. 142 | * @param macro the command execution macro 143 | */ 144 | protected void recordExecutionMacro(ExecutionMacro macro) { 145 | super.recordExecutionMacro(macro); 146 | 147 | if (styledText == null) { 148 | return; 149 | } 150 | 151 | if (macro.getCommandId().compareTo("org.eclipse.ui.edit.copy") == 0 || 152 | macro.getCommandId().compareTo("org.eclipse.jdt.ui.edit.text.java.copy.qualified.name") == 0) { 153 | int offset = styledText.getSelectionRange().x; 154 | String text = styledText.getSelectionText(); 155 | 156 | long time = Time.getCurrentTime(); 157 | CopyMacro cmacro = new CopyMacro(time, "Copy", macro.getPath(), offset, text); 158 | 159 | recordRawMacro(cmacro); 160 | dumpMacros(cmacro); 161 | 162 | } else if (macro.getCommandId().compareTo("org.eclipse.ui.edit.delete") == 0) { 163 | macro.setType("Delete"); 164 | } 165 | } 166 | 167 | /** 168 | * Records a trigger macro. 169 | * @param macro the trigger macro 170 | */ 171 | protected void recordTriggerMacro(TriggerMacro macro) { 172 | super.recordTriggerMacro(macro); 173 | } 174 | 175 | /** 176 | * Records a resource change macro. 177 | * @param macro the resource change macro 178 | */ 179 | protected void recordResourceMacro(ResourceMacro macro) { 180 | super.recordResourceMacro(macro); 181 | } 182 | 183 | /** 184 | * Records a compressed macro into the operation history and its original one in . 185 | * @param macro a document macro 186 | */ 187 | protected void recordUndoRedoMacro(DocumentMacro macro) { 188 | super.recordUndoRedoMacro(macro); 189 | } 190 | 191 | /** 192 | * Obtains the current contents of a file under recording. 193 | * @return the contents of source code, or null if source code does not exist 194 | */ 195 | protected String getCurrentCode() { 196 | IDocument doc = EditorUtilities.getDocument(editor); 197 | if (doc != null) { 198 | return doc.get(); 199 | } 200 | return null; 201 | } 202 | } 203 | -------------------------------------------------------------------------------- /MacroRecorder/src/org/jtool/macrorecorder/internal/recorder/MenuMacroRecorder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.macrorecorder.internal.recorder; 8 | 9 | import org.jtool.macrorecorder.Activator; 10 | import org.jtool.macrorecorder.recorder.Recorder; 11 | import org.jtool.macrorecorder.util.EditorUtilities; 12 | import org.jtool.macrorecorder.macro.CompoundMacro; 13 | import org.jtool.macrorecorder.macro.Macro; 14 | import org.jtool.macrorecorder.macro.ExecutionMacro; 15 | import org.jtool.macrorecorder.macro.TriggerMacro; 16 | import org.jtool.macrorecorder.macro.ResourceMacro; 17 | import org.eclipse.ui.IWorkbenchWindow; 18 | import org.eclipse.jface.viewers.ISelection; 19 | import org.eclipse.jface.text.ITextSelection; 20 | 21 | import java.util.ArrayList; 22 | import java.util.List; 23 | 24 | /** 25 | * Records macros performed on the editor. 26 | * @author Katsuhisa Maruyama 27 | */ 28 | public class MenuMacroRecorder { 29 | 30 | /** 31 | * A recorder that sends all kinds of macro events. 32 | */ 33 | private Recorder recorder; 34 | 35 | /** 36 | * The collection of raw macros that were recorded. 37 | */ 38 | private List rawMacros = new ArrayList(); 39 | 40 | /** 41 | * A compound macro that contains macros. 42 | */ 43 | private CompoundMacro compoundMacro; 44 | 45 | /** 46 | * A manger that manages command execution events. 47 | */ 48 | private CommandExecutionManager commandManager; 49 | 50 | /** 51 | * A manger that manages refactoring execution events. 52 | */ 53 | private RefactoringExecutionManager refactoringManager; 54 | 55 | /** 56 | * A manager that records operations related to resource changes in the Java model. 57 | */ 58 | private ResourceChangedManager resourceChangeManager; 59 | 60 | /** 61 | * A parent macro on which the current recorded macro dangles 62 | */ 63 | private Macro parentMacro; 64 | 65 | /** 66 | * The single instance of this menu recorder 67 | */ 68 | private static MenuMacroRecorder instance = new MenuMacroRecorder(); 69 | 70 | /** 71 | * Creates an empty object. 72 | */ 73 | private MenuMacroRecorder() { 74 | commandManager = new CommandExecutionManager(this); 75 | refactoringManager = new RefactoringExecutionManager(this); 76 | resourceChangeManager = new ResourceChangedManager(this); 77 | } 78 | 79 | /** 80 | * Sets the recorder that sends all kinds of macro events. 81 | * @param recorder the recorder. 82 | */ 83 | public void setRecorder(Recorder recorder) { 84 | this.recorder = recorder; 85 | } 86 | 87 | /** 88 | * Returns the single instance of this menu recorder. 89 | * @return the single instance 90 | */ 91 | public static MenuMacroRecorder getInstance() { 92 | return instance; 93 | } 94 | 95 | /** 96 | * Starts the recording of menu actions. 97 | */ 98 | public void start() { 99 | CommandExecutionManager.register(commandManager); 100 | RefactoringExecutionManager.register(refactoringManager); 101 | ResourceChangedManager.register(resourceChangeManager); 102 | 103 | rawMacros.clear(); 104 | compoundMacro = null; 105 | parentMacro = null; 106 | } 107 | 108 | /** 109 | * Stops the recording of menu actions. 110 | */ 111 | public void stop() { 112 | CommandExecutionManager.unregister(commandManager); 113 | RefactoringExecutionManager.unregister(refactoringManager); 114 | ResourceChangedManager.unregister(resourceChangeManager); 115 | 116 | rawMacros.clear(); 117 | } 118 | 119 | /** 120 | * Sets a parent macro related to a file. 121 | * @param parent the parent macro, or null if no parent exists 122 | */ 123 | void setParentMacro(Macro parent) { 124 | parentMacro = parent; 125 | } 126 | 127 | /** 128 | * Returns the parent macro. 129 | * @return the parent macro 130 | */ 131 | Macro getParentMacro() { 132 | return parentMacro; 133 | } 134 | 135 | /** 136 | * Records a command execution macro. 137 | * @param macro the command execution macro 138 | */ 139 | protected void recordExecutionMacro(ExecutionMacro macro) { 140 | breakMacro(); 141 | 142 | String path = macro.getPath(); 143 | DocMacroRecorder docMacroRecorder = getDocMacroRecorder(path); 144 | if (docMacroRecorder != null) { 145 | docMacroRecorder.recordExecutionMacro(macro); 146 | 147 | } else { 148 | recordRawMacro(macro); 149 | recordMacro(macro); 150 | } 151 | } 152 | 153 | /** 154 | * Records a trigger macro. 155 | * @param macro the trigger macro 156 | */ 157 | protected void recordTriggerMacro(TriggerMacro macro) { 158 | breakMacro(); 159 | 160 | String path = macro.getPath(); 161 | DocMacroRecorder docMacroRecorder = getDocMacroRecorder(path); 162 | if (docMacroRecorder != null) { 163 | docMacroRecorder.recordTriggerMacro(macro); 164 | 165 | } else { 166 | recordRawMacro(macro); 167 | recordMacro(macro); 168 | } 169 | } 170 | 171 | /** 172 | * Records a resource change macro. 173 | * @param macro the resource change macro 174 | */ 175 | protected void recordResourceMacro(ResourceMacro macro) { 176 | breakMacro(); 177 | 178 | String path = macro.getPath(); 179 | DocMacroRecorder docMacroRecorder = getDocMacroRecorder(path); 180 | 181 | if (docMacroRecorder != null) { 182 | macro.setOnEdit(true); 183 | docMacroRecorder.recordResourceMacro(macro); 184 | 185 | } else { 186 | macro.setOnEdit(false); 187 | recordRawMacro(macro); 188 | recordMacro(macro); 189 | } 190 | } 191 | 192 | /** 193 | * Records a raw macro. 194 | * @param macro the raw macro to be recored 195 | */ 196 | private void recordRawMacro(Macro macro) { 197 | rawMacros.add(macro); 198 | recorder.notifyRawMacro(macro); 199 | } 200 | 201 | /** 202 | * Records a macro. 203 | * @param macro the macro to be recorded 204 | */ 205 | private void recordMacro(Macro macro) { 206 | if (macro instanceof TriggerMacro) { 207 | TriggerMacro tmacro = (TriggerMacro)macro; 208 | if (compoundMacro == null && tmacro.isBegin()) { 209 | compoundMacro = new CompoundMacro(tmacro.getStartTime(), tmacro.getType(), macro.getPath()); 210 | 211 | } else if (tmacro.isEnd() || tmacro.isCursorChange()) { 212 | if (compoundMacro != null) { 213 | compoundMacro.setRawMacros(new ArrayList(rawMacros)); 214 | compoundMacro.setTimes(); 215 | rawMacros.clear(); 216 | 217 | recorder.notifyMacro(compoundMacro); 218 | } 219 | compoundMacro = null; 220 | } 221 | 222 | } else { 223 | if (compoundMacro != null) { 224 | compoundMacro.addMacro(macro); 225 | } else { 226 | macro.setRawMacros(new ArrayList(rawMacros)); 227 | rawMacros.clear(); 228 | 229 | recorder.notifyMacro(macro); 230 | } 231 | } 232 | } 233 | 234 | /** 235 | * Returns the a recorder that records macros related to a file 236 | * @param path the path of the file 237 | * @return the recorder 238 | */ 239 | protected DocMacroRecorder getDocMacroRecorder(String path) { 240 | if (path == null) { 241 | return null; 242 | } 243 | 244 | return Recorder.getDocRecorder(path); 245 | } 246 | 247 | /** 248 | * Break the current macro. 249 | */ 250 | public void breakMacro() { 251 | for (DocMacroRecorder docRecorder : Recorder.getDocRecorders()) { 252 | docRecorder.dumpLastDocumentMacro(); 253 | docRecorder.needDiff(); 254 | } 255 | } 256 | 257 | /** 258 | * Obtains the path of a active file existing on an editor. 259 | * @return @return the path of the file, or null if none 260 | */ 261 | protected String getActiveInputFilePath() { 262 | IWorkbenchWindow window = Activator.getPlugin().getWorkbench().getActiveWorkbenchWindow(); 263 | if (window != null) { 264 | ISelection selection = window.getSelectionService().getSelection(); 265 | if (selection instanceof ITextSelection) { 266 | return EditorUtilities.getActiveInputFilePath(); 267 | } 268 | } 269 | return null; 270 | } 271 | } 272 | -------------------------------------------------------------------------------- /MacroRecorder/src/org/jtool/macrorecorder/internal/recorder/RefactoringExecutionManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.macrorecorder.internal.recorder; 8 | 9 | import org.jtool.macrorecorder.macro.Macro; 10 | import org.jtool.macrorecorder.macro.TriggerMacro; 11 | import org.eclipse.ltk.core.refactoring.RefactoringCore; 12 | import org.eclipse.ltk.core.refactoring.history.IRefactoringExecutionListener; 13 | import org.eclipse.ltk.core.refactoring.history.RefactoringExecutionEvent; 14 | import org.eclipse.ltk.core.refactoring.history.IRefactoringHistoryListener; 15 | import org.eclipse.ltk.core.refactoring.history.RefactoringHistoryEvent; 16 | import org.eclipse.ltk.core.refactoring.history.IRefactoringHistoryService; 17 | 18 | /** 19 | * Manages refactoring events. 20 | * @author Katsuhisa Maruyama 21 | */ 22 | public class RefactoringExecutionManager implements IRefactoringExecutionListener, IRefactoringHistoryListener { 23 | 24 | /** 25 | * A recorder that records menu actions. 26 | */ 27 | private MenuMacroRecorder recorder; 28 | 29 | /** 30 | * Creates an object that records refectoring execution events. 31 | * @param recorder a recorder that records menu actions 32 | */ 33 | public RefactoringExecutionManager(MenuMacroRecorder recorder) { 34 | this.recorder = recorder; 35 | } 36 | 37 | /** 38 | * Registers a refactoring execution manager with the refactoring history service. 39 | * @param rm the refactoring execution manager 40 | */ 41 | public static void register(RefactoringExecutionManager rm) { 42 | IRefactoringHistoryService rs = RefactoringCore.getHistoryService(); 43 | if (rs != null) { 44 | rs.addExecutionListener(rm); 45 | // rs.addHistoryListener(rm); 46 | } 47 | } 48 | 49 | /** 50 | * Unregisters a refactoring execution manager with the refactoring history service. 51 | * @param rm the refactoring execution manager 52 | */ 53 | public static void unregister(RefactoringExecutionManager rm) { 54 | IRefactoringHistoryService rs = RefactoringCore.getHistoryService(); 55 | if (rs != null) { 56 | rs.removeExecutionListener(rm); 57 | // rs.removeHistoryListener(rm); 58 | } 59 | } 60 | 61 | /** 62 | * Receives an event when a refactoring execution event happened. 63 | * @param event the refactoring execution event 64 | */ 65 | @Override 66 | public void executionNotification(RefactoringExecutionEvent event) { 67 | long time = Time.getCurrentTime(); 68 | Macro macro = recorder.getParentMacro(); 69 | String path = null; 70 | if (macro != null) { 71 | path = macro.getPath(); 72 | } 73 | 74 | String commandId = event.getDescriptor().getDescription(); 75 | if (event.getEventType() == RefactoringExecutionEvent.ABOUT_TO_PERFORM) { 76 | TriggerMacro trigger = new TriggerMacro(time, commandId, path, TriggerMacro.Kind.BEGIN); 77 | recorder.recordTriggerMacro(trigger); 78 | 79 | } else if (event.getEventType() == RefactoringExecutionEvent.PERFORMED) { 80 | TriggerMacro trigger = new TriggerMacro(time, commandId, path, TriggerMacro.Kind.END); 81 | path = null; 82 | recorder.recordTriggerMacro(trigger); 83 | 84 | recorder.setParentMacro(null); 85 | } 86 | } 87 | 88 | /** 89 | * Receives an event when a refactoring history event happened. 90 | * @param event the refactoring history event 91 | */ 92 | @Override 93 | public void historyNotification(RefactoringHistoryEvent event) { 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /MacroRecorder/src/org/jtool/macrorecorder/internal/recorder/ResourceChangedManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.macrorecorder.internal.recorder; 8 | 9 | import org.eclipse.jdt.core.IElementChangedListener; 10 | import org.eclipse.jdt.core.ElementChangedEvent; 11 | import org.eclipse.jdt.core.IJavaElementDelta; 12 | import org.eclipse.jdt.core.IJavaElement; 13 | import org.eclipse.jdt.core.JavaCore; 14 | import org.jtool.macrorecorder.macro.ResourceMacro; 15 | import java.util.List; 16 | import java.util.ArrayList; 17 | 18 | /** 19 | * Manages operations related to element changes. 20 | * @author Katsuhisa Maruyama 21 | */ 22 | public class ResourceChangedManager implements IElementChangedListener { 23 | 24 | /** 25 | * A recorder that records menu actions. 26 | */ 27 | private MenuMacroRecorder recorder; 28 | 29 | /** 30 | * Creates an object that records resource change events. 31 | * @param recorder a recorder that records menu actions 32 | */ 33 | public ResourceChangedManager(MenuMacroRecorder recorder) { 34 | this.recorder = recorder; 35 | } 36 | 37 | /** 38 | * Registers an element change manager with the Java model. 39 | * @param em the element change manager 40 | */ 41 | public static void register(ResourceChangedManager em) { 42 | JavaCore.addElementChangedListener(em); 43 | } 44 | 45 | /** 46 | * Unregisters an element change manager with the Java model. 47 | * @param em the element change manager 48 | */ 49 | public static void unregister(ResourceChangedManager em) { 50 | JavaCore.removeElementChangedListener(em); 51 | } 52 | 53 | /** 54 | * Receives an event when one or more Java elements have changed. 55 | * @param event the change event 56 | */ 57 | @Override 58 | public void elementChanged(ElementChangedEvent event) { 59 | long time = Time.getCurrentTime(); 60 | ChangeCollector collector = new ChangeCollector(event.getDelta()); 61 | 62 | for (IJavaElementDelta delta : collector.deltas) { 63 | if (delta.getKind() == IJavaElementDelta.REMOVED) { 64 | ResourceMacro macro = createResourceRemovedMacro(time, delta); 65 | if (macro != null) { 66 | recorder.recordResourceMacro(macro); 67 | } 68 | } 69 | } 70 | 71 | for (IJavaElementDelta delta : collector.deltas) { 72 | if (delta.getKind() == IJavaElementDelta.ADDED) { 73 | ResourceMacro macro = createResourceAddedMacro(time, delta); 74 | if (macro != null) { 75 | recorder.recordResourceMacro(macro); 76 | } 77 | } 78 | } 79 | 80 | for (IJavaElementDelta delta : collector.deltas) { 81 | if (delta.getKind() == IJavaElementDelta.CHANGED) { 82 | ResourceMacro macro = createResourceChangedMacro(time, delta); 83 | if (macro != null) { 84 | recorder.recordResourceMacro(macro); 85 | } 86 | } 87 | } 88 | } 89 | 90 | /** 91 | * Creates a macro corresponding to the removed delta of the change. 92 | * @param time the time when the change occurred 93 | * @param delta the removed delta of the change 94 | * @return the created resource macro 95 | */ 96 | private ResourceMacro createResourceRemovedMacro(long time, IJavaElementDelta delta) { 97 | IJavaElement elem = delta.getElement(); 98 | String path = elem.getPath().toString(); 99 | if (path == null) { 100 | return null; 101 | } 102 | 103 | String type = "Removed"; 104 | if ((delta.getFlags() & IJavaElementDelta.F_MOVED_TO) != 0) { 105 | if (isRenamed(delta.getElement(), delta.getMovedToElement())) { 106 | type = "RenamedTo"; 107 | } else { 108 | type = "MovedTo"; 109 | } 110 | } 111 | 112 | return new ResourceMacro(time, type, path, elem); 113 | } 114 | 115 | /** 116 | * Creates a macro corresponding to the added delta of the change. 117 | * @param time the time when the change occurred 118 | * @param delta the added delta of the change 119 | * @return the created resource macro 120 | */ 121 | private ResourceMacro createResourceAddedMacro(long time, IJavaElementDelta delta) { 122 | IJavaElement elem = delta.getElement(); 123 | String path = elem.getPath().toString(); 124 | if (path == null) { 125 | return null; 126 | } 127 | 128 | String type = "Added"; 129 | if ((delta.getFlags() & IJavaElementDelta.F_MOVED_FROM) != 0) { 130 | if (isRenamed(delta.getElement(), delta.getMovedFromElement())) { 131 | type = "RenamedFrom"; 132 | } else { 133 | type = "MovedFrom"; 134 | } 135 | } 136 | 137 | return new ResourceMacro(time, type, path, elem); 138 | } 139 | 140 | /** 141 | * Creates a macro corresponding to the changed delta of the change. 142 | * @param time the time when the change occurred 143 | * @param delta the changed delta of the change 144 | * @return the created resource macro 145 | */ 146 | private ResourceMacro createResourceChangedMacro(long time, IJavaElementDelta delta) { 147 | IJavaElement elem = delta.getElement(); 148 | String path = elem.getPath().toString(); 149 | if (path == null) { 150 | return null; 151 | } 152 | 153 | if ((delta.getFlags() & IJavaElementDelta.F_CONTENT) != 0) { 154 | // System.out.println("CONTENT CHANGED" + path); 155 | return null; 156 | } 157 | 158 | return new ResourceMacro(time, "Changed", path, elem); 159 | } 160 | 161 | /** 162 | * Tests if the element was renamed by the change. 163 | * @param before the element before the change 164 | * @param after the element after the change 165 | * @return true if renaming was applied, otherwise false 166 | */ 167 | private boolean isRenamed(IJavaElement before, IJavaElement after) { 168 | if (before == null || after == null) { 169 | return true; 170 | } 171 | 172 | String beforen = ResourceMacro.getName(before); 173 | String aftern = ResourceMacro.getName(after); 174 | if (beforen.compareTo(aftern) != 0) { 175 | return true; 176 | } 177 | return false; 178 | } 179 | 180 | /** 181 | * Collects change deltas. 182 | */ 183 | class ChangeCollector { 184 | 185 | /** 186 | * The collection of change deltas 187 | */ 188 | List deltas = new ArrayList(); 189 | 190 | /** 191 | * Creates an object that collects the deltas of element changes. 192 | * @param delta the root delta of the change 193 | */ 194 | ChangeCollector(IJavaElementDelta delta) { 195 | collectDeltas(delta); 196 | } 197 | 198 | /** 199 | * Collects all the deltas of the changes. 200 | * @param delta the root delta of the change 201 | * @param deltas the collection of the deltas to be collected 202 | */ 203 | private void collectDeltas(IJavaElementDelta delta) { 204 | if (delta.getKind() == IJavaElementDelta.ADDED || 205 | delta.getKind() == IJavaElementDelta.REMOVED) { 206 | if (!contain(delta)) { 207 | deltas.add(delta); 208 | } 209 | } else if (delta.getKind() == IJavaElementDelta.CHANGED && 210 | ((delta.getFlags() & IJavaElementDelta.F_CONTENT) != 0)) { 211 | if (!contain(delta)) { 212 | deltas.add(delta); 213 | } 214 | } 215 | 216 | for (IJavaElementDelta d : delta.getAffectedChildren()) { 217 | collectDeltas(d); 218 | } 219 | } 220 | 221 | /** 222 | * Tests if a given change delta was already contained in the change collection. 223 | * @param delta the change delta 224 | * @return true if the change delta was contained in the change collection, otherwise false 225 | */ 226 | private boolean contain(IJavaElementDelta delta) { 227 | String path = delta.getElement().getPath().toString(); 228 | for (IJavaElementDelta d : deltas) { 229 | String p = d.getElement().getPath().toString(); 230 | if (p.compareTo(path) == 0 && d.getKind() == delta.getKind()) { 231 | return true; 232 | } 233 | } 234 | return false; 235 | } 236 | } 237 | } 238 | -------------------------------------------------------------------------------- /MacroRecorder/src/org/jtool/macrorecorder/internal/recorder/Time.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.macrorecorder.internal.recorder; 8 | 9 | import java.util.Calendar; 10 | 11 | /** 12 | * Obtains time information. 13 | * @author Katsuhisa Maruyama 14 | */ 15 | class Time { 16 | 17 | /** 18 | * Obtains the current time. 19 | * @return the current time 20 | */ 21 | static long getCurrentTime() { 22 | Calendar cal = Calendar.getInstance(); 23 | return cal.getTimeInMillis(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /MacroRecorder/src/org/jtool/macrorecorder/macro/CancelMacro.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.macrorecorder.macro; 8 | 9 | /** 10 | * Stores a cancel macro that cancels another macro. 11 | * @author Katsuhisa Maruyama 12 | */ 13 | public class CancelMacro extends DocumentMacro { 14 | 15 | /** 16 | * Creates an object storing information on a cancel macro. 17 | * @param time the time when the macro started and ended 18 | * @param type the type of the macro 19 | * @param path the path of a file or a package this macro was performed 20 | * @param start the leftmost offset of the document changed by this macro 21 | * @param itext the contents of the document inserted by the macro 22 | * @param dtext the contents of the document deleted by the macro 23 | */ 24 | public CancelMacro(long time, String type, String path, int start, String itext, String dtext) { 25 | super(time, time, type, path, start, itext, dtext); 26 | } 27 | 28 | /** 29 | * Returns the string for printing, which does not contain a new line character at its end. 30 | * @return the string for printing 31 | */ 32 | public String toString() { 33 | return "CANCEL = " + getStartTime() + "-" + getEndTime() + ": " + 34 | getPath() + " " + getStart() + " " + "[" + getInsertedText() + "][" + getDeletedText() + "]"; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /MacroRecorder/src/org/jtool/macrorecorder/macro/CompoundMacro.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.macrorecorder.macro; 8 | 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | /** 13 | * Stores a compound macro that contains macros. 14 | * @author Katsuhisa Maruyama 15 | */ 16 | public class CompoundMacro extends Macro { 17 | 18 | /** 19 | * The collection of macros contained in this compound macro. 20 | */ 21 | private List macros = new ArrayList(); 22 | 23 | /** 24 | * Creates an object storing information on a compound macro. 25 | * @param stime the time when the macro started 26 | * @param the type of the macro 27 | * @param path the path of a file or a package this macro was performed 28 | */ 29 | public CompoundMacro(long stime, String type, String path) { 30 | super(stime, stime, type, path); 31 | } 32 | 33 | /** 34 | * Adds a macro into this compound macro. 35 | * @param macro the macro to be added 36 | */ 37 | public void addMacro(Macro macro) { 38 | macros.add(macro); 39 | } 40 | 41 | /** 42 | * Removes a macro from this compound macro. 43 | * @param the index number of the macro to be removed 44 | */ 45 | public void removeMacro(int index) { 46 | macros.remove(index); 47 | } 48 | 49 | /** 50 | * Removes a macro that will be canceled by a given macro. 51 | * @param macro the macro that cancels the macro stored in this compound macro 52 | * @return true if the cancellation succeeded, otherwise false 53 | */ 54 | public boolean cancelMacro(DocumentMacro macro) { 55 | int index = getIndexOfCorrespondingMacro(macro); 56 | if (index < 0) { 57 | return false; 58 | } 59 | 60 | macros.remove(index); 61 | return true; 62 | } 63 | 64 | /** 65 | * Returns the collection of macros contained in this compound macro. 66 | * @return the the collection of the contained macros 67 | */ 68 | public List getMacros() { 69 | return macros; 70 | } 71 | 72 | /** 73 | * Sets the starting and ending times. 74 | */ 75 | public void setTimes() { 76 | for (Macro m : macros) { 77 | if (m.getStartTime() < startTime) { 78 | startTime = m.getStartTime(); 79 | } 80 | if (m.getEndTime() > endTime) { 81 | endTime = m.getEndTime(); 82 | } 83 | } 84 | } 85 | 86 | /** 87 | * Obtains the index number of the macro corresponding to a given macro. 88 | * @param macro the given macro 89 | * @return the index number of the corresponding macro 90 | */ 91 | private int getIndexOfCorrespondingMacro(DocumentMacro macro) { 92 | for (int i = 0; i < macros.size(); i++) { 93 | Macro m = macros.get(i); 94 | if (m instanceof DocumentMacro) { 95 | DocumentMacro dm = (DocumentMacro)m; 96 | if (dm.getStart() == macro.getStart() && 97 | dm.getInsertedText().compareTo(macro.getDeletedText()) == 0 && 98 | dm.getDeletedText().compareTo(macro.getInsertedText()) == 0) { 99 | return i; 100 | } 101 | } 102 | } 103 | return -1; 104 | } 105 | 106 | /** 107 | * Returns the string for printing, which does not contain a new line character at its end. 108 | * @return the string for printing 109 | */ 110 | public String toString() { 111 | return "COMP(" + getType() + ") = " + getPath() + " " + 112 | getStartTime() + "-" + getEndTime(); 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /MacroRecorder/src/org/jtool/macrorecorder/macro/CopyMacro.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.macrorecorder.macro; 8 | 9 | /** 10 | * Stores a macro occurring copy. 11 | * @author Katsuhisa Maruyama 12 | */ 13 | public class CopyMacro extends Macro { 14 | 15 | /** 16 | * The leftmost offset of the document copied by this macro. 17 | */ 18 | private int start; 19 | 20 | /** 21 | * The contents of the document copied by this macro. 22 | */ 23 | private String copiedText; 24 | 25 | /** 26 | * Creates an object storing information on a copy macro. 27 | * @param time the time when the macro started and ended 28 | * @param type the type of the macro 29 | * @param path the path of a file or a package this macro was performed 30 | * @param start the leftmost offset of the document changed by this macro 31 | * @param text the contents of the document copied by the macro 32 | */ 33 | public CopyMacro(long time, String type, String path, int start, String text) { 34 | super(time, time, type, path); 35 | this.start = start; 36 | this.copiedText = text; 37 | } 38 | 39 | /** 40 | * Returns the leftmost offset of the document changed by this macro. 41 | * @return the leftmost offset of the document 42 | */ 43 | public int getStart() { 44 | return start; 45 | } 46 | 47 | /** 48 | * Returns the contents of the document copied by this macro. 49 | * @return the copied contents of the document 50 | */ 51 | public String getCopiedText() { 52 | return copiedText; 53 | } 54 | 55 | /** 56 | * Returns the string for printing, which does not contain a new line character at its end. 57 | * @return the string for printing 58 | */ 59 | public String toString() { 60 | return "COPY = " + getStartTime() + "-" + getEndTime() + ": " + 61 | getPath() + " " + getStart() + " " + "[" + getCopiedText() + "]"; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /MacroRecorder/src/org/jtool/macrorecorder/macro/DiffMacro.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.macrorecorder.macro; 8 | 9 | /** 10 | * Stores a macro that represents difference between two versions of source code. 11 | * @author Katsuhisa Maruyama 12 | */ 13 | public class DiffMacro extends DocumentMacro { 14 | 15 | /** 16 | * Creates an object storing information on a difference macro. 17 | * @param time the time when the macro started and ended 18 | * @param type the type of the macro 19 | * @param path the path of a file or a package this macro was performed 20 | * @param start the leftmost offset of the document changed by this macro 21 | * @param itext the contents of the document inserted by the macro 22 | * @param dtext the contents of the document deleted by the macro 23 | */ 24 | public DiffMacro(long time, String type, String path, int start, String itext, String dtext) { 25 | super(time, time, type, path, start, itext, dtext); 26 | } 27 | 28 | /** 29 | * Returns the string for printing, which does not contain a new line character at its end. 30 | * @return the string for printing 31 | */ 32 | public String toString() { 33 | return "DIFF = " + getStartTime() + "-" + getEndTime() + ": " + 34 | getPath() + " " + getStart() + " " + "[" + getInsertedText() + "][" + getDeletedText() + "]"; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /MacroRecorder/src/org/jtool/macrorecorder/macro/DocumentMacro.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.macrorecorder.macro; 8 | 9 | /** 10 | * Stores a macro occurring a document change. 11 | * @author Katsuhisa Maruyama 12 | */ 13 | public class DocumentMacro extends Macro { 14 | 15 | /** 16 | * The leftmost offset of the document changed by this macro. 17 | */ 18 | private int start; 19 | 20 | /** 21 | * The contents of the document inserted by this macro. 22 | */ 23 | private String insertedText; 24 | 25 | /** 26 | * The contents of the document deleted by this macro. 27 | */ 28 | private String deletedText; 29 | 30 | /** 31 | * Creates an object storing information on a document macro. 32 | * @param stime the time when the macro started 33 | * @param etime the time when the macro ended 34 | * @param type the type of the macro 35 | * @param path the path of a file or a package this macro was performed 36 | * @param start the leftmost offset of the document changed by this macro 37 | * @param itext the contents of the document inserted by the macro 38 | * @param dtext the contents of the document deleted by the macro 39 | */ 40 | public DocumentMacro(long stime, long etime, String type, String path, int start, String itext, String dtext) { 41 | super(stime, etime, type, path); 42 | this.start = start; 43 | this.insertedText = itext; 44 | this.deletedText = dtext; 45 | } 46 | 47 | /** 48 | * Creates an object storing information on a document macro. 49 | * @param time the time when the macro started and ended 50 | * @param type the type of the macro 51 | * @param path the path of a file or a package this macro was performed 52 | * @param start the leftmost offset of the document changed by this macro 53 | * @param itext the contents of the document inserted by the macro 54 | * @param dtext the contents of the document deleted by the macro 55 | */ 56 | public DocumentMacro(long time, String type, String path, int start, String itext, String dtext) { 57 | this(time, time, type, path, start, itext, dtext); 58 | } 59 | 60 | /** 61 | * Returns the leftmost offset of the document changed by this macro. 62 | * @return the leftmost offset of the document 63 | */ 64 | public int getStart() { 65 | return start; 66 | } 67 | 68 | /** 69 | * Returns the contents of the document inserted by this macro. 70 | * @return the inserted contents of the document 71 | */ 72 | public String getInsertedText() { 73 | return insertedText; 74 | } 75 | 76 | /** 77 | * Returns the contents of the document deleted by this macro. 78 | * @return the deleted contents of the document 79 | */ 80 | public String getDeletedText() { 81 | return deletedText; 82 | } 83 | 84 | /** 85 | * Tests if this macro inserts any text and deletes no text. 86 | * @return true if this macro performs insertion, otherwise false> 87 | */ 88 | public boolean isInsert() { 89 | return insertedText.length() != 0 && deletedText.length() == 0; 90 | } 91 | 92 | /** 93 | * Tests if this macro inserts no text and deletes any text. 94 | * @return true if this macro performs deletion, otherwise false> 95 | */ 96 | public boolean isDelete() { 97 | return insertedText.length() == 0 && deletedText.length() != 0; 98 | } 99 | 100 | /** 101 | * Tests if this macro inserts any text and deletes any text. 102 | * @return true if this macro performs replacement, otherwise false> 103 | */ 104 | public boolean isReplace() { 105 | return insertedText.length() != 0 && deletedText.length() != 0; 106 | } 107 | 108 | /** 109 | * Returns the string for printing, which does not contain a new line character at its end. 110 | * @return the string for printing 111 | */ 112 | public String toString() { 113 | return "DOC(" + getType() + ") = " + getStartTime() + "-" + getEndTime() + ": " + 114 | getPath() + " " + getStart() + " " + "[" + getInsertedText() + "][" + getDeletedText() + "]"; 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /MacroRecorder/src/org/jtool/macrorecorder/macro/ExecutionMacro.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.macrorecorder.macro; 8 | 9 | /** 10 | * Stores an execution macro. 11 | * @author Katsuhisa Maruyama 12 | */ 13 | public class ExecutionMacro extends Macro { 14 | 15 | /** 16 | * The string representing the contents of this macro. 17 | */ 18 | private String commandId; 19 | 20 | /** 21 | * Creates an object storing information on an execution macro. 22 | * @param time the time when the macro started 23 | * @param type the type of the macro 24 | * @param path the path of a file or a package this macro was performed 25 | * @param commandId the string representing the contents of the macro 26 | */ 27 | public ExecutionMacro(long time, String type, String path, String commandId) { 28 | super(time, time, type, path); 29 | this.commandId = commandId; 30 | } 31 | 32 | /** 33 | * Returns the string representing the contents of this macro. 34 | * @return the information on this macro 35 | */ 36 | public String getCommandId() { 37 | return commandId; 38 | } 39 | 40 | /** 41 | * Returns the string for printing, which does not contain a new line character at its end. 42 | * @return the string for printing 43 | */ 44 | public String toString() { 45 | return "EXEC = " + getStartTime() + "-" + getEndTime() + ": " + 46 | getPath() + " " + getCommandId(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /MacroRecorder/src/org/jtool/macrorecorder/macro/Macro.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.macrorecorder.macro; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * Stores a macro. 13 | * @author Katsuhisa Maruyama 14 | */ 15 | public class Macro { 16 | 17 | /** 18 | * The time when this macro started. 19 | */ 20 | protected long startTime; 21 | 22 | /** 23 | * The time when this macro ended. 24 | */ 25 | protected long endTime; 26 | 27 | /** 28 | * The type of this macro. 29 | */ 30 | protected String type; 31 | 32 | /** 33 | * The path of a file or a package this macro was performed. 34 | */ 35 | private String path; 36 | 37 | /** 38 | * The collection of raw macros that were recorded. 39 | */ 40 | private List rawMacros; 41 | 42 | /** 43 | * Creates an object storing information on a macro. 44 | * @param stime the time when the macro started 45 | * @param etime the time when the macro ended 46 | * @param type the type of the macro 47 | * @param path the path of a file or a package this macro was performed 48 | */ 49 | public Macro(long stime, long etime, String type, String path) { 50 | this.startTime = stime; 51 | this.endTime = etime; 52 | this.type = type; 53 | this.path = path; 54 | } 55 | 56 | /** 57 | * Creates an object storing information on a macro. 58 | * @param time the time when the macro started and ended 59 | * @param type the type of the macro 60 | * @param path the path of a file or a package this macro was performed 61 | */ 62 | public Macro(long time, String type, String path) { 63 | this(time, time, type, path); 64 | } 65 | 66 | /** 67 | * Returns the time when this command started 68 | * @return the starting time of this macro 69 | */ 70 | public long getStartTime() { 71 | return startTime; 72 | } 73 | 74 | /** 75 | * Returns the time when this macro ended 76 | * @return the ending time of this macro 77 | */ 78 | public long getEndTime() { 79 | return endTime; 80 | } 81 | 82 | /** 83 | * Sets the type of this macro 84 | * @param type the type of the macro 85 | */ 86 | public void setType(String type) { 87 | this.type = type; 88 | } 89 | 90 | /** 91 | * Returns the type of this macro 92 | * @return the type of the macro 93 | */ 94 | public String getType() { 95 | return type; 96 | } 97 | 98 | /** 99 | * Returns the path of a file or a package this macro was performed 100 | * @return the path string 101 | */ 102 | public String getPath() { 103 | return path; 104 | } 105 | 106 | /** 107 | * Sets the collection of raw macros that were recorded. 108 | * @param macros the raw macros to be stored 109 | */ 110 | public void setRawMacros(List macros) { 111 | rawMacros = macros; 112 | } 113 | 114 | /** 115 | * Returns the collection of raw macros that were recorded. 116 | * @return raw macros 117 | */ 118 | public List getRawMacros() { 119 | return rawMacros; 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /MacroRecorder/src/org/jtool/macrorecorder/macro/ResourceMacro.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.macrorecorder.macro; 8 | 9 | import org.eclipse.core.resources.IResource; 10 | import org.eclipse.core.resources.IFile; 11 | import org.eclipse.core.runtime.CoreException; 12 | import org.eclipse.jdt.core.ICompilationUnit; 13 | import org.eclipse.jdt.core.IJavaElement; 14 | import org.eclipse.jdt.core.IPackageFragment; 15 | import org.eclipse.jdt.core.JavaCore; 16 | import org.eclipse.jdt.core.JavaModelException; 17 | 18 | /** 19 | * Stores a resource change macro. 20 | * @author Katsuhisa Maruyama 21 | */ 22 | public class ResourceMacro extends Macro { 23 | 24 | /** 25 | * The target of this resource change. 26 | */ 27 | private String target; 28 | 29 | /** 30 | * The path of a resource identical to the changed resource. 31 | */ 32 | private String identicalPath; 33 | 34 | /** 35 | * The contents of source code after the resource change. 36 | */ 37 | private String code; 38 | 39 | /** 40 | * The encoding of the changed source code. 41 | */ 42 | private String encoding; 43 | 44 | /** 45 | * A flag that indicates if the changed resource is currently edited. 46 | */ 47 | private boolean onEdit = false; 48 | 49 | /** 50 | * Creates an object storing information on an resource change macro. 51 | * @param time the time when the macro started 52 | * @param type the type of the change 53 | * @param path the path of the changed resource 54 | * @param elem the changed resource 55 | */ 56 | public ResourceMacro(long time, String type, String path, IJavaElement elem) { 57 | super(time, time, type, path); 58 | this.target = getTarget(elem); 59 | this.identicalPath = getIdenticalPath(elem); 60 | this.code = getCode(elem); 61 | this.encoding = getEncoding(elem); 62 | } 63 | 64 | /** 65 | * Creates an object storing information on an resource change macro. 66 | * @param time the time when the macro started 67 | * @param type the type of the change 68 | * @param path the path of the changed resource 69 | * @param res the changed resource 70 | */ 71 | public ResourceMacro(long time, String type, String path, IResource res) { 72 | this(time, type, path, JavaCore.create(res)); 73 | } 74 | 75 | /** 76 | * Returns the target of this resource change. 77 | * @param elem the changed element 78 | * @return the target of the change, or null if the target is not either a project, package, or file 79 | */ 80 | public String getTarget() { 81 | return target; 82 | } 83 | 84 | /** 85 | * Returns the path of a resource moved/renamed from or to. 86 | * @return the path of the identical resource 87 | */ 88 | public String getIdenticalPath() { 89 | return identicalPath; 90 | } 91 | 92 | /** 93 | * Returns source code after this resource change. 94 | * @return the contents of the source code, or an empty string if the changed resource is not a file 95 | */ 96 | public String getCode() { 97 | return code; 98 | } 99 | 100 | /** 101 | * Returns the encoding of the changed source code. 102 | * @return the encoding of the changed source code, or null 103 | */ 104 | public String getEncoding() { 105 | return encoding; 106 | } 107 | 108 | /** 109 | * Sets the flag that indicates if the changed resource is currently edited. 110 | * @param bool true if the changed resource is currently edited, otherwise false 111 | */ 112 | public void setOnEdit(boolean bool) { 113 | onEdit = bool; 114 | } 115 | 116 | /** 117 | * Tests if the changed resource is currently edited. 118 | * @return true if the changed resource is currently edited, otherwise false 119 | */ 120 | public boolean getOnEdit() { 121 | return onEdit; 122 | } 123 | 124 | /** 125 | * Tests if the type of the change belongs to removal. 126 | * @return true if this macro represents the removal change, otherwise false 127 | */ 128 | public boolean isRemoved() { 129 | return type.compareTo("Removed") == 0 || 130 | type.compareTo("RenamedTo") == 0 || 131 | type.compareTo("MovedTo") == 0; 132 | } 133 | 134 | /** 135 | * Tests if the type of the change belongs to addition. 136 | * @return true if this macro represents the addition change, otherwise false 137 | */ 138 | public boolean isAdded() { 139 | return type.compareTo("Added") == 0 || 140 | type.compareTo("RenamedFrom") == 0 || 141 | type.compareTo("MovedFrom") == 0; 142 | } 143 | 144 | /** 145 | * Returns the target of this resource change. 146 | * @param elem the changed element 147 | * @return the target of the change, or an empty string if the target is not either a project, package, or file 148 | */ 149 | private String getTarget(IJavaElement elem) { 150 | if (elem == null) { 151 | return ""; 152 | } 153 | 154 | int type = elem.getElementType(); 155 | if (type == IJavaElement.JAVA_PROJECT) { 156 | return "Project"; 157 | 158 | } else if (type == IJavaElement.PACKAGE_DECLARATION) { 159 | return "Package"; 160 | 161 | } else if (type == IJavaElement.COMPILATION_UNIT) { 162 | return "File"; 163 | } 164 | 165 | return elem.getElementName() + "@" + elem.getElementType(); 166 | } 167 | 168 | /** 169 | * Returns the path of a resource moved/renamed from or to. 170 | * @param elem the changed resource 171 | * @return the path of the identical resource 172 | */ 173 | private String getIdenticalPath(IJavaElement elem) { 174 | return elem.getPath().toString(); 175 | } 176 | 177 | /** 178 | * Obtains source code after this resource change. 179 | * @param elem the changed resource 180 | * @return the contents of the source code, or an empty string if the changed resource is not a file 181 | */ 182 | private String getCode(IJavaElement elem) { 183 | if (elem instanceof ICompilationUnit) { 184 | ICompilationUnit cu = (ICompilationUnit)elem; 185 | 186 | try { 187 | return cu.getSource(); 188 | } catch (JavaModelException e) { 189 | } 190 | } 191 | return ""; 192 | } 193 | 194 | /** 195 | * Returns the encoding of the changed source code. 196 | * @param elem the changed resource 197 | * @return the encoding of the source code, or null 198 | */ 199 | private String getEncoding(IJavaElement elem) { 200 | if (elem instanceof ICompilationUnit) { 201 | ICompilationUnit cu = (ICompilationUnit)elem; 202 | 203 | try { 204 | IFile file = (IFile)cu.getCorrespondingResource(); 205 | return file.getCharset(); 206 | } catch (CoreException e) { 207 | } 208 | } 209 | return null; 210 | } 211 | 212 | 213 | /** 214 | * Returns the string for printing, which does not contain a new line character at its end. 215 | * @return the string for printing 216 | */ 217 | public String toString() { 218 | return "RESO(" + getType() + ")= " + getStartTime() + "-" + getEndTime() + ": " + 219 | getPath() + " " + getTarget() + " FROM/TO " + getIdenticalPath(); 220 | } 221 | 222 | /** 223 | * Obtains the name of the specified element. 224 | * @param elem the element 225 | * @param type the type of the element 226 | * @return the name string 227 | */ 228 | public static String getName(IJavaElement elem) { 229 | int type = elem.getElementType(); 230 | if (type == IJavaElement.JAVA_PROJECT) { 231 | return elem.getResource().getName(); 232 | 233 | } else if (type == IJavaElement.PACKAGE_DECLARATION) { 234 | IPackageFragment jpackage = (IPackageFragment)elem; 235 | return jpackage.getElementName(); 236 | 237 | } else if (type == IJavaElement.COMPILATION_UNIT) { 238 | return elem.getResource().getName(); 239 | } 240 | 241 | return ""; 242 | } 243 | } 244 | -------------------------------------------------------------------------------- /MacroRecorder/src/org/jtool/macrorecorder/macro/TriggerMacro.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.macrorecorder.macro; 8 | 9 | /** 10 | * Stores a trigger macro. 11 | * @author Katsuhisa Maruyama 12 | */ 13 | public class TriggerMacro extends Macro { 14 | 15 | /** 16 | * The kinds of a trigger. 17 | */ 18 | public enum Kind { 19 | BEGIN, END, CURSOR_CHANGE; 20 | } 21 | 22 | /** 23 | * The kind of a trigger of the macro. 24 | */ 25 | private Kind kind = null; 26 | 27 | /** 28 | * Creates an object storing information on a macro. 29 | * @param time the time when the macro occurred 30 | * @param type the type of the macro 31 | * @param path the path of a file or a package this macro was performed 32 | * @param kind the kind of a trigger of the macro 33 | */ 34 | public TriggerMacro(long time, String type, String path, Kind kind) { 35 | super(time, time, type, path); 36 | this.kind = kind; 37 | } 38 | 39 | /** 40 | * Returns the kind of a trigger of the macro 41 | * @return the kind of the macro 42 | */ 43 | public Kind getKind() { 44 | return kind; 45 | } 46 | 47 | /** 48 | * Tests this compound macro indicates the beginning. 49 | * @return true if this compound macro indicates the beginning, otherwise false 50 | */ 51 | public boolean isBegin() { 52 | return kind == Kind.BEGIN; 53 | } 54 | 55 | /** 56 | * Tests this compound macro indicates the ending. 57 | * @return true if this compound macro indicates the ending, otherwise false 58 | */ 59 | public boolean isEnd() { 60 | return kind == Kind.END; 61 | } 62 | 63 | /** 64 | * Tests this compound macro indicates as the change of the current position of the cursor. 65 | * @return true if this compound macro indicates the cursor change, otherwise false 66 | */ 67 | public boolean isCursorChange() { 68 | return kind == Kind.CURSOR_CHANGE; 69 | } 70 | 71 | 72 | 73 | /** 74 | * Returns the string for printing, which does not contain a new line character at its end. 75 | * @return the string for printing 76 | */ 77 | public String toString() { 78 | return "TRIGGER(" + getType() + ") = " + getStartTime() + "-" + getEndTime() + ": " + 79 | getPath() + " " + getKind().toString(); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /MacroRecorder/src/org/jtool/macrorecorder/recorder/MacroCompressor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.macrorecorder.recorder; 8 | 9 | import org.jtool.macrorecorder.macro.DocumentMacro; 10 | 11 | /** 12 | * Compresses macros. 13 | * @author Katsuhisa Maruyama 14 | */ 15 | public class MacroCompressor { 16 | 17 | /** 18 | * Creates an object compressing macros. 19 | */ 20 | public MacroCompressor() { 21 | } 22 | 23 | /** 24 | * Tests if a document macros can be combined with its previous macro. 25 | * @param macro the document macro 26 | * @return true if the macros can be combined, otherwise false 27 | */ 28 | public boolean canCombine(DocumentMacro macro) { 29 | if (macro == null) { 30 | return false; 31 | } 32 | 33 | if (macro.isInsert()) { 34 | return combineWith(macro.getInsertedText()); 35 | } 36 | 37 | if (macro.isDelete()) { 38 | return combineWith(macro.getDeletedText()); 39 | } 40 | 41 | if (macro.isReplace()) { 42 | return combineWith(macro.getInsertedText()) && combineWith(macro.getDeletedText()); 43 | } 44 | 45 | return false; 46 | } 47 | 48 | /** 49 | * Combines successive two document macros. 50 | * @param last the former document macro 51 | * @param next the latter document macro 52 | * @return the combined macro, or null if the macro cannot be combined 53 | */ 54 | public DocumentMacro combine(DocumentMacro last, DocumentMacro next) { 55 | if (next == null) { 56 | return null; 57 | } 58 | 59 | if (next.isInsert()) { 60 | return combineInsertMacro(last, next); 61 | } 62 | 63 | if (next.isDelete()) { 64 | return combineDeleteMacro(last, next); 65 | } 66 | 67 | if (next.isReplace()) { 68 | return compressReplaceMacro(last, next); 69 | } 70 | 71 | return null; 72 | } 73 | 74 | /** 75 | * Combines successive two macro. 76 | * @param last the former document macro 77 | * @param next the latter document macro that represents the insertion 78 | * @return the combined macro, or null if the macros cannot be combined 79 | */ 80 | private DocumentMacro combineInsertMacro(DocumentMacro last, DocumentMacro next) { 81 | if (last == null) { 82 | return next; 83 | } 84 | 85 | if (!last.isInsert() || !combineWith(last.getInsertedText())) { 86 | return null; 87 | } 88 | 89 | if (last.getStart() + last.getInsertedText().length() == next.getStart()) { 90 | String text = last.getInsertedText() + next.getInsertedText(); 91 | return new DocumentMacro(last.getStartTime(), next.getEndTime(), 92 | last.getType(), last.getPath(), last.getStart(), text, ""); 93 | } 94 | 95 | return null; 96 | } 97 | 98 | /** 99 | * Combines successive two macros. 100 | * @param last the former document macro 101 | * @param next the latter document macro that represents deletion 102 | * @return the combined macro, or null if the macros cannot be combined 103 | */ 104 | private DocumentMacro combineDeleteMacro(DocumentMacro last, DocumentMacro next) { 105 | if (last == null) { 106 | return next; 107 | } 108 | 109 | if (!last.isDelete() || !combineWith(last.getDeletedText())) { 110 | return null; 111 | } 112 | 113 | if (last.getStart() > next.getStart()) { 114 | if (last.getStart() == next.getStart() + next.getDeletedText().length()) { 115 | String text = next.getDeletedText() + last.getDeletedText(); 116 | 117 | return new DocumentMacro(last.getStartTime(), next.getEndTime(), 118 | last.getType(), last.getPath(), next.getStart(), "", text); 119 | } 120 | 121 | } else { 122 | if (last.getStart() + last.getInsertedText().length() == next.getStart()) { 123 | String text = last.getDeletedText() + next.getDeletedText(); 124 | 125 | return new DocumentMacro(last.getStartTime(), next.getEndTime(), 126 | last.getType(), last.getPath(), last.getStart(), "", text); 127 | } 128 | } 129 | 130 | return null; 131 | } 132 | 133 | /** 134 | * Compresses successive two macros. 135 | * @param last the former document macro 136 | * @param next the latter document macro that represents replacement 137 | * @return the combined macro, or null if the macros cannot be combined 138 | */ 139 | private DocumentMacro compressReplaceMacro(DocumentMacro last, DocumentMacro next) { 140 | if (last == null) { 141 | return next; 142 | } 143 | 144 | if (!(last.isInsert() || last.isReplace()) || 145 | !combineWith(last.getInsertedText()) || !combineWith(last.getDeletedText())) { 146 | return null; 147 | } 148 | 149 | if (last.getStart() == next.getStart() && 150 | last.getInsertedText().compareTo(next.getDeletedText()) == 0) { 151 | String itext = next.getInsertedText(); 152 | String dtext = last.getDeletedText(); 153 | return new DocumentMacro(last.getStartTime(), next.getEndTime(), 154 | last.getType(), last.getPath(), last.getStart(), itext, dtext); 155 | } 156 | 157 | return null; 158 | } 159 | 160 | /** 161 | * Tests if a given text can be combined with another one. 162 | * @param text the text to be combined 163 | * @return true if the can be combined, otherwise false 164 | */ 165 | public boolean combineWith(String text) { 166 | char[] DELIMITER_CHARS = new char[] { '\n', '\r', ';', '{', '}' }; 167 | 168 | for (int i = 0; i < DELIMITER_CHARS.length; i++) { 169 | if (text.indexOf(DELIMITER_CHARS[i]) >= 0) { 170 | return false; 171 | } 172 | } 173 | return true; 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /MacroRecorder/src/org/jtool/macrorecorder/recorder/MacroEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.macrorecorder.recorder; 8 | 9 | import org.jtool.macrorecorder.macro.Macro; 10 | 11 | /** 12 | * Manages an event containing a macro. 13 | * @author Katsuhisa Maruyama 14 | */ 15 | public class MacroEvent { 16 | 17 | /** 18 | * The value indicating general macros. 19 | */ 20 | public static int GENERIC_MACRO = 1; 21 | 22 | /** 23 | * The value indicating raw macros per keystroke. 24 | */ 25 | public static int RAW_MACRO = 2; 26 | 27 | /** 28 | * A macro sent to listeners. 29 | */ 30 | private Macro macro; 31 | 32 | /** 33 | * The type of a macro sent to listeners. 34 | */ 35 | private int type; 36 | 37 | /** 38 | * Creates an object containing a macro. 39 | * @param macro the macro sent to listeners 40 | */ 41 | public MacroEvent(int type, Macro macro) { 42 | this.type = type; 43 | this.macro = macro; 44 | } 45 | 46 | /** 47 | * Returns the type of an event that listeners receive. 48 | * @return the type of the received event 49 | */ 50 | public int getEventType() { 51 | return type; 52 | } 53 | 54 | /** 55 | * Returns the macro of an event that listeners receive. 56 | * @return the macro contained in the received event 57 | */ 58 | public Macro getMacro() { 59 | return macro; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /MacroRecorder/src/org/jtool/macrorecorder/recorder/MacroListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.macrorecorder.recorder; 8 | 9 | /** 10 | * Defines the listener interface for receiving a macro event. 11 | * @author Katsuhisa Maruyama 12 | */ 13 | public interface MacroListener { 14 | 15 | /** 16 | * Receives a macro event when a new macro is added. 17 | * @param evt the macro event 18 | */ 19 | public void macroAdded(MacroEvent evt); 20 | 21 | /** 22 | * Receives a macro event when a document is changed. 23 | * @param evt the raw macro event 24 | */ 25 | public void documentChanged(MacroEvent evt); 26 | } 27 | -------------------------------------------------------------------------------- /MacroRecorder/src/org/jtool/macrorecorder/util/EditorUtilities.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.macrorecorder.util; 8 | 9 | import org.eclipse.core.resources.IFile; 10 | import org.eclipse.core.runtime.CoreException; 11 | import org.eclipse.jface.text.source.ISourceViewer; 12 | import org.eclipse.jface.text.source.SourceViewer; 13 | import org.eclipse.jface.text.source.ContentAssistantFacade; 14 | import org.eclipse.jface.text.IDocument; 15 | import org.eclipse.jface.text.ITextOperationTarget; 16 | import org.eclipse.swt.custom.StyledText; 17 | import org.eclipse.ui.IEditorInput; 18 | import org.eclipse.ui.IEditorPart; 19 | import org.eclipse.ui.IEditorReference; 20 | import org.eclipse.ui.IFileEditorInput; 21 | import org.eclipse.ui.IWorkbenchPage; 22 | import org.eclipse.ui.IWorkbenchWindow; 23 | import org.eclipse.ui.PlatformUI; 24 | import org.eclipse.ui.editors.text.TextFileDocumentProvider; 25 | import org.eclipse.ui.part.FileEditorInput; 26 | import java.util.ArrayList; 27 | import java.util.List; 28 | 29 | /** 30 | * Provides utilities that obtain information on editors. 31 | * @author Katsuhisa Maruyama 32 | */ 33 | public class EditorUtilities { 34 | 35 | /** 36 | * Obtains the source viewer of an editor. 37 | * @param editor the editor 38 | * @return the source viewer of the editor 39 | */ 40 | public static ISourceViewer getSourceViewer(IEditorPart editor) { 41 | if (editor == null) { 42 | return null; 43 | } 44 | 45 | ISourceViewer viewer = (ISourceViewer)editor.getAdapter(ITextOperationTarget.class); 46 | return viewer; 47 | } 48 | 49 | /** 50 | * Obtains the styled text of an editor. 51 | * @param editor the editor 52 | * @return the styled text of the editor 53 | */ 54 | public static StyledText getStyledText(IEditorPart editor) { 55 | ISourceViewer viewer = getSourceViewer(editor); 56 | if (viewer != null) { 57 | return viewer.getTextWidget(); 58 | } 59 | return null; 60 | } 61 | 62 | /** 63 | * Obtains the content assistant facade of an editor. 64 | * @param editor the editor 65 | * @return the content assistant facade of the editor 66 | */ 67 | public static ContentAssistantFacade getContentAssistantFacade(IEditorPart editor) { 68 | ISourceViewer viewer = getSourceViewer(editor); 69 | if (viewer != null && viewer instanceof SourceViewer) { 70 | return ((SourceViewer)viewer).getContentAssistantFacade(); 71 | } 72 | return null; 73 | } 74 | 75 | /** 76 | * Obtains a file existing on an editor. 77 | * @param editor the editor 78 | * @return the file existing on the editor, or null if none 79 | */ 80 | public static IFile getInputFile(IEditorPart editor) { 81 | IEditorInput input = editor.getEditorInput(); 82 | if (input instanceof IFileEditorInput) { 83 | IFile file = ((IFileEditorInput)input).getFile(); 84 | return file; 85 | } 86 | return null; 87 | } 88 | 89 | /** 90 | * Obtains the path of a file existing on an editor. 91 | * @param editor the editor 92 | * @return the path of the file, which is relative to the path of the workspace 93 | */ 94 | public static String getInputFilePath(IEditorPart editor) { 95 | IFile file = getInputFile(editor); 96 | return getInputFilePath(file); 97 | } 98 | 99 | /** 100 | * Obtains the path of a file. 101 | * @param file the file 102 | * @return the path of the file, which is relative to the path of the workspace 103 | */ 104 | public static String getInputFilePath(IFile file) { 105 | if (file != null) { 106 | return file.getFullPath().toString(); 107 | } 108 | return ""; 109 | } 110 | 111 | /** 112 | * Obtains the document of a file. 113 | * @param file the file 114 | * @return the document of the file, or null if none 115 | */ 116 | public static IDocument getDocument(IFile file) { 117 | if (file == null) { 118 | return null; 119 | } 120 | 121 | try { 122 | TextFileDocumentProvider provider = new TextFileDocumentProvider(); 123 | provider.connect(file); 124 | IDocument doc = provider.getDocument(file); 125 | provider.disconnect(file); 126 | return doc; 127 | } catch (CoreException e) { 128 | e.printStackTrace(); 129 | } 130 | return null; 131 | } 132 | 133 | /** 134 | * Obtains the document of a file existing on an editor. 135 | * @param editor the editor 136 | * @return the document of the file, or null if none 137 | */ 138 | public static IDocument getDocument(IEditorPart editor) { 139 | IFile file = getInputFile(editor); 140 | if (file != null) { 141 | return getDocument(file); 142 | } 143 | return null; 144 | } 145 | 146 | /** 147 | * Obtains the contents of source code appearing in an editor. 148 | * @param editor the editor 149 | * @return the contents of the source code, or null if the source code is not valid 150 | */ 151 | public static String getSourceCode(IEditorPart editor) { 152 | IDocument doc = getDocument(editor); 153 | if (doc != null) { 154 | return doc.get(); 155 | } 156 | return null; 157 | } 158 | 159 | /** 160 | * Obtains the contents of source code appearing in an editor. 161 | * @param file the file 162 | * @return the contents of the source code, or null if the source code is not valid 163 | */ 164 | public static String getSourceCode(IFile file) { 165 | IDocument doc = getDocument(file); 166 | if (doc != null) { 167 | return doc.get(); 168 | } 169 | return null; 170 | } 171 | 172 | /** 173 | * Obtains an editor that may edits the contents of a file. 174 | * @param file the file 175 | * @return the editor of the file, or null if none 176 | */ 177 | public static IEditorPart getEditor(IFile file) { 178 | IEditorInput input = new FileEditorInput(file); 179 | IWorkbenchWindow[] windows = PlatformUI.getWorkbench().getWorkbenchWindows(); 180 | 181 | for (IWorkbenchWindow window : windows) { 182 | IWorkbenchPage[] pages = window.getPages(); 183 | 184 | for (IWorkbenchPage page : pages) { 185 | IEditorPart part = page.findEditor(input); 186 | return part; 187 | } 188 | } 189 | return null; 190 | } 191 | 192 | /** 193 | * Obtains all editors that are currently opened. 194 | * @return the collection of the opened editors 195 | */ 196 | public static List getEditors() { 197 | List editors = new ArrayList(); 198 | IWorkbenchWindow[] windows = PlatformUI.getWorkbench().getWorkbenchWindows(); 199 | 200 | for (IWorkbenchWindow window : windows) { 201 | IWorkbenchPage[] pages = window.getPages(); 202 | 203 | for (IWorkbenchPage page : pages) { 204 | IEditorReference[] refs = page.getEditorReferences(); 205 | 206 | for (IEditorReference ref : refs) { 207 | IEditorPart part = ref.getEditor(false); 208 | if (part != null) { 209 | editors.add(part); 210 | } 211 | } 212 | } 213 | } 214 | return editors; 215 | } 216 | 217 | /** 218 | * Obtains an editor that is currently active. 219 | * @return the active editor, or null if none 220 | */ 221 | public static IEditorPart getActiveEditor() { 222 | IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); 223 | if (window != null) { 224 | IEditorPart part = window.getActivePage().getActiveEditor(); 225 | return part; 226 | } 227 | return null; 228 | } 229 | 230 | /** 231 | * Obtains the path of a active file existing on an editor. 232 | * @return the path of the file, which is relative to the path of the workspace 233 | */ 234 | public static String getActiveInputFilePath() { 235 | IEditorPart editor = getActiveEditor(); 236 | if (editor != null) { 237 | return getInputFilePath(editor); 238 | } 239 | return null; 240 | } 241 | } 242 | -------------------------------------------------------------------------------- /MacroRecorder/src/org/jtool/macrorecorder/util/WorkspaceUtilities.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package org.jtool.macrorecorder.util; 8 | 9 | import org.eclipse.core.resources.ResourcesPlugin; 10 | import org.eclipse.core.resources.IResource; 11 | import org.eclipse.core.resources.IProject; 12 | import org.eclipse.core.resources.IWorkspace; 13 | import org.eclipse.jdt.core.IJavaProject; 14 | import org.eclipse.jdt.core.ICompilationUnit; 15 | import org.eclipse.jdt.core.IPackageFragment; 16 | import org.eclipse.jdt.core.JavaCore; 17 | import org.eclipse.jdt.core.JavaModelException; 18 | import java.util.List; 19 | import java.util.ArrayList; 20 | 21 | /** 22 | * Provides utilities that obtain information on the workspace. 23 | * @author Katsuhisa Maruyama 24 | */ 25 | public class WorkspaceUtilities { 26 | 27 | /** 28 | * Obtains the workspace. 29 | * @return the workspace information 30 | */ 31 | public static IWorkspace getWorkspace() { 32 | return ResourcesPlugin.getWorkspace(); 33 | } 34 | 35 | /** 36 | * Obtains the encoding to use when reading text files in the workspace. 37 | * @return the encoding 38 | */ 39 | public static String getEncoding() { 40 | return ResourcesPlugin.getEncoding(); 41 | } 42 | 43 | /** 44 | * Collects all compilation units within the project. 45 | * @return the collection of the compilation units 46 | */ 47 | public static List collectAllCompilationUnits() { 48 | List units = new ArrayList(); 49 | 50 | try { 51 | IProject[] projects = getWorkspace().getRoot().getProjects(); 52 | for (int i = 0; i < projects.length; i++) { 53 | IJavaProject project = (IJavaProject)JavaCore.create((IProject)projects[i]); 54 | 55 | IPackageFragment[] packages = project.getPackageFragments(); 56 | for (int j = 0; j < packages.length; j++) { 57 | 58 | ICompilationUnit[] cus = packages[j].getCompilationUnits(); 59 | for (int k = 0; k < cus.length; k++) { 60 | IResource res = cus[k].getResource(); 61 | if (res.getType() == IResource.FILE) { 62 | String name = cus[k].getPath().toString(); 63 | if (name.endsWith(".java")) { 64 | units.add(cus[k]); 65 | } 66 | } 67 | } 68 | } 69 | } 70 | } catch (JavaModelException e) { 71 | e.printStackTrace(); 72 | } 73 | 74 | return units; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ContentAssist 2 | A code assist plugin for Eclipse. 3 | 4 | In recent integrated development environments, by utilizing collective intelligence obtained from a large amount of source code described in the past, the method with higher possibility to be used in the source code is preferentially recommended. The method based on the statistical data is suitable for code complementation tailored to the tendency of the developer as a whole, but it is not always possible to provide an appropriate complementary candidate for a specific development team or individual developer. In this project, we propose a method to calculate the degree of interest of developers by utilizing the editing history that the developer written in the past, and rearrange the order of code completion candidates that can be displayed based on it. 5 | 6 | ## Requirement 7 | JDK 1.7 or later 8 | 9 | Eclipse 4.6 (Neon) or late (Eclipse for committer) 10 | 11 | ## Installation 12 | 13 | 1. Please run `git clone git@github.com:liaoziyang/ContentAssist.git` to copy the files to local. 14 | 2. Import this project to your workspace. 15 | 16 | ## System structure 17 | ![alt text](structure.png) 18 | 19 | ## Compare to other content assist plugin 20 | ![alt text](compare.png) 21 | 22 | ## Publication 23 | Liao Ziyang, 丸山勝久, ["編集履歴から算出した開発者の関心度に基づくコード補完"](編集履歴から算出した開発者の関心度に基づくコード補完.pdf), 日本ソフトウェア科学会第33回大会,FOSE2-3, 2016 24 | -------------------------------------------------------------------------------- /RemoteSystemsTempFiles/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | RemoteSystemsTempFiles 4 | 5 | 6 | 7 | 8 | 9 | 10 | org.eclipse.rse.ui.remoteSystemsTempNature 11 | 12 | 13 | -------------------------------------------------------------------------------- /compare.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liaoziyang/ContentAssist/9f1c42158ddc765438b5e488ccf699372850fb2e/compare.png -------------------------------------------------------------------------------- /jp.ac.ritsumei.cs.fse.contentassist/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /jp.ac.ritsumei.cs.fse.contentassist/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | jp.ac.ritsumei.cs.fse.contentassist 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.pde.ManifestBuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.pde.SchemaBuilder 20 | 21 | 22 | 23 | 24 | 25 | org.eclipse.pde.PluginNature 26 | org.eclipse.jdt.core.javanature 27 | 28 | 29 | -------------------------------------------------------------------------------- /jp.ac.ritsumei.cs.fse.contentassist/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 4 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 5 | org.eclipse.jdt.core.compiler.compliance=1.5 6 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 7 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 8 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 9 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 10 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 11 | org.eclipse.jdt.core.compiler.source=1.5 12 | -------------------------------------------------------------------------------- /jp.ac.ritsumei.cs.fse.contentassist/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Bundle-ManifestVersion: 2 3 | Bundle-Name: Contentassist 4 | Bundle-SymbolicName: jp.ac.ritsumei.cs.fse.contentassist;singleton:=true 5 | Bundle-Version: 1.0.0.qualifier 6 | Bundle-Activator: jp.ac.ritsumei.cs.fse.contentassist.Activator 7 | Require-Bundle: org.eclipse.ui, 8 | org.eclipse.core.runtime, 9 | org.eclipse.jdt.ui, 10 | org.eclipse.jdt.core;bundle-version="3.10.2", 11 | org.eclipse.jface.text;bundle-version="3.8.101", 12 | ChangeRecorder;bundle-version="1.0.0" 13 | Bundle-ActivationPolicy: lazy 14 | -------------------------------------------------------------------------------- /jp.ac.ritsumei.cs.fse.contentassist/bin/.gitignore: -------------------------------------------------------------------------------- 1 | /jp/ 2 | -------------------------------------------------------------------------------- /jp.ac.ritsumei.cs.fse.contentassist/bin/jp/ac/ritsumei/cs/fse/contentassist/Activator.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liaoziyang/ContentAssist/9f1c42158ddc765438b5e488ccf699372850fb2e/jp.ac.ritsumei.cs.fse.contentassist/bin/jp/ac/ritsumei/cs/fse/contentassist/Activator.class -------------------------------------------------------------------------------- /jp.ac.ritsumei.cs.fse.contentassist/bin/jp/ac/ritsumei/cs/fse/contentassist/DataAnalyser/ConsoleOperationListener2.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liaoziyang/ContentAssist/9f1c42158ddc765438b5e488ccf699372850fb2e/jp.ac.ritsumei.cs.fse.contentassist/bin/jp/ac/ritsumei/cs/fse/contentassist/DataAnalyser/ConsoleOperationListener2.class -------------------------------------------------------------------------------- /jp.ac.ritsumei.cs.fse.contentassist/bin/jp/ac/ritsumei/cs/fse/contentassist/DataAnalyser/DataManager.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liaoziyang/ContentAssist/9f1c42158ddc765438b5e488ccf699372850fb2e/jp.ac.ritsumei.cs.fse.contentassist/bin/jp/ac/ritsumei/cs/fse/contentassist/DataAnalyser/DataManager.class -------------------------------------------------------------------------------- /jp.ac.ritsumei.cs.fse.contentassist/bin/jp/ac/ritsumei/cs/fse/contentassist/DataAnalyser/HistoryRecorder.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liaoziyang/ContentAssist/9f1c42158ddc765438b5e488ccf699372850fb2e/jp.ac.ritsumei.cs.fse.contentassist/bin/jp/ac/ritsumei/cs/fse/contentassist/DataAnalyser/HistoryRecorder.class -------------------------------------------------------------------------------- /jp.ac.ritsumei.cs.fse.contentassist/bin/jp/ac/ritsumei/cs/fse/contentassist/DataAnalyser/getProposalResult.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liaoziyang/ContentAssist/9f1c42158ddc765438b5e488ccf699372850fb2e/jp.ac.ritsumei.cs.fse.contentassist/bin/jp/ac/ritsumei/cs/fse/contentassist/DataAnalyser/getProposalResult.class -------------------------------------------------------------------------------- /jp.ac.ritsumei.cs.fse.contentassist/bin/jp/ac/ritsumei/cs/fse/contentassist/View/JavaCompletionProposalComputer1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liaoziyang/ContentAssist/9f1c42158ddc765438b5e488ccf699372850fb2e/jp.ac.ritsumei.cs.fse.contentassist/bin/jp/ac/ritsumei/cs/fse/contentassist/View/JavaCompletionProposalComputer1.class -------------------------------------------------------------------------------- /jp.ac.ritsumei.cs.fse.contentassist/bin/jp/ac/ritsumei/cs/fse/contentassist/entity/ApplyOperation.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liaoziyang/ContentAssist/9f1c42158ddc765438b5e488ccf699372850fb2e/jp.ac.ritsumei.cs.fse.contentassist/bin/jp/ac/ritsumei/cs/fse/contentassist/entity/ApplyOperation.class -------------------------------------------------------------------------------- /jp.ac.ritsumei.cs.fse.contentassist/build.properties: -------------------------------------------------------------------------------- 1 | source.. = src/ 2 | output.. = bin/ 3 | bin.includes = META-INF/,\ 4 | .,\ 5 | plugin.xml 6 | -------------------------------------------------------------------------------- /jp.ac.ritsumei.cs.fse.contentassist/plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 12 | 14 | 15 | 16 | 17 | 19 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /jp.ac.ritsumei.cs.fse.contentassist/src/jp/ac/ritsumei/cs/fse/contentassist/Activator.java: -------------------------------------------------------------------------------- 1 | package jp.ac.ritsumei.cs.fse.contentassist; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import jp.ac.ritsumei.cs.fse.contentassist.DataAnalyser.ConsoleOperationListener2; 7 | import jp.ac.ritsumei.cs.fse.contentassist.entity.ApplyOperation; 8 | 9 | import org.eclipse.core.runtime.CoreException; 10 | import org.eclipse.ui.IStartup; 11 | import org.eclipse.ui.plugin.AbstractUIPlugin; 12 | import org.jtool.changerecorder.editor.HistoryManager; 13 | import org.osgi.framework.BundleContext; 14 | 15 | /** 16 | * The activator class controls the plug-in life cycle 17 | */ 18 | public class Activator extends AbstractUIPlugin implements IStartup { 19 | 20 | // The plug-in ID 21 | public static final String PLUGIN_ID = "Contentassist"; //$NON-NLS-1$ 22 | 23 | // The shared instance 24 | private static Activator plugin; 25 | 26 | public static List applyoperationlist = new ArrayList(); 27 | 28 | /** 29 | * The constructor 30 | */ 31 | public Activator() { 32 | } 33 | 34 | /* 35 | * (non-Javadoc) 36 | * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) 37 | */ 38 | public void start(BundleContext context) throws Exception { 39 | super.start(context); 40 | plugin = this; 41 | HistoryManager hm = HistoryManager.getInstance(); 42 | hm.addOperationEventListener(new ConsoleOperationListener2()); 43 | System.out.println(PLUGIN_ID + " activated."); 44 | } 45 | 46 | /* 47 | * (non-Javadoc) 48 | * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) 49 | */ 50 | public void stop(BundleContext context) throws Exception { 51 | plugin = null; 52 | super.stop(context); 53 | } 54 | 55 | /** 56 | * Returns the shared instance 57 | * 58 | * @return the shared instance 59 | */ 60 | public static Activator getDefault() { 61 | return plugin; 62 | } 63 | 64 | public void earlyStartup() { 65 | // TODO Auto-generated method stub 66 | 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /jp.ac.ritsumei.cs.fse.contentassist/src/jp/ac/ritsumei/cs/fse/contentassist/DataAnalyser/ConsoleOperationListener2.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 3 | * Software Science and Technology Lab. 4 | * Department of Computer Science, Ritsumeikan University 5 | */ 6 | 7 | package jp.ac.ritsumei.cs.fse.contentassist.DataAnalyser; 8 | 9 | import jp.ac.ritsumei.cs.fse.contentassist.Activator; 10 | import jp.ac.ritsumei.cs.fse.contentassist.entity.ApplyOperation; 11 | 12 | import org.jtool.changerecorder.event.OperationEvent; 13 | import org.jtool.changerecorder.event.OperationEventListener; 14 | import org.jtool.changerecorder.operation.TextOperation; 15 | 16 | /** 17 | * Displays operations recorded on editors. 18 | * @author liaoziyang 19 | */ 20 | public class ConsoleOperationListener2 implements OperationEventListener { 21 | 22 | /** 23 | * Receives an operation event when operation history was updated. 24 | * @param evt the received event 25 | */ 26 | HistoryRecorder hr = new HistoryRecorder(); 27 | public static TextOperation ope; 28 | public void historyNotification(OperationEvent evt) { 29 | try { 30 | ConsoleOperationListener2.ope = (TextOperation) evt.getOperation(); 31 | } 32 | catch(Exception e) { 33 | 34 | } 35 | for (ApplyOperation ao : Activator.applyoperationlist) { 36 | ao.update(ope.getStart(), ope.getDeletedText(), ope.getInsertedText()); 37 | System.out.println(ao.toString()); 38 | } 39 | } 40 | } 41 | 42 | -------------------------------------------------------------------------------- /jp.ac.ritsumei.cs.fse.contentassist/src/jp/ac/ritsumei/cs/fse/contentassist/DataAnalyser/DataManager.java: -------------------------------------------------------------------------------- 1 | 2 | package jp.ac.ritsumei.cs.fse.contentassist.DataAnalyser; 3 | 4 | import java.util.List; 5 | 6 | 7 | import org.eclipse.core.runtime.IProgressMonitor; 8 | import org.eclipse.jdt.ui.text.java.ContentAssistInvocationContext; 9 | import org.eclipse.jface.text.contentassist.ICompletionProposal; 10 | import org.eclipse.jface.text.contentassist.IContextInformation; 11 | 12 | /** 13 | * @author liaoziyang 14 | * Manage the Dataanalyser's work 15 | */ 16 | public class DataManager { 17 | public getProposalResult getproposalresult; 18 | public HistoryRecorder historyrecorder = new HistoryRecorder(); 19 | ContentAssistInvocationContext context = null; 20 | IProgressMonitor monitor = null; 21 | 22 | public DataManager(){} 23 | 24 | public DataManager(ContentAssistInvocationContext context, IProgressMonitor monitor){ 25 | this.context = context; 26 | this.monitor = monitor; 27 | getproposalresult = new getProposalResult(context,monitor); 28 | } 29 | 30 | /** 31 | * @return The default result of java content assist 32 | */ 33 | public List JavaDefaultProposal(){ 34 | return getproposalresult.getAllProposalResult(); 35 | } 36 | 37 | public List ContextInformation(){ 38 | return getproposalresult.getAllProposalResultInformation(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /jp.ac.ritsumei.cs.fse.contentassist/src/jp/ac/ritsumei/cs/fse/contentassist/DataAnalyser/HistoryRecorder.java: -------------------------------------------------------------------------------- 1 | package jp.ac.ritsumei.cs.fse.contentassist.DataAnalyser; 2 | 3 | public class HistoryRecorder { 4 | 5 | public String getInsertString(){ 6 | return ConsoleOperationListener2.ope.getInsertedText(); 7 | } 8 | 9 | public String getDeleteString(){ 10 | return ConsoleOperationListener2.ope.getDeletedText(); 11 | } 12 | 13 | public int getOffset(){ 14 | return ConsoleOperationListener2.ope.getStart(); 15 | } 16 | public long getTime(){ 17 | return ConsoleOperationListener2.ope.getTime(); 18 | } 19 | public long getTimes(){ 20 | return ConsoleOperationListener2.ope.getSequenceNumber(); 21 | } 22 | public String getAuthor(){ 23 | return ConsoleOperationListener2.ope.getAuthor(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /jp.ac.ritsumei.cs.fse.contentassist/src/jp/ac/ritsumei/cs/fse/contentassist/DataAnalyser/getProposalResult.java: -------------------------------------------------------------------------------- 1 | package jp.ac.ritsumei.cs.fse.contentassist.DataAnalyser; 2 | 3 | import java.util.List; 4 | import java.util.HashSet; 5 | import java.util.Iterator; 6 | import java.util.List; 7 | import java.util.Set; 8 | 9 | import org.eclipse.core.runtime.IProgressMonitor; 10 | import org.eclipse.jface.text.BadLocationException; 11 | import org.eclipse.jface.text.IDocument; 12 | import org.eclipse.jface.text.contentassist.ICompletionProposal; 13 | import org.eclipse.jface.text.contentassist.IContextInformation; 14 | import org.eclipse.jdt.core.CompletionContext; 15 | import org.eclipse.jdt.core.CompletionProposal; 16 | import org.eclipse.jdt.core.IJavaElement; 17 | import org.eclipse.jdt.core.IJavaProject; 18 | import org.eclipse.jdt.core.IType; 19 | import org.eclipse.jdt.core.JavaCore; 20 | import org.eclipse.jdt.core.JavaModelException; 21 | import org.eclipse.jdt.core.Signature; 22 | import org.eclipse.jdt.ui.text.java.CompletionProposalCollector; 23 | import org.eclipse.jdt.ui.text.java.ContentAssistInvocationContext; 24 | import org.eclipse.jdt.ui.text.java.IJavaCompletionProposal; 25 | import org.eclipse.jdt.ui.text.java.JavaContentAssistInvocationContext; 26 | import org.eclipse.jdt.internal.ui.JavaPlugin; 27 | import org.eclipse.jdt.internal.ui.text.JavaHeuristicScanner; 28 | import org.eclipse.jdt.internal.ui.text.Symbols; 29 | import org.eclipse.jdt.internal.ui.text.java.*; 30 | /** 31 | * @author liaoziyang 32 | * Get the proposal result of the default java content assist 33 | */ 34 | public class getProposalResult extends JavaAllCompletionProposalComputer{ 35 | /** 36 | * @param context The instance of ContentAssistInvocationContext 37 | * @param monitor The instance of IProgressMonitor 38 | * @see JavaAllCompletionProposalComputer.java in org.eclipse.jdt.internal.ui.text.java 39 | * @return The proposal result of the default java content assist 40 | */ 41 | List proposallist; 42 | ContentAssistInvocationContext context; 43 | IProgressMonitor monitor; 44 | 45 | public getProposalResult(ContentAssistInvocationContext context, IProgressMonitor monitor){ 46 | // TODO Auto-generated constructor stub 47 | this.context = context; 48 | this.monitor = monitor; 49 | this.proposallist = computeCompletionProposals(context, monitor); 50 | } 51 | 52 | public List getAllProposalResult(){ 53 | 54 | return proposallist; 55 | } 56 | public List getAllProposalResultInformation(){ 57 | return computeContextInformation(context, monitor); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /jp.ac.ritsumei.cs.fse.contentassist/src/jp/ac/ritsumei/cs/fse/contentassist/View/JavaCompletionProposalComputer1.java: -------------------------------------------------------------------------------- 1 | package jp.ac.ritsumei.cs.fse.contentassist.View; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.Map; 6 | 7 | import jp.ac.ritsumei.cs.fse.contentassist.Activator; 8 | import jp.ac.ritsumei.cs.fse.contentassist.DataAnalyser.ConsoleOperationListener2; 9 | import jp.ac.ritsumei.cs.fse.contentassist.DataAnalyser.DataManager; 10 | import jp.ac.ritsumei.cs.fse.contentassist.DataAnalyser.getProposalResult; 11 | import jp.ac.ritsumei.cs.fse.contentassist.entity.ApplyOperation; 12 | 13 | import org.eclipse.core.runtime.IProgressMonitor; 14 | import org.eclipse.jdt.internal.ui.text.java.AbstractJavaCompletionProposal; 15 | import org.eclipse.jdt.internal.ui.text.java.ProposalInfo; 16 | import org.eclipse.jdt.ui.text.java.ContentAssistInvocationContext; 17 | import org.eclipse.jdt.ui.text.java.IJavaCompletionProposalComputer; 18 | import org.eclipse.jface.preference.JFacePreferences; 19 | import org.eclipse.jface.text.contentassist.CompletionProposal; 20 | import org.eclipse.jface.text.contentassist.ICompletionProposal; 21 | import org.eclipse.jface.text.contentassist.IContextInformation; 22 | import org.eclipse.jface.viewers.StyledString; 23 | import org.eclipse.jface.viewers.StyledString.Styler; 24 | 25 | public class JavaCompletionProposalComputer1 implements 26 | IJavaCompletionProposalComputer { 27 | public JavaCompletionProposalComputer1() { 28 | // TODO Auto-generated constructor stub 29 | 30 | } 31 | 32 | public void sessionStarted() { 33 | // TODO Auto-generated method stub 34 | 35 | } 36 | public static final Styler LIAOZIYANG = StyledString.createColorRegistryStyler( 37 | JFacePreferences.ACTIVE_HYPERLINK_COLOR, null); 38 | public List computeCompletionProposals(ContentAssistInvocationContext context, IProgressMonitor monitor) { 39 | List propList = new ArrayList(); 40 | List newpropList = new ArrayList(); 41 | List propList2 = new ArrayList(); 42 | 43 | ICompletionProposal first; 44 | DataManager datamanger = new DataManager(context,monitor); 45 | Activator.applyoperationlist.add(new ApplyOperation(ConsoleOperationListener2.ope.getStart(), ConsoleOperationListener2.ope.getAuthor(), ConsoleOperationListener2.ope.getFilePath(), propList)); 46 | List list = new ArrayList(); 47 | CompletionProposal proposal; 48 | propList = datamanger.JavaDefaultProposal(); 49 | propList2 = datamanger.ContextInformation(); 50 | ApplyOperation ao = new ApplyOperation(ConsoleOperationListener2.ope.getStart(), ConsoleOperationListener2.ope.getAuthor(), ConsoleOperationListener2.ope.getFilePath(), propList); 51 | System.out.println(ao.toString()); 52 | return newpropList; 53 | } 54 | 55 | public List computeContextInformation(ContentAssistInvocationContext context, IProgressMonitor monitor) { 56 | // TODO Auto-generated method stub 57 | return null; 58 | } 59 | 60 | public String getErrorMessage() { 61 | // TODO Auto-generated method stub 62 | return null; 63 | } 64 | 65 | public void sessionEnded() { 66 | // TODO Auto-generated method stub 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /jp.ac.ritsumei.cs.fse.contentassist/src/jp/ac/ritsumei/cs/fse/contentassist/entity/ApplyOperation.java: -------------------------------------------------------------------------------- 1 | package jp.ac.ritsumei.cs.fse.contentassist.entity; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import org.eclipse.jface.text.contentassist.ICompletionProposal; 7 | 8 | public class ApplyOperation { 9 | private int offset; 10 | private int last_offset; 11 | private List InputString = new ArrayList(); 12 | private long applytime; 13 | public String username; 14 | public String path; 15 | private boolean isApplied; 16 | private List propList; 17 | public ApplyOperation(int offset,String username,String path,List propList){ 18 | this.offset = offset; 19 | this.last_offset = offset; 20 | this.username = username; 21 | this.path = path; 22 | this.propList = propList; 23 | InputString.add('.'); 24 | 25 | } 26 | public int getOffset() { 27 | return offset; 28 | } 29 | public void setOffset(int offset) { 30 | this.offset = offset; 31 | } 32 | 33 | public List getInputString() { 34 | return InputString; 35 | } 36 | 37 | public long getApplytime() { 38 | return applytime; 39 | } 40 | public void setApplytime(long applytime) { 41 | this.applytime = applytime; 42 | } 43 | public String getUsername() { 44 | return username; 45 | } 46 | 47 | public String getPath() { 48 | return path; 49 | } 50 | public boolean isApplied(){ 51 | return isApplied; 52 | } 53 | public void update(int operation_offset,String delete_string,String insert_string){ 54 | if (operation_offset <= offset){ 55 | offset = offset + delete_string.length() - insert_string.length(); 56 | last_offset = last_offset + delete_string.length() - insert_string.length(); 57 | } 58 | else if(last_offset > operation_offset&&operation_offset > offset){ 59 | last_offset = last_offset + insert_string.length() - delete_string.length(); 60 | for(int i=0;i<=operation_offset - offset;i++){ 61 | InputString.remove(i); 62 | } 63 | InputString.add(operation_offset-offset, insert_string.charAt(0)); 64 | } 65 | 66 | } 67 | /* (non-Javadoc) 68 | * @see java.lang.Object#toString() 69 | */ 70 | @Override 71 | public String toString() { 72 | return "ApplyOperation [offset=" + offset + ", last_offset=" 73 | + last_offset + ", InputString=" + InputString + ", applytime=" 74 | + applytime + ", username=" + username + ", path=" + path 75 | + ", propList=" + propList + "]"; 76 | } 77 | 78 | 79 | } 80 | -------------------------------------------------------------------------------- /structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liaoziyang/ContentAssist/9f1c42158ddc765438b5e488ccf699372850fb2e/structure.png -------------------------------------------------------------------------------- /編集履歴から算出した開発者の関心度に基づくコード補完.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liaoziyang/ContentAssist/9f1c42158ddc765438b5e488ccf699372850fb2e/編集履歴から算出した開発者の関心度に基づくコード補完.pdf --------------------------------------------------------------------------------