programmers quotes

May 9, 2009

Create Your First iPhone App – Steps 3 of 3

Filed under: iPhone,Java Quotes,Mobile Application Development — Tags: — admin @ 8:45 pm

Now you get to add your nib file. You’ll be using the interface builder that doesn’t generate source code. You can, however, manipulate objects and then save them in the nib file. But first you have to create the nib file by going to developer/applications to launch the Interface Builder. You then need to select “Cocoa Touch” in the templates selection window and then select to view the template. You then choose File > new.

Next, you’ll see three objects and will choose “view.” But before you edit the view, you will need to save the file in your project director. “ControllerView” is a good file name. It must match the name you created when you had to create a file at the initWithNibName: bundle phase. When Interface Builder asks you if you want to save it, you do. Make sure you still have Xcode running. You also want to confirm the file is listed in the project files listing.

Configuring the file’s owner

You have to configure the file’s owner next and you do this by selecting the “File’s Owner” icon in the Interface Builder and then choose tools> identity inspector. The identity inspector will then show.

In the class field of the class identity section, enter MyViewController.

Connecting the view outlet

The only connection left is the view outlet. When you are in the Interface Builder, you need to drag the “File’s Owner” file to “view.” The Interface Builder will now show that there is only one outlet available. Click on “view” The view icon’s quick flash means that the nib file is loaded. You can now save the file. Click the Build and Go icon in the toolbar so that you can compile and run the application. Compilation should be error free and a white screen present in the simulator.

The view controller will load the nib file automatically.

Adding user interface elements

Now you will go to the Interface Builder and choose tools > Library to display the library window. You can then drag view items from the library and drop them onto the view. You can then resize and reposition. You can also add a text field, button, or label by typing UI and what you want (example: UITextField). You can customize your entire screen.

When you are in the view section during your changes, you want to choose “Clear Context” before drawing each element so that the previous string is removed before creating a new one. When you are finished, save your file.

Make connections

You make connections by dragging and dropping. You can do such things as connect the Lable and TextField. When you do such things as resize, you can see what outlets are available to you.

Once you have made connections and made changes that you need to make to your application, you can then test the application by building and running it. You should find that everything is working properly within the application. If you do find any errors, you can go back and make changes to get rid of those errors.

Step 1| Step 2 | Step 3

April 22, 2009

Java Properties without Getters and Setters

Filed under: Java,Java Quotes,Programmers,Programmers Quotes,Programming — Javier Paniza @ 8:50 am

During the recent Devoxx conference, Mark Reinhold, Sun’s chief engineer for Java SE, gave a presentation on the latest directions for Java 7. (Hamlet D’Arcy’s summary of Mark’s presentation is available here.)

One of the features that was discussed for possible inclusion in Java 7, but won’t find its way into the final release, is first class properties for Java. First-class support for properties would have gone beyond the simple setter and getter methods of the JavaBeans specification, and provided a succinct and elegant way for defining properties for Java objects.

Properties are already first-class elements of many modern languages, so this lack in Java 7 will be felt by many developers accustomed to other languages’ property support. At the same time, Java developers can resort to a handful of other techniques in working with property-like Java attributes, and some of the possible techniques work even in Java 1.4. In the rest of this article, I will demonstrate one such technique use a simple aspect, with AspectJ, and some following some conventions.

Motivation


The idea for this solution arose while working with the OpenXava 3 framework. OpenXava defines a mechanism to develop Java Enterprise applications using Business Components. It’s an alternative way to MVC: instead of organizing the code into Model, a View and a Controller, the code with OpenXava is organized around Invoice, Customer, Order, and similar business-centric objects. OpenXava initially used XML for defining components, but since version 3 the use of POJOs with Java 5 annotations also became available as the preferred way to define business components.

When using the XML-based object definition, you may specify a component in the following manner:

<component name="Teacher">

    <entity>
	<property name="id" type="String" key="true"
	    size="5" required="true"/>
	<property name="name" type="String" 
            size="40" required="true"/>
	<collection name="pupils">
            <reference model="Pupil"/>
        < /collection>
    < /entity>

< /component>

Using the annotation-based OpenXava 3, the same component would be defined as follows:

@Entity
public class Teacher {

 @Id @Column(length=5) @Required 
 private String id;

 @Column(length=40) @Required
 private String name;

 @OneToMany(mappedBy="teacher")
 private Collection pupils;

 public String getId() {
     return id;
 }

 public void setId(String id) {
     this.id = id;
 }

 public String getName() {
     return name;
 }

 public void setName(String name) {
     this.name = name;
 }

 public Collection getPupils() {
     return pupils;
 }

 public void setPupils(Collection pupils) {
     this.pupils = pupils;
 }

}

This illustrates some of the verbosity with the Java definition: 37 lines against the 13 of XML version. The problem occurs because of the getters and setters. The boilerplate code adds noise and increases the size of the file without increasing the information to the programmer. Use Java and annotations as a definition language in OpenXava would welcome a more succinct and elegant syntax.

A More Succinct Solution


A better solution can be obtained by defining the business component in this way:

@Entity
public class Teacher {

 @Id @Column(length=5) @Required 
 public String id;

 @Column(length=40) @Required
 public String name;

 @OneToMany(mappedBy="teacher")
 public Collection pupils;

}

This makes Java more beautiful, succinct and elegant… just as XML.

With this, you have to use the following properties without getters and setters. That is, instead of:

teacher.setName("M. Carmen");
String result = teacher.getName();

you write:

teacher.name = "M. Carmen";
String result = teacher.name;

In this case name is not a field, but a property. You can refine the access to this property, and even create pure calculated properties.

For example, if you wanted a calculated property, you could define it in this way:

@Entity
public class Person {

	...

	public String name;
	public String surname;

	transient public String fullName;	// (1)
	protected String getFullName() {	// (2)
	return name + " " + surname;	
	}
}

In order to define a calculated property, you define a public field (1) and then a protected (or private, but not public) getter (2). This getter, getFullName() in this case, is for implementing the logic for the property fullName.

Using this property is simple:

Person p = new Person();
p.name = "M. Carmen";
p.surname = "Gimeno Alabau";	
assertEquals("M. Carmen Gimeno Alabau", p.fullName);

When p.fullName is used, the method getFullName() is executed for returning the value. You can see that fullName is a property, not a simple field.

You can also refine access to writing and reading the properties. For example, you can define a property as following:

public String address;
protected String getAddress() {
	return address.toUpperCase();
}

When address is used from outside the class the method getAddress() is used to obtain the result, but this method only returns the address with some refinement. As we use address field from inside getAddress() field address from inside of its class is used, and the getter is not called.

Now you can use this property as follows:

Person p = new Person();
p.address = "Av. Baron de Carcer";	
assertEquals("AV. BARON DE CARCER", p.address);

As well, you can define setters, even for vetoing the data to be set, as in the next example:

public int age;
protected void setAge(int age) {	
    if (age > 200) {
	throw new IllegalArgumentException("Too old");
    }
    this.age = age;
}

As in the case of the getter, if a setter method is present it will be executed to set the data, you can use this logic to set the data to the field or for any other logic you want. Now you can use this property in this way:

Person p = new Person();
p.age = 33;
assertEquals(p.age, 33);
p.age = 250; // Here a IllegalArgumentException is thrown

In summary:

  • Properties behave from outside of the class as public fields.
  • If no getter or setter for the field exists, a direct access for the field is performed.
  • If a getter exists for the field, it will be executed when trying to read the field from outside.
  • If a setter exists for the field, it will be executed when trying to write the field from outside.
  • From inside the class, all references to the field are direct access, without calling getter or setter.

This provides a simple and natural way to have properties in Java without unnecessary getters and setters.

Implementation


This simple mechanism is easy to implement using AspectJ and a simple aspect, and it will work even in Java 1.4.

For this to work, you only need to have an aspect in your project:

aspect PropertyAspect {

    pointcut getter() : 
	get(public !final !static * *..model*.*.*) &&
	!get(public !final !static * *..model*.*Key.*) &&
	!within(PropertyAspect);
    pointcut setter() : 
	set(public !final !static * *..model*.*.*) &&
	!set(public !final !static * *..model*.*Key.*) &&
	!within(PropertyAspect);

    Object around(Object target, Object source) : 
	target(target) && this(source) && getter() {

	if (target == source) {	
	    return proceed(target, source);
	}
	try {
            String methodName = "get" + 
	    Strings.firstUpper(
	        thisJoinPointStaticPart.getSignature().getName()); 
	    Method method = 
	        target.getClass().
	            getDeclaredMethod(methodName, null);
	        method.setAccessible(true);
	    return method.invoke(target, null);
	}
	catch (NoSuchMethodException ex) {
	    return proceed(target, source);
	}
	catch (InvocationTargetException ex) {
	    Throwable tex = ex.getTargetException();
	    if (tex instanceof RuntimeException) {
	        throw (RuntimeException) tex;
	    }
	    else throw new RuntimeException(
	        XavaResources.getString("getter_failed", 
	        thisJoinPointStaticPart.
	        getSignature().getName(), 
	        target.getClass()), ex);
	    }
	catch (Exception ex) {	
	    throw new RuntimeException(
	        XavaResources.getString("getter_failed",
                    thisJoinPointStaticPart.getSignature().getName(), 
	            target.getClass()), ex);
	}
    }

    void around(Object target, Object source, Object newValue) : target(target) && this(source) && args(newValue) && setter() {	

	if (target == source) {	
	    proceed(target, source, newValue);
	    return;
	}
	try {	
	    String methodName = "set" + 
	    Strings.firstUpper(thisJoinPointStaticPart.getSignature().getName());
            Class fieldType = ((FieldSignature) 
                thisJoinPointStaticPart.getSignature()).getFieldType(	
	    Method method = 
	        target.getClass().
	        getDeclaredMethod(methodName, new Class[] {fieldType});
	    method.setAccessible(true);
	    method.invoke(target, new Object[] { newValue } );
	}
	catch (NoSuchMethodException ex) {
	    proceed(target, source, newValue);
	}
	catch (InvocationTargetException ex) {
	    Throwable tex = ex.getTargetException();
	    if (tex instanceof RuntimeException) {
	        throw (RuntimeException) tex;
	    }
	    else throw new RuntimeException(
	        XavaResources.getString("setter_failed", 
	        thisJoinPointStaticPart.getSignature().getName(), 
	        target.getClass()), ex);
	}
	catch (Exception ex) {	
	    throw new RuntimeException(
	        XavaResources.getString("setter_failed", 
	            thisJoinPointStaticPart.getSignature().getName(), 
	            target.getClass()), ex);
        }
    }
}
	

Having defined this aspect, you will need to compile your project using AspectJ.

The aspect intercepts all access to public fields in the model package, then use introspection to call to the getter or setter method if they exists.

Drawbacks

Unfortunately, this approach has at least two important drawbacks:

  1. It does not work when you access to the properties using introspection.
  2. With JPA, at least using the Hibernate implementation, lazy initialization does not work.

You may think that the introspection problem can be overcome with your own custom introspection code. But the man third party libraries, frameworks, and toolkits will not obey those rules. For example, if you are using a report generator that can generate a report from a collection of Java objects, the report generator may expect real public getters and setters in the objects.

The JPA the specification for Java Persistence API states that: 2.0:

“Instance variables must not be accessed by clients of the entity. The state of the entity is available to clients only through the entity methods i.e., accessor methods (getter/setter methods) or other business methods.”

JSR 317 : JavaTM Persistence API, Version 2.0 – Public Review Draft – Section 2.1

That is, portable JPA code should not rely on direct access to properties.

Conclusion


This article presents a very simple way to work with properties in Java, even though the language doesn’t support properties. If the AspectJ implementation is not practical, you can find other implementations of this idea using asm or cglib.

References


OpenXava – http://www.openxava.org/

AspectJ – http://www.eclipse.org/aspectj/


« Newer PostsOlder Posts »