Eclipse AST not changing files which are not opened in eclipse - eclipse-plugin

I am trying to modify source code using eclipse plugin, JDT and AST (Abstract Syntax Tree). I can read all Java files and make operation on all those file, But when i am saving those changes (Edits) in to files using
TextEdit edits = rewriter.rewriteAST();
// apply the text edits to the compilation unit
edits.apply(document);
iCompilationUnit.getBuffer().setContents(document.get());
It only make changes in file those are open in eclipse in unsaved mode. Rest of files are not affected.
Find my code snippet below:
CompilationUnit cu = parse(iCompilationUnit);
MethodVisitor visitor = new MethodVisitor();
cu.accept(visitor);
String source = iCompilationUnit.getSource();
Document document= new Document(source);
ASTRewrite rewriter = ASTRewrite.create(cu.getAST());
cu.recordModifications();
for (MethodDeclaration methodDeclaration : visitor.getMethods()) {
System.out.print("Method name: " + methodDeclaration.getName()
+ " Return type: " + methodDeclaration.getReturnType2());
MethodDeclaration methodDecl = methodDeclaration;
Block block = methodDecl.getBody();
ListRewrite listRewrite = rewriter.getListRewrite(block, Block.STATEMENTS_PROPERTY);
Statement placeHolder = (Statement) rewriter.createStringPlaceholder("System.out.println(\"Test Print\");", ASTNode.EMPTY_STATEMENT);
listRewrite.insertFirst(placeHolder, null);
}
TextEdit edits = rewriter.rewriteAST();
// apply the text edits to the compilation unit
edits.apply(document);
iCompilationUnit.getBuffer().setContents(document.get());

Try to:
Apply the TextEdit directly to the ICompilationUnit instead of using Document.
Use ICompilationUnit.commitWorkingCopy to save the changes
I use code similar to this:
iCompilationUnit.becomeWorkingCopy(new NullProgressMonitor());
CompilationUnit cu = parse(iCompilationUnit);
ASTRewrite rewriter = ASTRewrite.create(cu.getAST());
... process AST ...
iCompilationUnit.applyTextEdit(rewrite.rewriteAST(), new NullProgressMonitor());
iCompilationUnit.commitWorkingCopy(false, new NullProgressMonitor());

Related

Where and how do I make another folder to put text files so they work when I export?

I have a folder with my text files that can read and write and work in eclipse. But, when I export to jar, it fails because the files are not found, meaning they are not exported and I don't know how to make eclipse do that. I'm sure the solution is out there, but I don't know exactly what I'm searching for. Do I make a relative directory and how? Or another source folder? What exactly do I need to do?
This shows I have a folder called conf where my files are stored but it is not there on export.
Scanner in = new Scanner(new FileReader("conf/Admins.txt"));
FileWriter out = new FileWriter("conf/CurrentUser.txt");
int id = 0;
String name = "";
String pass = "";
boolean found = false;
while(in.hasNext()) {
id = in.nextInt();
name = in.next();
pass = in.next();
if(id == userID) {
out.write(id + " " + name + " " + pass + "\n");
found = true;
break;
}
}
All I had to do was once exported, put my conf file in the same place as the exported jar file. I don't know if, theres a better way but this is a win for me.

How to move text in PDF?

Is there a Java or Nodejs library that can move existing text in a PDF file?
I'd like to extract all the text nodes, then move some of them to a new location based on some conditions.
I tried PdfClown, galkahana/HummusJS, Hopding/pdf-lib, but seems they don't have exactly what I need.
can anyone help? thanks
After inspecting the variables, I figured out how to move text, here is the code
PrimitiveComposer composer = new PrimitiveComposer(page);
ContentScanner scanner = composer.getScanner();
tranverse(scanner);
composer.flush();
...
while (level.moveNext()){
ContentObject content = level.getCurrent();
if (content instanceof Text){
...
List<ContentObject> objects = text.getBaseDataObject().getObjects();
for(ContentObject co: objects){
if(co instanceof SetTextMatrix){
List<PdfDirectObject> operands = ((SetTextMatrix)co).getOperands();
PdfInteger y = (PdfInteger)operands.get(5);
operands.set(5, new PdfInteger(y.getIntValue()-100));
}
}

eclipse JDT setting the project

I am a beginner to Eclipse JDT. I was going through some tutorial and found one good example for creating the java file. In this below example in which project they will create the package and java file. I could not see any code pointing to any of the project name. Please make me understand if I am wrong. I just run the below example. I could not see any output..
AST ast = AST.newAST(AST.JLS3);
CompilationUnit unit = ast.newCompilationUnit();
PackageDeclaration packageDeclaration = ast.newPackageDeclaration();
packageDeclaration.setName(ast.newSimpleName("example"));
unit.setPackage(packageDeclaration);
ImportDeclaration importDeclaration = ast.newImportDeclaration();
QualifiedName name =
ast.newQualifiedName(
ast.newSimpleName("java"),
ast.newSimpleName("util"));
importDeclaration.setName(name);
importDeclaration.setOnDemand(true);
unit.imports().add(importDeclaration);
TypeDeclaration type = ast.newTypeDeclaration();
type.setInterface(false);
type.modifiers().add(ast.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD));
type.setName(ast.newSimpleName("HelloWorld"));
MethodDeclaration methodDeclaration = ast.newMethodDeclaration();
methodDeclaration.setConstructor(false);
List modifiers = methodDeclaration.modifiers();
modifiers.add(ast.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD));
modifiers.add(ast.newModifier(Modifier.ModifierKeyword.STATIC_KEYWORD));
methodDeclaration.setName(ast.newSimpleName("main"));
methodDeclaration.setReturnType2(ast.newPrimitiveType(PrimitiveType.VOID));
SingleVariableDeclaration variableDeclaration = ast.newSingleVariableDeclaration();
variableDeclaration.setType(ast.newArrayType(ast.newSimpleType(ast.newSimpleName("String"))));
variableDeclaration.setName(ast.newSimpleName("args"));
methodDeclaration.parameters().add(variableDeclaration);
org.eclipse.jdt.core.dom.Block block = ast.newBlock();
MethodInvocation methodInvocation = ast.newMethodInvocation();
name =
ast.newQualifiedName(
ast.newSimpleName("System"),
ast.newSimpleName("out"));
methodInvocation.setExpression(name);
methodInvocation.setName(ast.newSimpleName("println"));
InfixExpression infixExpression = ast.newInfixExpression();
infixExpression.setOperator(InfixExpression.Operator.PLUS);
StringLiteral literal = ast.newStringLiteral();
literal.setLiteralValue("Hello");
infixExpression.setLeftOperand(literal);
literal = ast.newStringLiteral();
literal.setLiteralValue(" world");
infixExpression.setRightOperand(literal);
methodInvocation.arguments().add(infixExpression);
ExpressionStatement expressionStatement = ast.newExpressionStatement(methodInvocation);
block.statements().add(expressionStatement);
methodDeclaration.setBody(block);
type.bodyDeclarations().add(methodDeclaration);
unit.types().add(type);
You may take a look at this. It uses Java Model, which means you will need to create a plug-in to make it work.
// create a project with name "TESTJDT"
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
IProject project = root.getProject("TESTJDT");
project.create(null);
project.open(null);
//set the Java nature
IProjectDescription description = project.getDescription();
description.setNatureIds(new String[] { JavaCore.NATURE_ID });
//create the project
project.setDescription(description, null);
IJavaProject javaProject = JavaCore.create(project);
//set the build path
IClasspathEntry[] buildPath = {
JavaCore.newSourceEntry(project.getFullPath().append("src")),
JavaRuntime.getDefaultJREContainerEntry() };
javaProject.setRawClasspath(buildPath, project.getFullPath().append(
"bin"), null);
//create folder by using resources package
IFolder folder = project.getFolder("src");
folder.create(true, true, null);
//Add folder to Java element
IPackageFragmentRoot srcFolder = javaProject
.getPackageFragmentRoot(folder);
//create package fragment
IPackageFragment fragment = srcFolder.createPackageFragment(
"com.programcreek", true, null);
//init code string and create compilation unit
String str = "package com.programcreek;" + "\n"
+ "public class Test {" + "\n" + " private String name;"
+ "\n" + "}";
ICompilationUnit cu = fragment.createCompilationUnit("Test.java", str,
false, null);
//create a field
IType type = cu.getType("Test");
type.createField("private String age;", null, true, null);

Adobe AIR NativeProcess fails with spaces in arguments?

I have a problem running the NativeProcess if I put spaces in the arguments
if (Capabilities.os.toLowerCase().indexOf("win") > -1)
{
fPath = "C:\\Windows\\System32\\cmd.exe";
args.push("/c");
args.push(scriptDir.resolvePath("helloworld.bat").nativePath);
}
file = new File(fPath);
var nativeProcessStartupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo();
nativeProcessStartupInfo.executable = file;
args.push("blah");
nativeProcessStartupInfo.arguments = args;
process = new NativeProcess();
process.start(nativeProcessStartupInfo);
in the above code, if I use
args.push("blah") everything works fine
if I use
args.push("blah blah") the program breaks as if the file wasn't found.
Seems like I'm not the only one:
http://tech.groups.yahoo.com/group/flexcoders/message/159521
As one of the users their pointed out, it really seems like an awful limitation by a cutting edge SDK of 21st century. Even Alex Harui didn't have the answer there and he's known to workaround every Adobe bug:)
Any ideas?
I am using AIR 2.6 SDK in JavaScript like this, and it is working fine even for spaces.
please check your code with this one.
var file = air.File.applicationDirectory;
file = file.resolvePath("apps");
if (air.Capabilities.os.toLowerCase().indexOf("win") > -1)
{
file = file.resolvePath(appFile);
}
var nativeProcessStartupInfo = new air.NativeProcessStartupInfo();
nativeProcessStartupInfo.executable = file;
var args =new air.Vector["<String>"]();
for(i=0; i<arguments.length; i++)
args.push(arguments[i]);
nativeProcessStartupInfo.arguments = args;
process = new air.NativeProcess();
process.addEventListener(air.ProgressEvent.STANDARD_OUTPUT_DATA, onOutputData);
process.addEventListener(air.ProgressEvent.STANDARD_INPUT_PROGRESS, inputProgressListener);
process.start(nativeProcessStartupInfo);
To expand on this: The reason that this works (see post above):
var args =new air.Vector["<String>"]();
for(i=0; i<arguments.length; i++)
args.push(arguments[i]);
nativeProcessStartupInfo.arguments = args;
is that air expects that the arguments being passed to the nativeProcess are delimited by spaces. It chokes if you pass "C:\folder with spaces\myfile.doc" (and BTW for AIR a file path for windows needs to be "C:\\folder with spaces\\myfile.doc") you would need to do this:
args.push("C:\\folder");
args.push("with");
args.push("spaces\\myfile.doc");
Hence, something like this works:
var processArgs = new air.Vector["<String>"]();
var path = "C:\\folder with spaces\\myfile.doc"
var args = path.split(" ")
for (var i=0; i<args.length; i++) {
processArgs.push(args[i]);
};
UPDATE - SOLUTION
The string generated by the File object by either nativePath or resolvePath uses "\" for the path. Replace "\" with "/" and it works.
I'm having the same problem trying to call 7za.exe using NativeProcess. If you try to access various windows directories the whole thing fails horribly. Even trying to run command.exe and calling a batch file fails because you still have to try to pass a path with spaces through "arguments" on the NativeProcessStartupInfo object.
I've spent the better part of a day trying to get this to work and it will not work. Whatever happens to spaces in "arguments" totally destroys the path.
Example 7za.exe from command line:
7za.exe a MyZip.7z "D:\docs\My Games\Some Game Title\Maps\The Map.map"
This works fine. Now try that with Native Process in AIR. The AIR arguments sanitizer is FUBAR.
I have tried countless ways to put in arguments and it just fails. Interesting I can get it to spit out a zip file but with no content in the zip. I figure this is due to the first argument set finally working but then failing for the path argument.
For example:
processArgs[0] = 'a';
processArgs[1] = 'D:\apps\flash builder 4.5\project1\bin-debug\MyZip.7z';
processArgs[2] = 'D:\docs\My Games\Some Game Title\Maps\The Map.map';
For some reason this spits out a zip file named: bin-debugMyZip.7z But the zip is empty.
Whatever AIR is doing it is fraking up path strings. I've tried adding quotes around those paths in various ways. Nothing works.
I thought I could fall back on calling a batch file from this example:
http://technodesk.wordpress.com/2010/04/15/air-2-0-native-process-batch-file/
But it fails as well because it still requires the path to be passed through arguments.
Anyone have any luck calling 7z or dealing with full paths in the NativeProcess? All these little happy tutorials don't deal with real windows folder structure.
Solution that works for me - set path_with_space as "nativeProcessStartupInfo.workingDirectory" property. See example below:
public function openPdf(pathToPdf:String):void
}
var nativeProcessStartupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo();
var file:File = File.applicationDirectory.resolvePath("C:\\Windows\\System32\\cmd.exe");
nativeProcessStartupInfo.executable = file;
if (Capabilities.os.toLowerCase().indexOf("win") > -1)
{
nativeProcessStartupInfo.workingDirectory = File.applicationDirectory.resolvePath(pathToPdf).parent;
var processArgs:Vector.<String> = new Vector.<String>();
processArgs[0] = "/k";
processArgs[1] = "start";
processArgs[2] = "test.pdf";
nativeProcessStartupInfo.arguments = processArgs;
process = new NativeProcess();
process.start(nativeProcessStartupInfo);
process.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, onOutputData);
}
args.push( '"blah blah"' );
Command line after all supports spaces if they are nested whithin "".
So if lets say you have a file argument :
'test/folder with space/blah'
Convert it to the following
'test/"folder with space"/blah'
Optionally use a filter:
I once had a problem like this in AIR, i just simply filter the text before i push it into the array. My refrence use CASA lib though
import org.casalib.util.ArrayUtil;
http://casalib.org/
/**
* Filters a string input for 'safe handling', and returns it
**/
public function stringFilter(inString:String, addPermitArr:Array = null, permitedArr:Array = null):String {
var sourceArr:Array = inString.split(''); //Splits the string input up
var outArr:Array = new Array();
if(permitedArr == null) {
permitedArr = ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" as String).split('');
}
if( addPermitArr != null ) {
permitedArr = permitedArr.concat( addPermitArr );
}
for(var i:int = 0; i < sourceArr.length; i++) {
if( ArrayUtil.contains( permitedArr, sourceArr[i] ) != 0 ) { //it is allowed
outArr.push( sourceArr[i] );
}
}
return (outArr.join('') as String);
}
And just filter it via
args.push( stringFilter( 'blah blah', new Array('.') ) );
Besides, it is really bad practice to use spaces in file names / arguments, use '_' instead. This seems to be originating from linux though. (The question of spaces in file names)
This works for me on Windws7:
var Xargs:Array = String("/C#echo#a trully hacky way to do this :)#>#C:\\Users\\Benjo\\AppData\\Roaming\\com.eblagajna.eBlagajna.POS\\Local Store\\a.a").split("#");
var args:Vector.<String> = new Vector.<String>();
for (var i:int=0; i<Xargs.length; i++) {
trace("Pushing: "+Xargs[i]);
args.push(Xargs[i]);
};
NPI.arguments = args;
If your application path or parameter contains spaces, make sure to wrap it in quotes. For example path of the application has spaces C:\Program Files (x86)\Camera\Camera.exe use quotes like:
"C:\Program Files (x86)\Camera\Camera.exe"

ClearCase : list the content of a directory (ls) using CAL

In ClearCase, you can list the content of a directory using "cleartool ls".
My question is how can I do the same thing using CAL (ClearCase Automation Layer). The reason I prefer the COM API is because I won't have to parse the output of "ls".
So far, I am able to get the VOB and the View successfully, but I didn't find any method for listing the content.
My code so far:
IClearCase cc = new ApplicationClass();
CCVOB vob = cc.get_VOB("\\VOB-name");
CCView view = cc.get_View("ViewTag");
Thank you for your help.
I wrote VonC's answer in C# for those interrested.
string[] files = Directory.GetFiles("View path here", "*.*", SearchOption.AllDirectories);
foreach (string file in files)
{
try
{
CCVersion ver = cc.get_Version(file);
Console.WriteLine(ver.Path);
}
catch(Exception) {/*the file is not versioned*/}
}
May be this is a good start:
Set CC = Wscript.CreateObject("ClearCase.Application")
Set DirVer = CC.Version(".")
Set FSO = CreateObject("Scripting.FileSystemObject")
Set Folder = FSO.GetFolder(DirVer.Path)
Wscript.Echo "Files under source control: "
For Each File in Folder.Files
On Error Resume Next
Set Ver = CC.Version(File.Name)
If Err.Number = 0 Then
Wscript.Echo Ver.ExtendedPath
End If
Next
The idea being to use ICCVersion methods to try accessing the version of a file. If it does not return an error, it is indeed a versioned file.
Now I know the file is versioned, how can I remove it (rmname).
Do not use RemoveVersion():
Removes irretrievably the version (equivalent to cleartool rmver)
WARNING! This is a potentially destructive operation. Because CAL does not prompt the user for input under any circumstances, there is no confirmation step when RemoveVersion is invoked. Invoking RemoveVersion is equivalent to running cleartool rmver with the -force option.
Instead use the RemoveName from the ICCElement interface.