query = em.createNamedQuery(Queries.CONTENT_FIND_BY_NAME,
+ Content.class);
+ query.setParameter(1, name);
+ found = query.getSingleResult();
+ } catch (NoResultException e) {
+ logger.info("No content found: {}", name);
+ }
+ return found;
+ }
+
+ @Override
+ public Content saveContent(Content content) {
+ Content saved = content;
+ if (content.getVersion() == null) {
+ em.persist(content);
+ } else {
+ saved = em.merge(content);
+ }
+ return saved;
+ }
+
+}
diff --git a/primefaces-webapp/src/main/java/com/mycompany/service/impl/CountryServiceImpl.java b/primefaces-webapp/src/main/java/com/mycompany/service/impl/CountryServiceImpl.java
new file mode 100644
index 0000000..3761d44
--- /dev/null
+++ b/primefaces-webapp/src/main/java/com/mycompany/service/impl/CountryServiceImpl.java
@@ -0,0 +1,226 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2013 Ian Hlavats.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+package com.mycompany.service.impl;
+
+import java.io.InputStream;
+import java.util.List;
+import java.util.Scanner;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.ejb.Stateless;
+import javax.enterprise.event.Observes;
+import javax.inject.Named;
+import javax.persistence.NoResultException;
+import javax.persistence.TypedQuery;
+import javax.servlet.ServletContext;
+import javax.transaction.UserTransaction;
+
+import com.mycompany.lifecycle.Initialized;
+import com.mycompany.lifecycle.ServletContextLifecycleNotifier;
+import com.mycompany.model.City;
+import com.mycompany.model.Country;
+import com.mycompany.model.ProvinceState;
+import com.mycompany.service.CountryService;
+import com.mycompany.util.Queries;
+
+/**
+ *
+ * Controller class for countries. Since this class holds application-wide
+ * state, namely a list of {@link Country} objects, we annotate it as an
+ * application-scoped CDI bean.
+ *
+ * @author Ian Hlavats (ian@tarantulaconsulting.com)
+ *
+ */
+@Named("countryService")
+@Stateless
+public class CountryServiceImpl extends AbstractService implements CountryService {
+
+ public ProvinceState createProvinceState(Country country, String name) {
+ ProvinceState state = null;
+ try {
+ // tx.begin();
+ state = new ProvinceState();
+ state.setName(name);
+ state.setCountry(country);
+ country.getProvinceStates().add(state);
+ em.persist(state);
+ // tx.commit();
+ } catch (Exception e) {
+ logger.error("Unable to create province/state object:", e);
+ }
+ return state;
+ }
+
+ public List findCitiesByState(ProvinceState state) {
+ String jql = "select c from City c where c.provinceState = ?1 order by c.name";
+ TypedQuery query = em.createQuery(jql, City.class);
+ query.setParameter(1, state);
+ return query.getResultList();
+ }
+
+ public City findCity(String name, ProvinceState provinceState) {
+ City city = null;
+ try {
+ TypedQuery query = em.createNamedQuery(
+ Queries.CITY_FIND_BY_NAME_AND_PROVINCE_STATE, City.class);
+ query.setParameter(1, name);
+ query.setParameter(2, provinceState);
+ city = query.getSingleResult();
+ } catch (NoResultException e) {
+ }
+ return city;
+ }
+
+ public City findCityById(Integer id) {
+ return em.find(City.class, id);
+ }
+
+ private Country findCountryByCode(String countryCode) {
+ return (Country) em.createNamedQuery(Queries.COUNTRY_FIND_BY_CODE)
+ .setParameter(1, countryCode)
+ .getSingleResult();
+ }
+
+ public Country findCountryById(Integer id) {
+ return em.find(Country.class, id);
+ }
+
+ @Override
+ public List findProvinceStatesByCountry(Country country) {
+ String jql = "select p from ProvinceState p where p.country = ?1 order by p.name";
+ TypedQuery query = em.createQuery(jql, ProvinceState.class);
+ query.setParameter(1, country);
+ return query.getResultList();
+ }
+
+ public ProvinceState findStateById(Integer id) {
+ return em.find(ProvinceState.class, id);
+ }
+
+ public ProvinceState findStateByName(Country country, String stateName) {
+ if (country == null) {
+ return null;
+ }
+ for (ProvinceState state : country.getProvinceStates()) {
+ if (state.getName().equals(stateName)) {
+ return state;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public List getCountries() {
+ return em.createNamedQuery(Queries.COUNTRY_FIND_ALL).getResultList();
+ }
+
+ @Override
+ public List getProvinceStates() {
+ String jql = "select p from ProvinceState p where p.country.code = 'US' order by p.name";
+ TypedQuery query = em.createQuery(jql, ProvinceState.class);
+ return query.getResultList();
+ }
+
+ private void importCities() {
+ InputStream in = getClass().getResourceAsStream("/cities.txt");
+ Scanner scanner = new Scanner(in);
+ Pattern pattern = Pattern.compile("([^:]+):([^:]+):([^:]+):(.*)");
+ Matcher matcher = null;
+ while (scanner.hasNextLine()) {
+ String line = scanner.nextLine();
+ matcher = pattern.matcher(line);
+ if (matcher.find()) {
+ String countryCode = matcher.group(1);
+ String stateName = matcher.group(2);
+ String cityName = matcher.group(3);
+ String coords = matcher.group(4);
+ String[] array = coords.split(",");
+ Double latitude = Double.parseDouble(array[0]);
+ Double longitude = Double.parseDouble(array[1]);
+ Country country = findCountryByCode(countryCode);
+ ProvinceState state = findStateByName(country, stateName);
+ if (state == null) {
+ state = new ProvinceState();
+ state.setName(stateName);
+ state.setCountry(country);
+ country.getProvinceStates().add(state);
+ em.persist(state);
+ }
+ City city = new City();
+ city.setName(cityName);
+ city.setProvinceState(state);
+ city.setLatitude(latitude);
+ city.setLongitude(longitude);
+ state.getCities().add(city);
+ em.persist(city);
+ }
+ }
+ }
+
+ private void importCountries() {
+ InputStream in = getClass().getResourceAsStream("/countries.txt");
+ Scanner scanner = new Scanner(in);
+ Pattern pattern = Pattern.compile("([A-Z]+):(.*)");
+ Matcher matcher = null;
+ while (scanner.hasNextLine()) {
+ String line = scanner.nextLine();
+ matcher = pattern.matcher(line);
+ if (matcher.find()) {
+ String isoCode = matcher.group(1);
+ String countryName = matcher.group(2);
+ Country country = new Country();
+ country.setCode(isoCode);
+ country.setName(countryName);
+ em.persist(country);
+ }
+ }
+ }
+
+ /**
+ * This method is responsible for initializing a List of Country objects
+ * when the web application is started. We use the CDI event handling system
+ * combined with the custom {@link Initialized} event to ensure this method
+ * is called at startup time. Note: since this class is not an EJB, to
+ * insert data we have to use bean-managed transactions with the
+ * {@link UserTransaction}.
+ *
+ * @param context
+ * @throws Exception
+ * @see ServletContextLifecycleNotifier
+ */
+ @Override
+ public void init(@Observes @Initialized ServletContext context) throws Exception {
+ List countries = getCountries();
+ if (countries == null || countries.isEmpty()) {
+ logger.info("Importing country and city data...");
+ importCountries();
+ importCities();
+ }
+ }
+
+}
diff --git a/primefaces-webapp/src/main/java/com/mycompany/service/impl/EventServiceImpl.java b/primefaces-webapp/src/main/java/com/mycompany/service/impl/EventServiceImpl.java
new file mode 100644
index 0000000..cd8e753
--- /dev/null
+++ b/primefaces-webapp/src/main/java/com/mycompany/service/impl/EventServiceImpl.java
@@ -0,0 +1,153 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2013 Ian Hlavats.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+package com.mycompany.service.impl;
+
+import java.util.Date;
+import java.util.List;
+
+import javax.ejb.Stateless;
+import javax.inject.Named;
+import javax.persistence.TypedQuery;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Join;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import com.mycompany.model.City;
+import com.mycompany.model.City_;
+import com.mycompany.model.Event;
+import com.mycompany.model.EventAttendance;
+import com.mycompany.model.EventType;
+import com.mycompany.model.Event_;
+import com.mycompany.model.ProvinceState;
+import com.mycompany.model.User;
+import com.mycompany.model.Venue;
+import com.mycompany.model.Venue_;
+import com.mycompany.service.EventService;
+import com.mycompany.util.Queries;
+
+@Named("eventService")
+@Stateless
+public class EventServiceImpl extends AbstractService implements EventService {
+
+ @Override
+ public List findAllEvents() {
+ return em.createNamedQuery(Queries.EVENT_FIND_ALL, Event.class).getResultList();
+ }
+
+ @Override
+ public List findAllEventsAttendanceByUser(User user) {
+ TypedQuery query = em.createNamedQuery(
+ Queries.EVENT_ATTENDANCE_FIND_BY_USER, EventAttendance.class);
+ query.setParameter(1, user);
+ return query.getResultList();
+ }
+
+ @Override
+ public EventAttendance findEventAttendance(Event event, User user) {
+ TypedQuery query = em.createNamedQuery(
+ Queries.EVENT_ATTENDANCE_FIND_BY_USER_AND_EVENT, EventAttendance.class);
+ query.setParameter(1, user);
+ query.setParameter(2, event);
+ List resultList = query.getResultList();
+ if (!resultList.isEmpty()) {
+ return resultList.get(0);
+ }
+ return null;
+ }
+
+ @Override
+ public Event findEventById(Integer id) {
+ return em.find(Event.class, id);
+ }
+
+ @Override
+ public List findUserEvents(Date start, Date end, User user) {
+ String jql = "select evt from Event evt where evt.createdBy = ?1 and evt.startDate between ?2 and ?3";
+ TypedQuery query = em.createQuery(jql, Event.class);
+ query.setParameter(1, user);
+ query.setParameter(2, start);
+ query.setParameter(3, end);
+ List events = query.getResultList();
+ return events;
+ }
+
+ @Override
+ public EventAttendance saveAttendance(EventAttendance attendance) {
+ EventAttendance saved = attendance;
+ if (attendance.getVersion() == null) {
+ em.persist(attendance);
+ } else {
+ saved = em.merge(attendance);
+ }
+ return saved;
+ }
+
+ @Override
+ public Event saveEvent(Event event) {
+ Event saved = event;
+ if (event.getVersion() == null) {
+ em.persist(event);
+ } else {
+ saved = em.merge(event);
+ }
+ return saved;
+ }
+
+ @Override
+ public List findEvents(City city, ProvinceState provinceState, EventType eventType,
+ String keyword) {
+ CriteriaBuilder cb = em.getCriteriaBuilder();
+ CriteriaQuery criteria = cb.createQuery(Event.class);
+ Root event = criteria.from(Event.class);
+ criteria.select(event);
+ Predicate andClause = cb.conjunction();
+ if (city != null) {
+ Join joinedVenue = event.join(Event_.venue);
+ Join joinedCity = joinedVenue.join(Venue_.city);
+ Predicate cityClause = cb.equal(joinedCity.get(City_.name), city.getName());
+ andClause = cb.and(andClause, cityClause);
+ }
+ if (provinceState != null) {
+ Join joinedVenue = event.join(Event_.venue);
+ Predicate provinceStateClause = cb.equal(joinedVenue.get(Venue_.provinceState),
+ provinceState);
+ andClause = cb.and(andClause, provinceStateClause);
+ }
+ if (eventType != null) {
+ Predicate eventTypeClause = cb.equal(event.get(Event_.eventType), eventType);
+ andClause = cb.and(andClause, eventTypeClause);
+ }
+ if (keyword != null) {
+ Predicate keywordClause = cb.like(event.get(Event_.title), "%" + keyword + "%");
+ andClause = cb.and(andClause, keywordClause);
+ }
+ criteria.where(andClause);
+ TypedQuery query = em.createQuery(criteria);
+ return query.getResultList();
+ }
+
+}
diff --git a/primefaces-webapp/src/main/java/com/mycompany/service/impl/IdeaServiceImpl.java b/primefaces-webapp/src/main/java/com/mycompany/service/impl/IdeaServiceImpl.java
new file mode 100644
index 0000000..63bffcf
--- /dev/null
+++ b/primefaces-webapp/src/main/java/com/mycompany/service/impl/IdeaServiceImpl.java
@@ -0,0 +1,91 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2013 Ian Hlavats.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+package com.mycompany.service.impl;
+
+import java.util.List;
+
+import javax.ejb.Stateless;
+import javax.inject.Named;
+import javax.persistence.TypedQuery;
+
+import org.primefaces.model.mindmap.DefaultMindmapNode;
+import org.primefaces.model.mindmap.MindmapNode;
+
+import com.mycompany.model.Idea;
+import com.mycompany.service.IdeaService;
+
+@Named("ideaService")
+@Stateless
+public class IdeaServiceImpl extends AbstractService implements IdeaService {
+
+ /**
+ * This method uses recursion to build the mind map data structure.
+ *
+ * @param parentIdea
+ * The parent {@link Idea}.
+ * @param parentNode
+ * The parent {@link MindmapNode}.
+ */
+ public void buildMindMap(Idea parentIdea, MindmapNode parentNode) {
+ Idea idea = parentIdea;
+ if (!em.contains(idea)) {
+ idea = em.find(Idea.class, idea.getId());
+ }
+ if (idea.getChildren().isEmpty()) {
+ return;
+ }
+ for (Idea childIdea : idea.getChildren()) {
+ String label = childIdea.getName();
+ MindmapNode childNode = new DefaultMindmapNode(label, childIdea, "6e9ebf", true);
+ parentNode.addNode(childNode);
+ buildMindMap(childIdea, childNode);
+ }
+ }
+
+ @Override
+ public Idea findIdea(Integer id) {
+ return em.find(Idea.class, id);
+ }
+
+ @Override
+ public List findIdeas() {
+ String jql = "select idea from Idea idea where idea.parent is null";
+ TypedQuery query = em.createQuery(jql, Idea.class);
+ List ideas = query.getResultList();
+ return ideas;
+ }
+
+ @Override
+ public Idea saveIdea(Idea idea) {
+ Idea saved = idea;
+ if (idea.getVersion() == null) {
+ em.persist(idea);
+ } else {
+ saved = em.merge(idea);
+ }
+ return saved;
+ }
+
+}
diff --git a/primefaces-webapp/src/main/java/com/mycompany/service/impl/UserServiceImpl.java b/primefaces-webapp/src/main/java/com/mycompany/service/impl/UserServiceImpl.java
new file mode 100644
index 0000000..c25a38f
--- /dev/null
+++ b/primefaces-webapp/src/main/java/com/mycompany/service/impl/UserServiceImpl.java
@@ -0,0 +1,133 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2013 Ian Hlavats.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+package com.mycompany.service.impl;
+
+import java.util.List;
+
+import javax.ejb.Stateless;
+import javax.inject.Named;
+import javax.persistence.NoResultException;
+import javax.persistence.TypedQuery;
+
+import com.mycompany.model.RelationshipType;
+import com.mycompany.model.User;
+import com.mycompany.model.UserRelationship;
+import com.mycompany.service.UserService;
+import com.mycompany.util.Queries;
+
+/**
+ * @uml.dependency supplier="javax.persistence.EntityManager"
+ */
+@Named("userService")
+@Stateless
+public class UserServiceImpl extends AbstractService implements UserService {
+
+ public UserRelationship findRelationshipToUser(User user1, User user2) {
+ UserRelationship found = null;
+ try {
+ String jql = "select r from UserRelationship r where r.fromUser = ?1 and r.toUser = ?2";
+ TypedQuery query = em.createQuery(jql, UserRelationship.class);
+ query.setParameter(1, user1);
+ query.setParameter(2, user2);
+ found = query.getSingleResult();
+ } catch (NoResultException e) {
+ }
+ return found;
+ }
+
+ @Override
+ public User findUser(String username, String password) {
+ TypedQuery query = em.createNamedQuery(Queries.USER_FIND_BY_USERNAME_PASSWORD, User.class);
+ query.setParameter(1, username);
+ query.setParameter(2, password);
+ List users = query.getResultList();
+ if (!users.isEmpty()) {
+ return users.get(0);
+ }
+ return null;
+ }
+
+ @Override
+ public User findUserById(Integer id) {
+ return em.find(User.class, id);
+ }
+
+ @Override
+ public User findUserByUsername(String username) {
+ String jql = "select u from User u where u.username = ?1";
+ TypedQuery query = em.createQuery(jql, User.class);
+ query.setParameter(1, username);
+ List users = query.getResultList();
+ if (!users.isEmpty()) {
+ return users.get(0);
+ }
+ return null;
+ }
+
+ @Override
+ public List findUsers() {
+ String jql = "select u from User u order by u.username";
+ List users = em.createQuery(jql, User.class).getResultList();
+ return users;
+ }
+
+ @Override
+ public List findUsersByName(String suggest) {
+ TypedQuery query = em.createNamedQuery(Queries.USER_FIND_BY_PARTIAL_NAME, User.class);
+ query.setParameter("name", "%" + suggest.trim() + "%");
+ List users = query.getResultList();
+ return users;
+ }
+
+ @Override
+ public List findUsersByType(RelationshipType type, User user) {
+ TypedQuery query = em.createNamedQuery(Queries.USER_FIND_BY_RELATIONSHIP_TYPE, User.class);
+ query.setParameter(1, type);
+ query.setParameter(2, user);
+ return query.getResultList();
+ }
+
+ @Override
+ public UserRelationship saveRelationship(UserRelationship relationship) {
+ UserRelationship saved = relationship;
+ if (relationship.getVersion() == null) {
+ em.persist(relationship);
+ } else {
+ saved = em.merge(relationship);
+ }
+ return saved;
+ }
+
+ @Override
+ public User saveUser(User user) {
+ User saved = user;
+ if (user.getVersion() == null) {
+ em.persist(user);
+ } else {
+ saved = em.merge(user);
+ }
+ return saved;
+ }
+}
diff --git a/primefaces-webapp/src/main/java/com/mycompany/service/impl/VenueServiceImpl.java b/primefaces-webapp/src/main/java/com/mycompany/service/impl/VenueServiceImpl.java
new file mode 100644
index 0000000..8796261
--- /dev/null
+++ b/primefaces-webapp/src/main/java/com/mycompany/service/impl/VenueServiceImpl.java
@@ -0,0 +1,72 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2013 Ian Hlavats.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+package com.mycompany.service.impl;
+
+import java.util.List;
+
+import javax.ejb.Stateless;
+import javax.inject.Named;
+import javax.persistence.TypedQuery;
+
+import com.mycompany.model.Venue;
+import com.mycompany.service.VenueService;
+
+@Named("venueService")
+@Stateless
+public class VenueServiceImpl extends AbstractService implements VenueService {
+
+ @Override
+ public void deleteVenue(Venue venue) {
+ Venue found = em.find(Venue.class, venue.getId());
+ if (found != null) {
+ em.remove(found);
+ }
+ }
+
+ @Override
+ public Venue findVenueById(Integer id) {
+ return em.find(Venue.class, id);
+ }
+
+ @Override
+ public List findVenues() {
+ String jql = "select v from Venue v order by v.name";
+ TypedQuery query = em.createQuery(jql, Venue.class);
+ List venues = query.getResultList();
+ return venues;
+ }
+
+ @Override
+ public Venue saveVenue(Venue venue) {
+ Venue saved = venue;
+ if (venue.getVersion() == null) {
+ em.persist(venue);
+ } else {
+ saved = em.merge(venue);
+ }
+ return saved;
+ }
+
+}
diff --git a/primefaces-webapp/src/main/java/com/mycompany/util/FacesUtils.java b/primefaces-webapp/src/main/java/com/mycompany/util/FacesUtils.java
new file mode 100644
index 0000000..a253bd2
--- /dev/null
+++ b/primefaces-webapp/src/main/java/com/mycompany/util/FacesUtils.java
@@ -0,0 +1,60 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2013 Ian Hlavats.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+package com.mycompany.util;
+
+import javax.faces.application.FacesMessage;
+import javax.faces.context.FacesContext;
+
+/**
+ * Utility class for common JSF API uses.
+ *
+ * @author Ian Hlavats (ian@tarantulaconsulting.com)
+ *
+ */
+public class FacesUtils {
+
+ /**
+ * Utility method to lookup a managed bean.
+ *
+ * @param name
+ * The managed bean name.
+ * @return A managed bean object.
+ */
+ public static Object getManagedBean(String name) {
+ FacesContext ctx = FacesContext.getCurrentInstance();
+ return ctx.getApplication().evaluateExpressionGet(ctx, "#{" + name + "}", Object.class);
+ }
+
+ /**
+ * Adds a {@link FacesMessage} to the {@link FacesContext}.
+ *
+ * @param message
+ * The FacesMessage
+ */
+ public static void addMessage(FacesMessage message) {
+ FacesContext.getCurrentInstance().addMessage(null, message);
+ }
+
+}
diff --git a/primefaces-webapp/src/main/java/com/mycompany/util/Queries.java b/primefaces-webapp/src/main/java/com/mycompany/util/Queries.java
new file mode 100644
index 0000000..52aa5c1
--- /dev/null
+++ b/primefaces-webapp/src/main/java/com/mycompany/util/Queries.java
@@ -0,0 +1,101 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2013 Ian Hlavats.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+package com.mycompany.util;
+
+import com.mycompany.model.Content;
+import com.mycompany.model.Country;
+import com.mycompany.model.Event;
+import com.mycompany.model.EventAttendance;
+import com.mycompany.model.Gender;
+import com.mycompany.model.ProvinceState;
+import com.mycompany.model.RelationshipType;
+import com.mycompany.model.User;
+
+/**
+ * Constant interface for named JPA queries.
+ *
+ * @author Ian Hlavats (ian@tarantulaconsulting.com)
+ *
+ */
+public interface Queries {
+
+ /**
+ * Finds a {@link City} by name and {@link ProvinceState}.
+ */
+ public static final String CITY_FIND_BY_NAME_AND_PROVINCE_STATE = "City.findByNameAndProvinceState";
+
+ /**
+ * Finds a {@link Content} by name.
+ */
+ public static final String CONTENT_FIND_BY_NAME = "Content.findByName";
+
+ /**
+ * Finds all {@link Country} objects.
+ */
+ public static final String COUNTRY_FIND_ALL = "Country.findAll";
+
+ /**
+ * Finds a {@link Country} by code.
+ */
+ public static final String COUNTRY_FIND_BY_CODE = "Country.findByCode";
+
+ /**
+ * Finds all {@link EventAttendance} for a particular {@link User}.
+ */
+ public static final String EVENT_ATTENDANCE_FIND_BY_USER = "EventAttendance.findByUser";
+
+ /**
+ * Finds a List of {@link EventAttendance} for a particular {@link User} and
+ * {@link Event}.
+ */
+ public static final String EVENT_ATTENDANCE_FIND_BY_USER_AND_EVENT = "EventAttendance.findByUserAndEvent";
+
+ /**
+ * Find a count of all {@link EventAttendance} objects by {@link Gender}.
+ */
+ public static final String EVENT_ATTENDANCE_FIND_GENDER_COUNT_BY_EVENT = "EventAttendance.findGenderCountByEvent";
+
+ /**
+ * Find all {@link Event} objects.
+ */
+ public static final String EVENT_FIND_ALL = "Event.findAll";
+
+ /**
+ * Finds a {@link User} by partial name.
+ */
+ public static final String USER_FIND_BY_PARTIAL_NAME = "User.findByPartialName";
+
+ /**
+ * Finds a List of {@link User} objects by {@link RelationshipType} to
+ * another {@link User}.
+ */
+ public static final String USER_FIND_BY_RELATIONSHIP_TYPE = "User.findByRelationshipType";
+
+ /**
+ * Finds a {@link User} by username and password.
+ */
+ public static final String USER_FIND_BY_USERNAME_PASSWORD = "User.findByUsernamePassword";
+
+}
diff --git a/primefaces-webapp/src/main/java/com/mycompany/util/UserSession.java b/primefaces-webapp/src/main/java/com/mycompany/util/UserSession.java
new file mode 100644
index 0000000..2634f7f
--- /dev/null
+++ b/primefaces-webapp/src/main/java/com/mycompany/util/UserSession.java
@@ -0,0 +1,86 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2013 Ian Hlavats.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+package com.mycompany.util;
+
+import java.io.Serializable;
+
+import javax.annotation.PreDestroy;
+import javax.enterprise.context.SessionScoped;
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import com.mycompany.model.ActiveUsers;
+import com.mycompany.model.User;
+
+/**
+ * Session-scoped CDI managed bean to store a {@link User} object.
+ *
+ * @author Ian Hlavats (ian@tarantulaconsulting.com)
+ *
+ */
+@Named("userSession")
+@SessionScoped
+public class UserSession implements Serializable {
+
+ @Inject
+ private ActiveUsers activeUsers;
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 8195784747974150341L;
+
+ private User user;
+
+ /**
+ * Returns the current {@link User}.
+ *
+ * @return A User object.
+ */
+ public User getUser() {
+ return user;
+ }
+
+ /**
+ * Sets the {@link User}.
+ *
+ * @param user
+ * The User object.
+ */
+ public void setUser(User user) {
+ this.user = user;
+ }
+
+ /**
+ * CDI calls this method before the bean is destroyed. Since this class is
+ * session-scoped, it will get called if the user session expires, allowing
+ * us to remove the user from the active user list.
+ */
+ @PreDestroy
+ public void release() {
+ activeUsers.remove(user);
+ }
+
+}
diff --git a/primefaces-webapp/src/main/java/com/mycompany/websocket/DefaultPushRule.java b/primefaces-webapp/src/main/java/com/mycompany/websocket/DefaultPushRule.java
new file mode 100644
index 0000000..449017a
--- /dev/null
+++ b/primefaces-webapp/src/main/java/com/mycompany/websocket/DefaultPushRule.java
@@ -0,0 +1,78 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2013 Ian Hlavats.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+package com.mycompany.websocket;
+
+import static org.atmosphere.cpr.BroadcasterLifeCyclePolicy.EMPTY_DESTROY;
+
+import org.atmosphere.cpr.AtmosphereRequest;
+import org.atmosphere.cpr.AtmosphereResource;
+import org.atmosphere.cpr.Broadcaster;
+import org.atmosphere.cpr.BroadcasterFactory;
+import org.atmosphere.cpr.BroadcasterLifeCyclePolicyListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Utility class for GlassFish WebSocket support with PrimeFaces.
+ */
+public class DefaultPushRule extends org.primefaces.push.DefaultPushRule {
+
+ public boolean apply(AtmosphereResource resource) {
+ AtmosphereRequest req = resource.getRequest();
+ String pathInfo = req.getPathInfo();
+ if (pathInfo == null) {
+ String servletPath = req.getServletPath();
+ String contextPath = req.getContextPath();
+ pathInfo = req.getRequestURI()
+ .replaceFirst(contextPath, "")
+ .replaceFirst(servletPath, "");
+ }
+ if (pathInfo == null || pathInfo == "") {
+ resource.setBroadcaster(BroadcasterFactory.getDefault().lookup("/*"));
+ return true;
+ }
+ final Broadcaster b = BroadcasterFactory.getDefault().lookup(pathInfo, true);
+ b.setBroadcasterLifeCyclePolicy(EMPTY_DESTROY);
+ b.addBroadcasterLifeCyclePolicyListener(new BroadcasterLifeCyclePolicyListener() {
+
+ private final Logger logger = LoggerFactory.getLogger(BroadcasterLifeCyclePolicyListener.class);
+
+ public void onEmpty() {
+ logger.trace("onEmpty {}", b.getID());
+ }
+
+ public void onIdle() {
+ logger.trace("onIdle {}", b.getID());
+ }
+
+ public void onDestroy() {
+ logger.trace("onDestroy {}", b.getID());
+ }
+ });
+ resource.setBroadcaster(b);
+
+ return true;
+ }
+}
diff --git a/primefaces-webapp/src/main/resources/META-INF/auth.conf b/primefaces-webapp/src/main/resources/META-INF/auth.conf
new file mode 100644
index 0000000..24d75d0
--- /dev/null
+++ b/primefaces-webapp/src/main/resources/META-INF/auth.conf
@@ -0,0 +1,4 @@
+AppLogin
+{
+ com.mycompany.util.AppLoginModule required
+};
\ No newline at end of file
diff --git a/primefaces-webapp/src/main/resources/META-INF/persistence.xml b/primefaces-webapp/src/main/resources/META-INF/persistence.xml
new file mode 100644
index 0000000..7abeea5
--- /dev/null
+++ b/primefaces-webapp/src/main/resources/META-INF/persistence.xml
@@ -0,0 +1,17 @@
+
+
+
+
+ org.hibernate.ejb.HibernatePersistence
+ java:app/jdbc/mycompanyDataSource
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/primefaces-webapp/src/main/resources/cities.txt b/primefaces-webapp/src/main/resources/cities.txt
new file mode 100644
index 0000000..989cc37
--- /dev/null
+++ b/primefaces-webapp/src/main/resources/cities.txt
@@ -0,0 +1,14 @@
+US:California:San Francisco:37.7810,-122.418
+US:California:Los Angeles:34.112,-118.246
+US:California:San Diego:32.776,-117.158
+US:New York:New York:40.739,-74.009
+US:New York:Buffalo:42.898,-78.878
+US:New York:Rochester:43.173,-77.609
+US:Illinois:Chicago:41.900,-87.627
+US:Texas:Dallas:32.843,-96.770
+CA:Ontario:Toronto:43.677,-79.386
+CA:Quebec:Montreal:45.527,-73.559
+CA:British Columbia:Vancouver:49.2660,-123.115
+CA:Nova Scotia:Halifax:44.6533,-63.577
+
+
diff --git a/primefaces-webapp/src/main/resources/countries.txt b/primefaces-webapp/src/main/resources/countries.txt
new file mode 100644
index 0000000..962d6e8
--- /dev/null
+++ b/primefaces-webapp/src/main/resources/countries.txt
@@ -0,0 +1,244 @@
+AF:Afghanistan
+AX:land Islands
+AL:Albania
+DZ:Algeria
+AS:American Samoa
+AD:Andorra
+AO:Angola
+AI:Anguilla
+AQ:Antarctica
+AG:Antigua and Barbuda
+AR:Argentina
+AM:Armenia
+AW:Aruba
+AU:Australia
+AT:Austria
+AZ:Azerbaijan
+BS:Bahamas
+BH:Bahrain
+BD:Bangladesh
+BB:Barbados
+BY:Belarus
+BE:Belgium
+BZ:Belize
+BJ:Benin
+BM:Bermuda
+BT:Bhutan
+BO:Bolivia
+BA:Bosnia and Herzegovina
+BW:Botswana
+BV:Bouvet Island
+BR:Brazil
+IO:British Indian Ocean Territory
+BN:Brunei Darussalam
+BG:Bulgaria
+BF:Burkina Faso
+BI:Burundi
+KH:Cambodia
+CM:Cameroon
+CA:Canada
+CV:Cape Verde
+KY:Cayman Islands
+CF:Central African Republic
+TD:Chad
+CL:Chile
+CN:China
+CX:Christmas Island
+CC:Cocos (Keeling) Islands
+CO:Colombia
+KM:Comoros
+CG:Congo
+CD:Congo, The Democratic Republic of The
+CK:Cook Islands
+CR:Costa Rica
+CI:Cote D'ivoire
+HR:Croatia
+CU:Cuba
+CY:Cyprus
+CZ:Czech Republic
+DK:Denmark
+DJ:Djibouti
+DM:Dominica
+DO:Dominican Republic
+EC:Ecuador
+EG:Egypt
+SV:El Salvador
+GQ:Equatorial Guinea
+ER:Eritrea
+EE:Estonia
+ET:Ethiopia
+FK:Falkland Islands (Malvinas)
+FO:Faroe Islands
+FJ:Fiji
+FI:Finland
+FR:France
+GF:French Guiana
+PF:French Polynesia
+TF:French Southern Territories
+GA:Gabon
+GM:Gambia
+GE:Georgia
+DE:Germany
+GH:Ghana
+GI:Gibraltar
+GR:Greece
+GL:Greenland
+GD:Grenada
+GP:Guadeloupe
+GU:Guam
+GT:Guatemala
+GG:Guernsey
+GN:Guinea
+GW:Guinea-bissau
+GY:Guyana
+HT:Haiti
+HM:Heard Island and Mcdonald Islands
+VA:Holy See (Vatican City State)
+HN:Honduras
+HK:Hong Kong
+HU:Hungary
+IS:Iceland
+IN:India
+ID:Indonesia
+IR:Iran, Islamic Republic of
+IQ:Iraq
+IE:Ireland
+IM:Isle of Man
+IL:Israel
+IT:Italy
+JM:Jamaica
+JP:Japan
+JE:Jersey
+JO:Jordan
+KZ:Kazakhstan
+KE:Kenya
+KI:Kiribati
+KP:Korea, Democratic People's Republic of
+KR:Korea, Republic of
+KW:Kuwait
+KG:Kyrgyzstan
+LA:Lao People's Democratic Republic
+LV:Latvia
+LB:Lebanon
+LS:Lesotho
+LR:Liberia
+LY:Libyan Arab Jamahiriya
+LI:Liechtenstein
+LT:Lithuania
+LU:Luxembourg
+MO:Macao
+MK:Macedonia, The Former Yugoslav Republic of
+MG:Madagascar
+MW:Malawi
+MY:Malaysia
+MV:Maldives
+ML:Mali
+MT:Malta
+MH:Marshall Islands
+MQ:Martinique
+MR:Mauritania
+MU:Mauritius
+YT:Mayotte
+MX:Mexico
+FM:Micronesia, Federated States of
+MD:Moldova, Republic of
+MC:Monaco
+MN:Mongolia
+ME:Montenegro
+MS:Montserrat
+MA:Morocco
+MZ:Mozambique
+MM:Myanmar
+NA:Namibia
+NR:Nauru
+NP:Nepal
+NL:Netherlands
+AN:Netherlands Antilles
+NC:New Caledonia
+NZ:New Zealand
+NI:Nicaragua
+NE:Niger
+NG:Nigeria
+NU:Niue
+NF:Norfolk Island
+MP:Northern Mariana Islands
+NO:Norway
+OM:Oman
+PK:Pakistan
+PW:Palau
+PS:Palestinian Territory, Occupied
+PA:Panama
+PG:Papua New Guinea
+PY:Paraguay
+PE:Peru
+PH:Philippines
+PN:Pitcairn
+PL:Poland
+PT:Portugal
+PR:Puerto Rico
+QA:Qatar
+RE:Reunion
+RO:Romania
+RU:Russian Federation
+RW:Rwanda
+SH:Saint Helena
+KN:Saint Kitts and Nevis
+LC:Saint Lucia
+PM:Saint Pierre and Miquelon
+VC:Saint Vincent and The Grenadines
+WS:Samoa
+SM:San Marino
+ST:Sao Tome and Principe
+SA:Saudi Arabia
+SN:Senegal
+RS:Serbia
+SC:Seychelles
+SL:Sierra Leone
+SG:Singapore
+SK:Slovakia
+SI:Slovenia
+SB:Solomon Islands
+SO:Somalia
+ZA:South Africa
+GS:South Georgia and The South Sandwich Islands
+ES:Spain
+LK:Sri Lanka
+SD:Sudan
+SR:Suriname
+SJ:Svalbard and Jan Mayen
+SZ:Swaziland
+SE:Sweden
+CH:Switzerland
+SY:Syrian Arab Republic
+TW:Taiwan, Province of China
+TJ:Tajikistan
+TZ:Tanzania, United Republic of
+TH:Thailand
+TL:Timor-leste
+TG:Togo
+TK:Tokelau
+TO:Tonga
+TT:Trinidad and Tobago
+TN:Tunisia
+TR:Turkey
+TM:Turkmenistan
+TC:Turks and Caicos Islands
+TV:Tuvalu
+UG:Uganda
+UA:Ukraine
+AE:United Arab Emirates
+GB:United Kingdom
+US:United States
+UM:United States Minor Outlying Islands
+UY:Uruguay
+UZ:Uzbekistan
+VU:Vanuatu
+VE:Venezuela
+VN:Viet Nam
+VG:Virgin Islands, British
+VI:Virgin Islands, U.S.
+WF:Wallis and Futuna
+EH:Western Sahara
+YE:Yemen
+ZM:Zambia
+ZW:Zimbabwe
\ No newline at end of file
diff --git a/primefaces-webapp/src/main/webapp/WEB-INF/beans.xml b/primefaces-webapp/src/main/webapp/WEB-INF/beans.xml
new file mode 100644
index 0000000..a3257e5
--- /dev/null
+++ b/primefaces-webapp/src/main/webapp/WEB-INF/beans.xml
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/primefaces-webapp/src/main/webapp/WEB-INF/dialogs/addShowDialog.xhtml b/primefaces-webapp/src/main/webapp/WEB-INF/dialogs/addShowDialog.xhtml
new file mode 100644
index 0000000..46c1089
--- /dev/null
+++ b/primefaces-webapp/src/main/webapp/WEB-INF/dialogs/addShowDialog.xhtml
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/primefaces-webapp/src/main/webapp/WEB-INF/dialogs/chatDialog.xhtml b/primefaces-webapp/src/main/webapp/WEB-INF/dialogs/chatDialog.xhtml
new file mode 100644
index 0000000..de8c79d
--- /dev/null
+++ b/primefaces-webapp/src/main/webapp/WEB-INF/dialogs/chatDialog.xhtml
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+
+ Users
+
+ #{user.username}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/primefaces-webapp/src/main/webapp/WEB-INF/dialogs/newContactDialog.xhtml b/primefaces-webapp/src/main/webapp/WEB-INF/dialogs/newContactDialog.xhtml
new file mode 100644
index 0000000..04f58e2
--- /dev/null
+++ b/primefaces-webapp/src/main/webapp/WEB-INF/dialogs/newContactDialog.xhtml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/primefaces-webapp/src/main/webapp/WEB-INF/dialogs/validationDialog.xhtml b/primefaces-webapp/src/main/webapp/WEB-INF/dialogs/validationDialog.xhtml
new file mode 100644
index 0000000..e9ead0f
--- /dev/null
+++ b/primefaces-webapp/src/main/webapp/WEB-INF/dialogs/validationDialog.xhtml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/primefaces-webapp/src/main/webapp/WEB-INF/faces-config.xml b/primefaces-webapp/src/main/webapp/WEB-INF/faces-config.xml
new file mode 100644
index 0000000..2176baf
--- /dev/null
+++ b/primefaces-webapp/src/main/webapp/WEB-INF/faces-config.xml
@@ -0,0 +1,29 @@
+
+
+
+ *
+
+ members
+ /protected/members/index.xhtml
+
+
+
+
+ *
+
+ login
+ /index.xhtml
+
+
+
+
+ com.mycompany.lifecycle.SecurityPhaseListener
+
+
+
+ mycompany.EditableStateConverter
+ com.mycompany.convert.EditableStateConverter
+
+
+
+
diff --git a/primefaces-webapp/src/main/webapp/WEB-INF/glassfish-resources.xml b/primefaces-webapp/src/main/webapp/WEB-INF/glassfish-resources.xml
new file mode 100644
index 0000000..50866a0
--- /dev/null
+++ b/primefaces-webapp/src/main/webapp/WEB-INF/glassfish-resources.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/primefaces-webapp/src/main/webapp/WEB-INF/mycompany.taglib.xml b/primefaces-webapp/src/main/webapp/WEB-INF/mycompany.taglib.xml
new file mode 100644
index 0000000..3321028
--- /dev/null
+++ b/primefaces-webapp/src/main/webapp/WEB-INF/mycompany.taglib.xml
@@ -0,0 +1,15 @@
+
+
+ My Company Custom Facelets Tag Library
+ My Company Tag Library
+ http://www.showtimeguru.com/taglib
+
+ editableStateConverter
+
+ mycompany.EditableStateConverter
+
+
+
\ No newline at end of file
diff --git a/primefaces-webapp/src/main/webapp/WEB-INF/templates/main.xhtml b/primefaces-webapp/src/main/webapp/WEB-INF/templates/main.xhtml
new file mode 100644
index 0000000..de25851
--- /dev/null
+++ b/primefaces-webapp/src/main/webapp/WEB-INF/templates/main.xhtml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/primefaces-webapp/src/main/webapp/WEB-INF/web.xml b/primefaces-webapp/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..2f99b9a
--- /dev/null
+++ b/primefaces-webapp/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,210 @@
+
+
+ primefaces-webapp
+
+ javax.faces.DEFAULT_SUFFIX
+ .xhtml
+
+
+ javax.faces.FACELETS_LIBRARIES
+ /WEB-INF/mycompany.taglib.xml
+
+
+ javax.faces.STATE_SAVING_METHOD
+ server
+
+
+ javax.faces.PROJECT_STAGE
+ Production
+
+
+ javax.faces.FACELETS_REFRESH_PERIOD
+ 1
+
+
+ javax.faces.FACELETS_SKIP_COMMENTS
+ false
+
+
+ javax.faces.validator.DISABLE_DEFAULT_BEAN_VALIDATOR
+ false
+
+
+ javax.faces.FACELETS_VIEW_MAPPINGS
+ *.jsf;*.xhtml;/faces/*
+
+
+ com.sun.faces.enableMissingResourceLibraryDetection
+ false
+
+
+ com.sun.faces.clientStateTimeout
+ 1200000
+
+
+ com.sun.faces.responseBufferSize
+ 500000
+
+
+ com.sun.faces.numberOfViewsInSession
+ 5
+
+
+ com.sun.faces.numberOfLogicalViews
+ 5
+
+
+ com.sun.faces.validateXml
+ false
+
+
+ com.sun.faces.verifyObjects
+ false
+
+
+ facelets.DEVELOPMENT
+ false
+
+
+ facelets.RECREATE_VALUE_EXPRESSION_ON_BUILD_BEFORE_RESTORE
+ false
+
+
+ facelets.BUILD_BEFORE_RESTORE
+ false
+
+
+ primefaces.PUBLIC_CAPTCHA_KEY
+ [YOUR RECAPTCHA PUBLIC KEY HERE]
+
+
+ primefaces.PRIVATE_CAPTCHA_KEY
+ [YOUR RECAPTCHA PRIVATE KEY HERE]
+
+
+ primefaces.THEME
+ #{userController.userTheme}
+
+
+
+
+
+ primefaces.PUSH_SERVER_URL
+ http://localhost:8080
+
+
+
+ com.sun.faces.config.ConfigureListener
+
+
+ com.mycompany.lifecycle.ServletContextLifecycleNotifier
+
+
+
+ Faces Servlet
+ javax.faces.webapp.FacesServlet
+ 1
+
+
+ Faces Servlet
+ /faces/*
+
+
+
+ PushServlet
+ org.primefaces.push.PushServlet
+
+
+ org.atmosphere.cpr.AtmosphereInterceptor
+ org.atmosphere.client.TrackMessageSizeInterceptor
+
+
+
+ org.atmosphere.cpr.sessionSupport
+ true
+
+
+ org.atmosphere.cpr.broadcasterCacheClass
+ org.atmosphere.cache.SessionBroadcasterCache
+
+
+
+ org.atmosphere.disableOnStateEvent
+ true
+
+
+
+ org.primefaces.push.rules
+ com.mycompany.websocket.DefaultPushRule
+
+ 1
+ true
+
+
+ PushServlet
+ /primepush/*
+
+
+
+
+
+ PrimeFaces FileUpload Filter
+ org.primefaces.webapp.filter.FileUploadFilter
+
+
+ PrimeFaces FileUpload Filter
+ Faces Servlet
+
+
+
+ txt
+ text/plain
+
+
+ html
+ text/html
+
+
+ css
+ text/css
+
+
+ xhtml
+ text/html
+
+
+ gif
+ image/gif
+
+
+ jpeg
+ image/jpeg
+
+
+ jpg
+ image/jpeg
+
+
+ png
+ image/png
+
+
+
diff --git a/primefaces-webapp/src/main/webapp/about.xhtml b/primefaces-webapp/src/main/webapp/about.xhtml
new file mode 100644
index 0000000..62e9ac7
--- /dev/null
+++ b/primefaces-webapp/src/main/webapp/about.xhtml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+ About Us
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/primefaces-webapp/src/main/webapp/error.xhtml b/primefaces-webapp/src/main/webapp/error.xhtml
new file mode 100644
index 0000000..bbc927d
--- /dev/null
+++ b/primefaces-webapp/src/main/webapp/error.xhtml
@@ -0,0 +1,16 @@
+
+
+
+
+
+ Error Page
+
+ There was an error processing your request. Please try again later.
+
+
+
+
diff --git a/primefaces-webapp/src/main/webapp/ideas.xhtml b/primefaces-webapp/src/main/webapp/ideas.xhtml
new file mode 100644
index 0000000..4d863ef
--- /dev/null
+++ b/primefaces-webapp/src/main/webapp/ideas.xhtml
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+ Ideas
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/primefaces-webapp/src/main/webapp/index.xhtml b/primefaces-webapp/src/main/webapp/index.xhtml
new file mode 100644
index 0000000..ef897fe
--- /dev/null
+++ b/primefaces-webapp/src/main/webapp/index.xhtml
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+ Welcome to our site
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+ Find out what's happening
+
+ -
+ Rate and review shows
+
+ -
+ Invite your friends
+
+ -
+ Join today!
+
+
+
+
+
+
+
+
diff --git a/primefaces-webapp/src/main/webapp/mobile/index.xhtml b/primefaces-webapp/src/main/webapp/mobile/index.xhtml
new file mode 100644
index 0000000..35fcf7a
--- /dev/null
+++ b/primefaces-webapp/src/main/webapp/mobile/index.xhtml
@@ -0,0 +1,510 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+ Find out what's happening
+
+ -
+ Rate and review shows
+
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dashboard
+
+
+ Venues
+
+
+ Shows
+
+
+ Reviews
+
+
+ Contacts
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/primefaces-webapp/src/main/webapp/protected/members/contacts.xhtml b/primefaces-webapp/src/main/webapp/protected/members/contacts.xhtml
new file mode 100644
index 0000000..a34fa1b
--- /dev/null
+++ b/primefaces-webapp/src/main/webapp/protected/members/contacts.xhtml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/primefaces-webapp/src/main/webapp/protected/members/dashboard.xhtml b/primefaces-webapp/src/main/webapp/protected/members/dashboard.xhtml
new file mode 100644
index 0000000..dd58019
--- /dev/null
+++ b/primefaces-webapp/src/main/webapp/protected/members/dashboard.xhtml
@@ -0,0 +1,103 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/primefaces-webapp/src/main/webapp/protected/members/index.xhtml b/primefaces-webapp/src/main/webapp/protected/members/index.xhtml
new file mode 100644
index 0000000..c298e14
--- /dev/null
+++ b/primefaces-webapp/src/main/webapp/protected/members/index.xhtml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+ Members
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/primefaces-webapp/src/main/webapp/protected/members/reviews.xhtml b/primefaces-webapp/src/main/webapp/protected/members/reviews.xhtml
new file mode 100644
index 0000000..eb06d63
--- /dev/null
+++ b/primefaces-webapp/src/main/webapp/protected/members/reviews.xhtml
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/primefaces-webapp/src/main/webapp/protected/members/shows.xhtml b/primefaces-webapp/src/main/webapp/protected/members/shows.xhtml
new file mode 100644
index 0000000..b21a093
--- /dev/null
+++ b/primefaces-webapp/src/main/webapp/protected/members/shows.xhtml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/primefaces-webapp/src/main/webapp/protected/members/venues.xhtml b/primefaces-webapp/src/main/webapp/protected/members/venues.xhtml
new file mode 100644
index 0000000..0c7ea6e
--- /dev/null
+++ b/primefaces-webapp/src/main/webapp/protected/members/venues.xhtml
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/primefaces-webapp/src/main/webapp/resources/css/main.css b/primefaces-webapp/src/main/webapp/resources/css/main.css
new file mode 100644
index 0000000..8e3fea7
--- /dev/null
+++ b/primefaces-webapp/src/main/webapp/resources/css/main.css
@@ -0,0 +1,129 @@
+body, ul {
+ font-family:Arial, Helvetica, sans-serif;
+ font-size:1.1em;
+ color:#4F4F4F;
+}
+div.header {
+ text-align:center;
+ margin-bottom:25px;
+}
+div.content table {
+ margin:0 auto;
+ text-align:center;
+}
+div.content table td {
+ text-align:left;
+}
+div.footer {
+ text-align:center;
+ margin-top:20px;
+ margin-bottom:20px;
+}
+div.footer a {
+ margin-right:15px;
+}
+ul li {
+ margin-bottom:15px;
+}
+.input-form input.ui-inputfield {
+ width:445px;
+}
+.input-form input.ui-inputfield.hasDatepicker {
+ width:394px;
+}
+button.ui-datepicker-trigger {
+ vertical-align:middle;
+ height:35px;
+ margin-left:5px;
+}
+.centered {
+ text-align:center;
+}
+.ui-tabs-hide {
+ position:absolute;
+ left:-10000px;
+}
+.ui-overlay-hidden {
+ position:absolute;
+ left:-10000px;
+}
+.ui-datepicker .ui-datepicker-title select {
+ font-size:0.7em;
+}
+.top {
+ vertical-align:top;
+}
+.left {
+ text-align:left;
+}
+.content-box {
+ width:50%;
+ margin:0 auto;
+}
+.person-item {
+ height:140px;
+ text-align:center;
+ width:200px;
+}
+.mobile-person-item {
+ height:130px;
+ text-align:center;
+ vertical-align:middle;
+ width:100%;
+ font-size:0.9em;
+}
+div.content .person-item table td {
+ text-align:center;
+}
+.chatlogs {
+ height:235px;
+ width:450px;
+ overflow:auto;
+ padding:0.5em 1em 0.5em 0.5em;
+}
+.ui-dashboard .ui-panel {
+ margin:10px;
+ width:265px;
+ font-size:0.9em;
+}
+.ui-dashboard .ui-panel .ui-widget-content {
+ height:200px;
+ overflow-y:auto;
+ font-size:0.8em;
+}
+.ui-dashboard .ui-panel .ui-widget-content img {
+ padding-right:10px;
+ padding-bottom:5px;
+}
+.align-left {
+ text-align:left;
+}
+.align-right {
+ text-align:right;
+}
+.content-controls {
+ text-align:center;
+}
+.content-box div.ui-editor {
+ text-align:center;
+ margin:0 auto;
+}
+.chat-users-column {
+ width:25%;
+}
+.chat-text-column {
+ width:75%;
+}
+.centervh {
+ text-align:center;
+ vertical-align:middle;
+}
+.no-border {
+ border:none;
+}
+.ui-panelgrid td.no-border {
+ border:none;
+}
+table.no-border .ui-widget-content {
+ border:none;
+}
\ No newline at end of file
diff --git a/primefaces-webapp/src/main/webapp/resources/images/about.png b/primefaces-webapp/src/main/webapp/resources/images/about.png
new file mode 100755
index 0000000..7d45c0d
Binary files /dev/null and b/primefaces-webapp/src/main/webapp/resources/images/about.png differ
diff --git a/primefaces-webapp/src/main/webapp/resources/images/add-user-icon.png b/primefaces-webapp/src/main/webapp/resources/images/add-user-icon.png
new file mode 100644
index 0000000..984a170
Binary files /dev/null and b/primefaces-webapp/src/main/webapp/resources/images/add-user-icon.png differ
diff --git a/primefaces-webapp/src/main/webapp/resources/images/home.png b/primefaces-webapp/src/main/webapp/resources/images/home.png
new file mode 100755
index 0000000..93b392c
Binary files /dev/null and b/primefaces-webapp/src/main/webapp/resources/images/home.png differ
diff --git a/primefaces-webapp/src/main/webapp/resources/images/members.png b/primefaces-webapp/src/main/webapp/resources/images/members.png
new file mode 100755
index 0000000..3c3fe32
Binary files /dev/null and b/primefaces-webapp/src/main/webapp/resources/images/members.png differ
diff --git a/primefaces-webapp/src/main/webapp/resources/images/offline-user-icon.png b/primefaces-webapp/src/main/webapp/resources/images/offline-user-icon.png
new file mode 100644
index 0000000..95f045f
Binary files /dev/null and b/primefaces-webapp/src/main/webapp/resources/images/offline-user-icon.png differ
diff --git a/primefaces-webapp/src/main/webapp/resources/images/privacy.png b/primefaces-webapp/src/main/webapp/resources/images/privacy.png
new file mode 100755
index 0000000..6ac92a4
Binary files /dev/null and b/primefaces-webapp/src/main/webapp/resources/images/privacy.png differ
diff --git a/primefaces-webapp/src/main/webapp/resources/images/showtime_logo.png b/primefaces-webapp/src/main/webapp/resources/images/showtime_logo.png
new file mode 100644
index 0000000..d5eb53f
Binary files /dev/null and b/primefaces-webapp/src/main/webapp/resources/images/showtime_logo.png differ
diff --git a/primefaces-webapp/src/main/webapp/resources/images/showtimes.png b/primefaces-webapp/src/main/webapp/resources/images/showtimes.png
new file mode 100755
index 0000000..3a5d44e
Binary files /dev/null and b/primefaces-webapp/src/main/webapp/resources/images/showtimes.png differ
diff --git a/primefaces-webapp/src/main/webapp/resources/images/status.gif b/primefaces-webapp/src/main/webapp/resources/images/status.gif
new file mode 100644
index 0000000..41bae58
Binary files /dev/null and b/primefaces-webapp/src/main/webapp/resources/images/status.gif differ
diff --git a/primefaces-webapp/src/main/webapp/resources/images/user-icon.png b/primefaces-webapp/src/main/webapp/resources/images/user-icon.png
new file mode 100644
index 0000000..4475c83
Binary files /dev/null and b/primefaces-webapp/src/main/webapp/resources/images/user-icon.png differ
diff --git a/primefaces-webapp/src/main/webapp/resources/images/user.png b/primefaces-webapp/src/main/webapp/resources/images/user.png
new file mode 100644
index 0000000..63e9bb9
Binary files /dev/null and b/primefaces-webapp/src/main/webapp/resources/images/user.png differ
diff --git a/primefaces-webapp/src/main/webapp/resources/js/main.js b/primefaces-webapp/src/main/webapp/resources/js/main.js
new file mode 100644
index 0000000..6f52eff
--- /dev/null
+++ b/primefaces-webapp/src/main/webapp/resources/js/main.js
@@ -0,0 +1,19 @@
+
+/*
+ * Shows dashboard panels.
+ */
+function showPanels() {
+ modalStatusWidget.hide();
+ eventsPanelWidget.show();
+ eventsPanelWidget.expand();
+ entertainmentPanelWidget.show();
+ entertainmentPanelWidget.expand();
+ weatherPanelWidget.show();
+ weatherPanelWidget.expand();
+ politicsPanelWidget.show();
+ politicsPanelWidget.expand();
+ sportsPanelWidget.show();
+ sportsPanelWidget.expand();
+ clicksPanelWidget.show();
+ clicksPanelWidget.expand();
+}
diff --git a/primefaces-webapp/src/main/webapp/resources/mycompany/contactList.xhtml b/primefaces-webapp/src/main/webapp/resources/mycompany/contactList.xhtml
new file mode 100644
index 0000000..ca3160f
--- /dev/null
+++ b/primefaces-webapp/src/main/webapp/resources/mycompany/contactList.xhtml
@@ -0,0 +1,69 @@
+
+
+
+
+Untitled Document
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/primefaces-webapp/src/main/webapp/showtimes.xhtml b/primefaces-webapp/src/main/webapp/showtimes.xhtml
new file mode 100644
index 0000000..8e26ba4
--- /dev/null
+++ b/primefaces-webapp/src/main/webapp/showtimes.xhtml
@@ -0,0 +1,121 @@
+
+
+
+
+
+
+ Show Times
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/primefaces-webapp/src/main/webapp/signup.xhtml b/primefaces-webapp/src/main/webapp/signup.xhtml
new file mode 100644
index 0000000..a60c268
--- /dev/null
+++ b/primefaces-webapp/src/main/webapp/signup.xhtml
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+ Sign Up
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/primefaces-webapp/src/test/java/.gitignore b/primefaces-webapp/src/test/java/.gitignore
new file mode 100644
index 0000000..86d0cb2
--- /dev/null
+++ b/primefaces-webapp/src/test/java/.gitignore
@@ -0,0 +1,4 @@
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
\ No newline at end of file
diff --git a/primefaces-webapp/src/test/resources/.gitignore b/primefaces-webapp/src/test/resources/.gitignore
new file mode 100644
index 0000000..86d0cb2
--- /dev/null
+++ b/primefaces-webapp/src/test/resources/.gitignore
@@ -0,0 +1,4 @@
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
\ No newline at end of file