Featured FREE Whitepapers

What's New Here?

agile-logo

Architects Need a Pragmatic Software Development Process

I have been a non-stop software architect since 2006. During my experience, I realized that it’s really hard to perform the role of architect in an organization that doesn’t have a software development process or have it too simplified. When the development is not fairly organized, project managers don’t find a room in their schedule to implement architectural recommendations. They probably have time and resources, but since they don’t have a precise idea of the team’s productivity, they feel afraid of accepting new non-functional requirements or changing existing ones. I’ve noticed that, in a chaotic environment, people become excessively pragmatic, averse to changes. Architects expect that the organization adopts a more predictable and transparent software process. This way, it’s possible to visualize the impact of recommendations and negotiate when they are going to be implemented. They minimally expect a process that has iterations inspired on the classical PDCA (Plan, Do, Check and Act) cycle because it has loops with feedback, which are the foundation for continuous improvement. The figure below depicts what could be considered as a pragmatic software process.Iterations are overlapped in time in order to optimize the use of resources and guarantee the feedback from previous iterations. Each iteration is performed in a fixed period of time. This time depends on the context and it tends to fall as the organization gains more maturity. An iteration is composed of 4 phases (plan, do, check and act) and 5 events that may occur according to the planning. They are:T1: It represents the beginning of the iteration, starting with its planning. The scope of the planning covers only the period of the current iteration. It should not be mixed with the general project planning, which is produced in one of the initial iterations to plan all other iterations. All members of the team participate in the planning. T2: The execution of what was planned for the iteration starts. All members of the team must have something to do within the scope of the iteration. Nothing planned for future iterations should be done in the current iteration. People may produce all sort of output, such as documents, code, reports, meeting minutes, etc. T3: Everything that is produced should be checked. Documents should be reviewed, code should be tested, user interfaces and integrations with other systems should be tested, etc. All found issues must be registered to be solved in due time. T4: Solve all issues found during the check phase and release all planned deliverables. Everybody should deliver something. In case time is not enough to solve some found issues, they must be included in the planning of the next iteration with the highest priority. Statistics should be produced during this phase in order to compare the planning with the execution. The planning of the next iteration also starts at this point, taking advantage of the experience from the previous iteration. T5: Once everything is released, the current iteration finishes. T2 of the next iteration immediately starts because most of resources are already available.T1 to T5 repeats several times, in a fixed period of time, until the end of the project. This suggestion is process-agnostic, thus it can be implemented no matter what software process we claim to have in place or any other modern process we can think of. In addition to the process, there are also some good practices:Consider everything that describes how the system implements business needs as use cases. It can also be functional and nonfunctional requirements, user stories, scenarios, etc; but there must be only one sort of artefact to describe business needs. Write use cases in a way that the text can be reused to: a) help business people to visualize how their needs will work; b) guide testers on the exploratory tests; and c) help the support team to prepare the user manual. Avoid technical terms in use cases. If really needed, technical details may be documented in another artefact, such as use case realizations. If needed, create use case realizations using UML models only. Representing use case realisations as documents implies on a huge overhead. Any necessary textual information can be added in the comments area of UML’s elements. Fix the size of use cases according to the effort to realize it. For example: we can fix that the maximum size of a use case is 1 week. If the estimation is higher than that, then the use case must be divided in two others. If the estimation is far lower than that, then the use case must be merged with another closely related use case. By simply counting the number of use cases we immediately know the effort and the resources required to execute the project. This fixed number is a parameter to compare the planning with the execution. By performing this comparison after every iteration, we gradually know how precise our estimations are becoming. Use a wiki to document use cases and other required documentations, such as test cases, release notes, etc. Create a wiki page for each use case and use signs to indicate what is still pending to be released. The advantages of the wiki are: a) use cases are immediately available for all stakeholders as they are gathered; b) stakeholders can follow the evolution of the use cases by following updates in the page; c) it’s possible to know everyone who contributed to the use case and what exactly they did; and d) it’s possible to add comments to use cases, preserving all the discussion around it. If the organization has business processes, which is another thing that architects also love, then put references in the business process’ activities pointing to the use cases that implement them. A reference is a link to the page where the use case is published on the wiki. Follow up use cases using an issue tracking system, such as Jira. Each use case must have a corresponding Jira ticket and every detail of the use case’s planning, execution, checking and delivery must be registered in that ticket. The advantages of linking Jira tickets with use cases are: a) Jira tickets represent the execution of the planning and their figures can be compared with the planning, generating statistics on which managers can rely on; b) we know exactly every person who contributed to the use case, what they did, and for how long; and c) it’s an important source of lessons learned. Test, test, test! It must be an obsessive compulsive behaviour. Nothing goes out without passing through the extensive test session. Constantly train and provide all needed bibliography to the team on the technologies in use. The more technical knowledge we have inside of the team, the highest is our capability to solve problems and increase productivity.Working this way, everything becomes quantifiable, predictable, comparable and traceable. From the practices above we can extract the traceability flow from business to the lowest IT level, as depicted in the figure below.Business process elements such as swimlanes and activities may inspire actors and use cases. Use cases and actors are documented on wiki pages. Each use case and actor has a page on the wiki, which has a unique URL and can be used to refer the element on email messages, documents, Jira tickets and so on. An Jira ticket is created for each use case and it contains a link to the use case’s wiki page. This wiki page can also have a link to the ticket since it also has a unique URL. Jira tickets can be automatically linked the source code through the version control system (SVN) and declaratively linked to system’s features and user interfaces. Since it’s possible to create mock-ups in wiki pages, then we also link those wiki pages with user interfaces to compare the mock-ups with the final user interface. We finally have actors linked to security roles. I admit that architects are not qualified to define and implement a software development process in the organization (they actually believe more in the Programming Motherfucker philosophy :D), but they are constantly willing to contribute to have one in place. As they have instruments to monitor servers, releases, tests, performance and so on, they also want project managers having instruments to estimate effort, predict events, anticipate problems and, therefore, produce better planning and results. Warning: Whatever we put in our software processes that is not quantifiable or measurable will become an expensive overhead. Reference: Architects Need a Pragmatic Software Development Process from our JCG partner Hildeberto Mendonca at the Hildeberto’s Blog blog....
javafx-logo

JavaFX 2.0 Layout Panes – HBox and VBox

If you want an overview on all different layout panes in JavaFX 2.0 or if you want to know yome basic facts about them, please see my previous post Layout Panes in JavaFX 2.0.The layout panes HBox and VBox are definitely the most basic layout containers in JavaFX 2.0. As you can already tell by their name, their purpose is to layout all their children in one horizontal row (HBox) or in one vertical column (VBox). Because they´re very easy to use and very useful regarding minor layout issues, you´ll probably use them a lot. I´ll give two examples on how you can use them. As in the other examples, first of all the code and afterwards the explanations. HBox and VBox – Example 1   import javafx.application.Application; import javafx.geometry.Pos; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; import javafx.stage.Stage;/** * * Created on: 20.03.2012 * @author Sebastian Damm */ public class HBoxandVBoxExample extends Application { @Override public void start(Stage primaryStage) throws Exception { HBox hbox = new HBox(50); hbox.setAlignment(Pos.CENTER); // default TOP_LEFT VBox vbox1 = new VBox(); vbox1.setAlignment(Pos.BOTTOM_CENTER); vbox1.setStyle("-fx-border-style: solid;" + "-fx-border-width: 1;" + "-fx-border-color: black"); VBox vbox2 = new VBox(10); vbox2.setAlignment(Pos.CENTER); vbox2.setStyle("-fx-border-style: solid;" + "-fx-border-width: 1;" + "-fx-border-color: black"); VBox vbox3 = new VBox(20); vbox3.setAlignment(Pos.TOP_CENTER); vbox3.setStyle("-fx-border-style: solid;" + "-fx-border-width: 1;" + "-fx-border-color: black"); for (int i = 0; i < 5; i++) { Button bt = new Button("Button " + (i+1)); Button bt2 = new Button("Button " + (i+1)); // unfortunately there´s no "clone" or "copy" method Button bt3 = new Button("Button " + (i+1));vbox1.getChildren().add(bt); vbox2.getChildren().add(bt2); vbox3.getChildren().add(bt3); } hbox.getChildren().addAll(vbox1, vbox2, vbox3); Scene scene = new Scene(hbox, 350, 250); // the hbox is the root node primaryStage.setTitle("HBox and VBox Example"); primaryStage.setScene(scene); primaryStage.show(); }public static void main(String[] args) { Application.launch(args); } } Basically we create three different VBoxes and put them into one HBox. In both classes you can define a spacing value either directly in the constructor or via the setSpacing method. This value will be used as the gap between the individual children in the pane. The line HBox hbox = new HBox(50); therefore creates a HBox to hold three VBoxes with a gap of 50 pixel between each of them.We use the setAlignment method to specify, how the individual VBoxes should arrange and layout all their childen.With setStyle you can apply custom CSS styles to any Node. I don´t want to go into much detail yet, because I´ll cover CSS styles in JavaFX 2.0 in one of my next posts, but if you´re already familiar with CSS you´ll probably already have noticed that the JavaFX 2.0 team fortunately decided to follow the CSS standards defined by W3C (http://www.w3.org) very closely. If you´re not familiar with CSS you just need to know that theses lines of CSS create a 1px wide black border around the component. I use them here to show you the size of the individual VBoxes.The next few lines should be pretty ordinary for you by now: We create five buttons for each VBox, put the different VBoxes into our HBox, declare a Scene object (with the HBox as root) and show our application.  Your application should look like this now:You can see that each VBox lays out their children buttons with the defined spacing value and that the HBox lays out the three VBoxes with a gap of 50 pixels. Because we set a different alignment for each VBox you can see that that they arrange the buttons inside their bounds in a specific way. Note: We also specified a alignment for the HBox, otherwise the three VBoxes would not have been layed out in the center! If you resize the window of your application it should look like this:You can see that the VBoxes grow and fill the space provided by their parent and that they still arrange their children according to their set alignment.HBox and VBox – Example 2The next example will show how to use the static setMargin and setHgrow (respectively setVgrow) methods: import javafx.application.Application; import javafx.geometry.Insets; import javafx.scene.Scene; import javafx.scene.control.*; import javafx.scene.layout.*; import javafx.stage.Stage;/** * * Created on: 20.03.2012 * @author Sebastian Damm */ public class HBoxandVBoxExample2 extends Application { @Override public void start(Stage primaryStage) throws Exception { StackPane root = new StackPane(); HBox hbox = new HBox(30); // create a HBox to hold 2 vboxes // create a vbox with a textarea that grows vertically VBox vbox = new VBox(10); Label lbName = new Label("I´m a label!"); TextField textField = new TextField(); TextArea textArea = new TextArea(); textArea.setPrefWidth(100); VBox.setVgrow(textArea, Priority.ALWAYS); vbox.getChildren().addAll(lbName, textField, textArea); // create a vbox that grows horizontally inside the hbox VBox vbox2 = new VBox(10); Label lbName2 = new Label("I´m also a label!"); TextField tf2 = new TextField(); tf2.setPromptText("type here"); TextArea textArea2 = new TextArea(); textArea2.setPrefWidth(100); vbox2.getChildren().addAll(lbName2, tf2, textArea2); HBox.setHgrow(vbox2, Priority.ALWAYS);// the next two lines behave equally - try to comment the first line out and use the 2nd line hbox.setPadding(new Insets(20)); // StackPane.setMargin(hbox, new Insets(20));hbox.getChildren().addAll(vbox, vbox2); root.getChildren().add(hbox); Scene scene = new Scene(root, 500, 300); // the stack pane is the root node primaryStage.setTitle("HBox and VBox Example 2"); primaryStage.setScene(scene); primaryStage.show(); }public static void main(String[] args) { Application.launch(args); } } In this example we create two VBoxes that are children of a HBox. Inside the VBoxes there are one label, one textfield and one textarea.The first remarkable line is VBox.setVgrow(textArea, Priority.ALWAYS). With this line we define, that the TextArea object should always grow vertically if it is contained by a VBox (otherwise there won´t be any effects). Next, put a focus on HBox.setHgrow(vbox2, Priority.ALWAYS). Here we tell the second VBox to grow horizontally inside the HBox.Finally with hbox.setPadding(new Insets(20)); or StackPane.setMargin(hbox, new Insets(20)) we give the whole HBox some padding. The two lines behave equally here because on the one side we specify a padding for the pane itself that should be used by the pane inside its bounds to layout its children and on the other side we tell the parent to lay out the pane with the given margin around it.Note: Margin is the outer distance/gap, padding the inner one. Here is a picture showing you the ‘CSS Box Model’ that demonstrates the relation between the content, the padding, the border, and the margin of an element.Source: w3Schools.comBecause the setPadding method is defined in the Region class, every layout pane can use this method. The Insets class is used a lot for those purposes and provides two different constructors: One that takes one double value and defines the same padding for each side and one constructor that takes four double values and defines the padding clockwise from the top to the left side.Hint: If you apply a border to the HBox and switch between the two lines for setting padding/margin, you will see the difference more clearly.Your application should look like this:Note the 10px padding around the HBox. If you now resize you window it should look similar to this:As you can see the TextArea in the left VBox grows vertically and the whole right VBox grows horizontally inside the HBox. Reference: JavaFX 2.0 Layout Panes – HBox and VBox from our JCG partner Sebastian Damm at the Just my 2 cents about Java blog....
jboss-hibernate-logo

Test JPQL / HQL without a deploy

Have you ever wanted to test your JPQL / HQL without doing a full deploy of your application? What we will see here today is simple solution that works for any JPA implementation: Hibernate, OpenJPA, EclipseLink and others. The base source code found in this post came from this book: “Pro JPA 2: Mastering the Java™ Persistence API – Mike Keith, Merrick Schincariol”. This post will add to the original code: query parameters and NamedQuery test. Model classes and data Generation Bellow are the model classes’ code: package com.model;import java.util.*;import javax.persistence.*;@Entity @NamedQueries({ @NamedQuery(name="Person.findByName", query="select p from Person p where p.name = :name"), @NamedQuery(name="Person.findByAge", query="select p from Person p where p.age = :age", hints={@QueryHint(name="org.hibernate.timeout", value="1000")}) })public class Person {public static final String FIND_BY_NAME = "Person.findByName"; public static final String FIND_BY_AGE = "Person.findByAge";@Id @GeneratedValue(strategy = GenerationType.AUTO) private int id;private String name; private int age;public Person() {}public Person(int id) { this.id = id; }public Person(String name, int age) { this.name = name; this.age = age; }@OneToMany(mappedBy = "person", cascade = CascadeType.ALL) private List<Dog> dogs;@OneToOne(cascade = CascadeType.ALL) @JoinColumn(name="address_id") private Address address;public int getId() { return id; }public void setId(int id) { this.id = id; }public String getName() { return name; }public void setName(String name) { this.name = name; }public int getAge() { return age; }public void setAge(int age) { this.age = age; }public List<Dog> getDogs() { if (dogs == null) { dogs = new ArrayList<Dog>(); }return dogs; }public void setDogs(List<Dog> dogs) { this.dogs = dogs; }public Address getAddress() { return address; }public void setAddress(Address address) { this.address = address; }@Override public int hashCode() { return getId(); }@Override public boolean equals(Object obj) { if (obj instanceof Person) { Person person = (Person) obj; return person.getId() == getId(); }return false; }@Override public String toString() { return "Person name: " + name; } } package com.model;import java.util.Date;import javax.persistence.*;@Entity @NamedQueries(value={@NamedQuery(name="Dog.FindByDateOfBirth", query="select d from Dog d where d.dateOfBirth = :dateOfBirth"), @NamedQuery(name="Dog.FindByPerson", query="select d from Dog d where d.person = :personObject")}) public class Dog {public static final String FIND_BY_DATE_OF_BIRTH = "Dog.FindByDateOfBirth";@Id @GeneratedValue(strategy = GenerationType.AUTO) private int id;private String name; private double weight;@Temporal(TemporalType.TIMESTAMP) private Date dateOfBirth;public Dog() {}public Dog(String name, double weight, Date dateOfBirth) { this.name = name; this.weight = weight; this.dateOfBirth = dateOfBirth; }public static void main(String[] args) {System.out.println(new Date()); }@ManyToOne private Person person;public int getId() { return id; }public void setId(int id) { this.id = id; }public String getName() { return name; }public void setName(String name) { this.name = name; }public double getWeight() { return weight; }public void setWeight(double weight) { this.weight = weight; }public Date getDateOfBirth() { return dateOfBirth; }public void setDateOfBirth(Date dateOfBirth) { this.dateOfBirth = dateOfBirth; }public Person getPerson() { return person; }public void setPerson(Person person) { this.person = person; }@Override public int hashCode() { return getId(); }@Override public boolean equals(Object obj) { if (obj instanceof Dog) { Dog dog = (Dog) obj; return dog.getId() == getId(); }return false; }@Override public String toString() { return "Dog name: " + name; } } package com.model;import javax.persistence.*;@Entity @NamedQuery(name="Address.FindAll", query="select a from Address a") public class Address {@Id @GeneratedValue(strategy = GenerationType.AUTO) private int id;private String streetName; private int houseNumber;public Address() {}public Address(String streetName, int houseNumber) { this.streetName = streetName; this.houseNumber = houseNumber; }public int getId() { return id; }public void setId(int id) { this.id = id; }public String getStreetName() { return streetName; }public void setStreetName(String streetName) { this.streetName = streetName; }public int getHouseNumber() { return houseNumber; }public void setHouseNumber(int houseNumber) { this.houseNumber = houseNumber; }@Override public int hashCode() { return getId(); }@Override public boolean equals(Object obj) { if (obj instanceof Address) { Address address = (Address) obj; return address.getId() == getId(); }return false; }@Override public String toString() { return "Adress street name: " + streetName; } } In the code above we got several JPA relationships as a sample. Bellow is the class that will handle the transaction and the data that will be written into the HSQLDB database: package com.main;import java.text.*; import java.util.Date;import javax.persistence.*;import com.model.*;public class CodeGenerator { private static EntityManagerFactory emf; private static EntityManager em;public static final String PERSON01_NAME = "John"; public static final String PERSON02_NAME = "Mary"; public static final String PERSON03_NAME = "Anna"; public static final String PERSON04_NAME = "Joseph"; public static final String PERSON05_NAME = "Mark"; public static final String PERSON06_NAME = "I will not have any relationship";public static void startConnection() { emf = Persistence.createEntityManagerFactory("QueryTester"); em = emf.createEntityManager(); em.getTransaction().begin(); }public static void closeConnection() { em.getTransaction().commit(); emf.close(); }public static void generateData() { int year = 1995; int month = 1; int day = 10;Dog dog01 = new Dog("Yellow", 3.5d, createNewDate(day, month, year)); Dog dog02 = new Dog("Brown", 8.5d, createNewDate(++day, ++month, ++year)); Dog dog03 = new Dog("Dark", 15.5d, createNewDate(++day, ++month, ++year)); Dog dog04 = new Dog("Kaka", 4.3d, createNewDate(++day, ++month, ++year)); Dog dog05 = new Dog("Pepe", 8.2d, createNewDate(++day, ++month, ++year)); Dog dog06 = new Dog("Casillas", 6.1d, createNewDate(++day, ++month, ++year)); Dog dog07 = new Dog("Fish", 6.7d, createNewDate(++day, ++month, ++year)); Dog dog08 = new Dog("Lion", 3.1d, createNewDate(++day, ++month, ++year)); Dog dog09 = new Dog("Cat", 5.5d, createNewDate(++day, ++month, ++year)); Dog dog10 = new Dog("Java", 21.7d, createNewDate(++day, ++month, ++year)); Dog dog11 = new Dog("JSF", 23.65d, createNewDate(++day, ++month, ++year)); Dog dog12 = new Dog("VRaptor", 24.0d, createNewDate(++day, ++month, ++year)); Dog dog13 = new Dog("Ferrari", 3.7d, createNewDate(++day, ++month, ++year)); Dog dog14 = new Dog("Porshe", 1.33d, createNewDate(++day, ++month, ++year)); Dog dog15 = new Dog("Bike", 4.44d, createNewDate(++day, ++month, ++year)); Dog dog16 = new Dog("Rambo", 5.44d, createNewDate(++day, ++month, 2015)); Dog dog17 = new Dog("Terminator", 3.88d, createNewDate(++day, ++month, 2016)); Dog dog18 = new Dog("John McClan", 3.88d, createNewDate(++day, ++month, 2016));Person person01 = new Person(PERSON01_NAME, 33); person01.getDogs().add(dog01); person01.getDogs().add(dog02); person01.getDogs().add(dog03); person01.setAddress(new Address("Street A", 30)); dog01.setPerson(person01); dog02.setPerson(person01); dog03.setPerson(person01);Person person02 = new Person(PERSON02_NAME, 27); person02.getDogs().add(dog04); person02.getDogs().add(dog05); person02.getDogs().add(dog06); person02.setAddress(new Address("Street B", 60)); dog04.setPerson(person02); dog05.setPerson(person02); dog06.setPerson(person02);Person person03 = new Person(PERSON03_NAME, 7); person03.getDogs().add(dog07); person03.getDogs().add(dog08); person03.getDogs().add(dog09); person03.setAddress(new Address("Street B", 90)); dog07.setPerson(person03); dog08.setPerson(person03); dog09.setPerson(person03);Person person04 = new Person(PERSON04_NAME, 43); person04.getDogs().add(dog10); person04.getDogs().add(dog11); person04.getDogs().add(dog12); person04.setAddress(new Address("Street C", 120)); dog10.setPerson(person04); dog11.setPerson(person04); dog12.setPerson(person04);Person person05 = new Person(PERSON05_NAME, 70); person05.getDogs().add(dog13); person05.getDogs().add(dog14); person05.getDogs().add(dog15); person05.getDogs().add(dog16); person05.setAddress(new Address("Street D", 150)); dog13.setPerson(person05); dog14.setPerson(person05); dog15.setPerson(person05); dog16.setPerson(person05);Person person06 = new Person(PERSON06_NAME, 45);em.persist(person01); em.persist(person02); em.persist(person03); em.persist(person04); em.persist(person05); em.persist(person06);em.persist(dog17); em.persist(dog18);em.flush(); }private static Date createNewDate(int day, int month, int year) { SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy"); try { return formatter.parse("" + day + "/" + month + "/" + year); } catch (ParseException e) { e.printStackTrace(); return null; } }public static EntityManager getEntityManager() { return em; } } The “persistence.xml” file can be found in the “src/META-INF” folder with the code bellow: <?xml version="1.0" encoding="UTF-8"?><persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"><persistence-unit name="QueryTester" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.ejb.HibernatePersistence</provider><properties> <property name="javax.persistence.jdbc.driver" value="org.hsqldb.jdbcDriver" /> <property name="javax.persistence.jdbc.url" value="jdbc:hsqldb:mem:." /> <property name="javax.persistence.jdbc.user" value="sa" /> <property name="javax.persistence.jdbc.password" value="" /> <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" /> <property name="hibernate.connection.shutdown" value="true" /> <property name="hibernate.hbm2ddl.auto" value="update" /> <property name="hibernate.show_sql" value="false" /> <property name="hibernate.format_sql" value="false"/> </properties> </persistence-unit> </persistence> Abstract test class package com.main;import javax.persistence.Query;import org.apache.commons.lang3.builder.ReflectionToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle;import com.model.Person;/** * @author Pro JPA 2 book * @Empowered by uaiHebert * */ public abstract class AbstractQueryTester {protected static void populateParameters(Query query, String parameters) { for (String parameter : parameters.split(";")) { String parameterKey = parameter.split("-")[0]; String parameterValue = parameter.split("-")[1]; String parameterType = parameter.split("-")[2];query.setParameter(parameterKey, configureParameterValue(parameterValue, parameterType)); } }private static Object configureParameterValue(String parameterValue, String parameterType) { if (parameterType.equalsIgnoreCase("integer")) { try { return Integer.parseInt(parameterValue); } catch (Exception e) { throw new IllegalArgumentException("Invalid parameter value as number: " + parameterValue); } }if (parameterType.equalsIgnoreCase("string")) { return parameterValue; }if (parameterType.equalsIgnoreCase("person")) { int personId;try { personId = Integer.valueOf(parameterValue); } catch (Exception e) { throw new IllegalArgumentException("Invalid parameter value as number: " + parameterValue); }return new Person(personId); }throw new IllegalArgumentException("Invalid parameter type: " + parameterType); }protected static void printResult(Object result) throws Exception { if (result == null) { System.out.print("NULL"); } else if (result instanceof Object[]) { Object[] row = (Object[]) result; System.out.print("["); for (int i = 0; i < row.length; i++) { printResult(row[i]); } System.out.print("]"); } else if (result instanceof Long || result instanceof Double || result instanceof String) { System.out.print(result.getClass().getName() + ": " + result); } else { System.out.print(ReflectionToStringBuilder.toString(result, ToStringStyle.SHORT_PREFIX_STYLE)); }System.out.println(); } } About the above code:The populateParameters method will populate all query parameters automatically. The Eclipse console will require that the developer type the Query information and the Query parameters if any is required. The Query parameters should follow the syntax requirements bellow:0 parameters: just press “Enter” 1 parameter: id-4-integer 2 or more parameters: name-John-string;age-33-integer The developer may use class as parameter: dog-33-DogThe configureParameterValue method will “cast” the parameterValue to the correct type required by the Query. It allows primitive values and classes. The printResult method will display the Query result.Dynamic Query test package com.main;import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.List;import javax.persistence.EntityManager; import javax.persistence.Query;/** * @author Pro JPA 2 book * @Empowered by uaiHebert * */ public class DynamicQueryTester extends AbstractQueryTester { public static void main(String[] args) throws IOException { CodeGenerator.startConnection();CodeGenerator.generateData();EntityManager em = CodeGenerator.getEntityManager();BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));for (;;) { System.out.print("Type your JPQL and press Enter > "); String dynamicQuery = reader.readLine();if (dynamicQuery.equals("quit")) { break; }if (dynamicQuery.length() == 0) { continue; }System.out.println("Type the namedQuery parameters."); System.out.println("All paramters should be like: id-2-integer;name-John-string"); System.out.println("Or just press enter for 0 parameters"); String parameters = reader.readLine();try { Query query = em.createQuery(dynamicQuery);if (parameters.length() > 0) { populateParameters(query, parameters); }@SuppressWarnings("rawtypes") List result = query.getResultList();if (result.size() > 0) { int count = 0; for (Object o : result) { System.out.print(++count + " "); printResult(o); } } else { System.out.println("0 results returned"); } } catch (Exception e) { e.printStackTrace(); } }CodeGenerator.closeConnection(); } } The code above will start a transaction, create the database data in runtime memory and allow a developer to test any kind of dynamic query. To test a JPQL / HQL the developer just need to type the Query code in the console. To finish the loop do not type any Query data, just type “quit” and press “Enter”. NamedQuery test   package com.main;import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.List;import javax.persistence.EntityManager; import javax.persistence.Query;/** * @author Pro JPA 2 book * @Empowered by uaiHebert * */ public class NamedQueryTester extends AbstractQueryTester { public static void main(String[] args) throws IOException { CodeGenerator.startConnection();CodeGenerator.generateData();EntityManager em = CodeGenerator.getEntityManager();BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));for (;;) { System.out.print("Type the NamedQuery name > "); String namedQueryName = reader.readLine();if (namedQueryName.equals("quit")) { break; }if (namedQueryName.length() == 0) { continue; }System.out.println("Type the namedQuery parameters."); System.out.println("Press enter for 0 parameters"); System.out.println("Or type all paramters like: id-2,name-4"); String parameters = reader.readLine();try { Query query = em.createNamedQuery(namedQueryName);if (parameters.length() > 0) { populateParameters(query, parameters); }@SuppressWarnings("rawtypes") List result = query.getResultList();if (result.size() > 0) { int count = 0; for (Object o : result) { System.out.print(++count + " "); printResult(o); } } else { System.out.println("0 results returned"); } } catch (Exception e) { System.err.println(e.getClass() + e.getMessage()); } }CodeGenerator.closeConnection(); } } The code above will start a transaction, create the database data in runtime memory and allow the test of NamedQueries that are configured in the model classes. To test the NamedQueries just type their name in the console. To finish the loop do not type any NamedQuery name, just type “quit” and press “Enter”. Running the application Run the class DynamicQueryTester and type the following text in the console: “select p from Person p”. Press enter twice and the following text will appear in the console:At the first “Enter” key hit a message will be displayed asking for parameters if there are any. Type in the console: “select p from Person p where p.age > :age” and press “Enter”. Type the parameter: “age-69-integer”. Press enter and the result bellow will be displayed:To finish the code that is running type the word “quit” and press the “Enter” button. Run now the code of the class NamedQueryTester. Type the NamedQuery name “Dog.FindByPerson” in the console and press enter. Type “personObject-1-person” parameter and the result bellow will be displayed:Using this post code with your application code You can use the code of this post in two ways: add your application model class to the project of this post or use the code found in the main package of this project in your application. Add your model class to the project of this post:Copy the model class to the “com.model” package. Set up the persistence.xml to access the databaseUse the code found in the main package in your application:Set up the PersistenceUnit found in the CodeGenerator class. Use the Apache library found in the libs folder: “commons-lang3-3-1.jar”.For both approaches the step bellow are required:Edit the method “AbstractQueryTester.configureParameterValue” to accept all attributes values/types/classes that will be used with the queries. Edit the “hibernate.hbm2ddl.auto” configuration to “none” or “validate”. This configuration is found in the “persistence.xml” file. Only invoke the methods to start/close the connection in the CodeGenerator class.Proposals Bellow you will find some proposals to do with this code:Use the Reflection technique to create the classes in the “AbstractQueryTester.configureParameterValue” method. Apply Jenkins to validate if some of the JPQLs are with the right syntax after a commit.The End I hope this post might help you. Click here to download the source code of this post. If you have any doubt/suggestion just post it. Reference: How to test your JPQL / HQL without a Deploy from our JCG partner Hebert Coelho at the uaiHebert blog....
android-logo

Android – Using Jelly Bean notifications

Last post was long ago! I’ve been very busy lately… but learning a lot from Android! (and Node js too… I’m in love with this platform!)Other things that I decided for those who are following me is that, since now, articles will only be in English (sorry =/ ) and all the source code of my examples will be available on github.Obviously, being an Android developer, Google I/O has been a great source of new things to learn… And one of the was Jelly Bean (Android 4.1 for those that don’t know it yet).One of the top new things Jelly Bean brings us is new notification functionalities. You can see them in the Google I/O Keynote or some of the articles all over the Internet (1, 2, 3, 4)So, Where do we have to begin? First of all, you’ll have to create an Android Project with Jelly Bean SDK version.Probably, most of you had used NotificationManager to push notifications on Android devices… For new Jelly Bean notifications it must be used almost in the same way. You can use something like this: NotificationManager notificationManager = getNotificationManager(); Notification notification = new Notification(android.R.drawable.ic_menu_camera, "Hello camera!", System.currentTimeMillis()); notification.flags |= Notification.FLAG_AUTO_CANCEL; notification.number += 1;Intent intent = new Intent(this, MainActivity.class); PendingIntent activity = PendingIntent.getActivity(this, 0, intent, 0); notification.setLatestEventInfo(this, "title", "content", activity);notificationManager.notify(0, notification);What do we have to do to use new Jelly Bean notifications? It’s pretty easy…. and I must admit that I prefer this way using the Builder pattern. This is an example of the Big picture style: Builder build = new Notification.Builder(this) .setContentTitle("New mail from me") .setContentText("subject") .setTicker("New email with photo") .setSmallIcon(R.drawable.ic_action_search) .addAction( android.R.drawable.ic_btn_speak_now, "Speak!", PendingIntent.getActivity(getApplicationContext(), 0, getIntent(), 0, null)) .addAction( android.R.drawable.ic_dialog_map, "Maps", PendingIntent.getActivity(getApplicationContext(), 0, getIntent(), 0, null)) .addAction( android.R.drawable.ic_dialog_info, "Info", PendingIntent.getActivity(getApplicationContext(), 0, getIntent(), 0, null));Notification notification = new Notification.BigPictureStyle(build) .bigPicture( BitmapFactory.decodeResource(getResources(), R.drawable.jellybean)).build();Intent notificationIntent = new Intent(this, MainActivity.class);notificationManager.notify(0, notification);All the code is available at my github account (where you can find the beggining of a new ORM solution for Android which I hope someday will be finished =/) on the following link. you can find in that project other example of the new notifications too (inbox style and big text).Here is how the three notifications will show up in your Android devices…. (if you have Jelly Bean on them )I hope you like the article, and you can ask me any doubt, follow me on twitter or write me and email.Reference: Using Jelly Bean notifications from our JCG partner Javier Manzano at the Javier Manzano’s Blog blog....
primefaces-logo

Full Web Application Tomcat JSF Primefaces JPA Hibernate – Part 1

We created this post that will show how to create a full web application using the following tools: Tomcat7, JSF2 (Facelets and Libraries) with Primefaces (with AutoComplete), JPA / Hibernate (with a relationship NxN), Login with Filter.If you want to see a full web application with JSF + EJB + JPA + JBoss 7 click here. To run the code of this post you will need the artifacts bellow (all jar file you will find in the last page of this post):Eclipse Indigo Tomcat7 Mojarra Primefaces Hibernate Driver PostgresYou can use the any database you want, you will need the specific driver of the database and to edit the URL connection at the persistence.xml. At the end of this post you will find the source code with all needed libraries to download. What you will see today in this post:Entity classes of the model. A relationship NxN (@ManyToMany), NamedQueries with JoinFetch, Enum as attribute. Generic DAO, application transaction methods, generic methods to populate query parameters. Façades an transactions, using the method findReferenceOnly, care using the entityManager.merge() method. Filters. ManagedBeans. How to inject a ManagedBean inside another ManagedBean, observations about @ViewScoped. JSFMessageUtil. Configurations file: log4j.properties, messages.properties. xhtml pages, Facelets. Primefaces AutoComplete, JSF Converter with “forClass”. Easiest way to use CSS/javascript/images with JSF. “web.xml” configurations. Increasing the security of your application. Running the application.The application that you will find in here will have a Dog and Person CRUD (Create, Read, Update, and Delete); only the ADMIN will have access to the Dog CRUD. Before you run this application you should create a database named “JSFCrudDB”. Model classes The following classes are the model classes and they should be in the “com.model” package: package com.model;public enum Role { ADMIN, USER; } package com.model;import java.io.Serializable;import javax.persistence.*;@Entity @Table(name = 'USERS') @NamedQuery(name = 'User.findUserByEmail', query = 'select u from User u where u.email = :email') public class User implements Serializable { private static final long serialVersionUID = 1L;public static final String FIND_BY_EMAIL = 'User.findUserByEmail';@Id @GeneratedValue(strategy = GenerationType.AUTO) private int id;@Column(unique = true) private String email; private String password; private String name; @Enumerated(EnumType.STRING) private Role role;// get and setpublic boolean isAdmin() { return Role.ADMIN.equals(role); }public boolean isUser() { return Role.USER.equals(role); }@Override public int hashCode() { return getId(); }@Override public boolean equals(Object obj) { if (obj instanceof User) { User user = (User) obj; return user.getId() == id; }return false; } } package com.model;import java.io.Serializable; import java.util.List;import javax.persistence.*;@Entity @NamedQuery(name = 'Person.findUserByIdWithDogs', query = 'select p from Person p left join fetch p.dogs where p.id = :personId') public class Person implements Serializable {private static final long serialVersionUID = 1L; public static final String FIND_USER_BY_ID_WITH_DOGS = 'Person.findUserByIdWithDogs';@Id @GeneratedValue(strategy = GenerationType.AUTO) private int id; private int age; private String name;@ManyToMany private List<Dog> dogs;// get and set@Override public int hashCode() { return id; }@Override public boolean equals(Object obj) { if (obj instanceof Person) { Person person = (Person) obj; return person.getId() == id; }return false; } } package com.model;import java.io.Serializable; import java.util.List;import javax.persistence.*;@Entity public class Dog implements Serializable{ private static final long serialVersionUID = 1L;@Id @GeneratedValue(strategy = GenerationType.AUTO) private int id; private int age; private String name;@ManyToMany(mappedBy='dogs') private List<Person> persons;// get and set@Override public int hashCode() { return id; }@Override public boolean equals(Object obj) { if (obj instanceof Dog) { Dog dog = (Dog) obj; return dog.getId() == id; }return false; }@Override public String toString() { return name; } }About the above code:The Person class has the namedQuery “Person.findUserByIdWithDogs”. This query will eagerly load the Dog list of the Person class. If we try to access the Dog list without a transaction and this query a LazyInitializationException will happen. Other solution to this situation would be the OpenSessionInView pattern; this pattern may generate the N+1 queries effect. If you want to know more about this exception click here. It is very easy to map an Enum with JPA/Hibernate. As you can see there is an option with the @Enumerated annotation that will set the database table field as String. If you want to read more about this annotation and see how to map an Enum as ORDINAL click here. Always override the equals/hashCode methods. These methods are often invoked by several frameworks. A lot of Primefaces “bugs” were solved by implementing these methods.You will need to create the “persistence.xml” file inside the “src/META-INF” folder: <?xml version='1.0' encoding='UTF-8'?><persistence version='2.0' xmlns='http://java.sun.com/xml/ns/persistence' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd'><persistence-unit name='JSFCrudPU' transaction-type='RESOURCE_LOCAL'> <provider>org.hibernate.ejb.HibernatePersistence</provider><properties> <property name='javax.persistence.jdbc.driver' value='org.postgresql.Driver' /> <property name='javax.persistence.jdbc.url' value='jdbc:postgresql://localhost:5432/JSFCrudDB' /> <property name='javax.persistence.jdbc.user' value='postgres' /> <property name='javax.persistence.jdbc.password' value='postgres' /> <property name='hibernate.dialect' value='org.hibernate.dialect.PostgreSQLDialect' /> <property name='hibernate.connection.shutdown' value='true' /> <property name='hibernate.hbm2ddl.auto' value='update' /> <property name='hibernate.show_sql' value='false' /> <property name='hibernate.format_sql' value='false'/> </properties> </persistence-unit> </persistence> About the above code:The “hibernate.hbm2ddl.auto” property with the value “update” indicates to the JPA to update, whenever necessary, the database according the model classes. It is not a good practice to leave this option as “update” or with any other value that may update the production/customer database. It is always good to use the “validate” option in the production environment and to create and execute the sql script manually. The hibernate.show_sql and the hibernate.format_sql properties are used to display the query in the console. In the file log4j.properties (page 08) there is an option that will allow displaying the query parameters values.DAO In the package “com.dao” you will need to create the following classes: package com.dao;import java.io.Serializable; import java.util.*; import java.util.Map.*;import javax.persistence.*; import javax.persistence.criteria.CriteriaQuery;abstract class GenericDAO<T> implements Serializable { private static final long serialVersionUID = 1L;private static final EntityManagerFactory emf = Persistence.createEntityManagerFactory('JSFCrudPU'); private EntityManager em;private Class<T> entityClass;public void beginTransaction() { em = emf.createEntityManager();em.getTransaction().begin(); }public void commit() { em.getTransaction().commit(); }public void rollback() { em.getTransaction().rollback(); }public void closeTransaction() { em.close(); }public void commitAndCloseTransaction() { commit(); closeTransaction(); }public void flush() { em.flush(); }public void joinTransaction() { em = emf.createEntityManager(); em.joinTransaction(); }public GenericDAO(Class<T> entityClass) { this.entityClass = entityClass; }public void save(T entity) { em.persist(entity); }public void delete(T entity) { T entityToBeRemoved = em.merge(entity);em.remove(entityToBeRemoved); }public T update(T entity) { return em.merge(entity); }public T find(int entityID) { return em.find(entityClass, entityID); }public T findReferenceOnly(int entityID) { return em.getReference(entityClass, entityID); }// Using the unchecked because JPA does not have a // em.getCriteriaBuilder().createQuery()<T> method @SuppressWarnings({ 'unchecked', 'rawtypes' }) public List<T> findAll() { CriteriaQuery cq = em.getCriteriaBuilder().createQuery(); cq.select(cq.from(entityClass)); return em.createQuery(cq).getResultList(); }// Using the unchecked because JPA does not have a // query.getSingleResult()<T> method @SuppressWarnings('unchecked') protected T findOneResult(String namedQuery, Map<String, Object> parameters) { T result = null;try { Query query = em.createNamedQuery(namedQuery);// Method that will populate parameters if they are passed not null and empty if (parameters != null && !parameters.isEmpty()) { populateQueryParameters(query, parameters); }result = (T) query.getSingleResult();} catch (NoResultException e) { System.out.println('No result found for named query: ' + namedQuery); } catch (Exception e) { System.out.println('Error while running query: ' + e.getMessage()); e.printStackTrace(); }return result; }private void populateQueryParameters(Query query, Map<String, Object> parameters) { for (Entry<String, Object> entry : parameters.entrySet()) { query.setParameter(entry.getKey(), entry.getValue()); } } } package com.dao;import java.util.*;import com.model.Person;public class PersonDAO extends GenericDAO<Person> {private static final long serialVersionUID = 1L;public PersonDAO() { super(Person.class); }public Person findPersonWithAllDogs(int personId) { Map<String, Object> parameters = new HashMap<String, Object>(); parameters.put('personId', personId);return super.findOneResult(Person.FIND_USER_BY_ID_WITH_DOGS, parameters); } } package com.dao;import java.util.*;import com.model.User;public class UserDAO extends GenericDAO<User> {private static final long serialVersionUID = 1L;public UserDAO() { super(User.class); }public User findUserByEmail(String email){ Map<String, Object> parameters = new HashMap<String, Object>(); parameters.put('email', email);return super.findOneResult(User.FIND_BY_EMAIL, parameters); } } package com.dao;import com.model.Dog;public class DogDAO extends GenericDAO<Dog> {private static final long serialVersionUID = 1L;public DogDAO() { super(Dog.class); } } About the above code:The DAO classes has methods to allow the Façades to control the transaction. This pattern is being applied to avoid the OpenSessionInView pattern; the OpenSessionInView pattern may cause the N+1 effect of queries. With the transaction controlled by the developer it is easier to understand the transaction flow, but we have a more verbose code. If you want to know more about the OpenSessionInView and the N+1 effect you can click here. You will find a method named “populateQueryParameters” in the GenericDAO class. This method will populate dynamically all the parameters of a query if needed. The classes PersonDAO and UserDAO have a sample code of how to invoke this method.Façades In the package “com.facade” you will need to create the classes bellow: package com.facade;import com.dao.UserDAO; import com.model.User;public class UserFacade { private UserDAO userDAO = new UserDAO();public User isValidLogin(String email, String password) { userDAO.beginTransaction(); User user = userDAO.findUserByEmail(email);if (user == null || !user.getPassword().equals(password)) { return null; }return user; } } package com.facade;import java.io.Serializable; import java.util.List;import com.dao.DogDAO; import com.model.Dog;public class DogFacade implements Serializable{ private static final long serialVersionUID = 1L;private DogDAO dogDAO = new DogDAO();public void createDog(Dog dog) { dogDAO.beginTransaction(); dogDAO.save(dog); dogDAO.commitAndCloseTransaction(); }public void updateDog(Dog dog) { dogDAO.beginTransaction(); Dog persistedDog = dogDAO.find(dog.getId()); persistedDog.setAge(dog.getAge()); persistedDog.setName(dog.getName()); dogDAO.update(persistedDog); dogDAO.commitAndCloseTransaction(); }public Dog findDog(int dogId) { dogDAO.beginTransaction(); Dog dog = dogDAO.find(dogId); dogDAO.closeTransaction(); return dog; }public List<Dog> listAll() { dogDAO.beginTransaction(); List<Dog> result = dogDAO.findAll(); dogDAO.closeTransaction(); return result; }public void deleteDog(Dog dog) { dogDAO.beginTransaction(); Dog persistedDog = dogDAO.findReferenceOnly(dog.getId()); dogDAO.delete(persistedDog); dogDAO.commitAndCloseTransaction(); } } package com.facade;import java.io.Serializable; import java.util.List;import com.dao.DogDAO; import com.dao.PersonDAO; import com.model.Dog; import com.model.Person;public class PersonFacade implements Serializable { private static final long serialVersionUID = 1L;private PersonDAO personDAO = new PersonDAO(); private DogDAO dogDAO = new DogDAO();public void createPerson(Person person) { personDAO.beginTransaction(); personDAO.save(person); personDAO.commitAndCloseTransaction(); }public void updatePerson(Person person) { personDAO.beginTransaction(); Person persistedPerson = personDAO.find(person.getId()); persistedPerson.setName(person.getName()); persistedPerson.setAge(person.getAge()); personDAO.commitAndCloseTransaction(); }public void deletePerson(Person person){ personDAO.beginTransaction(); Person persistedPersonWithIdOnly = personDAO.findReferenceOnly(person.getId()); personDAO.delete(persistedPersonWithIdOnly); personDAO.commitAndCloseTransaction();}public Person findPerson(int personId) { personDAO.beginTransaction(); Person person = personDAO.find(personId); personDAO.closeTransaction(); return person; }public List<Person> listAll() { personDAO.beginTransaction(); List<Person> result = personDAO.findAll(); personDAO.closeTransaction();return result; }public Person findPersonWithAllDogs(int personId) { personDAO.beginTransaction(); Person person = personDAO.findPersonWithAllDogs(personId); personDAO.closeTransaction(); return person; }public void addDogToPerson(int dogId, int personId) { personDAO.beginTransaction(); dogDAO.joinTransaction(); Dog dog = dogDAO.find(dogId); Person person = personDAO.find(personId); person.getDogs().add(dog); dog.getPerson().add(person); personDAO.commitAndCloseTransaction(); }public void removeDogFromPerson(int dogId, int personId) { personDAO.beginTransaction(); dogDAO.joinTransaction(); Dog dog = dogDAO.find(dogId); Person person = personDAO.find(personId); person.getDogs().remove(dog); dog.getPerson().remove(person); personDAO.commitAndCloseTransaction(); } } About the above code:Every transaction is controlled by the developer. The developer has the responsibility of never forgetting an opened transaction. The class PersonFacade uses a method named “findReferenceOnly“. This method has a better performance than the “find” method with operations that involves only operations where only the entity id is needed. A query will be triggered in the database to get only the ID of that entity. If any other attribute is invoked a new query will be fired in the database to bring that information. According the book “Pro JPA 2: Mastering the Java™ Persistence API” this method could also be used to edit items in a list. e.g. In the method Person.addDoAgToPerson the “find” method could be replace for the “findReferenceOnly“ Both methods ” Person.addDogToPerson” and “ Person.removeDogFromPerson” invoke the method “joinTransaction” in the DogDAO class. The EntityManager in the DogDAO will use the same transaction started at the PersonDAO.Cares about the EntityManager.merge() Take a look at the code bellow:It would be easier just invoke the method like this: “entityManager.merge(dog)” instead of querying for the persisted object and updating the data. If you invoke the merge method in a file received from the view you could damage the integrity of your database data. The developer must take care with this merge method; if a lazy relationship is not loaded and this relationship is null in the merged entity the JPA/Hibernate will erase this relationship in the database. e.g. If the developer invokes the method entityManager.merge(dog) and dog.getPersons() == null the JPA/Hibernate will delete all relationship between them in the database. The best practice is to find the object in the database than edit it. In this project the object were loaded from the database and it is in the detached state; for this specific situation where you find the object detached and the lazy relationship is not null the JPA will not erase the database data relationship. If the object were manually created and the relationship has the value List<Person> == null the JPA would have deleted the database data. Filter In the “com.filter” package you will need to create the classes bellow: package com.filter;import java.io.IOException;import javax.servlet.*; import javax.servlet.http.HttpServletRequest;public class AbstractFilter {public AbstractFilter() { super(); }protected void doLogin(ServletRequest request, ServletResponse response, HttpServletRequest req) throws ServletException, IOException { RequestDispatcher rd = req.getRequestDispatcher('/pages/public/login.xhtml'); rd.forward(request, response); }protected void accessDenied(ServletRequest request, ServletResponse response, HttpServletRequest req) throws ServletException, IOException { RequestDispatcher rd = req.getRequestDispatcher('/pages/public/accessDenied.xhtml'); rd.forward(request, response); } } package com.filter;import java.io.IOException; import java.util.*;import javax.servlet.*; import javax.servlet.http.*;import com.model.User;/** * Servlet Filter implementation class UserCheckFilter */ public class LoginCheckFilter extends AbstractFilter implements Filter { private static List<String> allowedURIs;/** * @see Filter#init(FilterConfig) */ public void init(FilterConfig fConfig) throws ServletException { if(allowedURIs == null){ allowedURIs = new ArrayList<String>(); allowedURIs.add(fConfig.getInitParameter('loginActionURI')); allowedURIs.add('/JSFCrudApp/javax.faces.resource/main.css.xhtml'); allowedURIs.add('/JSFCrudApp/javax.faces.resource/theme.css.xhtml'); allowedURIs.add('/JSFCrudApp/javax.faces.resource/primefaces.js.xhtml'); allowedURIs.add('/JSFCrudApp/javax.faces.resource/primefaces.css.xhtml'); allowedURIs.add('/JSFCrudApp/javax.faces.resource/jquery/jquery.js.xhtml'); allowedURIs.add('/JSFCrudApp/javax.faces.resource/messages/messages.png.xhtml'); allowedURIs.add('/JSFCrudApp/javax.faces.resource/images/ui-icons_2e83ff_256x240.png.xhtml'); allowedURIs.add('/JSFCrudApp/javax.faces.resource/images/ui-icons_38667f_256x240.png.xhtml'); } }/** * @see Filter#destroy() */ public void destroy() { }/** * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain) */ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpSession session = req.getSession();if (session.isNew()) { doLogin(request, response, req); return; }User user = (User) session.getAttribute('user');if (user == null && !allowedURIs.contains(req.getRequestURI())) { System.out.println(req.getRequestURI()); doLogin(request, response, req); return; }chain.doFilter(request, response); } } package com.filter;import java.io.IOException;import javax.servlet.*; import javax.servlet.http.HttpServletRequest;import com.model.User;public class AdminPagesFilter extends AbstractFilter implements Filter {@Override public void destroy() {}@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; User user = (User) req.getSession(true).getAttribute('user');if (!user.isAdmin()) { accessDenied(request, response, req); return; }chain.doFilter(request, response); }@Override public void init(FilterConfig arg0) throws ServletException {} } package com.filter;import java.io.IOException;import javax.servlet.*; import javax.servlet.http.HttpServletRequest;import com.model.User;public class DefaultUserPagesFilter extends AbstractFilter implements Filter {@Override public void destroy() {}@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; User user = (User) req.getSession(true).getAttribute('user');if(!user.isUser() && !user.isAdmin()){ accessDenied(request, response, req); return; }chain.doFilter(request, response); }@Override public void init(FilterConfig arg0) throws ServletException {} } About the above code:The classes that implements the Filter interface are responsible for the Authorization and Authentication of the user. At the page 13 will have more information about why do we need to check if the user is logged in and its role at every request. The method “fConfig.getInitParameter(“loginActionURI”);” that is invoked inside the class LoginCheckFilter will load a property from the “web.xml” file. The “loginActionURI” property has a value to indicate the login page to the Filter; the Filter will use this property to allow every user (logged or not) to access that specific page (you will see the property value in the page 12). This property value is added to a list of URLs that are allowed to be called without the need of a logged user. It is a good practice to have this list of allowed URLs in the “web.xml” file, but for commodity only one were added in the “web.xml” in this post to display how to do it. Each filter watches over a directory that an user may access. Other approach would be to have a file with all allowed URLs and its allowed roles, e.g. “JSFCrud/protected/manager;admin-manager”.Continue to the second part. Reference: Full Web Application with Tomcat JSF Primefaces JPA Hibernate from our JCG partner Hebert Coelho at the uaiHebert blog....
primefaces-logo

Full Web Application Tomcat JSF Primefaces JPA Hibernate – Part 2

ManagedBeans This post continues from part 1 of this tutorial. In the “com.mb” package you will need to create the classes bellow:             package com.mb;import org.primefaces.context.RequestContext;import com.util.JSFMessageUtil;public class AbstractMB { private static final String KEEP_DIALOG_OPENED = 'KEEP_DIALOG_OPENED';public AbstractMB() { super(); }protected void displayErrorMessageToUser(String message) { JSFMessageUtil messageUtil = new JSFMessageUtil(); messageUtil.sendErrorMessageToUser(message); }protected void displayInfoMessageToUser(String message) { JSFMessageUtil messageUtil = new JSFMessageUtil(); messageUtil.sendInfoMessageToUser(message); }protected void closeDialog(){ getRequestContext().addCallbackParam(KEEP_DIALOG_OPENED, false); }protected void keepDialogOpen(){ getRequestContext().addCallbackParam(KEEP_DIALOG_OPENED, true); }protected RequestContext getRequestContext(){ return RequestContext.getCurrentInstance(); } } package com.mb;import java.io.Serializable; import java.util.List;import javax.faces.bean.*;import com.facade.DogFacade; import com.model.Dog;@ViewScoped @ManagedBean public class DogMB extends AbstractMB implements Serializable { private static final long serialVersionUID = 1L;private Dog dog; private List<Dog> dogs; private DogFacade dogFacade;public DogFacade getDogFacade() { if (dogFacade == null) { dogFacade = new DogFacade(); }return dogFacade; }public Dog getDog() { if (dog == null) { dog = new Dog(); }return dog; }public void setDog(Dog dog) { this.dog = dog; }public void createDog() { try { getDogFacade().createDog(dog); closeDialog(); displayInfoMessageToUser('Created With Sucess'); loadDogs(); resetDog(); } catch (Exception e) { keepDialogOpen(); displayErrorMessageToUser('Ops, we could not create. Try again later'); e.printStackTrace(); } }public void updateDog() { try { getDogFacade().updateDog(dog); closeDialog(); displayInfoMessageToUser('Updated With Sucess'); loadDogs(); resetDog(); } catch (Exception e) { keepDialogOpen(); displayErrorMessageToUser('Ops, we could not create. Try again later'); e.printStackTrace(); } }public void deleteDog() { try { getDogFacade().deleteDog(dog); closeDialog(); displayInfoMessageToUser('Deleted With Sucess'); loadDogs(); resetDog(); } catch (Exception e) { keepDialogOpen(); displayErrorMessageToUser('Ops, we could not create. Try again later'); e.printStackTrace(); } }public List<Dog> getAllDogs() { if (dogs == null) { loadDogs(); }return dogs; }private void loadDogs() { dogs = getDogFacade().listAll(); }public void resetDog() { dog = new Dog(); } } package com.mb;import java.io.Serializable;import javax.faces.bean.*; import javax.faces.context.FacesContext; import javax.servlet.http.HttpServletRequest;import com.model.User;@SessionScoped @ManagedBean(name='userMB') public class UserMB implements Serializable { public static final String INJECTION_NAME = '#{userMB}'; private static final long serialVersionUID = 1L;private User user;public boolean isAdmin() { return user.isAdmin(); }public boolean isDefaultUser() { return user.isUser(); }public String logOut() { getRequest().getSession().invalidate(); return '/pages/public/login.xhtml'; }private HttpServletRequest getRequest() { return (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest(); }public User getUser() { return user; }public void setUser(User user) { this.user = user; } } package com.mb;import java.io.Serializable; import java.util.*;import javax.faces.bean.*;import com.facade.*; import com.model.*; import com.sun.faces.context.flash.ELFlash;@ViewScoped @ManagedBean public class PersonMB extends AbstractMB implements Serializable { private static final long serialVersionUID = 1L;private static final String SELECTED_PERSON = 'selectedPerson';private Dog dog; private Person person; private Person personWithDogs; private Person personWithDogsForDetail;private List<Dog> allDogs; private List<Person> persons;private DogFacade dogFacade; private PersonFacade personFacade;public void createPerson() { try { getPersonFacade().createPerson(person); closeDialog(); displayInfoMessageToUser('Created With Sucess'); loadPersons(); resetPerson(); } catch (Exception e) { keepDialogOpen(); displayErrorMessageToUser('Ops, we could not create. Try again later'); e.printStackTrace(); } }public void updatePerson() { try { getPersonFacade().updatePerson(person); closeDialog(); displayInfoMessageToUser('Updated With Sucess'); loadPersons(); resetPerson(); } catch (Exception e) { keepDialogOpen(); displayErrorMessageToUser('Ops, we could not create. Try again later'); e.printStackTrace(); } }public void deletePerson() { try { getPersonFacade().deletePerson(person); closeDialog(); displayInfoMessageToUser('Deleted With Sucess'); loadPersons(); resetPerson(); } catch (Exception e) { keepDialogOpen(); displayErrorMessageToUser('Ops, we could not create. Try again later'); e.printStackTrace(); } }public void addDogToPerson() { try { getPersonFacade().addDogToPerson(dog.getId(), personWithDogs.getId()); closeDialog(); displayInfoMessageToUser('Added With Sucess'); reloadPersonWithDogs(); resetDog(); } catch (Exception e) { keepDialogOpen(); displayErrorMessageToUser('Ops, we could not create. Try again later'); e.printStackTrace(); } }public void removeDogFromPerson() { try { getPersonFacade().removeDogFromPerson(dog.getId(), personWithDogs.getId()); closeDialog(); displayInfoMessageToUser('Removed With Sucess'); reloadPersonWithDogs(); resetDog(); } catch (Exception e) { keepDialogOpen(); displayErrorMessageToUser('Ops, we could not create. Try again later'); e.printStackTrace(); } }public Person getPersonWithDogs() { if (personWithDogs == null) { if (person == null) { person = (Person) ELFlash.getFlash().get(SELECTED_PERSON); }personWithDogs = getPersonFacade().findPersonWithAllDogs(person.getId()); }return personWithDogs; }public void setPersonWithDogsForDetail(Person person) { personWithDogsForDetail = getPersonFacade().findPersonWithAllDogs(person.getId()); }public Person getPersonWithDogsForDetail() { if (personWithDogsForDetail == null) { personWithDogsForDetail = new Person(); personWithDogsForDetail.setDogs(new ArrayList<Dog>()); }return personWithDogsForDetail; }public void resetPersonWithDogsForDetail(){ personWithDogsForDetail = new Person(); }public String editPersonDogs() { ELFlash.getFlash().put(SELECTED_PERSON, person); return '/pages/protected/defaultUser/personDogs/personDogs.xhtml'; }public List<Dog> complete(String name) { List<Dog> queryResult = new ArrayList<Dog>();if (allDogs == null) { dogFacade = new DogFacade(); allDogs = dogFacade.listAll(); }allDogs.removeAll(personWithDogs.getDogs());for (Dog dog : allDogs) { if (dog.getName().toLowerCase().contains(name.toLowerCase())) { queryResult.add(dog); } }return queryResult; }public PersonFacade getPersonFacade() { if (personFacade == null) { personFacade = new PersonFacade(); }return personFacade; }public Person getPerson() { if (person == null) { person = new Person(); }return person; }public void setPerson(Person person) { this.person = person; }public List<Person> getAllPersons() { if (persons == null) { loadPersons(); }return persons; }private void loadPersons() { persons = getPersonFacade().listAll(); }public void resetPerson() { person = new Person(); }public Dog getDog() { if (dog == null) { dog = new Dog(); }return dog; }public void setDog(Dog dog) { this.dog = dog; }public void resetDog() { dog = new Dog(); }private void reloadPersonWithDogs() { personWithDogs = getPersonFacade().findPersonWithAllDogs(person.getId()); } } package com.mb;import javax.faces.bean.*; import javax.faces.context.FacesContext; import javax.servlet.http.HttpServletRequest;import com.facade.UserFacade; import com.model.User;@RequestScoped @ManagedBean public class LoginMB extends AbstractMB { @ManagedProperty(value = UserMB.INJECTION_NAME) private UserMB userMB;private String email; private String password;public String getEmail() { return email; }public void setEmail(String email) { this.email = email; }public String getPassword() { return password; }public void setPassword(String password) { this.password = password; }public String login() { UserFacade userFacade = new UserFacade();User user = userFacade.isValidLogin(email, password);if(user != null){ userMB.setUser(user); FacesContext context = FacesContext.getCurrentInstance(); HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest(); request.getSession().setAttribute('user', user); return '/pages/protected/index.xhtml'; }displayErrorMessageToUser('Check your email/password');return null; }public void setUserMB(UserMB userMB) { this.userMB = userMB; } } About the above code:All ManagedBeans are responsible only for the VIEW actions; the ManagedBeans should be responsible to handle the only outcome of the business methods. There are no business rules in the ManagedBeans. It is very easy to do some business actions in the view layer but is not a good practice. The LoginMB class uses another ManagedBean (UserMB) there were injected inside of it. To inject a ManagedBean inside another ManagedBean you must do as bellow:Uses the @ManagedProperty on the top of the injected ManagedBean Create a set method to the property like “loginMB.setUserMB(…)“The PersonMB class could receive refactoring actions because it is too big. The PersonMB is like that to make easer for rookie developers to understand the code faster.Observations about @ViewScoped You will see in the managed beans with the @ViewScoped annotation some reload and reset methods. Both methods are required to reset the objects state; e.g. a dog object would hold values from the view after a method execution (persist in the database, display values in a dialog). If the user open de create dialog and successfully create a dog this dog object will hold all values while the user stays in the same page. If the user opens the create dialog again all the data of the last recorded dog will be displayed there. That is why we have the reset methods. If you update an object in the database the object in the user view must receive this update too, the ManagedBean objects must receive this new data. If you updated a dog name in the database the list of dog should receive this updated dog too. You can query this new data in the database or just update the managed bean values. A developer must be aware of:Reload the managed bean data querying the database (the reload methods): if the fired query to reload the ManagedBean object comes with a huge amount of data his query may affect the application performance. A developer could use a datatable with lazy load. Click here to see more about Lazy Datatable. Reload the updated object directly in the managed bean without querying the database: imagine that the user1 updates the dog1 name in the database and at the same time user2 updates the dog2 age. The user1 will see the old data about the dog2 that could cause a database integrity issue if the user1 updates the dog2. A solution to this approach could be a version field in the database table. Before the update takes place this field would be checked. If the version field does not hold the same value found in the database an exception could be raised. With this approach if the user1 updates the dog2 the version value would not be the same.JSFMessageUtil In the package “com.util” create the class bellow: package com.util;import javax.faces.application.FacesMessage; import javax.faces.application.FacesMessage.Severity; import javax.faces.context.FacesContext;public class JSFMessageUtil { public void sendInfoMessageToUser(String message) { FacesMessage facesMessage = createMessage(FacesMessage.SEVERITY_INFO, message); addMessageToJsfContext(facesMessage); }public void sendErrorMessageToUser(String message) { FacesMessage facesMessage = createMessage(FacesMessage.SEVERITY_WARN, message); addMessageToJsfContext(facesMessage); }private FacesMessage createMessage(Severity severity, String mensagemErro) { return new FacesMessage(severity, mensagemErro, mensagemErro); }private void addMessageToJsfContext(FacesMessage facesMessage) { FacesContext.getCurrentInstance().addMessage(null, facesMessage); } } This class will handle all JSF Messages that will be displayed to the user. This class will help our ManagedBeans to lose coupling between the classes. It is also a good idea to create a class to handle the dialogs actions. Configurations file In the source “src” folder create the following files: “log4.properties” # Direct log messages to stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target=System.out log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n# Root logger option log4j.rootLogger=ERROR, stdout# Hibernate logging options (INFO only shows startup messages) log4j.logger.org.hibernate=ERROR# Log JDBC bind parameter runtime arguments #log4j.logger.org.hibernate.type=TRACE “messages.properties” #Actions welcomeMessage=Hello! Show me the best soccer team logo ever update=Update create=Create delete=Delete cancel=Cancel detail=Detail logIn=Log In add=Add remove=Remove ok=Ok logOut= Log Out javax.faces.component.UIInput.REQUIRED={0}: is empty. Please, provide some value javax.faces.validator.LengthValidator.MINIMUM={1}: Length is less than allowable minimum of u2018u2019{0}u2019u2019 noRecords=No data to display deleteRecord=Do you want do delete the record#Login / Roles Validations loginHello=Login to access secure pages loginUserName=Username loginPassword=Password logout=Log Out loginWelcomeMessage=Welcome accessDeniedHeader=Wow, our ninja cat found you! accessDeniedText=Sorry but you can not access that page. If you try again, that ninja cat gonna kick you harder! >= ) accessDeniedButton=You got-me, take me out. =/#Person person=Person personPlural=Persons personName=Name personAge=Age personDogs=These dogs belongs to personAddDogTo=Add the selected Dog To personRemoveDogFrom=Remove the selected Dog from personEditDogs=Edit Dogs#Dog dog=Dog dogPlural=Dogs dogName=Name dogAge=Age Take a look at the “lo4j.properties” the line #log4j.logger.org.hibernate.type=TRACE is commented. If you want to see the created query by the Hibernate you need to edit other configurations of the file from ERROR to DEBUG and remove the # from the line above. You will be able to see the Hibernate executed query and its parameters. xhtml Pages, Facelets Inside the WebContent folder you will find the following files:Let us see how to apply Facelets to a project. Create the files bellow inside the folder “/WebContent/pages/protected/templates/”: “left.xhtml” <!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html xmlns='http://www.w3.org/1999/xhtml' xmlns:ui='http://java.sun.com/jsf/facelets' xmlns:h='http://java.sun.com/jsf/html' xmlns:p='http://primefaces.org/ui'><h:body> <ui:composition> <h:form> <p:commandButton styleClass='menuButton' icon='ui-icon-arrowstop-1-e' rendered='#{userMB.admin or userMB.defaultUser}' action='/pages/protected/defaultUser/defaultUserIndex.xhtml' value='#{bundle.personPlural}' ajax='false' immediate='true' /> <br /> <p:commandButton styleClass='menuButton' icon='ui-icon-arrowstop-1-e' rendered='#{userMB.admin}' action='/pages/protected/admin/adminIndex.xhtml' value='#{bundle.dogPlural}' ajax='false' immediate='true' /> <br /> </h:form> </ui:composition> </h:body> </html> “master.xhtml” <?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html xmlns='http://www.w3.org/1999/xhtml' xmlns:ui='http://java.sun.com/jsf/facelets' xmlns:h='http://java.sun.com/jsf/html' xmlns:p='http://primefaces.org/ui' xmlns:f='http://java.sun.com/jsf/core'><h:head> <title>CrudJSF</title> <h:outputStylesheet library='css' name='main.css' /> <meta http-equiv='Content-Type' content='text/html; charset=UTF-8' /> </h:head><h:body> <f:view contentType='text/html; charset=UTF-8' encoding='UTF-8' > <div id='divTop' style='vertical-align: middle;'> <ui:insert name='divTop'> <ui:include src='top.xhtml' /> </ui:insert> </div><div id='divLeft'> <ui:insert name='divLeft'> <ui:include src='left.xhtml' /> </ui:insert> </div><div id='divMain'> <p:growl id='messageGrowl' /> <ui:insert name='divMain' /> </div><h:outputScript library='javascript' name='jscodes.js' /> </f:view> </h:body> </html> “top.xhtml” <!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html xmlns='http://www.w3.org/1999/xhtml' xmlns:ui='http://java.sun.com/jsf/facelets' xmlns:h='http://java.sun.com/jsf/html' xmlns:p='http://primefaces.org/ui'> <h:body> <ui:composition> <div id='topMessage'> <h1> <h:form> #{bundle.loginWelcomeMessage}: #{userMB.user.name} | <p:commandButton value='#{bundle.logOut}' action='#{userMB.logOut()}' ajax='false' style='font-size: 20px;' /> </h:form> </h1> </div> </ui:composition> </h:body> </html> The above code will be the base for all the xhtml pages of the application. It is very important to apply the Facelets pattern to re-use the xhtml code. Bellow you can see how to apply Facelets in the xhtml page, notice that the developer just need to overwrite the desired section: <!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'> <html xmlns='http://www.w3.org/1999/xhtml' xmlns:ui='http://java.sun.com/jsf/facelets' xmlns:h='http://java.sun.com/jsf/html' xmlns:f='http://java.sun.com/jsf/core' xmlns:p='http://primefaces.org/ui' > <h:body> <ui:composition template='/pages/protected/templates/master.xhtml'> <ui:define name='divMain'> #{bundle.welcomeMessage} :<br/> <h:graphicImage library='images' name='logoReal.png' /> </ui:define> </ui:composition> </h:body> </html> Notice that only the “divMain” were overwritten and the other sections remained the same. That is the greatest advantage of the Facelets, you do not need to use the include all areas of the site in every page. Continue to the third part. Reference: Full Web Application with Tomcat JSF Primefaces JPA Hibernate from our JCG partner Hebert Coelho at the uaiHebert blog. ...
primefaces-logo

Full Web Application Tomcat JSF Primefaces JPA Hibernate – Part 3

Primefaces AutoComplete, JSF Converter This post continues from part 1 and part 2. The JSF has the Converter tool that helps us get some data from the user view and transform into an object loaded from the database or a cache.           In the “com.converter” package create the following class: package com.converter;import javax.faces.application.FacesMessage; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import javax.faces.convert.*;import com.facade.DogFacade; import com.model.Dog;@FacesConverter(forClass = com.model.Dog.class) public class DogConverter implements Converter {@Override public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) { DogFacade dogFacade = new DogFacade(); int dogId;try { dogId = Integer.parseInt(arg2); } catch (NumberFormatException exception) { throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, 'Type the name of a Dog and select it (or use the dropdow)', 'Type the name of a Dog and select it (or use the dropdow)')); }return dogFacade.findDog(dogId); }@Override public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) {if (arg2 == null) { return ''; } Dog dog = (Dog) arg2; return String.valueOf(dog.getId()); } } About the above code:In the @Converter annotation there is an attribute named “forClass”. This attribute indicates to the de JSF that all classes of the specified in the “forClass” will invoke the Converter. The DogConverter is annotated with “forClass = com.model.Dog.class”, every time the JSF needs a Converter for a Dog class the JSF will invoke the DogConverter. It was not necessary to write any code in the “web.xml” file.The Converter code is required in the Primefaces AutoComplete. Bellow you see how easy is to use the AutoComplete: personUpdateDialog.xhtmlPersonMB.javaAbout the above code:The AutoComplete function has several options like minimum query length, delay to start a query, dropdown to display all values and more. It is worth to see all the options: http://primefaces.org/showcase/ui/autoCompleteBasic.jsf and http://primefaces.org/showcase/ui/autocompleteHome.jsf The “complete” method has a cache of the values found in the database. The method goes to each object of the List<Dog> and keeps the matches. Notice that the Converter will always be called because the “itemValue=”#{dog}”” that you will find in the AutoComplete component.You can see bellow the AutoComplete working:CSS/javascript/images with JSF Take a look at the pictures bellow, it will display how that the application of this post handles resources: “master.xhtml”“index.xhtml”With JSF it is very easy to handle this kind of resources. The developer does not need to use the file relative path anymore. To use your resources like that create your files like bellow:The JSF will map all resources found in the folder “/WebContent/resources” and the developer will be able to use the resources like displayed above. “web.xml” configurations In the folder “WebContent/WEB-INF/” create the files bellow: “web.xml” <?xml version='1.0'?> <web-app version='3.0' xmlns='http://java.sun.com/xml/ns/javaee' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd'> <display-name>JSFCrudApp</display-name> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.xhtml</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>/pages/protected/index.xhtml</welcome-file> </welcome-file-list> <context-param> <param-name>javax.faces.PROJECT_STAGE</param-name> <param-value>Development</param-value> </context-param><filter> <filter-name>LoginCheckFilter</filter-name> <filter-class>com.filter.LoginCheckFilter</filter-class> <init-param> <param-name>loginActionURI</param-name> <param-value>/JSFCrudApp/pages/public/login.xhtml</param-value> </init-param> </filter> <filter-mapping> <filter-name>LoginCheckFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping><filter> <filter-name>AdminPagesFilter</filter-name> <filter-class>com.filter.AdminPagesFilter</filter-class> </filter> <filter-mapping> <filter-name>AdminPagesFilter</filter-name> <url-pattern>/pages/protected/admin/*</url-pattern> </filter-mapping><filter> <filter-name>DefaultUserPagesFilter</filter-name> <filter-class>com.filter.DefaultUserPagesFilter</filter-class> </filter> <filter-mapping> <filter-name>DefaultUserPagesFilter</filter-name> <url-pattern>/pages/protected/defaultUser/*</url-pattern> </filter-mapping> </web-app> “faces-config.xml” <?xml version='1.0' encoding='UTF-8'?><faces-config xmlns='http://java.sun.com/xml/ns/javaee' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd' version='2.0'> <application> <resource-bundle> <base-name>messages</base-name> <var>bundle</var> </resource-bundle> <message-bundle>messages</message-bundle> </application> </faces-config> About the above code:All security filters you will find mapped in the web.xml file. You could also use the @Filter annotations that would work the same. The property “javax.faces.PROJECT_STAGE” has the value DEVELOPMENT. One of the advantages of this configurations is that the JSF will append a “h:message” if none is found in the screen. If some exception happens and there is no component to display it the JSF will append a h:message component in the page. Inside the “faces-config” exist a tag named “message-bundle”. This tag allows the developer to override the JSF default messages, the value of this tag will point to a file with the default JSF messages key. In the “message.properties” file (page 08) has the key “javax.faces.component.UIInput.REQUIRED”, any value you write in this key will affect all the “required field” messages displayed in the application.Increasing the security of your application Do not concatenate the queries Do not use the usual “where id =” + id sql code. This kind of code allows the “SQL Injection” hacker attack. A developer that works with ORM is also vulnerable to this kind of attack but with different name: “HQL Injection”. The best way of doing a query you may find in the Person and User class:It does not matter if you use JPA or not, never concatenate your query with strings. The developer must be aware that “SQL Injection may happen in any query of your application”, and not only in the login query. If a user has a valid login to your application, this user is able to do “SQL Injection” in all your queries. AutoComplete Off In the page “login.xhtml” there is the following code:The tag “autocomplete” off tells to the browser that this field should not be saved. The great browsers (Firefox, Chrome, IE) respect this tag and it helps to protect your application. If you allow the browser to keep the password the browser must keep this password stored somewhere. If a hacker finds out where this key is stored he may try to crack it. Validate all incoming requests If the application was required just to validate if the user is or is not logged the user class would not need the role Enum. If there was no role validation a regular user could access any area of the system, like the admin pages. Notice that this application has filters that always validate the user role for all requests. “Hiding a link is not a protection measure. The developer should always validate all incoming requests”. A developer may hide a URL or a button, but a user could access any screen of your application if he types the URL in the browser or simulating get/post calls. Always use the h:outputText component An easy way to avoid the Cross-Site Scripting is using the h:outputText component to display data from the database. Notice that in this post that all the values displayed to de user that comes from the database are using the h:outputText component. A situation that the h:outputText component can be avoided is when the application will display system messages from a file like “message.properties”. Running the application Start the Tomcat and check the database; notice that there is no table inside the database yet. Type the following URL in the browser: http://localhost/JSFCrudApp/ . The following screen will be displayed:Type any value that you want and press the login button, do not bother if there is no user or tables. Just click on it. You will see an error message like this:Check your database again and you will see that all tables were created. The applications is controlling all transaction manually that is the reason for the JPA/Hibernate just create the table when is first invoked. You need to create a user with the role ADMIN (I named this user Real Madrid) and another user with the USER role (I named it Barcelona). The ADMIN user will have access to all system under all folders but the user with the USER role will have access to the pages under the folder defaultUser. If you log in with the ADMIN user you will see:Log in now with the user that has the USER role:The Dogs button were hidden. Even without the button a user could access the URL of the Dogs and the Dogs screen should be allowed only to ADMIN roles. To see how the application would behave with and illegal access, keep logged in with the USER role and try to access the following link: http://localhost/JSFCrudApp/pages/protected/admin/adminIndex.xhtml The next screen will be displayed:This screen will be displayed because the AdminPagesFilter check if the request comes from a ADMIN user. I the user is not in the ADMIN role our Ninja Cat will get it! [= Reference: Full Web Application with Tomcat JSF Primefaces JPA Hibernate from our JCG partner Hebert Coelho at the uaiHebert blog. ...
mockito-logo

Mockito – Better error messages on NPE with globally configured SmartNull

Writing the Mockito reference card I had an opportunity to take a closer look at the less popular, but very useful features of Mockito. Some of them were too advance or too rare in use to be described in a refcard which should be kept short. One of those things is SmartNull. Currently non void methods return “safe empty value” appropriate for known types (e.g.: 0, false, empty collection) or null in other cases. SmartNull to can be returned instead of pure null to receive a much more descriptive error message on NPE. Instead of just a line when NullPointerException occurred: java.lang.NullPointerException at PlantWaterer.generateNPE(PlantWaterer.java:24) at DefaultValuesTest.shouldReturnNicerErrorMessageOnNPE(DefaultValuesTest.java:64)we have also got descriptive information what method was not stubbed: org.mockito.exceptions.verification.SmartNullPointerException: You have a NullPointerException here: ?> at PlantWaterer.generateNPE(PlantWaterer.java: 24) because this method call was ?not? stubbed correctly: ?> at PlantWaterer.generateNPE(PlantWaterer.java: 24) wateringScheduler.returnNull();at PlantWaterer.generateNPE(PlantWaterer.java: 24) at DefaultValuesTest.shouldReturnNicerErrorMessageOnNPE(DefaultValuesTest.java:64)A particular mock can be instructed to return SmartNull instead of the null value: PlantWaterer plantWatererMock = mock(PlantWaterer.class, Mockito.RETURNS_SMART_NULLS);or @Mock(answer = Answers.RETURNS_SMART_NULLS) private PlantWaterer plantWatererMock;SmartNull will be probably the default bahavior in Mockito 2.0, but for the backward compatibility in 1.9.x it is necessary to tell every mock explicitly to use it. The need to write another piece of boilerplate code causes that almost nobody uses SmartNull despite it is a very useful feature. And there the second almost unknown element of Mockito enters the game – global configuration. Generally there is no need to configure Mockito. It just works. But for some rare cases the framework’s authors left a gate which allows to override the default configuration of a few core behaviors, including the default answer policy for unstubbed methods. To make it work it is necessary to create org.mockito.configuration.MockitoConfiguration class (necessarily in that package) which implements IMockitoConfiguration interface. Usually it is comfortable to extend DefaultMockitoConfiguration class and only override desired behavior(s). package org.mockito.configuration;import org.mockito.internal.stubbing.defaultanswers.ReturnsSmartNulls; import org.mockito.stubbing.Answer;public class MockitoConfiguration extends DefaultMockitoConfiguration {public Answer<Object> getDefaultAnswer() { return new ReturnsSmartNulls(); } }After that preparation we should get SmartNullPointerException with the verbose output instead of the pure NullPointerException for every mock in our module. @Test(expectedExceptions = SmartNullPointerException.class) public void shouldReturnNicerErrorMessageOnNPE() { //given //Mockito.RETURNS_SMART_NULLS not needed anymore WateringScheduler wateringSchedulerMock = mock(WateringScheduler.class); WaterSource waterSourceMock = mock(WaterSource.class); PlantWaterer plantWatererMock = new PlantWaterer(waterSourceMock, wateringSchedulerMock);//when plantWatererMock.generateNPE();//then //SmartNullPointerException exception expected }This post is the first part of the series Beyond the Mockito refcard. Reference: Beyond the Mockito refcard – part 1 – Better error messages on NPE with globally configured SmartNull from our JCG partner Marcin Zajaczkowski at the Solid Soft blog....
software-development-2-logo

Common Errors in Whiteboard Job Interviews with UML Diagrams

There are two important differences between drawing a Unified Modeling Language Diagram in a design tool and depict a design at a whiteboard (i) usually the tool prevents you from some common errors with build in syntax checks and (ii) you have a lot more time to refer to your records. To avoid humiliation during a job interview and/or a design meeting with you next project team – it is maybe necessary to train design at whiteboards. In the following basic knowledge of UML 2.x is premised. If you are not yet familiar with UML then the UML® Resource Page of OMG [ 1] would be a good starting point to study.   UML Activity Diagrams – Deadlock Error Missing knowledge about the token flow in UML Activity Diagrams is a very common source of errors.In Figure 1 a typical error is depicted. To execute an activity at each incoming connector needs one token – otherwise a deadlock will happen. In the wrong sample action X will wait for ever. Correct is an additional Merge Node before the action X.Figure 1: Deadlock Error SampleA innocent question like ‘How would you implement this in Java?’ shows your real knowledge about token flows in UML 2 Activity Diagrams. UML Activity Diagrams – Initial Node Error A similar token flow problem happens in Figure 2. Here the start node has two edges. This means that it is not clear if action X or Y will be executed. In the correct version a Fork Node splits the token for both actions.Figure 2: Initial Node Error Sample UML Class Diagrams – Composition Relationship to Self In Figure 3 the composition relationship to self is wrong. In UML 2 the filled diamond symbol indicates that the relation is a composition. This means that all related OrderItem instances would be destroyed if the owning OrderItem is deleted. In almost all cases an aggregation would be correct solution.Figure 3: Composition Relationship to Self SampleIn the aggregation relationship (not filled diamond symbol) the object does not take part in the life cycle of the component object. So, the related OrderItems can outlive the destroyed instance.In Wikipedia [ 2] you find a good sample : “For example, a university owns various departments (e.g., chemistry), and each department has a number of professors. If the university closes, the departments will no longer exist, but the professors in those departments will continue to exist. Therefore, a University can be seen as a composition of departments, whereas departments have an aggregation of professors. In addition, a Professor could work in more than one department, but a department could not be part of more than one university.”Knowing the exact difference between composition and aggregation is crucial for a lot of design questions.  RecommendationIn most industries just some of the 14 standard UML diagrams are really needed. My perception is that Use Case Diagram, Activity Diagram, Sequence Diagram, Class Diagram, Component Diagram and Deployment Diagram are most important. For embedded system development also State Machine Diagrams may be needed. So, when you start to learn UML focus on the 6 most important diagram types.     References[1] UML® Resource Page; http://www.uml.org [2] Wkipedia – Object Composition; http://en.wikipedia.org/wiki/Object_compositionReference: Three Common Errors in Whiteboard Job Interviews with UML® Diagrams from our JCG partner Markus Sprunck at the Software Engineering Candies blog....
java-logo

Catch a StackOverFlowError by it’s tail

One of the more annoying situations you might have to deal with when working with a Java program is a StackOverFlowError, if you have a nice producible test case then there are few options with regard to playing with the stack size, or setting a conditional breakpoint / trace of some kind. But if you have a test case that might fail once in a 100 times, perhaps a race condition in AWTMulticaster as in my case, then you want to improve the diagnostics. The problem is that by default the VM won’t any elements in a stack trace after the first 1024 entries. (At least for JDK 6) So if you run the following trivial example: package other;public class Overflow {public static final void call(double a, double b, double c, double d) { call(a,b,c,d); }public static void main(String[] args) { call(0,0,0,0); }}The output will stop before you get to the cause of the problem, making it very hard to resolve the issue. > java other.Overflow Exception in thread "main" java.lang.StackOverflowError at other.Overflow.call(Overflow.java:7) at other.Overflow.call(Overflow.java:7) at other.Overflow.call(Overflow.java:7) at other.Overflow.call(Overflow.java:7) at other.Overflow.call(Overflow.java:7) at other.Overflow.call(Overflow.java:7) at other.Overflow.call(Overflow.java:7) at other.Overflow.call(Overflow.java:7) [ lots of lines removed ] at other.Overflow.call(Overflow.java:7) at other.Overflow.call(Overflow.java:7) at other.Overflow.call(Overflow.java:7) at other.Overflow.call(Overflow.java:7) at other.Overflow.call(Overflow.java:7) at other.Overflow.call(Overflow.java:7) Process exited with exit code 1.The good news is that this limit is one of the many official and unofficial things you can tweak when starting a VM. > java -XX:MaxJavaStackTraceDepth=1000000 other.Overflow Exception in thread "main" java.lang.StackOverflowError at other.Overflow.call(Overflow.java:7) at other.Overflow.call(Overflow.java:7) at other.Overflow.call(Overflow.java:7) at other.Overflow.call(Overflow.java:7) at other.Overflow.call(Overflow.java:7) at other.Overflow.call(Overflow.java:7) at other.Overflow.call(Overflow.java:7) at other.Overflow.call(Overflow.java:7) [ lots of lines removed ] at other.Overflow.call(Overflow.java:7) at other.Overflow.call(Overflow.java:7) at other.Overflow.call(Overflow.java:7) at other.Overflow.call(Overflow.java:7) at other.Overflow.call(Overflow.java:7) at other.Overflow.main(Overflow.java:12) Process exited with exit code 1.Notice that end of the stack now contains the root of the problem which will be incredibly useful when trying to diagnose the issue. You probably don’t want to leave this property set long term on a production servers because I am not entirely sure about the impact of it. Looking at the C++ code it appears that this is just a maximum value and won’t affect most other stack traces as they are allocated in a linked list in segments of 32 entries. Reference: Catch a StackOverFlowError by it’s tail from our JCG partner Gerard Davison at the Gerard Davison’s blog blog....
Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close