Commits

Micha Kops  committed 58a3304

Java EE 6 Blog Tutorial - Initial Release

  • Participants

Comments (0)

Files changed (14)

+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+
+	<groupId>com.hascode.tutorial.jee6</groupId>
+	<artifactId>jee6-blog-tutorial</artifactId>
+	<version>0.0.1</version>
+	<packaging>war</packaging>
+
+	<name>hasCode.com Java EE 6 Blog Tutorial</name>
+
+	<properties>
+		<endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+	</properties>
+
+	<dependencies>
+		<dependency>
+			<groupId>javax</groupId>
+			<artifactId>javaee-web-api</artifactId>
+			<version>6.0</version>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
+			<groupId>javax.validation</groupId>
+			<artifactId>validation-api</artifactId>
+			<version>1.0.0.GA</version>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.hibernate</groupId>
+			<artifactId>hibernate-validator</artifactId>
+			<version>4.0.2.GA</version>
+		</dependency>
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<version>4.8.2</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.derby</groupId>
+			<artifactId>derby</artifactId>
+			<version>10.6.1.0</version>
+		</dependency>
+		<dependency>
+			<groupId>org.primefaces</groupId>
+			<artifactId>primefaces</artifactId>
+			<version>2.2-SNAPSHOT</version>
+		</dependency>
+		<dependency>
+			<groupId>javax.faces</groupId>
+			<artifactId>jsf-api</artifactId>
+			<version>2.0</version>
+			<scope>provided</scope>
+		</dependency>
+	</dependencies>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>2.3.2</version>
+				<configuration>
+					<source>1.6</source>
+					<target>1.6</target>
+					<compilerArguments>
+						<endorseddirs>${endorsed.dir}</endorseddirs>
+					</compilerArguments>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-war-plugin</artifactId>
+				<version>2.1</version>
+				<configuration>
+					<failOnMissingWebXml>false</failOnMissingWebXml>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-dependency-plugin</artifactId>
+				<version>2.1</version>
+				<executions>
+					<execution>
+						<phase>validate</phase>
+						<goals>
+							<goal>copy</goal>
+						</goals>
+						<configuration>
+							<outputDirectory>${endorsed.dir}</outputDirectory>
+							<silent>true</silent>
+							<artifactItems>
+								<artifactItem>
+									<groupId>javax</groupId>
+									<artifactId>javaee-endorsed-api</artifactId>
+									<version>6.0</version>
+									<type>jar</type>
+								</artifactItem>
+							</artifactItems>
+						</configuration>
+					</execution>
+				</executions>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-ejb-plugin</artifactId>
+				<configuration>
+					<ejbVersion>3.1</ejbVersion>
+					<archive>
+						<manifest>
+							<addClasspath>true</addClasspath>
+						</manifest>
+					</archive>
+				</configuration>
+			</plugin>
+		</plugins>
+		<finalName>jee6-blog-tutorial</finalName>
+	</build>
+
+	<repositories>
+		<repository>
+			<id>maven2-repository.dev.java.net</id>
+			<name>Java.net Repository for Maven</name>
+			<url>http://download.java.net/maven/2</url>
+		</repository>
+		<repository>
+			<id>JBoss repository</id>
+			<url>http://repository.jboss.com/maven2/</url>
+		</repository>
+		<repository>
+			<id>EclipseLink Repo</id>
+			<url>http://www.eclipse.org/downloads/download.php?r=1&amp;nf=1&amp;file=/rt/eclipselink/maven.repo</url>
+			<snapshots>
+				<enabled>true</enabled>
+			</snapshots>
+		</repository>
+		<repository>
+			<id>primefaces-repo</id>
+			<name>Prime Technology Maven Repository</name>
+			<url>http://repository.prime.com.tr</url>
+			<layout>default</layout>
+		</repository>
+	</repositories>
+</project>

File src/main/java/com/hascode/tutorial/jee6/blog/controller/BlogEntryBean.java

+package com.hascode.tutorial.jee6.blog.controller;
+
+import java.util.List;
+
+import javax.enterprise.context.RequestScoped;
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import com.hascode.tutorial.jee6.blog.ejb.BlogEntryEJB;
+import com.hascode.tutorial.jee6.blog.entity.BlogEntry;
+
+@Named(value = "blogEntryBean")
+@RequestScoped
+public class BlogEntryBean {
+	@Inject
+	private BlogEntryEJB	blogEntryEJB;
+
+	private BlogEntry		blogEntry	= new BlogEntry();
+
+	/**
+	 * @return the blogEntries
+	 */
+	public List<BlogEntry> getBlogEntries() {
+		return blogEntryEJB.findBlogEntries();
+	}
+
+	/**
+	 * @return the blogEntry
+	 */
+	public BlogEntry getBlogEntry() {
+		return blogEntry;
+	}
+
+	/**
+	 * @param blogEntry
+	 *            the blogEntry to set
+	 */
+	public void setBlogEntry(BlogEntry blogEntry) {
+		this.blogEntry = blogEntry;
+	}
+
+	public String saveBlogEntry() {
+		blogEntryEJB.saveBlogEntry(blogEntry);
+		return "success";
+	}
+
+	public void delete(BlogEntry blogEntry) {
+		blogEntryEJB.deleteBlogEntry(blogEntry);
+	}
+}

File src/main/java/com/hascode/tutorial/jee6/blog/ejb/BlogEntryEJB.java

+package com.hascode.tutorial.jee6.blog.ejb;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.ejb.Stateless;
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.Query;
+
+import com.hascode.tutorial.jee6.blog.entity.BlogEntry;
+
+@Stateless
+public class BlogEntryEJB {
+	@PersistenceContext(unitName = "defaultPersistenceUnit")
+	private EntityManager	em;
+
+	public BlogEntry saveBlogEntry(BlogEntry blogEntry) {
+		em.persist(blogEntry);
+		return blogEntry;
+	}
+
+	public List<BlogEntry> findBlogEntries() {
+		final Query query = em.createQuery("SELECT b FROM BlogEntry b ORDER BY b.created DESC");
+		List<BlogEntry> entries = query.getResultList();
+		if (entries == null) {
+			entries = new ArrayList<BlogEntry>();
+		}
+		return entries;
+	}
+
+	public void deleteBlogEntry(BlogEntry blogEntry) {
+		blogEntry = em.merge(blogEntry);
+		em.remove(blogEntry);
+	}
+}

File src/main/java/com/hascode/tutorial/jee6/blog/entity/BlogEntry.java

+package com.hascode.tutorial.jee6.blog.entity;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Lob;
+import javax.persistence.PrePersist;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Past;
+import javax.validation.constraints.Size;
+
+@Entity
+public class BlogEntry implements Serializable {
+	private static final long	serialVersionUID	= 1L;
+
+	@Id
+	@GeneratedValue
+	private Long				id;
+
+	@NotNull
+	@Size(min = 10, max = 100)
+	private String				title;
+
+	@Lob
+	@NotNull
+	@Size(min = 300, max = 4000)
+	private String				content;
+
+	@NotNull
+	@Size(min = 10, max = 40)
+	private String				author;
+
+	@Past
+	@Temporal(TemporalType.TIMESTAMP)
+	private Date				created;
+
+	@PrePersist
+	private void onCreate() {
+		created = new Date();
+	}
+
+	/**
+	 * @param id
+	 *            the id to set
+	 */
+	public void setId(Long id) {
+		this.id = id;
+	}
+
+	/**
+	 * @return the title
+	 */
+	public String getTitle() {
+		return title;
+	}
+
+	/**
+	 * @param title
+	 *            the title to set
+	 */
+	public void setTitle(String title) {
+		this.title = title;
+	}
+
+	/**
+	 * @return the content
+	 */
+	public String getContent() {
+		return content;
+	}
+
+	/**
+	 * @param content
+	 *            the content to set
+	 */
+	public void setContent(String content) {
+		this.content = content;
+	}
+
+	/**
+	 * @return the author
+	 */
+	public String getAuthor() {
+		return author;
+	}
+
+	/**
+	 * @param author
+	 *            the author to set
+	 */
+	public void setAuthor(String author) {
+		this.author = author;
+	}
+
+	/**
+	 * @return the created
+	 */
+	public Date getCreated() {
+		return created;
+	}
+
+	/**
+	 * @param created
+	 *            the created to set
+	 */
+	public void setCreated(Date created) {
+		this.created = created;
+	}
+
+	/**
+	 * @return the id
+	 */
+	public Long getId() {
+		return id;
+	}
+}

File src/main/resources/META-INF/persistence.xml

+<?xml version="1.0" encoding="UTF-8"?>
+<persistence version="1.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_1_0.xsd">
+	<persistence-unit name="defaultPersistenceUnit"
+		transaction-type="JTA">
+		<provider>oracle.toplink.essentials.PersistenceProvider</provider>
+		<jta-data-source>jdbc/__default</jta-data-source>
+		<class>com.hascode.tutorial.jee6.blog.entity.BlogEntry</class>
+		<properties>
+			<property name="eclipselink.ddl-generation" value="create-tables" />
+		</properties>
+	</persistence-unit>
+</persistence>
+

File src/main/resources/com/hascode/tutorial/jee6/blog/messages.properties

+listTitle=hasCode.com - Java EE 6 Blog Tutorial - Blog entries overview
+listHeading=Blog entries overview
+newArticle=Create new blog entry
+amountEntries=Blog entries available
+author=Author
+options=Options
+delete=Delete
+created=Created
+
+createTitle=hasCode.com - Java EE 6 Blog Tutorial - Create a new blog entry
+createHeading=Create a new blog entry
+title=Title
+content=Content
+save=Save article

File src/main/webapp/WEB-INF/beans.xml

Empty file added.

File src/main/webapp/WEB-INF/faces-config.xml

+<?xml version="1.0" encoding="UTF-8"?>
+<faces-config version="2.0" xmlns="http://java.sun.com/xml/ns/javaee"
+	xmlns:xi="http://www.w3.org/2001/XInclude" 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">
+	<application>
+		<resource-bundle>
+			<base-name>com.hascode.tutorial.jee6.blog.messages</base-name>
+			<var>i18n</var>
+		</resource-bundle>
+	</application>
+	
+	<navigation-rule>
+		<from-view-id>/list.xhtml</from-view-id>
+		<navigation-case>
+			<from-outcome>create</from-outcome>
+			<to-view-id>/create.xhtml</to-view-id>
+		</navigation-case>
+	</navigation-rule>
+	<navigation-rule>
+		<from-view-id>/create.xhtml</from-view-id>
+		<navigation-case>
+			<from-outcome>success</from-outcome>
+			<to-view-id>/list.xhtml</to-view-id>
+			<redirect/>
+		</navigation-case>
+	</navigation-rule>
+</faces-config>

File src/main/webapp/WEB-INF/web.xml

+<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	version="3.0"
+	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
+		<display-name>jee6-blog-tutorial</display-name>
+		<servlet>
+			<servlet-name>Faces Servlet</servlet-name>
+			<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
+		</servlet>
+		<servlet-mapping>
+			<servlet-name>Faces Servlet</servlet-name>
+			<url-pattern>*.xhtml</url-pattern>
+		</servlet-mapping>
+		<welcome-file-list>
+			<welcome-file>/list.xhtml</welcome-file>
+		</welcome-file-list>
+	</web-app>

File src/main/webapp/_decorator.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:h="http://java.sun.com/jsf/html"
+	xmlns:f="http://java.sun.com/jsf/core"
+	xmlns:ui="http://java.sun.com/jsf/facelets"
+	xmlns:p="http://primefaces.prime.com.tr/ui">
+<h:head>
+	<title><ui:insert name="title">hasCode.com - Java EE 6 Blog Tutorial</ui:insert></title>
+	<link rel="stylesheet" type="text/css" href="css/style.css" />
+</h:head>
+<h:body>
+	<p:panel>
+		<h:panelGrid columns="2" cellpadding="10">
+			<img src="image/logo.png" width="100" height="100" alt="hasCode.com logo"/>
+			<h:panelGroup>
+				<h1><ui:insert name="heading">Java EE 6 Tutorial - Blog Application</ui:insert></h1>
+			</h:panelGroup>
+		</h:panelGrid>
+		<ui:insert name="body">Welcome to the tutorial .. you should never see this content ;)</ui:insert>
+	</p:panel>
+</h:body>
+</html>

File src/main/webapp/create.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:h="http://java.sun.com/jsf/html"
+	xmlns:f="http://java.sun.com/jsf/core"
+	xmlns:ui="http://java.sun.com/jsf/facelets"
+	xmlns:p="http://primefaces.prime.com.tr/ui">
+<ui:composition template="/_decorator.xhtml">
+	<ui:define name="title">#{i18n.createTitle}</ui:define>
+	<ui:define name="heading">#{i18n.createHeading}</ui:define>
+	<ui:define name="body">
+		<h:form>
+			<p:panel id="createPnl" header="#{i18n.newArticle}"
+				toggleable="true" closable="false" toggleSpeed="500"
+				onCloseUpdate="growl" closeSpeed="2000" onToggleUpdate="growl"
+				widgetVar="panel">
+				<h:panelGrid columns="3" cellpadding="10">
+					<label>#{i18n.title}</label>
+					<h:inputText label="Title" id="lblTitle"
+						value="#{blogEntryBean.blogEntry.title}" required="true" />
+					<h:message for="lblTitle" class="errorMsg"/>
+					<label>#{i18n.author}</label>
+					<h:inputText label="Author" id="lblAuthor"
+						value="#{blogEntryBean.blogEntry.author}" required="true" />
+					<h:message for="lblAuthor" class="errorMsg"/>
+					<label>#{i18n.content}</label>
+					<h:inputTextarea label="Content" id="lblContent"
+						value="#{blogEntryBean.blogEntry.content}" required="true" />
+					<h:message for="lblContent" class="errorMsg"/>
+					<h:commandButton title="#{i18n.save}" value="#{i18n.save}"
+						action="#{blogEntryBean.saveBlogEntry()}" />
+				</h:panelGrid>
+			</p:panel>
+		</h:form>
+	</ui:define>
+</ui:composition>
+</html>

File src/main/webapp/css/style.css

+h1 {
+	font-size: 34px;
+}
+.errorMsg {
+	background-color:#D97C7C;
+	color:#A30000;	
+	display:block;
+	padding:5px;
+}

File src/main/webapp/image/logo.png

Added
New image

File src/main/webapp/list.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:h="http://java.sun.com/jsf/html"
+	xmlns:f="http://java.sun.com/jsf/core"
+	xmlns:ui="http://java.sun.com/jsf/facelets"
+	xmlns:p="http://primefaces.prime.com.tr/ui">
+<ui:composition template="/_decorator.xhtml">
+	<ui:define name="title">
+		<h:outputText value="#{i18n.listTitle}" />
+	</ui:define>
+	<ui:define name="heading">
+		<h:outputText value="#{i18n.listHeading}" />
+	</ui:define>
+	<ui:define name="body">
+		<h:form>
+			<h:commandButton title="#{i18n.newArticle}"
+				value="#{i18n.newArticle}" action="create" />
+			<br />
+			<hr />
+			<br />
+			<p:panel
+				header="#{blogEntryBean.getBlogEntries().size()} #{i18n.amountEntries}" 
+				toggleable="true" closable="true" toggleSpeed="500">
+				<ui:repeat value="#{blogEntryBean.getBlogEntries()}" var="entry">
+					<h:panelGrid columns="2" cellpadding="10">
+						<f:facet name="header">
+							<h:outputText value="#{entry.title}" />
+						</f:facet>
+						<h:outputText value="#{i18n.author}: #{entry.author}" />
+						<h:panelGroup>
+							<h:outputText value="#{entry.content}" />
+							<p:contextMenu>
+								<p:menuitem value="#{i18n.delete}"
+									actionListener="#{blogEntryBean.delete(entry)}" update="@form" />
+							</p:contextMenu>
+						</h:panelGroup>
+						<f:facet name="footer">
+							<h:outputText value="#{i18n.created}: #{entry.created}" />
+						</f:facet>
+					</h:panelGrid>
+					<hr />
+				</ui:repeat>
+			</p:panel>
+		</h:form>
+	</ui:define>
+</ui:composition>
+</html>