Eclipse AST variable binding on standalone java application - java

I'm trying to use Eclipse ASTParser in order to analyse and, if possible, add some code to some classes. One of the information I need requires to have bindings, but because this is a standalone project (the final goal it's a command line tool, independent from eclipse) I can't have them (requireBinding() returns null).
After reading a lot of posts, the far that I can go is using this examples in order to use FileASTRequestor but that's not the way to go since it seems to me that we have to give the KEY to bind before generating the AST tree.
I've found somewhere that we can use ASTParser.setEnvironment method in order to use the bindings in a standalone java application, but I don't think I'm doing it correctly. What's wrong with the code below?
private static final String rootDir = "D:\\workspace\\stateless\\";
private static final String[] classpath = java.lang.System.getProperty( "java.class.path" ).split(";");
private static final String source =
"package de.siemens.tools.stateless.test.examples; " +
"public class ClassWithFinalMemberVariables {" +
"private final int _memberIntVariable = 0;" +
"public void method() {" +
"int localVariable = 0;" +
"System.out.println(_memberIntVariable + localVariable);" +
"}" +
"}";
public static void main(String[] args) throws CoreException {
Document document = new Document(source);
ASTParser parser = ASTParser.newParser(AST.JLS4);
parser.setKind(ASTParser.K_COMPILATION_UNIT);
parser.setEnvironment(classpath, new String[] { rootDir },
new String[] { "UTF8" }, true);
parser.setSource(document.get().toCharArray());
parser.setResolveBindings(true);
parser.setBindingsRecovery(true);
CompilationUnit unit = (CompilationUnit)parser.createAST(null);
unit.recordModifications();
unit.accept(new ASTVisitor() {
#Override
public void endVisit(VariableDeclarationFragment node) {
IVariableBinding bind = node.resolveBinding();
if(bind == null)
System.out.println("ERROR: bind is null");
super.endVisit(node);
}
Output is always "ERROR: bind is null".

I've already solved it, the code is here:
http://pasteit.com/19433
Even though I prefer the ASTVisitor model, this one gives me every binding available.
And here is the discussion about the problem, for those of you who are curious: https://bugs.eclipse.org/bugs/show_bug.cgi?id=206391
EDIT: I don't have any idea if this is the best solution or not, if you have any suggestion please let me know

Related

Get .js file value using Java

I have one config.js file:
sOptions = {
enabled: true,
vtest: assign,
stest: remove
}
I want to get value of 'vtest' using Java. I tried below code
ScriptEngine ee = new ScriptEngineManager().getEngineByName("nashorn");
ee.eval(new FileReader("config.js"));
System.out.println("ee: "+ee);
I am not seeing anything is write in log file.
First thing you need valid javascript. When I ran your original js I got exception messsages.
In the fix below I quoted both of your 'assign' and 'remove' values. Also, you need to print out the value that you want.
import javax.script.*;
public class NashornTest{
public static void main(String[] args) throws Exception{
String js = "sOptions = {\n" +
" enabled: true,\n" +
" vtest: 'assign',\n" +
" stest: 'remove'\n" +
"}";
ScriptEngine ee = new ScriptEngineManager().getEngineByName("nashorn");
ee.eval(js);
System.out.println("ee:" + ee);
System.out.println("sOptions: "+ee.get("sOptions"));
}
}
Which shows.
ee:jdk.nashorn.api.scripting.NashornScriptEngine#b3ca52e
sOptions: [object Object]
The next step is to get what you want from the data. Also, if you're just using JSON, you might want to use a JSON library instead of javascript.

Should I map all my indexes with my analyzer on ElasticSearch

I'm "almost" new on Elastic Search. I've been using it for a while but never used Analyzers before.
I can make a full text search on my project but the problem is, when I try to find a name like "Alex", I should completely type down the name correcly. It doesn't work with "Al" or "Ale". It says something like "no match found".
I found some source codes from different sites, but it makes me confused.
What should I do is:
1) Creating a nGram tokenizer
2) Then mapping it with my all indexes?
I have lots of indexes already created and I got errors while creating a mapping on them.
Should I create my analyzer settings and mapping very in the beggining just before indexing my records ?
I'm working on a Java project, so answers on JAVA API will be very appreciated.
Thanks a lot!
mappings should always be created first and then the data should be indexed. if possible, delete your old indices and recreate with new mapping. if you are concerned about loosing your data, then just create a new type for an existing index. the new type can use the new mapping.
for example, here is a piece that uses the Java API to create a custom mapping
public class MappingCreator {
static Logger log = Logger.getLogger(MappingCreator.class.getName());
final static String indexName = "indexName";
final static String typeName = "typeName";
final static String mappingFileName = "pathToMapping.jsonFile";
final static String clusterName = "elasticsearch"; // or name of your cluster
final static String hostName = "localhost";
public static void main(String args[]) throws IOException
{
MappingCreator mapCreator = new MappingCreator();
Client myESclient = getClient();
IndicesExistsResponse res = myESclient.admin().indices().prepareExists(indexName).execute().actionGet();
if (res.isExists()) {
log.warn("Index "+indexName +" already exists. Will be deleted");
final DeleteIndexRequestBuilder deleteIndexBuilder = myESclient.admin().indices().prepareDelete(indexName);
deleteIndexBuilder.execute().actionGet();
}
final CreateIndexRequestBuilder createIndexBuilder = myESclient.admin().indices().prepareCreate(indexName)
.addMapping(typeName, mapCreator.getIndexFieldMapping());
CreateIndexResponse createIndexResponse = createIndexBuilder.execute().actionGet();
log.debug("Created mapping "+createIndexResponse.toString());
myESclient.close();
}
private String getIndexFieldMapping() throws IOException {
return IOUtils.toString(getClass().getClassLoader().getResourceAsStream(mappingFileName));
}
private static Client getClient() {
TransportClient transportClient = null;
try
{
Settings settings = ImmutableSettings.settingsBuilder().put("cluster.name", clusterName).build();
transportClient = new TransportClient(settings);
transportClient = transportClient.addTransportAddress(new InetSocketTransportAddress(hostName, 9300));
/* be very careful about the port number here. by default its 9300. note that this is the TCP port which the java api will use. unlike the http port which is 9200 */
}
catch (Exception e)
{
log.error("Error in MappingCreator creating Elastic Search Client\n"
+ "Message "+e.getMessage()+"\n"
+ "StackTrace "+e.getStackTrace()
);
}
return (Client) transportClient;
}
}
i hope this helps. by the way its really cool that you are making your own nGram tokenizer. i would love to see the code for that and how it is done :)

Last modied by detail for a file using SVNkit

Hi how to get the last modified by value for a file using SVNkit.
Scenario : the file is updated from SVN and itr is available in local repo(working copy).
You could use svn keywords http://svnbook.red-bean.com/en/1.4/svn.advanced.props.special.keywords.html 'modified by' should be author.
You have to ensure, that the file with the keywords will be changed before every check in. This could be done with an ant script.
The keyword could be used in a constant with a second constant extracting the interesting part:
private static final String SVN_AUTHOR_BASE = "$Author: 113665 $";
/** Is filled in automatically on check in */
public static final String SVN_AUTHOR = SVN_AUTHOR_BASE.
substring(9,SVN_AUTHOR_BASE.indexOf('$', 9) - 1);
public static String getLastModifiedBy(File localPath) throws SVNException {
final SVNStatus status = SVNClientManager.newInstance().getStatusClient().doStatus(localPath, false);
return status != null ? status.getAuthor() : null;
}
SVNProperties props=new SVNProperties();
repository.getFile(filePath,new Long(-1),props,null);
String author=props.getSVNPropertyValue("svn:entry:last-author").toString();
is working fine.

Java properties containing dollar delimited variables

I'm storing my app settings in properties file that I use in Ant and in the Java app. Maybe it's not good pratice, but I find it very handy to avoid duplications. The file contains variables such as:
usefulstuff.dir = ${user.home}/usefulstuff
So that other people can run the program on *nix systems, provided that they have the usefulstuff folder in their home directory.
Now, the fascinating thing is that this properties file works fine in Ant (the variable gets resolved to /home/username), while when I load the same file directly in the Java app, I get a string containing ${user.home}/usefulstuff, which is not very useful indeed.
I load the props with this code in Ant:
<loadproperties srcFile="myProps.properties"/>
And in the Java app:
FileInputStream ins = new FileInputStream(propFilePath);
myProps.load(ins);
ins.close();
Am I missing anything? Maybe is there a better way to load properties in a Java app than load()?
I don't think it's particularly "fascinating" that this works in Ant - Ant is deliberately written to do so:
Properties are key-value-pairs where Apache Ant tries to expand ${key} to value at runtime.
and
Ant provides access to all system properties as if they had been defined using a <property> task. For example, ${os.name} expands to the name of the operating system.
If you want the same behaviour, you'll need to implement the same sort of logic. It's possible that you could use the classes from Ant directly, if they do what you want - and if you're happy to ship the relevant binaries (and abide by the licence).
Otherwise, you might want to use a regular expression to find all the matches - or (probably simpler) iterate over all of the system properties and do a simple replacement on them.
As Jon said, it should be straighforward to write the property handling yourself. For eg:
import java.util.*;
public class PropertiesTest
{
public static void main(String[] args)
{
Properties props = new Properties();
props.setProperty("foo", "foo/${os.name}/baz/${os.version}");
props.setProperty("bar", "bar/${user.country}/baz/${user.country}");
System.out.println("BEFORE:");
printProperties(props);
resolveSystemProperties(props);
System.out.println("\n\nAFTER:");
printProperties(props);
}
static void resolveSystemProperties(Properties props)
{
Map<String, String> sysProps = readSystemProperties();
Set<String> sysPropRefs = sysProps.keySet();
Enumeration names = props.propertyNames();
while (names.hasMoreElements())
{
String name = (String) names.nextElement();
String value = props.getProperty(name);
for (String ref : sysPropRefs)
{
if (value.contains(ref))
{
value = value.replace(ref, sysProps.get(ref));
}
}
props.setProperty(name, value);
}
}
static Map<String, String> readSystemProperties()
{
Properties props = System.getProperties();
Map<String, String> propsMap =
new HashMap<String, String>(props.size());
Enumeration names = props.propertyNames();
while (names.hasMoreElements())
{
String name = (String) names.nextElement();
propsMap.put("${" + name + "}", props.getProperty(name));
}
return propsMap;
}
static void printProperties(Properties props)
{
Enumeration names = props.propertyNames();
while (names.hasMoreElements())
{
String name = (String) names.nextElement();
String value = props.getProperty(name);
System.out.println(name + " => " + value);
}
}
}

Trouble accessing Java classes from Firefox extension's Javascript

I'm going to develop a Firefox extension which uses some Java classes.
The extension gets the value of <input type="file"> fields, using Javascript.
The Java class I'm going to create is the following:
public class Firefox {
public static String inFileName;
public static void main(String[] args) throws IOException {
inFileName = "";
try {
inFileName = args[0];
} catch (Exception ex) {}
}
On Javascript, I have to use Java reflection in order to access Java classes.
In this manner I can create my Java object:
var fileInput = e.explicitOriginalTarget; // is an object HTMLInputElement, I get this when a file is selected
strArray = java.lang.reflect.Array.newInstance(java.lang.Class.forName("java.net.URL"),3);
classLoader = java.net.URLClassLoader.newInstance(strArray);
parameters = java.lang.reflect.Array.newInstance(java.lang.Class.forName("java.lang.String"),1);
parameters[0]= fileInput.value;
var aClass = java.lang.Class.forName("Firefox", true, classLoader);
var aStaticMethod = aClass.getMethod("main", [parameters.getClass()]); //gets the main(String[] args) method, here I get the exception*
var myJava = aStaticMethod.invoke(null, [parameters]); //invokes the main method
I've been trying this extension on Firefox-3.5b4 and everything goes fine, but when I try it on Firefox-3.0.10 I get the following exception*:
`InternalError: Unable to convert JavaScript value class [Ljava.lang.String; to Java value of type java.lang.Class[]`
For example, putting the following line before the main method invokation:
alert(parameters + " - " + parameters[0]);
on both Firefox-3.0.10 and 3.5b4 I get an alert window which says:
`[Ljava.lang.String;#194ca6c - /root/demo.pdf` //demo.pdf is the selected file
But only on 3.0.10 I get the exception, ONLY on my GNU/Linux machine. On Windows XP instead I have no problems on both Firefox versions!
Note that on both Windows and Linux the Java plugin version is 6 update 13.
Where am I wrong? Is it a possible bug on Firefox-3.0.10 Javascript engine or must I do any other thing before getting the main(...) method?
assuming your complete class name is "your.package.Firefox" you could do:
importPackage("your.package");
args = java.lang.reflect.Array.newInstance(java.lang.String.TYPE, 1);
Firefox.main(args)
you are incorrectly invoiking the method using;
[parameters.getClass()]
which is passing an argument of type java.lang.Class[] into the signature that is expecting a String object. simply pass the parameters object in as it is.

Categories