BlackBerry 5.0 Control for free-text search - search

I'm developing a BlackBerry 5.0 app.
I have an entity to be displayed on screen in a grid format.
Entity: Employee
Fields: EmpId(int), FirstName(string), LastName(string), Hobby(string)
Once I display the list of entites (which I know how to do), I also need to provide an option for the user to be able to search for an employee (similar to the contacts list). However, the search should be a free-text search and on any field.
E.g. if I have 3 employees
1|Ian|Botham|Cricket
2|Ravi|Shastri|Cricket
3|Ravi|Bopara|Football
and if the user types Ravi, it should show up emp 2 & 3. If he types Cricket, it should show up 1&2 and so forth.
I have tried using KeywordFilterField. However, I'm able to search only on one field. How can I extend this to search for more fields? Or is there a different way to do this? Are there any out-of-the-box controls available for this kind of functionality?
Thanks in advance

Say you have a class for your entity
class Entity
{
int empId;
String firstName;
String lastName;
String hobby ;
public String getSearchableString()
{
return firstName+lastName+hobby;
}
}
Every time you do a search , check to compare entityObject.getSearchableString().
by doing it this way, everytime there is a match in either firstName,lastName or hobby, the search will pick up this object.

Related

Can I create multiple identity tables in ASP.NET MVC?

In my project, Admin adds Instructors, then each Instructor adds his students. When they are added, they'll receive an email asks them to complete registration .
I have the following classes in my project :
1-Student class
Student: int id, int Registry number, int grade, string password, string email, string name
2-Instructor class:
Instructor: int id, string name , string email , string password
3-My database context:
public class InstructorContext:DbContext
{
public InstructorContext() : base("InstructorContext")
{
}
public DbSet<Instructor> Instructors { get; set; }
public DbSet<Student> Students { get; set; }}
When a user loges in , I must determine whether he is an Admin or Instructor or Student. Do I have to use role-based authentication? I already have 2 separate classes for different roles. Is it possible for both of them to inherit from IdentityUser?
No, you cannot have multiple user tables with Identity, at least not technically. All the other core components of Identity (roles, claims, logins, etc.) are setup with foreign keys to one user table.
For your scenario here, you should use inheritance. For example:
public class ApplicationUser : IdentityUser
public class Instructor : ApplicationUser
public class Student : ApplicationUser
By default, Entity Framework will create the one table for ApplicationUser and add a Discriminator column to it. This column will have one of three possible values: "ApplicationUser", "Instructor", and "Student". When EF reads from this table, it will use this column to instantiate the right class. This is what's known as single-table inheritance (STI) or alternatively as table-per-hierarchy (TPH). The main downside to this approach is that all of the properties for all of the classes must be represented on the same table. If you're creating a new Student for example, the columns for an Instructor would still be on the record, only with nulls or defaults for those values. This also means that you can't enforce a property on something like Instructor be required at the database level, as that would prevent saving ApplicationUser and Student instances which are unable to provide those values. In other words, all your properties on your derived classes must be nullable. However, you can always still enforce something like a property being required for the purpose of a form using view models.
If you really want to have separate tables, you can somewhat achieve that goal by changing the inheritance strategy to what's called table-per-type (TPT). What this will do is keep the table for ApplicationUser, but add two additional tables, one each for Instructor and Student. However, all the core properties, foreign keys, etc. will be on the table for ApplicationUser, since that is where those are defined. The tables for Instructor and Student would house only properties that are defined on those classes (if any) and a foreign key to the table for ApplicationUser. When querying, EF will then do joins to bring in the data from all of these tables and instantiate the appropriate classes with the appropriate data. Some purists like this approach better as keeps the data normalized in the database. However, it's necessarily heavier on the query side because of the joins.
One last word of caution, as this trips people up constantly dealing with inheritance with Identity. The UserManager class is a generic class (UserManager<TUser>). The default instance in AccountController, for example, is an instance of UserManager<ApplicationUser>. As a result, if you use that instance, all users returned from queries will be ApplicationUser instances, regardless of the value of the Discriminator column. To get Instructor instances, you would need to instantiate UserManager<Instructor> and use that for your Instructor-related queries.
This is especially true with creating users for the first time. Consider the following:
var user = new Instructor();
UserManager.Create(user);
You might expect that the user would be saved with a discriminator value of "Instructor", but it will actually be saved with "ApplicationUser". This is because, again, UserManager is an instance of UserManager<ApplicationUser> and your Instructor is being upcasted. Again, as long as you remember to use the appropriate type of UserManager<TUser> you'll be fine.

Liferay - Find users by Full name

Is there a way to find Liferay users by FullName? I see there are methods to get a user by screen name and email address, but did not come across anything to get users based on full name. Is it possible?
To get a list of users by their name you'll need to use one of UserLocalServiceUtil's or UserServiceUtil's search method. Like the one below for Liferay Portal 6.1:
public List<User> search(
long companyId, String firstName, String middleName,
String lastName, String screenName, String emailAddress, int status,
LinkedHashMap<String, Object> params, boolean andSearch, int start,
int end, OrderByComparator obc)
throws SystemException
You can pass null for any field, including obc, if you have no other requirement or desired ordering.
If you want to fetch users from database, then dynamic query API can be used to write your own query to fetch matched details.
You may refer this wiki page about writing dynamic queries.
If you like to fetch from search indexer, then faceted search may be used.

JSF displaying entities with IDs: how to translate IDs to descriptions?

In a JSF page I have to display the data from an entity.
This entity has some int fields which cannot be displayed directly but need to be translated into a descriptive string.
Between them some can have a limited number of values, others have lots of possible values (such as a wordlwide Country_ID) and deserve a table on the Db with the association (ID, description).
This latter case can easily be solved navigating via relationship from the original entity to the entity corresponding to the dictionary table (ID, description) but I don't want to introduce new entities just to solve translations form ID to description.
Besides another integer field has special needs: the hundred thousand number should be changed with a letter according to a rule such as 100015 -> A00015, 301023 -> C01023.
Initially I put the translation code inside the entity itself but I know the great limits and drawbacks of this solution.
Then I created a singletone (EntityTranslator) with all the methods to translate the different fields. For cases where the field values are a lot I put them inside a table which is loaded from the singletone and transformed in a TreeMap, otherwise the descriptions are in arrays inside the class.
In the ManagedBean I wrote a getter for EntityTranslator and inside the jsf I use quite long el statements like the following:
#{myManagedBean.entityTranslator.translateCountryID(myManagedBean.selectedEntity.countryID)}
I think the problem is quite general and I'm looking for a standard way to solve it but, as already stated, I don't want to create new 'stupid' entities only to associate an ID to a description, I think it is overkill.
Another possibility is the use of converters Object(Integer) <-> String but I'm more comfortable in having all the translation needs for an Entity inside the same class.
Your question boils down to the following simple line:
How can I display a field different from id of my entity in my view and how can I morph an integer field into something more meaningful.
The answer is that it depends on a situation.
If you solely want to input/output data, you don't need id at all apart from the possible view parameter like ?id=12345. In this case you can input/output anything you want in your view: the id is always there.
If you want to create a new entity most possibly you have a way of generating ids via JPA, or database, or elsehow besides the direct input from the user. In this situation you don't need to mess with ids as well.
If you want to use information on other entities like show user a dropdown box with e.g. a list of countries, you always have the option to separate label (let it be name) and value (let it be id), or even have a unique not null column containing the country name in your database table that will serve as a natural identifier. If you'd like to get data from the user using an input text field you always can create a converter that will do the job of transforming user input strings to actual entity objects.
Regarding the transformation of your integers, you've actually got several choices: the first one is to attach a converter for these fields that will roughly do 301023 -> C01023 and C01023 -> 301023 transformations, the second one is to write a custom EL function and the third one is to prepare the right model beforehand / do the transformations on-the-fly.

Function for listing user parameters

I want to add a form into my application for generating rules considering the attributes of Liferay Users.
Do you know a function for getting a list of this attributes? (List of parameter names)
Example:
1. Address,
2. FullName,
3. AccountId,
4. Create Date,
5. Employee Numbre,
6. And so on.....
Do you know a function for getting the type of each parameter? (Due to check type errors)
Example:
1. Address -> String
2. FullName -> String
Thank you,
Oriol
AFAIK, there is not such a method. But even if it existed, it would not provide all the info you're going for, because some of it, is not an attribute of the User Class, or the corresponding 'user_' table in the LF database.
If you understand how ServiceBuilder Model works, you'll see that there's a complex Model running under the hood, and it's not working like attributes.
For example, there is no 'user.getAddress()'., Because, Address is a Complex Class, subclassing Contact, and keeps a FK to the User. If you want one of his addresses, You can only get all his addresses (User.getAddresses()), and iterate through them, check by ContantactType and e.g. get his "business address". Respectfully, you can't call 'user.setAddress(String)', not even a "user.addAddress(Address)". A working code would look much more like :
//update an existing Address
existingAddr.setStreet1(street);
existingAddr.setZip(zip);
existingAddr.setCity(city);
AddressLocalServiceUtil.updateAddress(existingAddr);
//then update the user, to store the changes.
UserLocalServiceUtil.updateUser(user);
The same goes for the birthday, the Phones, websites and facebook urls etc
For the rest of the 'Attributes' (names and Types), you should look here
You can get a User object by calling:
User u = userService.getUserById(0);
or check liferay docs for UserService
then you can use getters like:
u.getAddresses();
u.getBirthday();
u.getFullName();
you can get it from:
User user = UserLocalServiceUtil.getUser(userId);
user.getFullName();
user.getEmailAddress();

DDD class design dilemma with Value Objects with DB id and Entities

This is a long question so i am gonna go straight to the point. This is pseudo code for better illustration of the problem
DB Structure
User (UserID, Name, LastName)
Address(AddressID, UserID, Street, City, State, ZipCode) =>Many to One User relationship
Phone (PhoneID, UserID, Number, IsPrimary) =>Many to One User relationship
Domain Classes
class User:IEntity
{
public string Name {get;set;}
public string LastName {get;set;}
public ContactInfo{get;set;}
}
class Phone: IValueObject or IEntity? will see later.
{
public int id; // persistence ID, not domain ID
public string Number {get;set;}
}
class Address: IValueObject or IEntity? will see later.
{
public string Line1 {get;set;}
public string City {get;set;}
public string State {get;set;}
public string ZipCode {get;set;}
}
class ContactInfo: IValueObject or IEntity? will see later.
{
List<Address> Addresses {get;set;}
List<Phone> PhoneNumbers {get;set;}
}
So, so far we have a very basic representation of this domain and its models.
My question is the following. Let's say that i want to Update one of the addreses or fix the area code for one of the numbers because of misspelling wnen it was initially typed in.
If i follow Evan's bible about DDD, Value Objects should be immutable. Meaning, no changes to its properties or fields after it was created.
If that's the case, then i guess, none of my classes are a ValueObject, since i can't just recreate the whole ContactInfo class just because one portion of the string in the phone number is wrong. So, i guess that makes all my classes Entities?
Keep in mind that i have a "persistence id" for each of this classes since they are stored in a database.
Let's say that i decide to make Phone a value object, since it's easy to recreate in the constructor
public Phone(string newNumber)
so, it would be something like adding a method to User (agg root) AND contactinfo? (Demeter Law)
like...
User....
public void UpdatePrimaryPhoneNumber(string number)
{
this.ContactInfo.UpdatePrimaryPhoneNumber(number);
}
ContactInfo....
public void UpdatePrimaryPhoneNumber(string number)
{
var oldPhone = Phones.Where(p=>p.IsPrimary).Single();
var newPhone = new Phone(number, oldPhone.persistenceid???-> this is not part of the domain)
oldPhone = newPhone;
}
but i still have to deal with persistence id... grrrrr. what a headache.
Sometimes i feel when i read those blogs that most "ddd experts" that value objects are overused or i would say misused.
What would be the best solution to this scenario?
Thank you
If i follow Evan's bible about DDD, Value Objects should be immutable.
Meaning, no changes to its properties or fields after it was created.
If that's the case, then i guess, none of my classes are a
ValueObject, since i can't just recreate the whole ContactInfo class
just because one portion of the string in the phone number is wrong.
So, i guess that makes all my classes Entities?
While the VO itself may be immutable, a VO doesn't exist on its own - it is always part of an aggregate. Therefore, a VO can be immutable, but the object which references that VO doesn't have to be. What helped me understand VOs is to compare them to something like a primitive Int32 value. The value of each individual integer is immutable - a 5 is always a 5. But anywhere you have an Int32 you can set another value there.
For you domain, what that means is that you can have an immutable address VO, but a given use entity can reference any instance of an address VO. This is what will allow corrections and any other changes to be made. You don't change the individual fields on the address VO - you replace it with a whole new VO instance.
Next, "Persistence ids" shouldn't be expressed in anywhere in domain code. They exist solely to satisfy the needs of the relational databases and NoSQL databases don't require them at all.
The primary phone scenario should look more like this:
public void UpdatePrimaryPhoneNumber(string number)
{
var existingPrimaryNumber = this.Phones.FirstOrDefault(x => x.IsPrimary == true);
if (existingPrimaryNumber != null)
this.Phones.Remove(existingPrimaryNumber);
this.Phones.Add(new Phone(phoneNumber: number, isPrimary = true));
}
This method encapsulates the idea of updating an existing primary phone number. The fact that phone number VOs are immutable means that you have to remove an existing value and replace it with a new one. What usually happens on the database end, especially with ORMs like NHibernate, is it will issue a SQL delete and a subsequent insert to effectively replace all phone numbers. This is OK since the ID of the VOs doesn't matter.
An Entity has a rather unique and individual life-cycle. It has meaning when it stands alone.
The classic example of Order/OrderItem may help with this.
If an OrderItem becomes an Entity it would have a life-cycle of its own. However, this doesn't make too much sense since it is part of an Order. This always seems obvious when looking at an order but less so when looking at your own classes because there can be some references between classes. For instance, an OrderItem represents some Product that we are selling. A Product has a life-cycle of its own. We can have an independent list of Products. How we model the link between an OrderItem and the Product is probably another discussion but I would denormalize the Product data I require into the OrderItem and store the original Product.Id also.
So is the Address class an Entity or a Value Object? This is always an interesting one in that we have that favourite of answers: it depends.
It will be context-specific. But ask yourself whether you have (or need) an independent list of Addresss and then only have a need for the link to that Address in your User. If this is the case then it is an Entity. If, however, your Address makes sense only when it is part of your User then it is a Value Object.
The fact that a Value Object is immutable does not mean you need to replace more than just the specific Value Object. I don't know if I would have a ContactInfo class in your current design since it only wraps the two collections (Address/PhoneNumber) but I would keep it if there is more to it (probably is). So simply replace the relevant PhoneNumber. If you have something like primary/secondary then it is as simple as:
AR.ReplacePrimaryPhoneNumber(new PhoneNumber('...'))
If it is a list of arbitrary numbers then a Remove/Add would be appropriate.
Now for the persistence Id. You do not need one. When you have a primary/secondary scenario you know what your use case is and you can execute the relevant queries in your DB (to update the primary PhoneNumber, for instance). If you have an arbitrary list you may go for add all new numbers in my list and delete those numbers from the DB not in my list; else just delete all the numbers and add everything you have. If this seems like a lot of heavy movement: it is. Event sourcing would move a lot of this to in-memory processing and it is something I will be pushing for seriously going forward.
I hope this all makes sense. Getting away from focusing on the data side of things is rather difficult but necessary. Focus on the domain as though you have no database. When you find friction then do your utmost to not pull database thinking into your domain but try to think about ways you could keep your domain clean and still use your DB of choice.
I would create a class PhoneNumber which contains the String number of the current Phone class and use that as a Value object within your Phone class:
class Phone implements IEntity
{
public int id; // persistence ID, not domain ID
public PhoneNumber number {get;set;}
}
class PhoneNumber implements IValueObject
{
public String number {get;set;};
}
Later when your code evolves you will need (for example) phone number validation and you can put it in the PhoneNumber class. This class can then be reused over the whole application at different places.
The Address is in my opinion a Value object which you can treat like a whole. Although you could model Street, City, etc... which are normally entities, but this is probably over-modelling. No part of the address can change, the whole object is always replaced when changing after initial creation.
The User class is within this example with these boundaries an Aggregate root (and thus also an Entity).
The ContactInfo class is not a ValueObject (not immutable) and not an Entity (no real identity) but an Aggregate. It contains multiple classes which should be seen as a whole.
More info on http://martinfowler.com/bliki/DDD_Aggregate.html
Usually whenever a persistence id is there you should be thinking of an Entity.
If however you would want to add the persistence id's, I would start splitting like the Phone and PhoneNumber class. For example Address (Entity containing id) and AddressValue containing all the other fields (and logic about address values).
This should also solve the headache about managing the persistence identities, since you replace the whole value object and the persistence identity stays the same in case of the updatePrimaryPhoneNumber.

Resources