Generated toString() text from class name - java

I am devicing an abstract class that will override toString() with an automated message, as such:
public abstract class AbstractTask {
abstract void run();
abstract int calculate();
private String makeMessage() {
String raw = this.getClass().toString();
// do regex stuff here!
}
#Override
public String toString() {
return makeMessage();
}
My implemented (extends AbstractTask) classes might be called something like
TaskXRQMinimize
TaskListParallell
TaskVerifyRepositoryEmpty
TaskCreateXRQs
TaskCreateZRQs
TaskSendAllSRQToTLS
The output I want to have when calling the classes toString() methods are:
Task XRQ Minimize
Task List Parallell
Task Verify Repository Empty
Task Create XRQs
Task Create ZRQs
Task Send All SRQ To TLS
I made a simple regex pattern to find these words:
([A-Z]{1}[a-z]+|[A-Z]{3}[a-z]?)
How do I implement this?

Make your toString() abstract as well, force subclasses to implement it by returning fixed string. Throw away parsing class name and using regular expressions - too fragile and with poor performance. If you really want to make it this way, at least do the computations once per class, not every time toString() is called.
As for the regular expression, I have something better: StringUtils#splitByCharacterTypeCamelCase() from Apache Commons Lang (there is really no need to reinvent some things):
StringUtils.splitByCharacterTypeCamelCase("fooBar") = ["foo", "Bar"]
StringUtils.splitByCharacterTypeCamelCase("foo200Bar") = ["foo", "200", "Bar"]
StringUtils.splitByCharacterTypeCamelCase("ASFRules") = ["ASF", "Rules"]
In your case:
//yields [Task, Send, All, SRQ, To, TLS]
StringUtils.splitByCharacterTypeCamelCase("TaskSendAllSRQToTLS")

you should use something like str.replaceAll("(\\w)([A-Z]\\w)", "$1 $2")
I have not tried this but it looks reasonable. It replaces all sequence like aBc to "a Bc".

this should put you on the right track:
Parts of the regex that you want to extract, surround with (). then
String raw = "TaskXRQMinimize";
String regexp = "([A-Z]{1}[a-z]+)([A-Z]{3})[a-z]?";
Pattern pattern = Pattern.compile(regexp);
Matcher matcher = pattern.matcher(raw);
if (matcher.find())
{
System.out.println("AFSDgaf " + matcher.groupCount());
System.out.println("afdgafd " + matcher.group(1));
System.out.println("afdgafd " + matcher.group(2));
}

I would just iterate on the name of the class and build a new String. the rule is pretty simple: if the current char is upper case and the next is lower case, then you sould insert a space before the current.

Related

Android arraylist into Textview error

I tried to set value in TextView using my array logic.
Problem:
Instead of my actual value it might set address of string in
textview. I'm guessing this issue is simple, possibly not specifying .toString()?
Value that is being outputted:
com.android.carModel.Car#eacea24f
My code:
StringBuilder builder = new StringBuilder();
val = carDAO.carOutput(carId);
textbx.setText("");
for (Car details : val){
builder.append(details + "\n");
}
textbx.setText(builder.toString());
Your code is actually append someObjectClassname#hashcodenumber i.e com.android.carModel.Car#eacea24f in your case to stringBuilder. To get the desired output you need to do something like this.
`builder.append(details.getName() /*or anything*/ + "\n")`
Do you have access to the Car class? If so, add this method:
public String toString() {
return carName;
}
Replace carName with whatever you want to display. This toString() method is part of the Object class that all classes extend, and when overridden, it will change what something like a List will display.

Java regex and/or string magic to extract IDs from String

I have a Java app that is hitting a 3rd party RESTful web service that is returning the following JSON:
{"fizz":
{"widgets":
[
{
"widget_id":"295874"
},
{
"widget_id":"295873"
},
{
"widget_id":"295872"
}
],
"otime":1361993756
},
"resp":"ok"
}
Normally I would use GSON or Genson to map this back to a Java POJO, but this is the only area of the code where I have to do this and I want to be lazy here ;-).
I'm trying to come up with a nifty method that extracts the 3 widget_id values (, and `) and returns them as aList`:
public List<Long> extractIdsFromJson(String json) {
// Can I solve this with a regex perhaps?
}
Not sure what the right approach is - regex, replaceAll, something else? Thanks in advance.
Being lazy here will just bite you in the long run. Parse the JSON and extract the values that way; the 'effort' involved will be less, the code will be more understandable, and future code maintainers will not curse your name.
// untested
public List<Long> extractIdsFromJson(String json) {
List<Long> list = new ArrayList<Long>();
Matcher matcher = Pattern.compile("\"widget_id\":\"?(\\d+)\"?").matcher(json);
while (matcher.find())
list.add(Long.valueOf(matcher.group(1)));
return list;
}
If you like being lazy. Here is the solution. I hope you know whatever entails your choice of solving the problem with regex:
It doesn't check for the structure of the JSON. You ignore the fact that the JSON may be malformed and just blindly extract the data.
It works here since you want a property whose value is not an Object or Array.
RAW regex:
"widget_id"\s*:\s*"(\d+)"
In literal string:
"\"widget_id\"\\s*:\\s*\"(\\d+)\""
Use the regex above with Matcher loop:
Pattern p = Pattern.compile("\"widget_id\"\\s*:\\s*\"(\\d+)\"");
Matcher m = p.matcher(inputString);
while (m.find()) {
System.out.println(m.group(1));
}

Howto convert the value of a hashmap to String i Java

I have a HashMap. I am trying to retrieve the value and print it using the key from the user-code.
The code is:
lib.addbook(book2.getISBN(), book2);
Book ret = lib.getbook("978-81-291-1979-7");
System.out.println(ret);
Current Output:
O/P: LibraryPackage.Book#527c6768
I want the output to be a string and to display the actual value not the address of the book.
You have to implement (and override) the toString() method in your Book class, and specify what you want the output to be. E.g.:
#Override
String toString()
{
return this.author+": " + this.title;
}
commons-lang has a great utility for this if you don't want to override the .toString() method, or need to represent it differently in different situations:
Here's a call to build a string based on reflection:
String str = ToStringBuilder.reflectionToString(object);
In fact, this is a great way to implement the .toString() method itself. Another alternative use of this class would be a field by field creation of the string:
String str = new ToStringBuilder(object)
.append("field1", field1)
.append("field2", field2)
.toString();

Java CLI arguments syntax for object initialization

I'm looking for a tool which will allow me use command-line-style (preferably POSIX) strings to initialize an object' properties and attributes.
For example, you'd provide it with String input formatted like so:
String input = "--firstName=John --MiddleName=\"Louis Victor\" --lastName=Smith";
... and it would setFirstName("John"), setMiddleName("Louis Victor") and setLastName("Smith") on a given object. (which could be a JavaBean)
Please note that the input is a single String, not an array String[] as is the case with many popular CLI argument "parsers".
This is all similar to args4j but I couldn't get that to work... and I'm hoping to avoid using #annotations.
Does anyone have code/libraries/tools which could accomplish this?
For your use case, forget regular CLI parsers, you need a custom-tailored solution. If you really have such a simple argument syntax (parameters always begin with --, no occurrences of -- in the parameter values), you can use a simple Guava-based solution like this class:
Parse the String Arguments
public class ArgParser{
// split on (optional whitespace) + "--"
private final Splitter paramSplitter = Splitter.on(
Pattern.compile("\\s*\\-{2}")).omitEmptyStrings();
// find key=value (with optional double quotes around value)
private final Pattern keyValuePattern = Pattern
.compile("(.+?)=\"?(.*?)\"?$");
public Map<String, String> getParamValues(final String posixString){
final Map<String, String> paramValues = Maps.newLinkedHashMap();
Matcher matcher;
for(final String param : paramSplitter.split(posixString)){
matcher = keyValuePattern.matcher(param);
if(!matcher.find()){
throw new IllegalArgumentException("Bad parameter: " + param);
}
paramValues.put(matcher.group(1), matcher.group(2));
}
return paramValues;
}
}
Usage
final String input =
"--firstName=John --middleName=\"Louis Victor\" --lastName=Smith";
System.out.println(new ArgParser().getParamValues(input));
Output
{firstName=John, middleName=Louis Victor, lastName=Smith}
Now you can take the map and use it with a Bean library like commons-beanutils (I prefer the Spring BeanWrapper personally, but that only makes sense if you use Spring anyway)
Define the Bean Class
Any way, I'll use this value holder class:
public class Name{
private String firstName;
private String middleName;
private String lastName;
#Override
public String toString(){
return Objects
.toStringHelper(this)
.add("first name", firstName)
.add("middle name", middleName)
.add("last name", lastName)
.toString();
}
// + getters & setters
}
Set the Bean Properties
Now we'll use BeanUtils.populate(Object, Map) to apply the parameter values, like this:
final String input =
"--firstName=John --middleName=\"Louis Victor\" --lastName=Smith";
final Map<String, String> paramValues =
new ArgParser().getParamValues(input);
final Name name = new Name();
BeanUtils.populate(name, paramValues);
System.out.println(name);
Output:
Name{first name=John, middle name=Louis Victor, last name=Smith}
Caveat: Supported Property Types
BeanUtils.populate() supports setting the following property types:
... String, boolean, int, long, float, and double.
In addition, array setters for these
types (or the corresponding primitive
types) can also be identified.
Source: BeanUtilsBean.populate(Object, Map)
If you need parameter conversion beyond that, you should probably look into using the Spring BeanWrapper after all, it's extremely powerful, has many built-in property editors and you can add custom property editors. Just change the code like this:
final Name name = new Name();
final BeanWrapper wrapper = new BeanWrapperImpl(name);
wrapper.setPropertyValues(paramValues);
Reference:
BeanWrapper
PropertyAccessor.setPropertyValues(Map)
If I understand correctly, you are looking for a Java library to parse POSIX-style command line parameters. I used JSAP some time ago and it was really cool (it was using XML configuration back then).
This
-firstName John -lastName Smith
is no POSIX, you mean
--firstName John --lastName Smith
This may be the reason, why you can't get it working.
Update:
As I look at the example, it doesn't look like it could be the reason.

Custom conversion specifiers in java

I want my data structures to be custom formatted.
e.g. I have a DS
Address {
string house_number,
string street,
string city,
long pin_code,
}
Now, I want to associate certain conversion specifiers with each of these fields.
e.g. house_number -> H
street -> S,
city -> C,
pin_code -> P
...
So that something like
myPrintWriter.printf("Mr A lives in %C", address_instance)
yields "Mr A lives in boston" (if address_instance.city = boston) etc..
It seems there is no easy way to do this. java.util.Formatter seems to be final. The only customization it provides is via the interface Formattable, but that helps in customizing the 's' conversion specifier only.
Is there a way to add our custom conversion specifiers? Any help will be much appreciated.
Thanks,
It seems there is no easy way to do this. java.util.Formatter seems to be final.
That's true, but you can still use composition. I would do something like the following:
class ExtendedFormatter {
private Formatter defaultFormatter;
// provide the same methods like the normal Formatter and pipe them through
// ...
// then provide your custom method, or hijack one of the existing ones
// to extend it with the functionality you want
// ...
public Formatter format(String format, Object... args) {
// extract format specifiers from string
// loop through and get value from param array
ExtendedFormattable eft = (ExtendedFormattable)args1;
String specifierResult = eft.toFormat(formatSpecifier); // %C would return city
// use specifierResult for the just queried formatSpecifier in your result string
}
}
The hard part is to know how to attach the different format specifiers to the fields you want to output. The first way I can think of, is to provide your own ExtendedFormattable interface that each class that should be used with the ExtendedFormatter can implement, and return the according values for your custom format specifiers. That could be:
class Address implements ExtendedFormattable {
public String toFormat(String formatSpecifier) { // just an very simple signature example
// your custom return values here ...
}
}
There's also annotations, but I think that's not a very viable way.
A sample call would look like:
ExtendedFormatter ef = new ExtendedFormatter();
ef.format("Mr A lives in %C", address_instance);
I believe you will need to write your own formatter which works the way you want.

Categories

Resources