/*
* Copyright 2009-2010 junithelper.org.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
package org.junithelper.plugin.action;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.ui.IActionDelegate;
import org.eclipse.ui.IEditorActionDelegate;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPage;
import org.junithelper.core.config.Configuration;
import org.junithelper.core.constant.StringValue;
import org.junithelper.core.extractor.ClassMetaExtractor;
import org.junithelper.core.extractor.CurrentLineBreakDetector;
import org.junithelper.core.generator.LineBreakProvider;
import org.junithelper.core.generator.TestCaseGenerator;
import org.junithelper.core.generator.TestCaseGeneratorFactory;
import org.junithelper.core.meta.ClassMeta;
import org.junithelper.core.meta.CurrentLineBreak;
import org.junithelper.core.util.IOUtil;
import org.junithelper.core.util.ThreadUtil;
import org.junithelper.core.util.UniversalDetectorUtil;
import org.junithelper.plugin.constant.Dialog;
import org.junithelper.plugin.io.PropertiesLoader;
import org.junithelper.plugin.util.EclipseIFileUtil;
import org.junithelper.plugin.util.ResourceRefreshUtil;
public class OpenTestCaseAction extends AbstractAction implements IActionDelegate, IEditorActionDelegate {
ISelection selection = null;
public void selectionChanged(IAction action, ISelection selection) {
this.selection = selection;
}
public void setActiveEditor(IAction action, IEditorPart targetEditor) {
}
public void run(IAction action) {
store = getIPreferenceStore();
Configuration config = getConfiguration(store, selection);
PropertiesLoader props = getPropertiesLoader(config.language);
String resourcePathForTestCaseFile = null;
StructuredSelection structuredSelection = null;
try {
if (selection instanceof StructuredSelection) {
// select in view(package explorer, navigator)
structuredSelection = (StructuredSelection) selection;
}
// dialog to confirm
if (isNotSelected(structuredSelection)) {
openWarningForRequired(props);
return;
} else if (isSelectedSeveral(structuredSelection)) {
openWarningForSelectOneOnly(props);
return;
}
String projectName = getProjectName(structuredSelection);
String resourcePathForTargetClassFile = getResourcePathForTargetClassFile(structuredSelection);
String targetClassName = getClassNameFromResourcePathForTargetClassFile(resourcePathForTargetClassFile);
if (targetClassName == null) {
// required to select java file
openWarningForSelectJavaFile(props);
return;
}
resourcePathForTestCaseFile = resourcePathForTargetClassFile.replace(
config.directoryPathOfProductSourceCode, config.directoryPathOfTestSourceCode).replace(
StringValue.FileExtension.JavaFile,
StringValue.JUnit.TestClassNameSuffix + StringValue.FileExtension.JavaFile);
String projectRootAbsolutePath = getWorkspaceRootAbsolutePath(getIWorkspaceRoot())
+ StringValue.DirectorySeparator.General + projectName + StringValue.DirectorySeparator.General;
String testCaseFileAbsolutePath = projectRootAbsolutePath + resourcePathForTestCaseFile;
File testCaseIOFile = new File(testCaseFileAbsolutePath);
if (!testCaseIOFile.exists()) {
// ----------------------------------------
// create new file
String testCaseFilename = getTestClassNameFromClassName(targetClassName);
String msg = props.get(Dialog.Common.notExist) + " (" + testCaseFilename + ")" + StringValue.LineFeed
+ props.get(Dialog.Common.confirmToCreateNewFile);
if (testCaseFilename != null && openConfirm(props, msg)) {
new CreateNewTestCaseAction().run(action, selection);
}
return;
}
// ----------------------------------------
// open test case
int retryCount = 0;
IEditorPart editorPart = null;
while (true) {
try {
IProject project = getIProject(projectName);
IWorkbenchPage page = getIWorkbenchPage();
// -------------------------
// overwrite config
// http://code.google.com/p/junithelper/issues/detail?id=72
String absolutePath = projectRootAbsolutePath + StringValue.DirectorySeparator.General;
config.directoryPathOfProductSourceCode = absolutePath + config.directoryPathOfProductSourceCode;
config.directoryPathOfTestSourceCode = absolutePath + config.directoryPathOfTestSourceCode;
// ----------------------------------------
// target class
IFile targetFile = getIFile(project, resourcePathForTargetClassFile);
String targetFileEncoding = UniversalDetectorUtil.getDetectedEncoding(EclipseIFileUtil
.getInputStreamFrom(targetFile));
String targetSourceCodeString = IOUtil.readAsString(
EclipseIFileUtil.getInputStreamFrom(targetFile), targetFileEncoding);
ClassMeta targetClassMeta = new ClassMetaExtractor(config).extract(targetSourceCodeString);
// ----------------------------------------
// test class
IFile testCaseFile = getIFile(project, resourcePathForTestCaseFile);
String testCaseFileEncoding = UniversalDetectorUtil.getDetectedEncoding(EclipseIFileUtil
.getInputStreamFrom(testCaseFile));
String currentTestCodeString = IOUtil.readAsString(EclipseIFileUtil
.getInputStreamFrom(testCaseFile), testCaseFileEncoding);
CurrentLineBreak currentLineBreak = CurrentLineBreakDetector.detect(currentTestCodeString);
LineBreakProvider lineBreakProvider = new LineBreakProvider(config, currentLineBreak);
TestCaseGenerator generator = TestCaseGeneratorFactory.create(config, lineBreakProvider);
String newTestCodeString = generator.initialize(targetClassMeta)
.getTestCaseSourceCodeWithLackingTestMethod(currentTestCodeString);
// ----------------------------------------
// write file
OutputStreamWriter writer = null;
FileOutputStream outputStream = null;
try {
outputStream = new FileOutputStream(testCaseIOFile);
writer = new OutputStreamWriter(outputStream, getDetectedEncodingFrom(testCaseFile,
config.outputFileEncoding));
writer.write(newTestCodeString);
} finally {
IOUtil.close(writer);
IOUtil.close(outputStream);
}
// ----------------------------------------
// resource refresh
if (!ResourceRefreshUtil.refreshLocal(null, projectName + StringValue.DirectorySeparator.General
+ resourcePathForTestCaseFile + "/..")) {
openWarningForResourceRefreshError(props);
System.err.println("Resource refresh error!");
return;
}
// ----------------------------------------
// open test case file
retryCount = 0;
ThreadUtil.sleep(1500);
while (true) {
try {
editorPart = getIEditorPart(page, testCaseFile);
if (editorPart == null) {
throw new NullPointerException();
}
break;
} catch (Exception e) {
retryCount++;
if (retryCount > 3) {
break;
}
ThreadUtil.sleep(1500);
}
}
editorPart.setFocus();
} catch (Exception e) {
retryCount++;
if (retryCount > 10) {
break;
}
e.printStackTrace();
ThreadUtil.sleep(1500);
}
break;
}
} catch (Exception e) {
e.printStackTrace();
}
}
}