Some JSF notes

March 31, 2007

While working on the JSF tutorials, I observed a few things:

We can change the error messages for reqired fields by changing messages.properties or creating our own MyMessages.properties and pointing to it from the faces-config.xml file. Messages for the properties we do not change will continue to be served form messages.properties.

In a custom Validator we can set the severity of error messages. I tried setting the severity of a error message to Severity.ERROR, but it resulted in a compilation error. The correct constant was FacesMessage.SEVERITY_ERROR. Hmmmm I would have thought Severity.ERROR was a better choice… especially since it already exists in the Severity class.

To use a custom converter we have to use the tag <f:converter …> but to use one of the default converters like the DateTimeConverter we use another tag <f:convertDateTime …> I think they should have just used the f:converter tag and supplied some default converters for us. This would have kept the tag library simpler and uniform.


JSF Tutorials

March 31, 2007

When I stated learning JSF, I searched the net for good tutorials. The tutorials offered by Netbeans are a good starting point, however they focus on creating a JSF project using the Netbeans IDE. If you are using another IDE, you may have to go around the Netbeans specific stuff.


Some basics

July 25, 2006

Learned and refreshed many interesting things:

  • int a(2); can be used to initialize the variable a to 2, just like int a = 2;
  • A String is not a fundamental data type in C++, but a part of the standard C++ library. We have to include <string> to use this class.
  • This is how we create a string consisting of wide chars. string s = L”Hello”;
  • In C++ we can do typecasting using a functional notation, so that int i =(int)f; is the same as int i = int(f); I think this is possible because C++ contains functions like int, float, etc, that are overloaded with the appropriate types and return an int, float, respectively. Must verify this fact. Will this work with user defined types as well?
  • cout does not add a newline by default. We must add it explicitly by using “\n” or the constant endl. endl will also flush the stream, however since cout because it is not buffered, we can use them interchangeably.
  • In the following line of code int i; cin >> i; cin will process bytes from the input stream based on what we expect from the stream. In this case it will process 4 bytes and store the int value in the variable i. cin will not process the input stream unless we explicitly “RETURN”. The code cin >> a >> b; will process 2 values entered by the user. These values must be seperated by a space, tab, or a newline character.
  • cin does not verify the values entered. It also has problems with accepting strings with a space in them, since it will treat multiple words as seperate data values. To resolve these issues we use the function getline(cin, variableName); to accept a line of input from the user into a string. We then use the string as a stream and extract the data we need, using stringstream(str) >> variable;

Things that I am bit embarrased to include, but will include them anyways :-)

  • Any character can be written with a \ followed by it’s ACII code. char c = \97;
  • #define does not need a ; at the end of the statement. It is optional.
  • int i += 3; The operator that would otherwise have been after the = and between the operators is now before the = sign. I wonder why.
  • A string consists of const char*.

Learning C++

July 25, 2006

Now that the basics (C programming) are covered, I will move on to C++.

The study plan is to read the basic online tutorial at http://www.cplusplus.com/doc/tutorial/ and then follow up with Bruce Eckel’s “Thinking in C++”. I might complement it with ACM’s online C++ course.


Thinking in C: Chapt 8b – Pointers 102

July 24, 2006

This was a nice advanced chapter. I remembered as well as learned many things.

Some basic stuff:

When a signed number is bit shifted right, the sign bit is propogated.

typedef declares synonyms. For eg:

typedef struct Student Student;

says that Student is a synonym for struct Student.

We can have nested pointers, such as pointers to pointers and pointers to pointers to pointers… uptil 12 levels. However 2 levels is what is practically used.

When sizeof is applied to a pointer to an array, the value it returns is the size of the array. An interesting idiom to find out the number of elements in an array is:

int a[10];

int num_ele = sizeof a/sizeof a[0];

Generic Pointers:

Void pointers are generic pointers. They are used when we do not know what type of pointer to accept or send. In C any pointer type can be assigned to void and the other way round.

Constant Pointers:

Pointers can be constant, which means that the pointer cannot point to another location, and the pointer’s referent can also be constant, which means that the value held in the location pointed by the pointer cannot be changed. Here is how we use them.

int* const i; Here i is a constant pointer. The value of the referent can be changed, but i cannot be changed.

const int* i; Here the referent is constant. The value of the pointer can be changed but the value of what it is pointing to cannot be changed.

Pointer Arithmatic:

When doing pointer arithmatic, when we add to or subtract from a pointer, the pointer is incremented or decremented by the number of elements and not the number of bytes. For eg:

int a[10];

a is a pointer to the begining of the array of integers. a++, a will not point to the next address, but to the next int in the array. So if an int is 4 bytes on your machine, a will be incremented by 4 bytes.

Similarly subtracting 2 pointers yeilds the number of elements between them. It follows that we cannot do arithmatic with pointers of different types.

Function pointers:

We can also have pointers to functions. Here is how we can get a pointer to printf.

int (*fp) (const char*,…) = printf;

This means that fp is a pointer to a function called printf which takes a const char* and an unknown number of parameters after that.

Incomplete types:

Incomplete types are used when we do not have the information in advance or we want to hide it from clients.

They are used with arrays and structures. For eg:

extern int a[]; Struct Employee;

Further Research

  • What happens when a signed number is bit shifted left? Is the sign bit maintained, or is it shifted out?
  • What happens when we have pointers of two different types and we cast them into void pointers to do arithmatic with them?
  • When a variable is declared extern, does the compiler try to verify it?

Thinking in C: Chapt 7 – Pointers 101

July 21, 2006

This was a very interesting chapter. I had forgotten some basic concepts related to pointers and it was nice to refresh them.

Pointers are used to support reference semantics in C. When we pass an array to a function in C, we are in reality passing a pointer to it. Arrays CANNOT be passed by value in C.

Pointers allow us to create dynamic objects whose size we do not know at compile time. Dynamic objects are created with malloc or calloc, and live on the heap. When an object is no longer needed, it’s memory must be returned to the heap by using ‘free’. Another function that C gives us is realloc() which updates the size of memory alloctaed using malloc. We might want to use the sizeof operator when allocating memory. To use these functions be sure to include <stdlib.h>

C has a NULL pointer which does not point to any valid memory location. Since it does not point to a valid memory location, it cannot be dereferenced. A NULL pointer is usually used for comparisons, with pointers returned from a method (where a NULL pointer denotes an error).

C supports two operators for working with pointers to structs. The . operator and the -> operator. When we use the -> operator, we do not need to dereference the pointer to struct.

An interesting note: Most operating systems will free memory used by a program when it exits, however it is usually a good idea to explicitly free memory because if our program takes huge amounts of memory then it might exhaust all the memory available on the system.

Did the assignment. Learned something interesting. If I have a structure Employee

struct Employee {

char name[16] ;

}

struct Employee emp = malloc(sizeof(struct Employee));

emp->name = someCharPointer; //does not compile

strcpy(emp->name, someCharPointer); //works just fine

Why does the first line not work? I think it is because name is initialized as an array of 16 chars, while someCharPointer is also a char pointer, but we do not know it’s size. I think the compiler senses that things could go wrong and disallows the assignment.

Research:

  • Does realloc work if the memory was allocated using calloc()?

Chapt 6 – Thinking in C: Programming with functions

July 21, 2006

A function must be either declared or defined before it’s use. To declare a function we need to specify the function prototype like this:

float avg(int, int);

A void is used to signify no parameters. If a function sayHello() takes no parameters, it can be defined like this:
void sayHello(void) {}
or like this
void sayHello() {}
In this case we may pass parameters to the function, but they will be ignored by the compiler as well as the runtime.

This section goes beyond functions and also mentions different variable types:

  • local variables are those that are declared in methods. They exist on the stack.
  • constant variables declared at the file level, reside in the data segment, and cannot be accessed from other files
  • variables declared at the file level also reside on the data segment, but can be accessed from other files

Research:

  • What is the data segment?

Follow

Get every new post delivered to your Inbox.