"Generic" Parameters on model (Java) - java

In C # I could use (on data-annotations) this code below without problems:
[RegularExpression(#"^myRegex$", ErrorMessage = "The field {0} is not in the correct format.")]
public string Name { get; set; }
But in Java it doesn't work, I tried it:
#Pattern(regexp = "^myRegex$", message = "The field {0} is not in the correct format.")
private String name;
The {0} just return {0}, not the "name" field.
So, could someone help me with some example in Java to make it work?

Related

Proto Message - Get Field by String (name)

I want to get a specific Field from a proto Message with a String, i will try my best to explain what i need to know:
For example we have this .proto File:
message Employee {
string id = 1;
PersonData person_data = 2;
...
}
message PersonData {
string first_name = 1;
string surname = 2;
...
}
Now iam getting a String with a field name like "person_data.first_name".
For example if you want to get the id you must just write:
FieldDescriptor fieldDescriptor = message.getDescriptorForType().findFieldByName("id");
But i need the field "first_name". How can i manage this?
I tried a lot of methods but nothing worked.
Anyone any ideas?

RavenDB query returns null

I'm on RavenDB 3.5.35183. I have a type:
import com.mysema.query.annotations.QueryEntity;
#QueryEntity
public class CountryLayerCount
{
public String countryName;
public int layerCount;
}
and the following query:
private int getCountryLayerCount(String countryName, IDocumentSession currentSession)
{
QCountryLayerCount countryLayerCountSurrogate = QCountryLayerCount.countryLayerCount;
IRavenQueryable<CountryLayerCount> levelDepthQuery = currentSession.query(CountryLayerCount.class, "CountryLayerCount/ByName").where(countryLayerCountSurrogate.countryName.eq(countryName));
CountryLayerCount countryLayerCount = new CountryLayerCount();
try (CloseableIterator<StreamResult<CountryLayerCount>> results = currentSession.advanced().stream(levelDepthQuery))
{
while(results.hasNext())
{
StreamResult<CountryLayerCount> srclc = results.next();
System.out.println(srclc.getKey());
CountryLayerCount clc = srclc.getDocument();
countryLayerCount = clc;
break;
}
}
catch(Exception e)
{
}
return countryLayerCount.layerCount;
}
The query executes successfully, and shows the correct ID for the document I'm retrieving (e.g. "CountryLayerCount/123"), but its data members are both null. The where clause also works fine, the country name is used to retrieve individual countries. This is so simple, but I can't see where I've gone wrong. The StreamResult contains the correct key, but getDocument() doesn't work - or, rather, it doesn't contain an object. The collection has string IDs.
In the db logger, I can see the request coming in:
Receive Request # 29: GET - geodata - http://localhost:8888/databases/geodata/streams/query/CountryLayerCount/ByName?&query=CountryName:Germany
Request # 29: GET - 22 ms - geodata - 200 - http://localhost:8888/databases/geodata/streams/query/CountryLayerCount/ByName?&query=CountryName:Germany
which, when plugged into the browser, correctly gives me:
{"Results":[{"countryName":"Germany","layerCount":5,"#metadata":{"Raven-Entity-Name":"CountryLayerCounts","Raven-Clr-Type":"DbUtilityFunctions.CountryLayerCount, DbUtilityFunctions","#id":"CountryLayerCounts/212","Temp-Index-Score":0.0,"Last-Modified":"2018-02-03T09:41:36.3165473Z","Raven-Last-Modified":"2018-02-03T09:41:36.3165473","#etag":"01000000-0000-008B-0000-0000000000D7","SerializedSizeOnDisk":164}}
]}
The index definition:
from country in docs.CountryLayerCounts
select new {
CountryName = country.countryName
}
AFAIK, one doesn't have to index all the fields of the object to retrieve it in its entirety, right ? In other words, I just need to index the field(s) to find the object, not all the fields I want to retrieve; at least that was my understanding...
Thanks !
The problem is related to incorrect casing.
For example:
try (IDocumentSession sesion = store.openSession()) {
CountryLayerCount c1 = new CountryLayerCount();
c1.layerCount = 5;
c1.countryName = "Germany";
sesion.store(c1);
sesion.saveChanges();
}
Is saved as:
{
"LayerCount": 5,
"CountryName": "Germany"
}
Please notice we use upper case letters in json for property names (this only applies to 3.X versions).
So in order to make it work, please update json properties names + edit your index:
from country in docs.CountryLayerCounts
select new {
CountryName = country.CountryName
}
Btw. If you have per country aggregation, then you can simply query using:
QCountryLayerCount countryLayerCountSurrogate =
QCountryLayerCount.countryLayerCount;
CountryLayerCount levelDepthQuery = currentSession
.query(CountryLayerCount.class, "CountryLayerCount/ByName")
.where(countryLayerCountSurrogate.countryName.eq(countryName))
.single();

How to Bind a Model to a SWT Text but showing only one field in the text

I have a Remote File Model which has fields as file name, file path, and connection IP,connection port etc for the remote directory.I want to show only the file path in a Text.
I am using JFace Data binding for binding the model to SWT Text but I am able to bind only 1 field to it.
Please help me to bind the Complete model to the Text and showing only one field.
Also tell me if it is possible or not or there is some other way.
If I understand you correctly you want to show multiple model fields in one SWT Text widget? You can do it in the following way:
class FileModel {
private String name;
private String filePath;
private String ip;
// other fields, getters and setters
public String getFileSummary() {
return name + " : " + filePath + " : " + ip;
}
public void setFileSummary(String summary) {
// ignore
}
}
Then you can bind it like this:
FileModel model;
new DataBindingContext().bindValue(SWTObservables.observeText(text, SWT.Modify),
BeansObservables.observeValue(model, "fileSummary"), new UpdateValueStrategy(), new UpdateValueStrategy());
The idea is that while specifying "fileSummary" field name to bind in your model, JFace will look for getter and setter for that field, so you don't actually need a field itself.
In getter you can provided required info and you could even parse some special format in setter and assign those to related fields, something like this:
public void setFileSummary(String summary) {
// todo: implement in a smart way;)
String[] parts = summary.split(" : ");
name = parts[0];
filePath = parts[1];
ip = parts[2];
}

Include parameters for spring shell before method

I am working on a Spring Shell project. The tool is a command line tool to manipulate data in a database. There are commands like add user (which adds a record to a table in database). In order to execute any commands the user of the tool has to be connected to the database. I would like to be able to run this all in one line. The user of my tool should be able to write a command like the following.
--database connection string xyz --username abc --password mno add user --username bob --role AA_ADMIN --company Microsoft
Here the three parameters database connection string, username and password are required to run the add user command.
Below I have included some sample code it is from the spring shell reference docs
package commands;
import org.springframework.shell.core.CommandMarker;
import org.springframework.shell.core.annotation.CliAvailabilityIndicator;
import org.springframework.shell.core.annotation.CliCommand;
import org.springframework.shell.core.annotation.CliOption;
import org.springframework.stereotype.Component;
#Component
public class UserManipulation implements CommandMarker {
private boolean simpleCommandExecuted = false;
#CliAvailabilityIndicator({"hw simple"})
public boolean isSimpleAvailable() {
//always available
return true;
}
#CliAvailabilityIndicator({"hw complex", "hw enum"})
public boolean isComplexAvailable() {
if (simpleCommandExecuted) {
return true;
} else {
return false;
}
}
#CliCommand(value = "hw simple", help = "Print a simple hello world message")
public String simple(
#CliOption(key = { "message" }, mandatory = true, help = "The hello world message") final String message,
#CliOption(key = { "location" }, mandatory = false, help = "Where you are saying hello", specifiedDefaultValue="At work") final String location) {
simpleCommandExecuted = true;
return "Message = [" + message + "] Location = [" + location + "]";
}
#CliCommand(value = "hw complex", help = "Print a complex hello world message")
public String hello(
#CliOption(key = { "message" }, mandatory = true, help = "The hello world message") final String message,
#CliOption(key = { "name1"}, mandatory = true, help = "Say hello to the first name") final String name1,
#CliOption(key = { "name2" }, mandatory = true, help = "Say hello to a second name") final String name2,
#CliOption(key = { "time" }, mandatory = false, specifiedDefaultValue="now", help = "When you are saying hello") final String time,
#CliOption(key = { "location" }, mandatory = false, help = "Where you are saying hello") final String location) {
return "Hello " + name1 + " and " + name2 + ". Your special message is " + message + ". time=[" + time + "] location=[" + location + "]";
}
#CliCommand(value = "hw enum", help = "Print a simple hello world message from an enumerated value")
public String eenum(
#CliOption(key = { "message" }, mandatory = true, help = "The hello world message") final MessageType message){
return "Hello. Your special enumerated message is " + message;
}
enum MessageType {
Type1("type1"),
Type2("type2"),
Type3("type3");
private String type;
private MessageType(String type){
this.type = type;
}
public String getType(){
return type;
}
}
}
So currently, hw simple is a command that is required to be executed before running hw complex or hw enum command. I do not want hw simple to be a command instead it the message parameter within the hw simple command should be a parameter that is required as a prerequisite to run hw complex or hw enum. So for example the command that I would like to run is.
--message hw complex --message abc --name1 def --name2 ghi --time 7:98 --location: Seattle
Does anyone know how to do this? If it is not possible to do this I would like to hear that or any alternative ideas if possible.
You have 2 options here:
either make those 3 additional parameters (database, username, password) parameters of each and every command that require them (note that in your particular example, you would need to rename one of those username parameters [the one to connect to the DB, or the one that represents the user to add] as you can't have 2 parameters with the same name obviously).
Use the #CliAvailabilityIndicator approach, similar to what is described in the example, where a first command (maybe named use or connect) first tests the connection with the 3 given parameters and stores them somewhere, so that any further "real" command (such as add user) can use those values.
Also note that you can actually use a combination of the two (i.e. use solution 2 to provide defaults, that may be overridden on a case by case basis by solution 1).
Lastly, please note that you'll never be able to have something like what you describe at the beginning of your question, as command names must be at the beginning and they can't contain -- (options do)

how use protocol buffers?

I watched a lot of tutorials, but I can not understand how to use protocol buffers
Why "message User "? why not "class User "? and how Eclipse has created such a message?
and why name = 2 ? not name = "Max"
ption java_outer_classname="ProtoUser";
message User {
required int32 id = 1; // DB record ID
required string name = 2;
required string firstname = 3;
required string lastname = 4;
required string ssn= 5;
// Embedded Address message spec
message Address {
required int32 id = 1;
required string country = 2 [default = "US"];;
optional string state = 3;
optional string city = 4;
optional string street = 5;
optional string zip = 6;
enum Type {
HOME = 0;
WORK = 1;
}
optional Type addrType = 7 [default = HOME];
}
repeated Address addr = 16;
}
Why "message User "? why not "class User "?
Google Protocol Buffers (GPB) does not have class in its syntax, it has message instead.
https://developers.google.com/protocol-buffers/docs/style
This file is just text file, it should have .proto extension. After all you will run a utility on it which would generate real Java classes which you can import and easily use in your project.
https://developers.google.com/protocol-buffers/docs/javatutorial
Compiling Your Protocol Buffers
protoc -I=$SRC_DIR --java_out=$DST_DIR $SRC_DIR/addressbook.proto
required string lastname = 4;
4 stands for the field id, not a value, it is going to be used to generate a bit stream.
Protobuffer use message(keyword) instead of class
Inside the class you define the structure of. schema.
For example
message Person{
string name = 1;
repeated string id = 2;
Type phoneType = 3;
}
enum Type{
CellPhone = 0;
HomePhone = 1;
}
In the above example, we are defining the structure of the Person Message.
It has name which datatype is a string, id which is an array of the string and type(when you expect only certain values then use an enum. In this case, we assume that phoneNumber can be either CellPhone or HomePhone. If someone is sending any other value then IT will through UNKNOWN proto value exception)
required: means parameter is required
To use proto first create proto classes using mvn clean install
Then create protobuilder
Protobuilder to set for above proto
Person person = Person.newBuilder().setName("testName")
.setPhoneType(Type.CellPhone)
.addAllId(listIds)
.build;
Once you set the value you can not change it. If you want to change the value then you need to create another proto.
Pesron person1 = Person.newBuilder(person).setName("ChangeName").build;
person1 will have the name ChangeName, phoneType CellPhone, and ids arrays of strings.
More information: https://developers.google.com/protocol-buffers

Categories

Resources