I am trying to restrict the results of my BabelNet query to a specific (Babel)domain. To do that, I'm trying to find out a way to compare the synsets' domains with the domain I need (Geographical). However, I'm having trouble getting the right output, since although the 2 strings match, it still gives me the wrong output. I'm surely doing something wrong here, but I'm out of ideas.
After many trials, the following code was the one that gave me the nearest result to the desired output:
public class GeoRestrict {
public static void main(String[] args) throws IOException {
String file = "/path/to/file/testdata.txt";
BabelNet bn = BabelNet.getInstance();
BufferedReader br = new BufferedReader(new FileReader(file));
String word = null;
while ((word = br.readLine()) != null) {
BabelNetQuery query = new BabelNetQuery.Builder(word)
.build();
List<BabelSynset> wordSynset = bn.getSynsets(query);
for (BabelSynset synset : wordSynset) {
BabelSynsetID id = synset.getID();
System.out.println("\n" + "Synset ID for " + word.toUpperCase() + " is: " + id);
HashMap<Domain, Double> domains = synset.getDomains();
Set<Domain> keys = domains.keySet();
String keyString = domains.keySet().toString();
List<String> categories = synset.getDomains().keySet().stream()
.map(domain -> ((BabelDomain) domain).getDomainString())
.collect(Collectors.toList());
for (String category : categories) {
if(keyString.equals(category)) {
System.out.println("The word " + word + " has the domain " + category);
} else {
System.out.println("Nada! " + category);
}
}
}
}
br.close();
}
}
The output looks like this:
Synset ID for TURIN is: bn:00077665n
Nada! Geography and places
Any ideas on how to solve this issue?
I found my own error. For the sake of completeness I'm posting it.
The BabelDomain needs to be declared and specified (before the while-loop), like this:
BabelDomain domain = BabelDomain.GEOGRAPHY_AND_PLACES;
Related
In my query I can't use hibernate and I need to generate a String as follows:
I have Map<String, String> restrictions instance with 3 keys (id, name and value) and I want to get the entry (String).
if (restrictions.get("id") != null && restrictions.get("name") == null && restrictions.get("value") == null){
return "ID = " + restrictions.get("id");
} else if (restrictions.get("id") != null && restrictions.get("name") != null && restrictions.get("value" != null)){
return "ID = " + restrictions.get("id") + " and Name = " + restrictions.get("name");
}
And so forth...
Explicitly writting the if-else clauses is very unflexible and hardly maintainable way. Any ideas?
Use java.util.StringJoiner:
import java.util.HashMap;
import java.util.Map;
import java.util.StringJoiner;
public class SOPlayground {
public static void main(String[] args) throws Exception {
Map<String, String> restrictions = new HashMap<>();
restrictions.put("id", "foo");
restrictions.put("name", "bar");
restrictions.put("not set", null);
StringJoiner joiner = new StringJoiner(" AND ");
restrictions.keySet().stream().filter((column) -> (restrictions.get(column) != null)).map((column) -> {
StringBuilder builder = new StringBuilder();
builder.append(column).append("='").append(restrictions.get(column)).append("'");
return builder;
}).map((builder) -> builder.toString()).forEach((term) -> {
joiner.add(term);
});
System.out.println(joiner.toString());
}
}
Output:
id='foo' AND name='bar'
Just try to search for questions on "how to iterate over a map in java". How to efficiently iterate over each Entry in a Map? should give you an example.
As for comment, below can be the code, though you can easily optimize it:
StringBuffer clause = new StringBuffer();
for(Map.Entry<String, String> entry : restrictions.entrySet()) {
clause.append(entry.getKey()).append(\"=\").append(entry.getValue());
clause.append(" AND ");
}
String strClause = clause.toString();
strClause = strCluase.subString(0, strClause.length() - 5); //5 is length of " AND "
This question has been answered before. I would prefer using Colin Hebert answer in my opinion.
Your if-else would be fine but you could always override the functions to meet your needs thanks to OOP (code re-usability).
What you want to achieve could be done in various ways and everyone has his own way of coding.
I'm trying to put some Strings to a HashMap, but they wont add.
My code looks like this and I can't seem to understand why they won't add. Can someone help me and give me an explanation to what I'm doing wrong?
HashMap <String, String> akro = new HashMap <String, String>();
public void lesFil() {
try {
BufferedReader br = new BufferedReader(new FileReader("akronymer.txt"));
String line;
while((line = br.readLine()) != null) {
if(!line.contains(" ")) {
continue;
}
String[] linje = line.split("\\s+", 2);
String akronym = linje[0];
String betydning = linje[1];
// System.out.println(a + " || " + b);
akro.put(akronym, betydning);
}
} catch(Exception e) {
System.out.println("Feilen som ble fanget opp: " + e);
}
}
When I'm removing "//", both akronym and betydning prints out fine.
I tried to add this method to test the HashMap but nothing prints out and the size = 0
public void skrivUt() {
for(Map.Entry <String, String> entry : akro.entrySet()) {
System.out.print("Key: " + entry.getKey());
System.out.println(", Value: " + entry.getValue());
}
System.out.println("Antall akronymer: " + akro.size());
}
Part of the file I'm reading from(txt file):
...
CS Chip Select
CS Clear to Send
CS Code Segment
C/S Client/Server
...
Remember that a Map in Java maps one key to one value. In the sample data you provide, it seems that you have multiple values ("Chip Select", "Clear to Send", "Code Segment") for one key ("CS").
You can solve this by either picking a structure other than a Map, changing what you want to store, or changing the value of the Map to a List<String>.
For example:
List<String> values = akro.get(akronym);
if(values == null) {
values = new LinkedList<String>();
akro.put(akronym, values);
}
values.add(betydning);
I'm using Java and Jena API. I have a class Marriage which have 3 Object Properties called "hasHusband", "Haswife" and "dateOfMarriage". The first two are associated with a class Person which has the datatypeproperties hasFirstName, hasLastName, dateOfBirth....
Through the code below I can access the hasFirstName property of the husband.
StmtIterator iter = onto.model.listStatements(null,onto.hasHusband,(RDFNode)null);
while (iter.hasNext()) {
Statement stmt = iter.nextStatement();
Resource P = ((Resource) stmt.getObject());
StmtIterator iter2 = onto.model.listStatements(((Resource) P),onto.hasFirstName,(RDFNode)null);
while (iter2.hasNext()) {
Statement stmt2 = iter2.nextStatement();
firstnameHusband = stmt2.getObject().toString();
}}
I would like to modify this line
StmtIterator iter2 = onto.model.listStatements(((Resource) P),onto.hasFirstName,(RDFNode)null);
in order to access also the hasLastName and hasDateofBirth...
Can you explain me how can I do this?
Thanks
EDITED:
#Pierre
Now it concerns only the class Person.
In case of womans I want to output in a new file (text file) this line below for each woman:
[label= \"" +firstName+ " \"\n\n\"D.Naiss:"+dnai1+"\", "+shape2+"]
And for each man this:
[label= \"" +firstName+ " \"\n\n\"D.Naiss:"+dnai1+"\", "+shape+"]
The diference is in the value of shape.
The problem I have is that he only outputs one woman and one man.
A person is represented like this in my rdf file:
<rdf:Description rdf:about="http://www.fam.com/FAM#Bruno04/02/1980 ">
<j.0:FAMhasGender>H</j.0:FAMhasGender>
<j.0:FAMhasDateOfBirth>04/02/1980</j.0:FAMhasDateOfBirth>
<j.0:FAMhasLastName>DS </j.0:FAMhasLastName>
<j.0:FAMhasFirstName> Bruno</j.0:FAMhasFirstName>
</rdf:Description>
Here is the relevant code:
public void accessProp() {
readFile(inputFile); // rdf
String fname;
String dd;
String gen;
ExtendedIterator instances = onto.person.listInstances();
Individual instance = null;
Individual firstInstance = null;
while (instances.hasNext()) {
instance = (Individual) instances.next();
gen = instance.getPropertyValue(onto.hasGender).toString();
fname = instance.getPropertyValue(onto.hasFirstName).toString();
dd = instance.getPropertyValue(onto.hasDateOfBirth).toString();
writeFile(fname, dd, genr);
}
}
// Write text file
public void writeFile(String fn, String dbir, String gn) {
String fileout = "D:/file1.txt";
String firstName = fn;
String dateB = dbir;
String gender = gn;
BufferedWriter out;
try {
out = new BufferedWriter(new FileWriter(fileout, true));
if (gender.equals("F")) {
out.write("[label= \"" + firstName + " \"\n\n\"D.Naiss:" + dnai1 + "\", " + shape + "]");
}
else if (gender.equals("M")) {
out.write("[label= \"" + firstName + " \"\n\n\"D.Naiss:" + dnai1 + "\", " + shape2 + "]");
}
out.newLine();
// flushes and closes the stream
out.close();
} catch (IOException e) {
System.out.println("There was a problem:" + e);
}
}
Can you tell me what should I do to solve my problem?
Thanks
If I understand the intent of the question, you want an iterator that gives you the first name, last name, date of birth etc for each Resource. The iterator would be one row per Resource.
This is what SPARQL can do for you.
In outline:
PREFIX : ...
SELECT *
{ ?z :hasHusband ?p .
?p :hasFirstName ?firstName ;
:hasLastName ?lastName ;
:hasDateOfBirth ?dob ;
.
}
and query onto.model.
create a helper function to get a specific property:
public RDFNode getProperty(Resource subject,Property prop)
{
RDFNode object=null;
StmtIterator iter2 = this.onto.model.listStatements(subject,prop,(RDFNode)null);
while (iter2.hasNext()) {
object = iter2.nextStatement().getObject();
break;
}}
iter2.close();
return object;
}
public String getPropertyAsString(Resource subject,Property prop)
{
RDFNode object=getProperty(subject,prop);
return object==null?null:object.toString();
}
(...)
String s1=getPropertyAsString(P,onto.hasFirstName);
String s2=getPropertyAsString(P,onto.hasLastName);
(...)
Suppose I have a simple program which takes argument input in one of the following forms
do1 inputLocation outputLocation
do2 inputLocation outputLocation
do3 [30 or 60 or 90] inputLocation outputLocation
do4 [P D or C] inputLocation outputLocation
do5 [G H I] inputLocation outputLocation
I also have 5 functions with the same names in the program that I need to call. So far I thought of doing it this way (In 'semi pseudocode')
static void main(String[] args)
{
if (args.length == 3)
processTriple(args);
if (args.length == 4)
processQuadruple(args);
throw new UnsupportedOperationException("dasdhklasdha");
}
where the process functions look like this
processDouble(String args[])
{
String operation = "args[0]";
Location input = getInput(args[1]);
Location output = getInput(args[2]);
if (operation.equals("do1"))
do1(input,output);
if (operation.equals("do2"))
do2(input,output);
... etc
}
The way I'm doing it doesn't seem very extensible. If a function's arguments change, or new functions are added it seems like this would be a pain to maintain.
What's the "best" way of going about something like this
at this point I would use commons-cli or jargs. Unless you are trying to do something really special with arguments I would say focus in the real business of your app and don't deal with the mess of the application arguments
Use a command line parsing library.
Ive used JOpt Simple in the past with great results. It lets you abstract away the command line arg mess, and keep a really clean update-able list of arguments. An added benefit is it will generate the help output that standard command line utilities have.
Heres a quick example:
private void runWithArgs (String[] args) {
OptionParser parser = getOptionParser ();
OptionSet options = null;
try {
options = parser.parse (args);
}
catch (OptionException e) {
log.error ("Sorry the command line option(s): " + e.options () +
" is/are not recognized. -h for help.");
return;
}
if (options.has ("h")) {
try {
log.info ("Help: ");
parser.printHelpOn (System.out);
}
catch (IOException e) {
log.error ("Trying to print the help screen." + e.toString ());
}
return;
}
if (options.has ("i")) {
defaultHost = (String) options.valueOf ("i");
}
if (options.has ("p")) {
defaultPort = (Integer) options.valueOf ("p");
}
if (options.has ("q")) {
String queryString = (String) options.valueOf ("q");
log.info ("Performing Query: " + queryString);
performQuery (queryString, defaultHost, defaultPort);
return;
}
}
You can use Cédric Beust's JCommander library
Because life is too short to parse command line parameters
I even creatively violate the original intent of the library to parse NMEA 0183 sentences like $GPRTE as follows:
import java.util.List;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.internal.Lists;
public class GPRTE {
#Parameter
public List<String> parameters = Lists.newArrayList();
#Parameter(names = "-GPRTE", arity = 4, description = "GPRTE")
public List<String> gprte;
}
Code snippet that processes NMEA 0183 sentence $GPRTE from $GPRTE,1,1,c,*37 into -GPRTE 1 1 c *37 to comply with JCommander parsing syntax:
/**
* <b>RTE</b> - route message<p>
* Processes each <b>RTE</b> message received from the serial port in following format:<p>$GPRTE,d1,d2,d3,d4<p>Example: $GPRTE,1,1,c,*37
* #param sequences result of {#link #Utils.process(String)} method
* #see <a href="http://www.gpsinformation.org/dale/nmea.htm#RTE">http://www.gpsinformation.org/dale/nmea.htm#RTE<a><p>*/
public static void processGPRTE(final String command){
final String NMEA_SENTENCE = "GPRTE";
final String PARAM = "\u0001";
final String DOLLAR = "\u0004";
final String COMMA = "\u0005";
String parsedString = command;
if (parsedString.contains("$"+NMEA_SENTENCE)){
parsedString = parsedString.replaceAll("\\$", DOLLAR+PARAM);
parsedString = parsedString.replaceAll(",", COMMA);
System.out.println("GPRTE: " + parsedString);
String[] splits = parsedString.split(DOLLAR);
for(String info: splits){
if (info.contains(PARAM+NMEA_SENTENCE)) {
info = info.replaceFirst(PARAM, "-");
System.out.println("GPRTE info: " + info);
String[] args = info.split(COMMA);
GPRTE cmd = new GPRTE();
new JCommander(cmd, processEmptyString(args));
List<String> message = cmd.gprte;
String data1 = SerialOutils.unescape(message.get(0));
System.out.println("GPRTE: data1 = " + data1);
String data2 = SerialOutils.unescape(message.get(1));
System.out.println("GPRTE: data2 = " + data2);
String data3 = SerialOutils.unescape(message.get(2));
System.out.println("GPRTE: data3 = " + data3);
String data4 = SerialOutils.unescape(message.get(3));
System.out.println("GPRTE: data4 = " + data4);
System.out.println("");
}
}
}
}
I've used args4j with successful results before as well.
Just another option.
I am new to eclipse plugin development and I am trying to convert a IMethod to a string representation of the full method name. I.E.
my.full.package.ClassName.methodName(int param, String string)
so far I have had to hand roll my own solution. Is there a better way?
private static String getMethodFullName(IMethod iMethod)
{
String packageString = "[Default Package]";
try {
IPackageDeclaration[] declarations = iMethod.getCompilationUnit().getPackageDeclarations();
if(declarations.length > 0)
{
packageString = declarations[0].getElementName();
}
} catch (JavaModelException e) {
}
String classString = iMethod.getCompilationUnit().getElementName();
classString = classString.replaceAll(".java", "");
String methodString = iMethod.getElementName() + "(";
for (String type : iMethod.getParameterTypes()) {
methodString += type + ",";
}
methodString += ")";
return packageString + "." + classString + "." + methodString;
}
You can get the Fully qualified name for the type using
method.getDeclaringType().getFullyQualifiedName();
This is probably easier than accessing the package from the compilation unit. The rest of you function looks correct.
One small point: you should use StringBuilder to build up the string instead of adding to a standard String. Strings are immutable so addition creates loads of unrecesary temparary objects.
private static String getMethodFullName(IMethod iMethod)
{
StringBuilder name = new StringBuilder();
name.append(iMethod.getDeclaringType().getFullyQualifiedName());
name.append(".");
name.append(iMethod.getElementName());
name.append("(");
String comma = "";
for (String type : iMethod.getParameterTypes()) {
name.append(comma);
comma = ", ";
name.append(type);
}
name.append(")");
return name.toString();
}
Thanks to iain and some more research I have come up with this solution. It seems like something like this should be built into the JDT....
import org.eclipse.jdt.core.Signature;
private static String getMethodFullName(IMethod iMethod)
{
StringBuilder name = new StringBuilder();
name.append(iMethod.getDeclaringType().getFullyQualifiedName());
name.append(".");
name.append(iMethod.getElementName());
name.append("(");
String comma = "";
String[] parameterTypes = iMethod.getParameterTypes();
try {
String[] parameterNames = iMethod.getParameterNames();
for (int i=0; i<iMethod.getParameterTypes().length; ++i) {
name.append(comma);
name.append(Signature.toString(parameterTypes[i]));
name.append(" ");
name.append(parameterNames[i]);
comma = ", ";
}
} catch (JavaModelException e) {
}
name.append(")");
return name.toString();
}
I am not sure it would take into account all cases (method within an internal class, an anonymous class, with generic parameters...)
When it comes to methods signatures, the classes to look into are:
org.eclipse.jdt.internal.corext.codemanipulation.AddUnimplementedMethodsOperation
org.eclipse.jdt.internal.corext.codemanipulation.StubUtility2
You need to get the jdt.core.dom.IMethodBinding, from which you can extract all what you need.
If you have a MethodInvocation, you can:
//MethodInvocation node
ITypeBinding type = node.getExpression().resolveTypeBinding();
IMethodBinding method=node.resolveMethodBinding();