How to get text format of message without filling up fields - java

I have got my protobuf GeneratedMessage(only castable to this base) and I would like to get the text format(parsable by TextFormat class) including all fields of this message.
I see only two ways:
by reflection find all setters and put in some values, then use TextFormat
get list of fields(from api) and recreate this format
Neither of them is good, so my question is: is there any better way? If not which of these you find better?

If you have a GeneratedMessage, you may simply pass it into any of TextFormat's print methods. GeneratedMessage implements the MessageOrBuilder interface which these methods want.
EDIT: I see, your problem is that you want it to actually print all the fields, and TextFormat only prints fields that have been filled in.
You will have to fill in the fields with dummy data. This is actually pretty easy, though:
Message fillAllFields(Message prototype) {
Message.Builder builder = prototype.newBuilderForType();
for (FieldDescriptor field: builder.getDescriptorForType().getFields()) {
builder.setField(field, prototype.getField(field));
}
return builder.build();
}
The trick here is that we're calling setField() for every defined field, not just the ones that are set in prototype. For the ones that aren't set there, prototype.getField() will return the default value, but we're still explicitly setting the field to that value, so it will now show up in text format. Note that this actually creates a different message from the original -- setting a field to its default value is detectably different from leaving the field unset.

Related

Java getter vs Kotlin getter - any difference?

Lets have these two getters in Kotlin:
data class Foo(var id: String){
val reference get() = Reference("Patient/$id")
}
data class Foo(var id: String){
fun getReference(){ return Reference("Patient/$id") }
}
Does the first one have some performance cons? I like it more, but I am not sure if they are built into same bytecode, or the first one adds more things, because I am basically delaring new variable and not just method.
In your example, they are equivalent behind the scenes (but obviously, you need different syntax for using the property vs. the method). Specifically, Kotlin will generate a backing field if any of the accessors use the field identifier, and the autogenerated get and set accessors do use field. So in order to avoid a backing field, you need to supply your own get accessor and (in the case of a var property) a set accessor, and none of them must use field.
Whether a property has a backing field or not, reading the property turns into a method call to get() behind the scenes, and if it's a var, assigning to the property turns into a method call to set().
Note that it's possible to get into weird situations with var if your accessors are inconsistent: var foo: Int = 3; get() = 42 will always return 42 when you read it, irrespective of the initial value and whatever you might assign to it, because you will get an autogenerated backing field since you omitted the setter, and that's what the autogenerated setter will set.
Using properties instead of Java-style getter/setter methods is strongly preferred in Kotlin.
(Thanks to #AlexeyRomanov for pointing out the specific rules.)

Is it possible to disable "Optional used as field or parameter type" inspection in IntelliJ for private methods?

I don't want to disable the warning altogether and I already know why you supposedly shouldn't use Optional as a parameter. However, I don't think it's relevant to my case.
For illustrative purposes, I have code that looks like this:
//IntelliJ reports: 'Optional<ForeignDataTransferObject>' used as type for parameter 'data'
private LocalSystemPerson extractPerson(Optional<ForeignDataTransferObject> data) {
return data
.map(data -> data.getPeopleListWrapper())
.map(peopleListWrapper -> peopleListWrapper.getList())
.map(listOfForeignPeople -> listOfForeignPeople.stream())
.orElseGet(Stream::empty)
.findFirst()
.map(foreignPerson -> convertToLocalSystemPerson(foreignPerson))
.orElse(someFallbackValue);
}
It's getting the list of people then the the first item then converting it. Since I'm calling an external API and getting a data transfer object with a bunch of fields any of which can be null, any collections are wrapped in an extra class, and even then getting an empty list is a valid case. So, I end up with a verbose code like that to convert a single value. I squirrelled it into a separate helper method to avoid having all that verbosity in one place.
However IntelliJ is complaining that I'm passing an Optional parameter. That is something I'd normally agree with but I don't see it as a problem if it's a private method that I am using to save another method from getting too long - I might need to grab more than one value off the data transfer object.
I still want to avoid creating public methods that accept Optional or fields that hold Optional but I want to disable the inspection for private methods.
I'd prefer to not have to annotate each method with #SuppressWarnings("OptionalUsedAsFieldOrParameterType") as it quickly gets annoying. I can have multiple of these methods in various classes that accept some foreign DTO.
Similarly, I also don't want to pass in a non-Optional parameter only to wrap it inside the method. Especially since In some cases I only have an Optional already, so I'd have to unwrap it then wrap it back with something like myMethod(data.orElse(null)) and then do Optiona.ofNullable(parameter) in the method.
All in all, it seems like an unreasonable limitation to always treat that as a problem even if it's not going to be transferring data across systems or across layers, etc.
So, can I disable that generally from the settings for just private methods but nothing else?
For the current moment there is no option to disable the inspection for private methods. Please follow/comment the issue created for your feature request at YouTrack:
https://youtrack.jetbrains.com/issue/IDEA-207468
Thank you

How can I reset a jMonthChooser and a jYearChooser?

For text fields FieldName.setText(null); can reset the field. How can I do the same for JMonthChooser and JYearChooser fields to reset them to default values?
I don't think there is a way to "reset" a JYearChooser field because its setValue() method takes a primitive int as argument. Therefore:
JYearChooser field = new JYearChooser();
field.setValue(null); // compile error
field.setValue(""); // compile error
Setting the year to a negative value doesn't work either. Your best bet (which is what I have done) is to include a check box that will enable or disable this component. That way, you can do something like this:
if (field.isEnabled())
{
// Do something
}
I needed to do this for a feature that I created to override values. Since I could not set these fields to blank, I needed something to ignore the field if an override wasn't required. This was the best I could come up with to work around that issue.
I assume that JMonthChooser has the same problem. However, this is not the case for JDateChooser. For those field types, you can do the following to check if it is blank:
if (!(JTextField) prodStartDate.getDateEditor().getUiComponent()).getText().equals(""))
{
// Do something
}

How to pass Java null strings to Fitnesse

Following the Fitnesse TestBlankAndNullCells documentation, I am trying to pass null fields into the verify tables. My data types are Strings.
When I leave the field blank, there is a solid red square with no information. When I try adding "null," the actual is empty. The same problem occurred using "blank". Am I missing something?
Here is more documentation on it, which states the keywords "blank" or "null" are required. I was able to manually return the string "null" as the actual, which works when the expected is also the literal "null," but I am hoping to find a cleaner solution in which I can pass in null fields.
According to this question on the Fitnesse forums, it looks like Strings are treated differently with null values.
In the Java world, there are some differences in the way nulls are handled between the 'classic' fixtures like ColumnFixture and the FitLibrary fixtures developed by Rick. My guess is the classic fixtures support the 'null' keyword but FitLibrary doesn't.
In the .NET world, the 'null' keyword is supported by all fixtures.
I found a solution after browsing the Fitnesse forums, straight from one of the developers for Fit, Rick Mugridge:
public String findString(String s) {
if ("".equals(s))
return null;
return s;
}
}
I included this in the ArrayFixture and it worked! Here are some interesting points from Rick's message:
When the myList() method is called for the second table, FitLibrary
automatically wraps it with a SetFixture (because the returned value is
a Set). When it checks each of the name elements, which are of type
String, it determines that there is a findString() method of the right
types, so it calls it to parse the value from the cells in the name
column. That method turns an empty string into a null so that it will
match correctly with the actual value of null.
For any type T, FitLibrary checks for a method public Object
findT(String s). It calls it to parse the String value from a table
cell. This can be used in several ways.
SetFixture, ArrayFixture,
etc will access private instance variables if necessary (eg, no
getter)
Arrays, Lists, Maps, Sets and other Objects are all
auto-wrapped with an appropriate fixture in flow
Flow occurs when
the first fixture in a DoFixture (In the next release, a DoFixture
doesn't need to be the first fixture for flow to occur; it just
starts later.)

Setting a value into a object using reflection

I have an object that has a lot of attributes, each one with it's getter and setter. Each attribute has a non primitive type, that I don't know at runtime.
For example, what I have is this:
public class a{
private typeA attr1;
private typeB attr2;
public typeA getAttr1(){ return attr1; }
public typeB getAttr2(){ return attr2; }
public void setAttr1(typeA at){ attr1 = at; }
public void setAttr2(typeB at){ attr2 = at; }
}
public class typeA{
public typeA(){
// doesn't matter
}
}
public class typeB{
public typeB(){
// doesn't matter
}
}
So, using reflection, I obtained the setter method for an attribute. Setting a value in the standard way is something like this:
a test = new a();
a.setAttr1(new typeA());
But how can I do this using reflection? I already got the setAttr1() method using reflection, but I don't know how to create a new typeA object to be inserted in the setter.
Use Class#newInstance().
Class<TypeA> cls = TypeA.class;
TypeA typeA = cls.newInstance();
Or, in your specific case when you have to determine the type of the method parameter:
Class<?> cls = setterMethod.getParameterTypes()[0];
Object value = cls.newInstance();
setterMethod.invoke(bean, value);
You can learn more about reflection in Sun tutorial on the subject. That said, classnames ought to start with uppercase. I've corrected it in the above example.
By the way, instead of reinventing the Javabean reflection wheel, you may find one of the tools mentioned here useful as well.
Use getDeclaredFields() method in the Class object, to get all fields, then use field.set(classInstance, value) to set the value of field in an instance. Note: you may have to set the accessible flag on the field to true, if the field is private. No need to rely on setter methods.
I encountered this on some stuff I was doing. My general conclusion was that whenever I felt like I needed a class with a bunch of fields I was doing it wrong. Here's my thought process:
Problem:
- I need a large number of fields to hold this data
- All these fields require huge amounts of boilerplate
Solution:
use reflection to reduce the boilerplate < "you are here"
Use metadata to specify how the fields should be used
New Problems:
Reflection is difficult to understand when someone new looks at the code
Once you go meta enough to eliminate more boilerplate, the fields often have no mention in the code except through the metadata--why are they fields?
Specifying the metadata in code becomes bulky quite quickly (easiest way is a string array, by the way)
Solution: Start storing data in a collection and Specify metadata in an external data file
New problem: Errors become hard to find
Be meticulous about error checking and very explicit with your error messages. Make sure any other programmers that might use your code read the error messages. Attempt to indicate when metadata is missing or wrong and how the programmer should update the metdata--include the location of the metadata file.
Problem: No type safety
Yeah, this became somewhat annoying at times. I ended up including type information in the metadata so that if someone put the wrong value in a field, it could be detected--essentially this moves type safety from build time to run time which was fine in my case.
Problem: The metadata is needed repeatedly throughout the life of the object
Rather than looking it up by name every time it's used, I'd parse the metadata at the beginning and put it in an object (call it an IntHolder). This holder would end up in the hashtable and it would contain the current value as well as a reference to the parsed metadata.
Example
Here's what my metadata would end up for one field of a style sheet:
FieldName: Age
FieldType Integer
ScreenBinding: AgeTextField
DBBinding: User.age
Validation: IntRange(0, 120); "Age is out of range"
The field name might be how it is displayed to the user or just for use in your program. In general, you shouldn't need to directly manipulate this type of data by name--but of course you do sometimes.
When you do need to use, use getInt("Age") and setInt("Age", 12) instead of getAge() and setAge(12)--slightly more verbose but not really a problem.
If it is a problem, you can make getAge/setAge helper methods and you never need to know it's not a field, but that does start piling on the boilerplate again.
FieldType: specifies how it's stored and lets you implement type checking.
ScreenBinding and DBBinding are used to copy the value into and out of other systems. I also used this type of mechanism to transfer the data from server to client and back.
The fun one is Validation. When pulling data off the screen it can be passed to a validator in a very progmatic way. The same validator can be used before committing to the DB.
Validators can do a lot more than that, they can act as triggers (if a value changes, do this) or actions (when user submits a screen, do this). These are a simple objects with the ability to take a value (through an interface)--they can be as flexible or powerful as you like but are not tied directly to any object except through the meta-data.
The only problem with this approach is you have to be the type of programmer that enjoys writing fixtures instead of error-prone boilerplate. (Yes, I find that the amount of time is about equal, but I tend to get really slow when I have to implement boilerplate)
After doing this a few times I really love the pattern, but it gets difficult to implement. Next time I do it I'm going to try to make it into a library of some type.
If you want to set a "fresh" object in each setter of your class, you can typically do it by getting the Method, for each Method you get the Class of the arguments with getParameterTypes() , for each Class you invoke Class.newInstance() ... and cross your fingers (that should break with primitive types -I doubt Java does autoboxing here).
You can always ask if a parameter is a pimitive calling isPrimitive()
Why would you want to set "empty" instances for primitive fields of a class? They are already initialized. Do you want to "reset" them ?

Categories

Resources