I'm translating a Java program to vb.net where settings in the application is controlled by a enum.
private enum SmsTagRule {
// KEYWORD DOMAIN BusinessClass PREFIX SEARCHNAME SEARCHPARAM SENDEMAIL KEYWORDS...
BAG_TAG("BagTag", "BagTag", "FoundBagTag", "b", "SearchBagTag", "490_TagNumber", true, "BagTag"),
SKI_TAG("SkiTag", "SkiTag", "FoundSkiTag", "a", "SearchSki", "518_LabelNo", false, "SkiTag", "ski"),
PC_TAG("PcTag", "ds", "FoundPC", "", "SearchPcTag", "585_LabelNo", false, "pc");
And depending on witch "TAG" in chosen different settings are getting returned. Is there any way to do this in vb.NET. I have thought about creating one enum for each one of these TAG's but it seems like it should be a better solution to this.
Any Ideas?
Go on and create a custom Type representing your settings:
Class TagRule
Public Shared BAG = new TagRule("BagTag", "BagTag", "FoundBagTag", ...)
Public Shared Ski = new TagRule("SkiTag", "SkiTag", "FoundSkiTag", ...)
...
Dim _keyword As String
Public Property Keyword as String
Public Get
return _keyword
End
Private Set
_keyword = value
End
End Property
...
Private Sub New(keyword as String, domain as String, businessclass as String, ...)
_keyword = keyword
_domain = domain
....
End Sub
End Class
And you can use it like this:
Dim setting As TagRule = Nothing
If somecondition Then
setting = TagRule.Ski
Else
setting = TagRule.BAG
End If
Dim keyword = setting.Keyword
Dim domain = setting.Domain
Related
A simple question on SPEL collection selection.
Look at section 10.5.17 Collection Selection on this page
https://docs.spring.io/spring/docs/4.3.10.RELEASE/spring-framework-reference/html/expressions.html
List<Inventor> list = (List<Inventor>) parser.parseExpression(
"Members.?[Nationality == 'Serbian']").getValue(societyContext);
What i need is the selection 'Serbian' to come from outside and not be a fixed hard coded String.
Just for arguments sake consider that, we could get it as "selectedNationality" from the same society class from the same page in the link.
Modified class with selectedNationality
public class Society {
private String name;
public static String Advisors = "advisors";
public static String President = "president";
private List<Inventor> members = new ArrayList<Inventor>();
private Map officers = new HashMap();
// new selector field
private String selectedNationality;
......
}
New Selection
The new selection SPEL would look like
List<Inventor> list = (List<Inventor>) parser.parseExpression(
"Members.?[Nationality == selectedNationality]").getValue(societyContext);
When we try that the error is that "selectedNationality" is not a part of the Member object.
Does that mean that for collection selection in spring expression language we would need a hard coded String ? If yes does anyone know why ?
Found out how to do it. So the way is to use variables
see 10.5.11 Variables # [https://docs.spring.io/spring/docs/4.3.10.RELEASE/spring-framework-reference/html/expressions.html][1]
Set Variable
So in our case we wold do this set variable :
Inventor tesla = new Inventor("Nikola Tesla", "Serbian");
StandardEvaluationContext context = new StandardEvaluationContext(tesla);
context.setVariable("selectedNationality ", "Serbian");
New Selection
The new selection SPEL would look like this with #selectedNationality
List<Inventor> list = (List<Inventor>) parser.parseExpression(
"Members.?[Nationality == #selectedNationality]").getValue(societyContext);
Works like a charm !
I'm trying to find a simple/efficient way to store multiple values under each index for my application, for example:
1 = {54, "Some string", false, "Some other string"}
2 = {12, "Some string", true, "Some other string"}
3 = {18, "Some string", true, "Some other string"}
So that I can set this as a static variable which can then be accessed from various object instances via the single index value (the only variable within each object). Essentially, sort of like a "multi dimensional dictionary".
I have looked at 2D arrays, but they seem to be limited to single data types (Int, string, etc) and also looked at hash maps - which also seemed limited as if using more than two values, would require a list variable which again comes back the the single data type problem. Any advice on a simple solution for this please?
Define a class for those entries, and use an array of objects. So the class might be something like:
class Thingy {
private int someNumber;
private String someString;
private boolean someBool;
private String someOtherString;
public Thingy(int _someNumber, String _someString, boolean _someBool, String _someOtherString) {
this.someNumber = _someNumber;
this.someString = _someString;
this.someBool = _someBool;
this.someOtherString = _someOtherString;
}
public int getSomeNumber() {
return this.someNumber;
}
// ...setter if appropriate...
// ...add accessors for the others...
}
...and then you do:
Thingy[] thingies = new Thingy[] {
new Thingy(54, "Some string", false, "Some other string"),
new Thingy(12, "Some string", true, "Some other string"),
new Thingy(18, "Some string", true, "Some other string")
};
The backbone of Python heavily relies on dictionary data structures, many instances can be reflected, assigned and accessed through using the __dict__ attribute. If you have a model that frequently has to access a dozen dictionaries or so, replicating something like the following in Python would reduce quite a lot of the unnecessary Java idiosyncrasies:
class ExampleObject:
spam = "example"
title = "email title"
content = "some content"
obj = ExampleObject()
print obj.spam # prints "example"
print obj.__dict__["spam"] # also prints "example"
Just throwing an alternative option out there for you.
I have a property file (a.txt) which has the values (Example values given below) like below
test1=10
test2=20
test33=34
test34=35
By reading this file, I need to produce an output like below
value = 35_20_34_10
which means => I have a pattern like test34_test2_test33_test1
Note, If the 'test33' has any value other than 34 then I need to produce the value like below
value = 35_20_10
which means => I have a pattern like test34_test2_test1
Now my problem is, every time when the customer is making the change in the logic, I am making the change in the code. So what I expect is, I want to keep the logic (pattern) in another property file so I will be sending the two inputs to the util (one input is the property file (A.txt) another input will be the 'pattern.txt'),
My util has to be compare the A.txt and the business logic 'pattern.txt' and produce the output like
value = 35_20_34_10 (or)
value = 35_20_10
If there an example for such pattern based logic as I expect?
Any predefined util / java class does this?
Any help would be Great.
thanks,
Harry
First of all, svasa's answer makes a lot of sense, but covers different level of
abstraction. I recommend you read his answer too, that pattern should
be useful.
You may wanna look at Apache Velocity and FreeMarker libraries to see how they structure their API.
Those are template engines - they usually have some abstraction of pattern or format, and abstraction of variable/value binding (or namespace, or source). You can render a template by binding it with a binding/namespace, which yields the result.
For example, you may wanna have a pattern "<a> + <b>", and binding that looks like a map: {a: "1", b: "2"}. By binding that binding to that pattern you'll get "1 + 2", when interpreting <...> as variables.
You basically load the pattern from your pattern.txt, then load your data file A.txt (for example, by treating it as properties and using Properties class) and construct binding based on these properties. You'll get your output and possibility to customize the pattern all the time.
You may call the sequences like test34_test2_test33_test1 as a pattern, let me call them as constraints when building something.
To me this problem best fits into a
builder pattern.
When building the value you want, you tell the builder that these are my constraints(pattern) and these are my original properties like below:
new MyPropertiesBuilder().setConstraints(constraints).setProperties(original).buildValue();
Details:
Set some constraints in a separate file where you specify the order of the properties and their values like :
test34=desiredvalue-could-be-empty
test2=desiredvalue-could-be-empty
test33=34
test1=desiredvalue-could-be-empty
The builder goes over the constraints in the order specified, but get the values from the original properties and build the desired string.
One way to achieve your requirement through builder pattern is to define classes like below :
Interface:
public interface IMyPropertiesBuilder
{
public void setConstraints( Properties properties );
public void setProperties( Properties properties );
public String buildValue();
}
Builder
public class MyPropertiesBuilder implements IMyPropertiesBuilder
{
private Properties constraints;
private Properties original;
#Override
public void setConstraints( Properties constraints )
{
this.constraints = constraints;
}
#Override
public String buildValue()
{
StringBuilder value = new StringBuilder();
Iterator it = constraints.keySet().iterator();
while ( it.hasNext() )
{
String key = (String) it.next();
if ( original.containsKey( key ) && constraints.getProperty( key ) != null && original.getProperty( key ).equals( constraints.getProperty( key ) ) )
{
value.append( original.getProperty( key ) );
value.append( "_" );
}
}
return value.toString();
}
#Override
public void setProperties( Properties properties )
{
this.original = properties;
}
}
User
public class MyPropertiesBuilderUser
{
private Properties original = new Properties().load(new FileInputStream("original.properties"));;
private Properties constraints = new Properties().load(new FileInputStream("constraints.properties"));
public String getValue()
{
String value = new MyPropertiesBuilder().setConstraints(constraints).setProperties(original).buildValue();
}
}
I am trying to save an Enum field to database but I am having a problem mapping the field to database. The code I have is as follows:
public enum InvoiceStatus {
PAID,
UNPAID;
}
and I am using this enum in one of my application classes as follows:
public class Invoice {
Enumerated(EnumType.ORDINAL)
#Column(name="INVOICE_STATUS", nullable = false, unique=false)
private InvoiceStatus invoiceStatus;
}
finally I let the app user select the Invoice Status from the view (JSP) using a drop down menu.
But I am not sure how to map the value received from the drop down menu selection to the Invoice Status field
I tried mapping the value received to short as follows, but it won't compile
invoice.setInvoiceStatus(Short.parseShort(request.getParameter("inbStatus")));
can someone please tell me how to map the data received from the view to the enum field?
Enum ordinal values are zero based indexes. In your case:
PAID = 0
UNPAID = 1
So the following code will return PAID:
int invoiceStatus = 0;
invoice.setInvoiceStatus(InvoiceStatus.values()[invoiceStatus]);
And the following code will return UNPAID:
int invoiceStatus = 1;
invoice.setInvoiceStatus(InvoiceStatus.values()[invoiceStatus]);
That means you should be able to do this way:
short invoiceStatus = Short.parseShort(request.getParameter("inbStatus"));
invoice.setInvoiceStatus(InvoiceStatus.values()[invoiceStatus]);
But only if inbStatus is 0 or 1. You should always validate user input for null and invalid values.
I see that u are using
Enumerated(EnumType.ORDINAL)
however after a while it could be quite difficult to troubleshoot if your enum will grow. Another issue with the ordinal is that you could refactor your code and change the order of the enum values and after that you could be in trouble. Mainly if it is a shared codebase and someone just decides to cleanup the code and "group the relevant enum constants together". If you'll use:
Enumerated(EnumType.STRING)
Directly the enum "name" will be inserted into the database. (Therefore you need Varchar type). If you want to present more user friendly version of your enum you could probably have:
public enum InvoiceStatus {
PAID(0, "Paid"), UNPAID(1, "Unpaid"), FAILED(2, "Failed"), PENDING(3, "Pending");
private int st;
private in uiLabel;
private InvoiceStatus(int st, String uiLabel){
this.st = st;
this.uiLabel = uiLabel;
}
private Map<String, InvoiceStatus> uiLabelMap = new HashMap<String, InvoiceStatus> ();
static {
for(InvoiceStatus status : values()) {
uiLableMap.put(status.getUiLabel(), status);
}
}
/** Returns the appropriate enum based on the String representation used in ui forms */
public InvoiceStatus fromUiLabel(String uiLabel) {
return uiLableMap.get(uiLabel); // plus some tweaks (null check or whatever)
}
//
// Same logic for the ORDINAL if you are keen to use it
//
}
Probably this could be also a solution for your problem, however i would really not use the ORDINAL based mapping. But just personal feeling.
I want to bind an indexed property to JFace ComboViewer.
Lets say that I have a DataModel class like this:
class DataModel {
private String[] props = {"A","B","C"};
private PropertyChangeSupport pcs = new PropertyChangeSupport(this);
public String getProperties( int idx ){
return props[idx];
}
public void setProperties( int idx, String value ){
String oldVal = props[idx];
props[idx] = value;
pcs.fireIndexedPropertyChange( "properties", idx, oldVal, value );
}
// code to add/remove PropertyChangeListener
// ...
}
The data binding code for simple property would look like this:
DataModel dataModel = ...
ComboViewer propertyChoice = ...
DataBindingContext ctx = new DataBindingContext();
IObservableValue target = ViewerProperties.singleSelection().observe( propertyChoice );
IObservableValue model = BeanProperties.value( DataModel.class, "properties" ).observe(dataModel);
ctx.bindValue( target, model );
but with an indexed property I have to inform the ctx at which index is the value that I want to bind. I have tried
IObservableValue model = BeanProperties.value( DataModel.class, "properties[0]" ).observe(dataModel);
but it doesn't work.
Is it possible to bind indexed property instead of simple property? How?
Unfortunately this seems to be unsupported. I was looking for exactly the same functionality. There is no documentation in BeanProperties that says it is supported.
When looking into the implementation of BeanProperties.value, you find that it delegates to BeanPropertyHelper for reading and writing a property. The method Object readProperty(Object source, PropertyDescriptor propertyDescriptor) does not know about the subclass IndexedPropertyDescriptor. When it is invoked for an indexed property, readProperty tries to use a read method that reads the entire array. I think this method is optional for indexed properties. For indexed properties it should use the IndexedPropertyDescriptor.getIndexedReadMethod().
Depending on your use case you may be able to workaround the problem by using BeanProperties.list. However you cannot use this in combination with indexed properties. I tried this by adding a method that returns the entire array but still keeping the method that does a "fireIndexedPropertyChange". Unfortunately this gives a ClassCastException: Eclipse's BeanListProperty seems to suppose that the value in the change event is an array or list. However for an indexed property it is a single element of the array.
Or perhaps you can use an observable map instead?