How to recommend parameters in java? - java

Is there any possible way to recommend parameters when I use the method? (Just like annotations?)
I made lots of static final String parameter for url connection and I want to know whether I use right input parameter or not when I code.
Below is my example.
public void myRequest(String inputParameter) {
String requestURL = "";
static final String ex1 = "http://example.com/xml1";
static final String ex2 = "http://example.com/xml2";
static final String ex3 = "http://example.com/xml3";
static final String ex4 = "http://example.com/xml4";
static final String ex5 = "http://example.com/xml5";
static final String ex6 = "http://example.com/xml6";
static final String ex7 = "http://example.com/xml7";
// too many..
// ....
static final String ex125 = "http://example.com/xm125";
if(inputParameter.equals("ex1")) {
requestURL = ex1;
} else if(inputParameter.equals("ex2")) {
requestURL = ex2;
}
// just like this..
// .....
else if(inputParameter.equals("ex125")) {
requestURL = ex125;
}
String requestURL = inputParameter;
URL url = new URL(requestURL);
URLConnection urlConnection = url.openConnection();
// below codes are unnecessary.
}
and I will use that method in the "main" method
public static void main(String[] args) {
myRequest("ex1"); // this!!
}
The point is, when I write the method "myRequest()", IDE will tell me the information about parameter (when the cursor is between '(' and ')'). The only one, that I can be noticed, is "You should write String object." not "You can use ex1 which means loading ex1.xml, ex2 meaning ex2.xml or ... ex125 meaning xm125.xml"
If my hope comes true, the result seems like this.
(Writing the methods)
myRequest(|); // there is cursor between ( and )
"What xml should I request? Umm.. there is ex1 to ex125. Ok.. ex1 means.. my hometown history.. ex2 means my school history.. and Umm.. I should use ex4 ok!"
(And I write below method)
myRequest("ex4");
I want IDE to inform me what String Parameter should I use.
Is there any possible way?

Given your updates to the question, the answer is build around enums and maps.
In other words: you simply, never ever put down a list of constants like you do there; that are then "mapped" (by hard wiring in your code; as you do in your example) to some other incoming strings.
Instead: you could use an enum to hold those constants; and you could also add some method to that enum class that knows how to map incoming strings to the available enum constants.
But the main point is: you want to abandon "raw" strings. The IDE (respectively the compiler) can't help you with adding an "ext1" string as method parameter.
But when you have:
public enum ExUrls {
EX1("http://example.com/xml1"), EX2("...
... a private constructor that takes that url string)
then you do:
void someMethod(ExURls ex) {
and all of a sudden, the IDE will be able to suggest the all potential ExUrl constants to you!

I'm not sure if I got your question right but you can use javadocs.
Here is an example from oracle.
/**
* Returns an Image object that can then be painted on the screen.
* The url argument must specify an absolute {#link URL}. The name
* argument is a specifier that is relative to the url argument.
* <p>
* This method always returns immediately, whether or not the
* image exists. When this applet attempts to draw the image on
* the screen, the data will be loaded. The graphics primitives
* that draw the image will incrementally paint on the screen.
*
* #param url an absolute URL giving the base location of the image
* #param name the location of the image, relative to the url argument
* #return the image at the specified URL
* #see Image
*/
public Image getImage(URL url, String name) {
try {
return getImage(new URL(url, name));
} catch (MalformedURLException e) {
return null;
}
}
All you need to do is type /** and press enter on top of your function then you can add details. These will show up when you hover to its function call.
In your case maybe like this
/**
* This method is very amazing it will cure cancer
* (ex1 - hometown history),
* (ex2 - school history),
* (ex3 - blah blah),
* (ex4 - what is the meaning of life),
* ...
* (ex125 - choose this)
*
* #param inputParameter - (String) You can input ex1 up to ex125
*/
public void myRequest(String inputParameter) {
but if you're looking to restrict input to ex1-ex125 only you need something else.

Related

Parse Java code between braces using Regex and groups

I am creating some java code that takes correctly written .java files as input, and i want to extract the text between braces using a regular expression. I want to use the Pattern and Matcher classes, and not for loops.
I believe its best to create a regex that groups the text in the whole class, and later another regex that will be aplied to the previous output and groups the text in methods.
I got close to getting the class text using the following regex on online regex testers:
\w\sclass.*\{((.*\s*)*)\}
but i'm pretty sure i am doing it wrong by using two groups instead of just one. Furthermore when i use this expression in Java i am actually getting nothing.
Here is an example file that i am using for debugging
package foo.bar;
import java.io.File;
public class Handy {
{
// static block, dont care!
}
/**
* Check if a string is Null and Empty
* #param str
* #return
*/
public static boolean isNullOrEmpty(String str) {
Boolean result = (str == null || str.isEmpty());
return result;
}
/**
* Mimics the String.format method with a smaller name
* #param format
* #param args
* #return
*/
public static String f(String format, Object... args)
{
return String.format(format, args);
}
}
With the example code above, i expect to get:
entire class text
{
// static block, dont care!
}
/**
* Check if a string is Null and Empty
* #param str
* #return
*/
public static boolean isNullOrEmpty(String str) {
Boolean result = (str == null || str.isEmpty());
return result;
}
/**
* Mimics the String.format method with a smaller name
* #param format
* #param args
* #return
*/
public static String f(String format, Object... args)
{
return String.format(format, args);
}
individual method text
Boolean result = (str == null || str.isEmpty());
return result;
return String.format(format, args);
I know how to use the Pattern and Matcher classes already, i just need the right regexes...
After some confusion in the comments section, i would like to share my solution for what i asked, even if it was not very clear.
This is not thoroughly tested code, but it works for my purpose. Some adjustments or improvements are very likely possible. I took some inspiration from the comments i read in this post, and others like this.
I feed each of the following methods the entire plain text found in a .java file, and from there i use Pattern and Matcher to extract what i want.
private static String patternMatcher(String content, String patternText, int groupIndex) {
Pattern pattern = Pattern.compile(patternText);
Matcher matcher = pattern.matcher(content);
if (matcher.find()) {
return matcher.group(groupIndex);
} else {
return "";
}
}
public static String getPackageName(String content) {
return patternMatcher(content, ".*package\\s+(.*)\\s*\\;", 1);
}
public static String getClassName(String content) {
return patternMatcher(content, ".*class\\s+(\\w+)[\\w\\s]+\\{", 1);
}
public static String getClassCode(String content) {
return patternMatcher(content, ".*class.*\\{((.*\\s*)*)\\}", 1);
}
public static String getMethodName(String code) {
String uncommentedCode = removeComments(code).trim();
return patternMatcher(uncommentedCode,
"(public|private|static|protected|abstract|native|synchronized) *([\\w<>.?, \\[\\]]*)\\s+(\\w+)\\s*\\([\\w<>\\[\\]._?, \\n]*\\)\\s*([\\w ,\\n]*)\\s*\\{",
3);
}
public static String removeComments(String content) {
return content.replaceAll("\\/\\*[\\s\\S]*?\\*\\/|([^:]|^)\\/\\/.*$", "$1 ").trim();
}
I double checked but i hope i didn't forget any escape character, be carefull with those.
Lots of people recomended that i used an actual code parsing library, like ANTLR, but i assumed it would take much longer for me to learn how to work with it, then it would take to do with with RegEx. Furthermore i wanted to improve my Regex skills, this exercise definitely taught me some things.

Java question on building HashMap for multiple enums

I'm making an RPG game in Java for a school assignment. In the game I take user input and the first word is the "command word", so I create an enum to convert the strings for user input to enum constants:
public enum CommandWord
{
GO("go"), QUIT("quit"), HELP("help"), BACK("back"), LOOK("look"), DROP("drop"), GRAB("grab"), USE("use"), UNKNOWN("?");
private String commandString;
/*
* Initialize with the corresponding command string.
* #param commandString the command string.
*/
CommandWord(String commandString) {
this.commandString = commandString;
}
public String toString()
{
return commandString;
}
Sometimes the second word is a direction following "go" so I have a second enum for directions with more constants:
UP("up"), DOWN("down"), NORTH("north"), SOUTH("south"), EAST("east"), WEST("west"), UNKNOWN("unknown");
I'm trying to come up with the best method for building a HashMap to store strings and the related enum constants. For command words I have this class:
public class CommandWords
{
// A mapping between a command word and the CommandWord
// that is associated with it
private HashMap<String, CommandWord> validCommands;
/**
* Constructor - initialise the command words.
*/
public CommandWords()
{
validCommands = new HashMap<>();
for (CommandWord command : CommandWord.values()) {
if(command != CommandWord.UNKNOWN) {
validCommands.put(command.toString(), command);
}
}
}
/**
* Searches the HashMap of valid commands for the supplied word.
* #param commandWord The word we're searching for.
* #return The CommandWord that is mapped to the supplied string commandWord,
* or UNKNOWN if it is not in valid command.
*/
public CommandWord getCommandWord(String commandWord)
{
CommandWord command = validCommands.get(commandWord);
if (command!= null) {
return command;
}
else {
return CommandWord.UNKNOWN;
}
}
}
Then I can take userinput and search for the command word, but I can't reuse it for directions, or items, characters etc. I looked at using a generic class but I can't call methods like .values() on it, is there a good way to do this so I can reuse the CommandWords class on different enums?
We have valueOf(String) method on Enum, you don't have to build that map.
For your case, you have a value, and you know which Enum type you would like to convert to. So, just use:
CommandWord.valueOf("QUIT");
Items.valueOf("GEM");
etc..
Enums must be determined at compile-time.

Finding a class reflectively by its simple-name alone

I was wondering if there is any given function that allows me to introspect a class without having to write the packages where the class is contained.
For example, I want to take a look at the methods and superclasses of the class Integer in order to do that I have to specify the packages where the class is located. This will be "java.lang.Integer"
Instead of doing that I want to just type the class name in order to have the information of the class displayed. Just like this "Integer"
How can I make that my program just check the class name, no matter where is it located?
Java will not stop you from creating your own my.company.Integer class and my.other.company.Integer class, so how it cannot know which Integer class is the right one.
The closes thing to an answer I can suggest is to create a pre-defined list of packages where you want to search the class for, and keep trying each until you find your class.
So something like:
class ClassFinder{
public static final String[] searchPackages = {
"java.lang",
"java.util",
"my.company",
"my.company.other" };
public Class<?> findClassByName(String name) {
for(int i=0; i<searchPackages.length; i++){
try{
return Class.forName(searchPackages[i] + "." + name);
} catch (ClassNotFoundException e){
//not in this package, try another
} catch (...){
//deal with other problems...
}
}
//nothing found: return null or throw ClassNotFoundException
return null;
}
}
If you want to get a list of all available packages instead of hard-coding them, see here.
Be warned that this method is unlikely to perform very well, so use it sparingly.
Borrowed code, slightly modified (...from #rodion's answer)
/**
* Returns first loaded Class found in the searchPackages
* #param classname the simple class name (e.g. "String")
* #param searchPackages String[] of packages to search.
* <li>Place the more important packages at the top since the first Class
* found is returned</li>
* <code>//Example
* public static final String[] searchPackages = {
* "java.lang",
* "java.util",
* "my.company",
* "my.company.other" };
* </code>
* #return the loaded Class or null if not found
*/
public static final Class<?> findClassByName(String classname, String[] searchPackages) {
for(int i=0; i<searchPackages.length; i++){
try{
return Class.forName(searchPackages[i] + "." + classname);
} catch (ClassNotFoundException e){
//not in this package, try another
}
}
//nothing found: return null or throw ClassNotFoundException
return null;
}
same code modified to throw an exception if duplicate Class names found
/**
* Returns the loaded Class found in the searchPackages
* #param classname the simple class name (e.g. "String")
* #param searchPackages String[] of packages to search.
* <li>Place the more important packages at the top since the first Class
* found is returned</li>
* <code>//Example
* public static final String[] searchPackages = {
* "java.lang",
* "java.util",
* "my.company",
* "my.company.other" };
* </code>
* #throws RuntimeException if more than one class of the same classname found in multiple packages
* #return the loaded Class (guaranteed to be unique among the searchPackages) or null if not found
*/
public static final Class<?> findClassByNameNoDupes(String classname, String[] searchPackages) {
Class<?> foundClass = null;
for(int i=0; i<searchPackages.length; i++){
try{
boolean wasNull = foundClass == null;
foundClass = Class.forName(searchPackages[i] + "." + classname);
if (!wasNull) throw new RuntimeException(classname + " exists in multiple packages!");
} catch (ClassNotFoundException e){
//not in this package, try another
}
}
return foundClass;
}
That's not possible, classes are loaded dynamically once referenced. So, there is no way to drill down the list of available packages as there is no such thing.
However, there are ways to inspect jars as these are zip files (including the standard JVM jars).

Converting String to Pointer for JNA

I'm trying to use JNA to query the effective permissions for a file in Windows. Eventually, I plan on using the GetEffectiveRightsFromAcl function, but to do so, I need to provide a pointer to a populated TRUSTEE structure. The JNA Platform (platform.jar) doesn't appear define this struct, so I'm trying to define it myself instead. Here's what I have so far:
public static class TRUSTEE extends Structure {
public TRUSTEE() {
super();
}
public TRUSTEE(Pointer p) {
super(p);
read();
}
public Pointer pMultipleTrustee;
public int MultipleTrusteeOperation;
public int TrusteeForm;
public int TrusteeType;
public Pointer ptstrName;
}
I'm trying to populate the structure like this:
private TRUSTEE createTrusteeForCurrentUser() {
TRUSTEE result = new TRUSTEE();
result.TrusteeForm = TRUSTEE_FORM.TRUSTEE_IS_NAME;
result.TrusteeType = TRUSTEE_TYPE.TRUSTEE_IS_USER;
String strName = "CURRENT_USER";
// How can I set result.ptstrName using strName?
}
This Google Groups thread recommends using String fields in structures when a char * is called for. However, I don't think this is appropriate in my situation, considering the ptstrName field is allowed to point to different types of things, depending on the value of TrusteeForm. So, I think I somehow need to convert from String to Pointer instead. I found the NativeString class in JNA, which would work, except it's a package-private class.
What's the recommended way to convert a Java String to a native format and obtain a Pointer to it? Am I even using the right data type for the TRUSTEE struct? I'm somewhat new to JNA, so please excuse me if I'm missing something obvious.
Update
I found a solution to my problem, but if anyone has a better solution I'd still like to hear it.
Assuming you want char * on the native side (you may need more memory allocated if the string contains non-ascii characters),
String myString = "CURRENT_USER";
Pointer m = new Memory(myString.length() + 1); // WARNING: assumes ascii-only string
m.setString(0, myString);
You can then use m wherever you need to reference the "native" string.
For wide strings (wchar_t *),
String myString = "CURRENT_USER";
Pointer m = new Memory(Native.WCHAR_SIZE * (myString.length() + 1));
m.setWideString(0, myString);
I solved the problem by copying the source code for package-private NativeString class and creating a public copy in my project. I had to make one minor alteration due to the use of a package-private method in the constructor.
Update: As #fragorl notes in the comments, the implementation of NativeString shown below is by now quite out-of-date.
Usage:
private static TRUSTEE createTrusteeForCurrentUser() {
TRUSTEE result = new TRUSTEE();
result.TrusteeForm = TRUSTEE_FORM.TRUSTEE_IS_NAME;
result.TrusteeType = TRUSTEE_TYPE.TRUSTEE_IS_USER;
result.ptstrName = new NativeString("CURRENT_USER",true).getPointer();
result.write();
return result;
}
NativeString.java:
/** Provides a temporary allocation of an immutable C string
* (<code>const char*</code> or <code>const wchar_t*</code>) for use when
* converting a Java String into a native memory function argument.
*
* #author Todd Fast, todd.fast#sun.com
* #author twall#users.sf.net
*/
public class NativeString implements CharSequence, Comparable {
private Pointer pointer;
private boolean wide;
/** Create a native string (NUL-terminated array of <code>char</code>).<p>
* If the system property <code>jna.encoding</code> is set, its value will
* be used to encode the native string. If not set or if the encoding
* is unavailable, the default platform encoding will be used.
*/
public NativeString(String string) {
this(string, false);
}
/** Create a native string as a NUL-terminated array of <code>wchar_t</code>
* (if <code>wide</code> is true) or <code>char</code>.<p>
* If the system property <code>jna.encoding</code> is set, its value will
* be used to encode the native <code>char</code>string.
* If not set or if the encoding is unavailable, the default platform
* encoding will be used.
*
* #param string value to write to native memory
* #param wide whether to store the String as <code>wchar_t</code>
*/
public NativeString(String string, boolean wide) {
if (string == null) {
throw new NullPointerException("String must not be null");
}
// Allocate the memory to hold the string. Note, we have to
// make this 1 element longer in order to accommodate the terminating
// NUL (which is generated in Pointer.setString()).
this.wide = wide;
if (wide) {
int len = (string.length() + 1 ) * Native.WCHAR_SIZE;
pointer = new Memory(len);
pointer.setString(0, string, true);
}
else {
byte[] data = Native.toByteArray(string);
pointer = new Memory(data.length + 1);
pointer.write(0, data, 0, data.length);
pointer.setByte(data.length, (byte)0);
}
}
public int hashCode() {
return toString().hashCode();
}
public boolean equals(Object other) {
if (other instanceof CharSequence) {
return compareTo(other) == 0;
}
return false;
}
public String toString() {
String s = wide ? "const wchar_t*" : "const char*";
s += "(" + pointer.getString(0, wide) + ")";
return s;
}
public Pointer getPointer() {
return pointer;
}
public char charAt(int index) {
return toString().charAt(index);
}
public int length() {
return toString().length();
}
public CharSequence subSequence(int start, int end) {
return CharBuffer.wrap(toString()).subSequence(start, end);
}
public int compareTo(Object other) {
if (other == null)
return 1;
return toString().compareTo(other.toString());
}
}
try using Pointer class in http://jna.java.net/javadoc/com/sun/jna/Pointer.html.

read a file using Scanner: Why am I getting an error when using Scanner for read files in java?

This example demonstrates using Scanner to read a file line by line (it does not perform a write operation) I don't know why I get an error when I try to compile. Could somebody explain the reason to me?. I'm using jcreatorLE and JDK 1.6 to run my program:
import java.io.*;
import java.util.Scanner;
public final class File_read {
public static void main(String... aArgs) throws FileNotFoundException {
ReadWithScanner parser = new ReadWithScanner("C:\\Temp\\test.txt");
parser.processLineByLine();
log("Done.");
}
/**
* #param aFileName full name of an existing, readable file.
*/
public ReadWithScanner(String aFileName){
fFile = new File(aFileName);
}
/** Template method that calls {#link #processLine(String)}. */
public final void processLineByLine() throws FileNotFoundException {
Scanner scanner = new Scanner(fFile);
try {
//first use a Scanner to get each line
while ( scanner.hasNextLine() ){
processLine( scanner.nextLine() );
}
}
finally {
//ensure the underlying stream is always closed
scanner.close();
}
}
/**
* Overridable method for processing lines in different ways.
*
* <P>This simple default implementation expects simple name-value pairs, separated by an
* '=' sign. Examples of valid input :
* <tt>height = 167cm</tt>
* <tt>mass = 65kg</tt>
* <tt>disposition = "grumpy"</tt>
* <tt>this is the name = this is the value</tt>
*/
protected void processLine(String aLine){
//use a second Scanner to parse the content of each line
Scanner scanner = new Scanner(aLine);
scanner.useDelimiter("=");
if ( scanner.hasNext() ){
String name = scanner.next();
String value = scanner.next();
log("Name is : " + quote(name.trim()) + ", and Value is : " + quote(value.trim()) );
}
else {
log("Empty or invalid line. Unable to process.");
}
//(no need for finally here, since String is source)
scanner.close();
}
// PRIVATE //
private final File fFile;
private static void log(Object aObject){
System.out.println(String.valueOf(aObject));
}
private String quote(String aText){
String QUOTE = "'";
return QUOTE + aText + QUOTE;
}
}
This is the result from running it:
--------------------Configuration: <Default>--------------------
C:\Users\administrador\Documents\File_read.java:15: invalid method declaration; return type required
public ReadWithScanner(String aFileName){
^
1 error
Process completed.
When you lifted that code from here :-), you renamed the class but not the constructor. Only constructors are allowed to not have return types.
I suggest you either rename the class back or rename the constructor.
I hope this isn't homework. As it stands, your educator would have an easy time proving plagiarism. You'll need to at least change the variable names as well as class names, you might want to also reformat it a bit including changing the order of methods in the class.
That's if it's homework. Which it's not, right? :-)
Your "ReadWithScanner" constructor needs to match the name of the class ("File_read")
public File_read(String aFileName){
fFile = new File(aFileName);
}
Your class is named File_read and your constructor is named ReadWithScanner. The warning is that your constructor needs to be named the same as the class.
The name of the class is File_read, so the constructor name should be File_read but you gave the name as ReadWithScanner that is why its complaining. Compiler thinking its a method name so expecting a return type.

Categories