diff --git a/primefaces-webapp/.classpath b/primefaces-webapp/.classpath new file mode 100644 index 0000000..0d6bd5f --- /dev/null +++ b/primefaces-webapp/.classpath @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/primefaces-webapp/.euml2 b/primefaces-webapp/.euml2 new file mode 100644 index 0000000..e348ac9 --- /dev/null +++ b/primefaces-webapp/.euml2 @@ -0,0 +1,7 @@ + + + + + + + diff --git a/primefaces-webapp/.factorypath b/primefaces-webapp/.factorypath new file mode 100644 index 0000000..2ddac7b --- /dev/null +++ b/primefaces-webapp/.factorypath @@ -0,0 +1,5 @@ + + + + + + + + + + + + diff --git a/primefaces-webapp/.project b/primefaces-webapp/.project new file mode 100644 index 0000000..cfa0d1f --- /dev/null +++ b/primefaces-webapp/.project @@ -0,0 +1,42 @@ + + + primefaces-webapp + + + + + + org.eclipse.wst.jsdt.core.javascriptValidator + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.eclipse.wst.validation.validationbuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jem.workbench.JavaEMFNature + org.eclipse.wst.common.modulecore.ModuleCoreNature + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + org.eclipse.wst.common.project.facet.core.nature + org.eclipse.wst.jsdt.core.jsNature + + diff --git a/primefaces-webapp/.settings/.jsdtscope b/primefaces-webapp/.settings/.jsdtscope new file mode 100644 index 0000000..b46b920 --- /dev/null +++ b/primefaces-webapp/.settings/.jsdtscope @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/primefaces-webapp/.settings/org.eclipse.jdt.apt.core.prefs b/primefaces-webapp/.settings/org.eclipse.jdt.apt.core.prefs new file mode 100644 index 0000000..7d52ece --- /dev/null +++ b/primefaces-webapp/.settings/org.eclipse.jdt.apt.core.prefs @@ -0,0 +1,4 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.apt.aptEnabled=true +org.eclipse.jdt.apt.genSrcDir=.apt_generated +org.eclipse.jdt.apt.reconcileEnabled=true diff --git a/primefaces-webapp/.settings/org.eclipse.jdt.core.prefs b/primefaces-webapp/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..66c3cd6 --- /dev/null +++ b/primefaces-webapp/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,13 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.processAnnotations=enabled +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/primefaces-webapp/.settings/org.eclipse.jpt.core.prefs b/primefaces-webapp/.settings/org.eclipse.jpt.core.prefs new file mode 100644 index 0000000..7f6edff --- /dev/null +++ b/primefaces-webapp/.settings/org.eclipse.jpt.core.prefs @@ -0,0 +1,3 @@ +eclipse.preferences.version=1 +org.eclipse.jpt.core.platform=generic2_0 +org.eclipse.jpt.jpa.core.discoverAnnotatedClasses=true diff --git a/primefaces-webapp/.settings/org.eclipse.m2e.core.prefs b/primefaces-webapp/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/primefaces-webapp/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/primefaces-webapp/.settings/org.eclipse.wst.common.component b/primefaces-webapp/.settings/org.eclipse.wst.common.component new file mode 100644 index 0000000..4dd5c78 --- /dev/null +++ b/primefaces-webapp/.settings/org.eclipse.wst.common.component @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/primefaces-webapp/.settings/org.eclipse.wst.common.project.facet.core.prefs.xml b/primefaces-webapp/.settings/org.eclipse.wst.common.project.facet.core.prefs.xml new file mode 100644 index 0000000..d564e65 --- /dev/null +++ b/primefaces-webapp/.settings/org.eclipse.wst.common.project.facet.core.prefs.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/primefaces-webapp/.settings/org.eclipse.wst.common.project.facet.core.xml b/primefaces-webapp/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 0000000..d125834 --- /dev/null +++ b/primefaces-webapp/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/primefaces-webapp/.settings/org.eclipse.wst.jsdt.ui.superType.container b/primefaces-webapp/.settings/org.eclipse.wst.jsdt.ui.superType.container new file mode 100644 index 0000000..3bd5d0a --- /dev/null +++ b/primefaces-webapp/.settings/org.eclipse.wst.jsdt.ui.superType.container @@ -0,0 +1 @@ +org.eclipse.wst.jsdt.launching.baseBrowserLibrary \ No newline at end of file diff --git a/primefaces-webapp/.settings/org.eclipse.wst.jsdt.ui.superType.name b/primefaces-webapp/.settings/org.eclipse.wst.jsdt.ui.superType.name new file mode 100644 index 0000000..05bd71b --- /dev/null +++ b/primefaces-webapp/.settings/org.eclipse.wst.jsdt.ui.superType.name @@ -0,0 +1 @@ +Window \ No newline at end of file diff --git a/primefaces-webapp/.umlproject b/primefaces-webapp/.umlproject new file mode 100644 index 0000000..e348ac9 --- /dev/null +++ b/primefaces-webapp/.umlproject @@ -0,0 +1,7 @@ + + + + + + + diff --git a/primefaces-webapp/pom.xml b/primefaces-webapp/pom.xml new file mode 100644 index 0000000..4812a4b --- /dev/null +++ b/primefaces-webapp/pom.xml @@ -0,0 +1,270 @@ + + 4.0.0 + com.mycompany + primefaces-webapp + 0.0.1-SNAPSHOT + war + + + prime-repo + PrimeFaces Maven Repository + http://repository.primefaces.org + default + + + codehaus-snapshots + http://snapshots.repository.codehaus.org + + + jboss-public-repository-group + JBoss Public Maven Repository Group + https://repository.jboss.org/nexus/content/groups/public-jboss/ + default + + + + + + + org.primefaces + primefaces + 3.5 + + + org.primefaces + primefaces-mobile + 1.0.0-SNAPSHOT + + + org.glassfish + javax.faces + 2.1.10 + + + + + + org.atmosphere + atmosphere-runtime + 1.0.10 + + + slf4j-api + org.slf4j + + + + + + + rome + rome + 1.0 + + + + + commons-fileupload + commons-fileupload + 1.2.1 + + + + + + + org.primefaces.themes + all-themes + 1.0.9 + + + + + org.hibernate + hibernate-jpamodelgen + 1.0.0.Final + provided + + + org.hibernate + hibernate-entitymanager + 3.5.1-Final + + + org.slf4j + slf4j-simple + 1.5.8 + + + javax.validation + validation-api + 1.0.0.GA + + + org.hibernate + hibernate-validator + 4.0.2.GA + + + slf4j-api + org.slf4j + + + + + + + org.jboss.spec + jboss-javaee-6.0 + 1.0.0.Final + pom + provided + + + + + commons-lang + commons-lang + 2.6 + + + + + org.codehaus.jackson + jackson-mapper-asl + 1.9.11 + + + + mysql + mysql-connector-java + 5.1.22 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + 1.6 + 1.6 + true + lines,vars,source + -proc:none + + + + + run-annotation-processors-only + generate-sources + + -proc:only + + **/model/*.java + + + + **/model/*_.java + **/model/Abstract*.java + + + + compile + + + + + + org.bsc.maven + maven-processor-plugin + 2.1.1 + + + process + + process + + generate-sources + + UTF-8 + + src/main/java + + + + + + maven-clean-plugin + 2.4.1 + + + + ../${project.artifactId}/src/main/java + + **/*_.java + + + + + + + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + org.codehaus.mojo + build-helper-maven-plugin + [1.3,) + + add-source + + + + + + + + + org.bsc.maven + maven-processor-plugin + [2.1.0,) + + process + + + + + + + + + + + + + + \ No newline at end of file diff --git a/primefaces-webapp/src/main/java/com/mycompany/controller/AbstractController.java b/primefaces-webapp/src/main/java/com/mycompany/controller/AbstractController.java new file mode 100644 index 0000000..0ef330e --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/controller/AbstractController.java @@ -0,0 +1,105 @@ +/* + * 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.controller; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.Serializable; + +import javax.faces.application.FacesMessage; +import javax.faces.bean.ManagedProperty; +import javax.faces.context.FacesContext; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.mycompany.model.User; +import com.mycompany.util.UserSession; + +/** + * Base class for controller objects. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +/** + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +public abstract class AbstractController implements Serializable { + + /** + * + */ + private static final long serialVersionUID = -4862069600034765532L; + + protected transient Logger logger = LoggerFactory.getLogger(getClass()); + + @ManagedProperty(value = "#{userSession}") + protected UserSession userSession; + + /** + * Adds a global error message to the response. + * + * @param summary + * The message summary. + */ + protected void addErrorMessage(String summary) { + FacesMessage msg = new FacesMessage(summary); + msg.setSeverity(FacesMessage.SEVERITY_ERROR); + FacesContext.getCurrentInstance().addMessage(null, msg); + } + + /** + * Convenience method to return the logged in user. + * + * @return A {@link User} object. + */ + protected User getLoggedInUser() { + User user = null; + if (userSession != null) { + user = userSession.getUser(); + } + return user; + } + + /** + * Handle deserialization from passivated session and restore transient + * fields. + * + * @param ois + * The ObjectInputStream object. + * @throws IOException + * @throws ClassNotFoundException + */ + private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { + ois.defaultReadObject(); + logger = LoggerFactory.getLogger(getClass()); + } + + public void setUserSession(UserSession userSession) { + this.userSession = userSession; + } +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/controller/ChartController.java b/primefaces-webapp/src/main/java/com/mycompany/controller/ChartController.java new file mode 100644 index 0000000..826c7e6 --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/controller/ChartController.java @@ -0,0 +1,175 @@ +/* + * 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.controller; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.faces.application.FacesMessage; +import javax.faces.bean.ManagedBean; +import javax.faces.bean.ManagedProperty; +import javax.faces.bean.ViewScoped; +import javax.faces.context.FacesContext; +import javax.faces.event.ComponentSystemEvent; +import javax.persistence.EntityManager; + +import org.primefaces.event.ItemSelectEvent; +import org.primefaces.model.chart.CartesianChartModel; +import org.primefaces.model.chart.ChartSeries; +import org.primefaces.model.chart.PieChartModel; + +import com.mycompany.model.Gender; +import com.mycompany.model.User; +import com.mycompany.service.ChartService; +import com.mycompany.service.UserService; + +/** + * Controller class for charts. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +@ManagedBean +@ViewScoped +public class ChartController extends AbstractController { + + /** + * + */ + private static final long serialVersionUID = -1999623701433215717L; + + private CartesianChartModel barChartModel; + + @ManagedProperty(value = "#{chartService}") + private ChartService chartService; + + @ManagedProperty(value = "#{userService}") + private UserService userService; + + private PieChartModel pieChartModel; + + private ChartSeries buildChartSeries(List results, String label) { + ChartSeries series = new ChartSeries(); + series.setLabel(label); + // calculate monthly totals + SimpleDateFormat sdf = new SimpleDateFormat("MMM/yy"); + List months = new ArrayList(); + Map monthTotals = new HashMap(); + for (Object[] result : results) { + Date date = (Date) result[0]; + Long count = (Long) result[1]; + String month = sdf.format(date); + if (!months.contains(month)) { + months.add(month); + } + Long total = monthTotals.get(month); + if (total == null) { + total = 0L; + } + monthTotals.put(month, count + total); + } + // add the data to the chart series + for (String month : months) { + series.set(month, monthTotals.get(month).intValue()); + } + return series; + } + + private void createBarChartModel() { + List maleResults = chartService.findEventAttendanceByGender(Gender.MALE); + List femaleResults = chartService.findEventAttendanceByGender(Gender.FEMALE); + if (maleResults.isEmpty() && femaleResults.isEmpty()) { + return; + } + barChartModel = new CartesianChartModel(); + ChartSeries males = buildChartSeries(maleResults, "Male"); + ChartSeries females = buildChartSeries(femaleResults, "Female"); + barChartModel.addSeries(males); + barChartModel.addSeries(females); + } + + private void createPieModel() { + pieChartModel = new PieChartModel(); + List users = userService.findUsers(); + for (User user : users) { + Integer count = user.getClickCount(); + if (count == null) { + count = 0; + } + String username = user.getUsername(); + pieChartModel.getData().put(username, count); + } + } + + public CartesianChartModel getBarChartModel() { + return barChartModel; + } + + /** + * This method builds a {@link PieChartModel} of active user click counts. + * + * @return A PieChartModel. + */ + public PieChartModel getLivePieModel() { + return pieChartModel; + } + + public PieChartModel getPieChartModel() { + return pieChartModel; + } + + /** + * Initializes the pie chart and bar chart models from data in our database. + * We can't do this in the constructor because the {@link EntityManager} is + * injected after the object is constructed, so this method handles the + * initialization during the pre-render view event. + * + * @param event + * The view event. + */ + public void init(ComponentSystemEvent event) { + createBarChartModel(); + createPieModel(); + } + + public void itemSelect(ItemSelectEvent event) { + FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Item selected", + "Item Index: " + event.getItemIndex() + ", Series Index:" + event.getSeriesIndex()); + + FacesContext.getCurrentInstance().addMessage(null, msg); + } + + public void setChartService(ChartService chartService) { + this.chartService = chartService; + } + + public void setUserService(UserService userService) { + this.userService = userService; + } +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/controller/ChatController.java b/primefaces-webapp/src/main/java/com/mycompany/controller/ChatController.java new file mode 100644 index 0000000..7e7a7a9 --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/controller/ChatController.java @@ -0,0 +1,94 @@ +/* + * 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.controller; + +import javax.faces.bean.ManagedBean; +import javax.faces.bean.ViewScoped; +import javax.inject.Inject; + +import org.primefaces.context.RequestContext; +import org.primefaces.push.PushContext; +import org.primefaces.push.PushContextFactory; + +import com.mycompany.model.ActiveUsers; +import com.mycompany.model.User; + +/** + * Controller class for chat functionality. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +@ManagedBean +@ViewScoped +public class ChatController extends AbstractController { + + /** + * + */ + private static final long serialVersionUID = -2706002474535643832L; + + private String globalMessage; + + private static final String CHANNEL = "/chat/"; + + @Inject + private ActiveUsers activeUsers; + + private final PushContext pushContext = PushContextFactory.getDefault().getPushContext(); + + public String getGlobalMessage() { + return globalMessage; + } + + public void beginChat() { + User user = getLoggedInUser(); + RequestContext requestContext = RequestContext.getCurrentInstance(); + requestContext.execute("socketWidget.cfg.request.trackMessageLength = true;"); + requestContext.execute("socketWidget.connect('/" + user.getUsername() + "')"); + pushContext.push(CHANNEL + "*", user.getUsername() + " joined the channel."); + } + + public void endChat() { + // remove user and update ui + User user = getLoggedInUser(); + RequestContext.getCurrentInstance().update("chatForm:users"); + // disconnect websocket + RequestContext requestContext = RequestContext.getCurrentInstance(); + requestContext.execute("socketWidget.disconnect('/" + user.getUsername() + "')"); + // push leave information + pushContext.push(CHANNEL + "*", user.getUsername() + " left the channel."); + } + + public void sendGlobal() { + String username = getLoggedInUser().getUsername(); + pushContext.push(CHANNEL + "*", username + ": " + globalMessage); + } + + public void setGlobalMessage(String globalMessage) { + this.globalMessage = globalMessage; + } + +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/controller/ContactsController.java b/primefaces-webapp/src/main/java/com/mycompany/controller/ContactsController.java new file mode 100644 index 0000000..9446df5 --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/controller/ContactsController.java @@ -0,0 +1,158 @@ +/* + * 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.controller; + +import java.util.List; + +import javax.faces.bean.ManagedBean; +import javax.faces.bean.ManagedProperty; +import javax.faces.bean.ViewScoped; +import javax.faces.event.ActionEvent; +import javax.faces.event.ComponentSystemEvent; + +import org.primefaces.event.SelectEvent; + +import com.mycompany.model.RelationshipType; +import com.mycompany.model.User; +import com.mycompany.model.UserRelationship; +import com.mycompany.service.UserService; + +/** + * Controller class for contacts related functionality. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +@ManagedBean +@ViewScoped +public class ContactsController extends AbstractController { + + /** + * + */ + private static final long serialVersionUID = -1709154434943491658L; + + private List colleagues; + + @ManagedProperty(value = "#{userService}") + private UserService userService; + + private List family; + + private List friends; + + private UserRelationship relationship; + + private RelationshipType relationshipType; + + public List findUsersByName(String suggest) { + if (suggest == null) { + return null; + } + List users = userService.findUsersByName(suggest); + // remove current user from list + users.remove(getLoggedInUser()); + logger.info("Found {} users for '{}'", users.size(), suggest); + return users; + } + + public List getColleagues() { + if (colleagues == null) { + colleagues = userService.findUsersByType(RelationshipType.COLLEAGUE, getLoggedInUser()); + } + return colleagues; + } + + public List getFamily() { + if (family == null) { + family = userService.findUsersByType(RelationshipType.FAMILY, getLoggedInUser()); + } + return family; + } + + public List getFriends() { + if (friends == null) { + friends = userService.findUsersByType(RelationshipType.FRIEND, getLoggedInUser()); + } + return friends; + } + + public UserRelationship getRelationship() { + return relationship; + } + + public RelationshipType getRelationshipType() { + return relationshipType; + } + + public RelationshipType[] getRelationshipTypes() { + return RelationshipType.values(); + } + + public RelationshipType[] getUserTypes() { + return RelationshipType.values(); + } + + public void init(ComponentSystemEvent event) { + if (relationship == null) { + relationship = new UserRelationship(); + relationship.setFromUser(getLoggedInUser()); + } + } + + public void newRelationship(ActionEvent event) { + relationship = new UserRelationship(); + } + + public String saveRelationship() { + if (relationship.getToUser().equals(getLoggedInUser())) { + // throw new + // IllegalArgumentException("Unable to create relationship to self"); + addErrorMessage("Unable to create relationship to self"); + return null; + } + userService.saveRelationship(relationship); + relationship = null; + family = null; + friends = null; + colleagues = null; + return null; + } + + public void setUserService(UserService userService) { + this.userService = userService; + } + + public void setRelationship(UserRelationship relationship) { + this.relationship = relationship; + } + + public void userSelected(SelectEvent event) { + // load an existing relationship so it can be edited + relationship = userService.findRelationshipToUser(getLoggedInUser(), + relationship.getToUser()); + } + +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/controller/ContentController.java b/primefaces-webapp/src/main/java/com/mycompany/controller/ContentController.java new file mode 100644 index 0000000..6c56127 --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/controller/ContentController.java @@ -0,0 +1,122 @@ +/* + * 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.controller; + +import java.util.Date; + +import javax.enterprise.context.Conversation; +import javax.faces.bean.ManagedBean; +import javax.faces.bean.ManagedProperty; +import javax.faces.bean.ViewScoped; +import javax.faces.context.FacesContext; +import javax.faces.event.ActionEvent; +import javax.faces.event.ComponentSystemEvent; +import javax.faces.event.ValueChangeEvent; +import javax.inject.Inject; + +import com.mycompany.model.Content; +import com.mycompany.service.ContentService; + +/** + * Controller class for content editing. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +@ManagedBean +@ViewScoped +public class ContentController extends AbstractController { + + /** + * + */ + private static final long serialVersionUID = -5256865616437754501L; + + private Content content; + + @ManagedProperty(value = "#{contentService}") + private ContentService contentService; + + @Inject + private Conversation conversation; + + private boolean editing; + + public void contentChanged(ValueChangeEvent event) { + saveContentAndStopEditing(); + } + + public Content getContent() { + return content; + } + + public void init(ComponentSystemEvent event) { + String viewId = FacesContext.getCurrentInstance().getViewRoot().getViewId(); + if (content == null || !viewId.equals(content.getViewId())) { + content = contentService.findContentByName(viewId); + } + if (content == null) { + content = new Content(); + content.setViewId(viewId); + content.setCreatedBy(getLoggedInUser()); + content.setCreatedDate(new Date()); + } + if (conversation.isTransient()) { + conversation.begin(); + } + } + + public boolean isEditing() { + return editing; + } + + public void saveContent(ActionEvent event) { + saveContentAndStopEditing(); + } + + private void saveContentAndStopEditing() { + contentService.saveContent(content); + content = null; + editing = false; + conversation.end(); + } + + public void setContent(Content content) { + this.content = content; + } + + public void setContentService(ContentService contentService) { + this.contentService = contentService; + } + + public void setEditing(boolean editing) { + this.editing = editing; + } + + public void toggleEditing(ActionEvent event) { + editing = !editing; + } + +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/controller/DashboardController.java b/primefaces-webapp/src/main/java/com/mycompany/controller/DashboardController.java new file mode 100644 index 0000000..588a8d2 --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/controller/DashboardController.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.controller; + +import javax.faces.application.FacesMessage; +import javax.faces.bean.ManagedBean; +import javax.faces.bean.ViewScoped; +import javax.faces.context.FacesContext; + +import org.primefaces.event.DashboardReorderEvent; +import org.primefaces.model.DashboardColumn; +import org.primefaces.model.DashboardModel; +import org.primefaces.model.DefaultDashboardColumn; +import org.primefaces.model.DefaultDashboardModel; + +/** + * Controller class for dashboard screen. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +@ManagedBean +@ViewScoped +public class DashboardController extends AbstractController { + + /** + * + */ + private static final long serialVersionUID = -291033332986147359L; + + private DashboardModel model; + + public DashboardController() { + model = new DefaultDashboardModel(); + DashboardColumn column1 = new DefaultDashboardColumn(); + DashboardColumn column2 = new DefaultDashboardColumn(); + DashboardColumn column3 = new DefaultDashboardColumn(); + + column1.addWidget("sports"); + column1.addWidget("events"); + + column2.addWidget("weather"); + column2.addWidget("clicks"); + + column3.addWidget("politics"); + column3.addWidget("entertainment"); + + model.addColumn(column1); + model.addColumn(column2); + model.addColumn(column3); + } + + public void handleReorder(DashboardReorderEvent event) { + FacesMessage message = new FacesMessage(); + message.setSeverity(FacesMessage.SEVERITY_INFO); + message.setSummary("Reordered: " + event.getWidgetId()); + message.setDetail("Item index: " + event.getItemIndex() + ", Column index: " + + event.getColumnIndex() + ", Sender index: " + event.getSenderColumnIndex()); + addMessage(message); + } + + private void addMessage(FacesMessage message) { + FacesContext.getCurrentInstance().addMessage(null, message); + } + + public DashboardModel getModel() { + return model; + } +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/controller/EventController.java b/primefaces-webapp/src/main/java/com/mycompany/controller/EventController.java new file mode 100644 index 0000000..3bcf72f --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/controller/EventController.java @@ -0,0 +1,326 @@ +/* + * 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.controller; + +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +import javax.faces.bean.ManagedBean; +import javax.faces.bean.ManagedProperty; +import javax.faces.bean.ViewScoped; +import javax.faces.event.ActionEvent; +import javax.faces.event.ComponentSystemEvent; +import javax.persistence.EntityManager; + +import org.primefaces.event.ScheduleEntryMoveEvent; +import org.primefaces.event.ScheduleEntryResizeEvent; +import org.primefaces.event.SelectEvent; +import org.primefaces.model.DefaultScheduleEvent; +import org.primefaces.model.LazyScheduleModel; +import org.primefaces.model.ScheduleEvent; +import org.primefaces.model.ScheduleModel; + +import com.mycompany.model.Event; +import com.mycompany.model.EventAttendance; +import com.mycompany.model.EventType; +import com.mycompany.model.User; +import com.mycompany.service.EventService; + +/** + * This class implements controller behavior for a number of screens in the + * application. It supports the member dashboard, shows, and reviews screens. + * This class is responsible for handling any calendar event related data and + * functionality for the application. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +@ManagedBean +@ViewScoped +public class EventController extends AbstractController { + + /** + * + */ + private static final long serialVersionUID = 1256165484728132802L; + + private List allEvents; + + private List allEventsAttendance; + + private Event event; + + @ManagedProperty(value = "#{eventService}") + private EventService eventService; + + private ScheduleModel userScheduleModel; + + /** + * This method is called when the user clicks on a date in the calendar. It + * sets the start and end date of the calendar {@link Event} object. + * + * @param evt + * The {@link SelectEvent} object. + */ + public void dateSelected(SelectEvent evt) { + event.setStartDate((Date) evt.getObject()); + Calendar cal = Calendar.getInstance(); + cal.setTime((Date) evt.getObject()); + cal.roll(Calendar.HOUR_OF_DAY, 1); + event.setEndDate(cal.getTime()); + } + + /** + * This method is called when the user moves a calendar {@link Event} from + * one date/time to another date/time. It updates the object and saves the + * changes to the database. + * + * @param evt + * The {@link ScheduleEntryMoveEvent} object. + */ + public void eventMoved(ScheduleEntryMoveEvent evt) { + ScheduleEvent scheduleEvent = evt.getScheduleEvent(); + Event event = (Event) scheduleEvent.getData(); + event = eventService.findEventById(event.getId()); + event.setStartDate(scheduleEvent.getStartDate()); + event.setEndDate(scheduleEvent.getEndDate()); + eventService.saveEvent(event); + } + + /** + * This method is called when the user resizes an event. It handles changing + * the start and/or end dates of the {@link Event} object and updates the + * database. + * + * @param evt + * The {@link ScheduleEntryResizeEvent} object. + */ + public void eventResized(ScheduleEntryResizeEvent evt) { + ScheduleEvent scheduleEvent = evt.getScheduleEvent(); + Event event = (Event) scheduleEvent.getData(); + event = eventService.findEventById(event.getId()); + event.setStartDate(scheduleEvent.getStartDate()); + event.setEndDate(scheduleEvent.getEndDate()); + eventService.saveEvent(event); + } + + /** + * This method is called when the user clicks on an existing event in the + * schedule. It assigns the selected event to an instance variable so it can + * be used for editing. + * + * @param evt + * The {@link SelectEvent} object. + */ + public void eventSelected(SelectEvent evt) { + ScheduleEvent scheduleEvent = (ScheduleEvent) evt.getObject(); + event = (Event) scheduleEvent.getData(); + } + + /** + * This method returns all {@link Event} objects in the database. + * + * @return A List of all objects. + */ + public List getAllEvents() { + if (allEvents == null) { + allEvents = eventService.findAllEvents(); + } + return allEvents; + } + + /** + * This method returns a list of {@link EventAttendance} objects + * encapsulating information about a user's attendance for a particular + * event. + * + * @return A List of EventAttendance objects. + */ + public List getAllEventsAttendance() { + if (allEventsAttendance == null) { + allEventsAttendance = eventService.findAllEventsAttendanceByUser(getLoggedInUser()); + } + return allEventsAttendance; + } + + /** + * This method returns the currently selected {@link Event}. + * + * @return An object. + */ + public Event getEvent() { + return event; + } + + /** + * This method returns an array of {@link EventType} enum objects. + * + * @return An array of EventType objects. + */ + public EventType[] getEventTypes() { + return EventType.values(); + } + + /** + * This method provides a {@link LazyScheduleModel} for the PrimeFaces + * schedule component. It loads all events for the current user that have a + * start date between two dates. The overridden + * {@link LazyScheduleModel#loadEvents(Date, Date)} method is called by + * PrimeFaces when data is needed for a particular date range. + * + * @return A {@link ScheduleModel} object. + */ + public ScheduleModel getUserScheduleModel() { + if (userScheduleModel == null) { + userScheduleModel = new LazyScheduleModel() { + + private static final long serialVersionUID = 1L; + + @Override + public void loadEvents(Date start, Date end) { + clear(); + User user = getLoggedInUser(); + List events = eventService.findUserEvents(start, end, user); + for (Event event : events) { + String title = event.getTitle(); + Date startDate = event.getStartDate(); + Date endDate = event.getEndDate(); + addEvent(new DefaultScheduleEvent(title, startDate, endDate, event)); + } + } + }; + } + return userScheduleModel; + } + + /** + * This method is called by JSF when the view is first loaded. It loads all + * the {@link Event} objects from the database so they can be displayed in + * the UI, and prepares the {@link EventAttendance} model for the current + * user. + * + * @param evt + * The JSF {@link ComponentSystemEvent} object. + */ + public void init(ComponentSystemEvent evt) { + if (event == null) { + event = new Event(); + userScheduleModel = null; + } + if (allEvents == null) { + // initialize user attendance model + User user = getLoggedInUser(); + List events = getAllEvents(); + for (Event event : events) { + EventAttendance attendance = eventService.findEventAttendance(event, user); + if (attendance == null) { + attendance = new EventAttendance(); + attendance.setEvent(event); + attendance.setUser(user); + eventService.saveAttendance(attendance); + } + } + } + } + + /** + * This method is called when the user clicks on the "New Event" button in + * the mobile web application. It simply creates a new {@link Event} object + * and assigns it to the {@link #event} instance variable. + * + * @param evt + * The JSF {@link ActionEvent} object. + */ + public void newEvent(ActionEvent evt) { + event = new Event(); + } + + /** + * This method is called from the reviews screen to refresh the + * {@link EventAttendance} data. When the user reloads the dashboard, the + * {@link #getAllEventsAttendance()} method will see that this instance + * variable is null, and reload the data to update the graph. + * + * @param event + * The JSF {@link ActionEvent} object. + */ + public void refreshAttendance(ActionEvent event) { + allEventsAttendance = null; + } + + /** + * This method is called when the user clicks the "Save" button in the new + * event dialog. It saves the {@link Event} object to the database. + * + * @param evt + * The JSF {@link ActionEvent} object. + */ + public void saveEvent(ActionEvent evt) { + event.setCreatedBy(getLoggedInUser()); + eventService.saveEvent(event); + event = null; + allEvents = null; + allEventsAttendance = null; + userScheduleModel = null; + } + + /** + * Sets the {@link Event}. + * + * @param event + * The Event object. + */ + public void setEvent(Event event) { + this.event = event; + } + + public void setEventService(EventService eventService) { + this.eventService = eventService; + } + + /** + *

+ * This method updates the current user's EventAttendance object for a + * particular event. It uses the JPA {@link EntityManager#merge(Object)} + * method to save the object's changes to the database, and then replaces + * this object in the {@link #allEventsAttendance} list to ensure the latest + * object is loaded in the UI. + *

+ *

+ * Note: this method is called directly from the UI since it takes advantage + * of the Expression Language (EL) 2.2 feature that allows method argument + * passing from JSF. + *

+ * + * @param attendance + * The {@link EventAttendance} object. + */ + public void updateAttendance(EventAttendance attendance) { + EventAttendance updated = eventService.saveAttendance(attendance); + allEventsAttendance.set(allEventsAttendance.indexOf(attendance), updated); + } + +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/controller/LoginController.java b/primefaces-webapp/src/main/java/com/mycompany/controller/LoginController.java new file mode 100644 index 0000000..9da76c6 --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/controller/LoginController.java @@ -0,0 +1,132 @@ +/* + * 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.controller; + +import java.io.IOException; + +import javax.faces.application.NavigationHandler; +import javax.faces.bean.ManagedBean; +import javax.faces.bean.ManagedProperty; +import javax.faces.bean.ViewScoped; +import javax.faces.context.ExternalContext; +import javax.faces.context.FacesContext; +import javax.faces.event.ComponentSystemEvent; + +import com.mycompany.model.ActiveUsers; +import com.mycompany.model.Credentials; +import com.mycompany.model.User; +import com.mycompany.service.UserService; + +/** + * Controller class for desktop and mobile login functionality. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * @uml.dependency supplier="com.mycompany.controller.AbstractController" + */ +@ManagedBean +@ViewScoped +public class LoginController extends AbstractController { + + /** + * + */ + private static final long serialVersionUID = -6710063228036238737L; + + @ManagedProperty(value = "#{activeUsers}") + private ActiveUsers activeUsers; + + @ManagedProperty(value = "#{credentials}") + private Credentials credentials; + + @ManagedProperty(value = "#{userService}") + private UserService userService; + + public void checkPermission(ComponentSystemEvent event) throws IOException { + if (!isLoggedIn()) { + FacesContext ctx = FacesContext.getCurrentInstance(); + ExternalContext external = ctx.getExternalContext(); + if (!external.isResponseCommitted()) { + NavigationHandler handler = ctx.getApplication().getNavigationHandler(); + handler.handleNavigation(ctx, null, "login"); + } + } + } + + public boolean isLoggedIn() { + return getLoggedInUser() != null; + } + + public String login() { + String outcome = null; + try { + String username = credentials.getUsername(); + String password = credentials.getPassword(); + User user = userService.findUser(username, password); + if (user == null) { + addErrorMessage("Invalid login"); + userSession.setUser(null); + } else { + userSession.setUser(user); + if (!activeUsers.contains(user)) { + activeUsers.add(user); + } + outcome = "members"; + } + } catch (Exception e) { + logger.error("Unable to login:", e); + } + return outcome; + } + + public String loginMobile() { + login(); + if (isLoggedIn()) { + return "pm:members"; + } + return null; + } + + public String logout() { + FacesContext.getCurrentInstance().getExternalContext().invalidateSession(); + return "login"; + } + + public String logoutMobile() { + FacesContext.getCurrentInstance().getExternalContext().invalidateSession(); + return "pm:main?reverse=true"; + } + + public void setActiveUsers(ActiveUsers activeUsers) { + this.activeUsers = activeUsers; + } + + public void setCredentials(Credentials credentials) { + this.credentials = credentials; + } + + public void setUserService(UserService userService) { + this.userService = userService; + } +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/controller/MindMapController.java b/primefaces-webapp/src/main/java/com/mycompany/controller/MindMapController.java new file mode 100644 index 0000000..2ac5fc1 --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/controller/MindMapController.java @@ -0,0 +1,126 @@ +/* + * 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.controller; + +import java.util.List; + +import javax.faces.bean.ManagedBean; +import javax.faces.bean.ManagedProperty; +import javax.faces.bean.ViewScoped; +import javax.faces.event.ActionEvent; +import javax.faces.event.ComponentSystemEvent; + +import org.primefaces.event.SelectEvent; +import org.primefaces.model.mindmap.DefaultMindmapNode; +import org.primefaces.model.mindmap.MindmapNode; + +import com.mycompany.model.Idea; +import com.mycompany.service.IdeaService; + +/** + * Controller class for mind map feature. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +@ManagedBean +@ViewScoped +public class MindMapController extends AbstractController { + + /** + * + */ + private static final long serialVersionUID = 4810848975079411459L; + + @ManagedProperty(value = "#{ideaService}") + private IdeaService ideaService; + + private Idea newIdea; + + private MindmapNode root; + + private Idea selectedIdea; + + private MindmapNode selectedNode; + + public Idea getNewIdea() { + return newIdea; + } + + public MindmapNode getRoot() { + return root; + } + + public MindmapNode getSelectedNode() { + return selectedNode; + } + + public void init(ComponentSystemEvent event) { + if (newIdea == null) { + newIdea = new Idea(); + loadIdeas(); + } + } + + private void loadIdeas() { + List ideas = ideaService.findIdeas(); + if (!ideas.isEmpty()) { + Idea rootIdea = ideas.get(0); + String label = rootIdea.getName(); + root = new DefaultMindmapNode(label, rootIdea, "FFCC00", true); + ideaService.buildMindMap(rootIdea, root); + } + } + + public void onNodeDblselect(SelectEvent event) { + this.selectedNode = (MindmapNode) event.getObject(); + this.selectedIdea = (Idea) this.selectedNode.getData(); + } + + public void onNodeSelect(SelectEvent event) { + } + + public void saveIdea(ActionEvent event) { + if (selectedIdea != null) { + newIdea.setParent(selectedIdea); + } + newIdea.setAuthor(getLoggedInUser()); + ideaService.saveIdea(newIdea); + root = null; + newIdea = null; + } + + public void setIdeaService(IdeaService ideaService) { + this.ideaService = ideaService; + } + + public void setNewIdea(Idea newIdea) { + this.newIdea = newIdea; + } + + public void setSelectedNode(MindmapNode selectedNode) { + this.selectedNode = selectedNode; + } +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/controller/SearchController.java b/primefaces-webapp/src/main/java/com/mycompany/controller/SearchController.java new file mode 100644 index 0000000..3d49708 --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/controller/SearchController.java @@ -0,0 +1,308 @@ +/* + * 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.controller; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLEncoder; +import java.util.List; + +import javax.ejb.TransactionAttribute; +import javax.ejb.TransactionAttributeType; +import javax.faces.bean.ManagedBean; +import javax.faces.bean.ManagedProperty; +import javax.faces.bean.ViewScoped; +import javax.faces.event.ActionEvent; +import javax.faces.event.ComponentSystemEvent; + +import org.codehaus.jackson.JsonNode; +import org.codehaus.jackson.map.ObjectMapper; +import org.primefaces.event.map.OverlaySelectEvent; +import org.primefaces.model.map.DefaultMapModel; +import org.primefaces.model.map.LatLng; +import org.primefaces.model.map.MapModel; +import org.primefaces.model.map.Marker; +import org.primefaces.model.map.Overlay; + +import com.mycompany.model.City; +import com.mycompany.model.Event; +import com.mycompany.model.EventType; +import com.mycompany.model.ProvinceState; +import com.mycompany.model.Venue; +import com.mycompany.service.CountryService; +import com.mycompany.service.EventService; + +/** + * Controller class for searching for shows and events. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +@ManagedBean +@ViewScoped +public class SearchController extends AbstractController { + + /** + * + */ + private static final long serialVersionUID = 3648708195333963881L; + + private boolean alcoholPermitted; + + private City city; + + @ManagedProperty(value = "#{countryService}") + private CountryService countryService; + + @ManagedProperty(value = "#{eventService}") + private EventService eventService; + + private EventType eventType; + + private String keyword; + + private String mapCenter; + + private Integer mapZoom; + + private int maxResults; + + private boolean noCoverCharge; + + private boolean outdoorVenue; + + private ProvinceState provinceState; + + private MapModel searchResultsModel; + + private Event selectedEvent; + + public SearchController() { + searchResultsModel = new DefaultMapModel(); + } + + public void eventSelected(OverlaySelectEvent evt) { + Overlay overlay = evt.getOverlay(); + this.selectedEvent = (Event) overlay.getData(); + } + + public List getCitiesForState() { + if (provinceState == null) { + return null; + } + return countryService.findCitiesByState(provinceState); + } + + public City getCity() { + return city; + } + + private LatLng getCoordinates(Venue venue) { + LatLng coords = null; + try { + if (venue.getLatitude() == null || venue.getLongitude() == null) { + // lookup address coordinates using Google Geocoding API + String address = URLEncoder.encode(venue.getCompleteAddress(), "UTF-8"); + String uri = "http://maps.googleapis.com/maps/api/geocode/json?sensor=true&address=" + + address; + ObjectMapper mapper = new ObjectMapper(); + JsonNode root = mapper.readTree(new URL(uri)); + logger.info("{}", root); + JsonNode geometry = root.findValue("geometry"); + if (geometry.isMissingNode()) { + return null; + } + JsonNode location = geometry.path("location"); + JsonNode latitude = location.path("lat"); + JsonNode longitude = location.path("lng"); + City city = venue.getCity(); + if (city.getLatitude() == null || city.getLongitude() == null) { + city.setLatitude(latitude.asDouble()); + city.setLongitude(longitude.asDouble()); + // Google Geocoding license does not permit storing in DB + } + venue.setLatitude(latitude.asDouble()); + venue.setLongitude(longitude.asDouble()); + } + coords = new LatLng(venue.getLatitude(), venue.getLongitude()); + } catch (UnsupportedEncodingException e) { + logger.error("Exception: {}", e); + } catch (MalformedURLException e) { + logger.error("Exception: {}", e); + } catch (IOException e) { + logger.error("Exception: {}", e); + } + return coords; + } + + public EventType getEventType() { + return eventType; + } + + public String getKeyword() { + return keyword; + } + + public String getMapCenter() { + if (mapCenter == null) { + if (city == null) { + // center on USA + mapCenter = "38.889722,-77.008889"; + } else { + mapCenter = city.getLatitude() + "," + city.getLongitude(); + } + } + return mapCenter; + } + + public Integer getMapZoom() { + if (mapZoom == null) { + mapZoom = 2; + } + return mapZoom; + } + + public int getMaxResults() { + return maxResults; + } + + public ProvinceState getProvinceState() { + return provinceState; + } + + public List getProvinceStates() { + return countryService.getProvinceStates(); + } + + public MapModel getSearchResultsModel() { + return searchResultsModel; + } + + public Event getSelectedEvent() { + return selectedEvent; + } + + public void init(ComponentSystemEvent event) { + } + + public boolean isAlcoholPermitted() { + return alcoholPermitted; + } + + public boolean isNoCoverCharge() { + return noCoverCharge; + } + + public boolean isOutdoorVenue() { + return outdoorVenue; + } + + /** + * This method searches the database for events. + * + * @param evt + */ + @TransactionAttribute(TransactionAttributeType.SUPPORTS) + public void search(ActionEvent evt) { + + // Get the list of shows from our database + List events = eventService.findEvents(city, provinceState, eventType, keyword); + if (events.isEmpty()) { + // zoom out to show world + mapZoom = 2; + return; + } + + // reset center + mapCenter = null; + + // zoom in to show city + mapZoom = 12; + + // Build a model for the Google map + for (Event event : events) { + LatLng coords = getCoordinates(event.getVenue()); + if (coords == null) { + logger.warn("Warning - no coordinates for location: " + + event.getVenue().getCompleteAddress()); + continue; + } + searchResultsModel.addOverlay(new Marker(coords, event.getTitle(), event)); + + // center map on city of first event + if (mapCenter == null) { + City eventCity = event.getVenue().getCity(); + mapCenter = eventCity.getLatitude() + "," + eventCity.getLongitude(); + } + } + } + + public void setAlcoholPermitted(boolean alcoholPermitted) { + this.alcoholPermitted = alcoholPermitted; + } + + public void setCity(City city) { + this.city = city; + } + + public void setCountryService(CountryService countryService) { + this.countryService = countryService; + } + + public void setEventService(EventService eventService) { + this.eventService = eventService; + } + + public void setEventType(EventType eventType) { + this.eventType = eventType; + } + + public void setKeyword(String keyword) { + this.keyword = keyword; + } + + public void setMaxResults(int maxResults) { + this.maxResults = maxResults; + } + + public void setNoCoverCharge(boolean noCoverCharge) { + this.noCoverCharge = noCoverCharge; + } + + public void setOutdoorVenue(boolean outdoorVenue) { + this.outdoorVenue = outdoorVenue; + } + + public void setProvinceState(ProvinceState state) { + this.provinceState = state; + } + + public void setSelectedEvent(Event selectedEvent) { + this.selectedEvent = selectedEvent; + } + +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/controller/SignupController.java b/primefaces-webapp/src/main/java/com/mycompany/controller/SignupController.java new file mode 100644 index 0000000..5b278c7 --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/controller/SignupController.java @@ -0,0 +1,146 @@ +/* + * 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.controller; + +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +import javax.faces.application.FacesMessage; +import javax.faces.bean.ManagedBean; +import javax.faces.bean.ManagedProperty; +import javax.faces.bean.ViewScoped; +import javax.faces.context.FacesContext; +import javax.faces.event.ActionEvent; + +import com.mycompany.model.Country; +import com.mycompany.model.Gender; +import com.mycompany.model.User; +import com.mycompany.service.CountryService; +import com.mycompany.service.UserService; + +/** + * Controller class for new user signup. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * @uml.dependency supplier="com.mycompany.model.Country" + */ +@ManagedBean +@ViewScoped +public class SignupController extends AbstractController { + + /** + * + */ + private static final long serialVersionUID = -3479887222411577225L; + + @ManagedProperty(value = "#{countryService}") + private CountryService countryService; + + private User user; + + @ManagedProperty(value = "#{userService}") + private UserService userService; + + public SignupController() { + user = new User(); + } + + public void createUser(ActionEvent event) { + user = new User(); + } + + public List getCountries() { + return countryService.getCountries(); + } + + public Gender[] getGenders() { + return Gender.values(); + } + + /** + * Return a date 100 years ago. + * + * @return + */ + public Date getMinDate() { + Calendar cal = Calendar.getInstance(); + cal.roll(Calendar.YEAR, -100); + return cal.getTime(); + } + + public User getUser() { + return user; + } + + /** + * This method checks to see if the username already exists. + * + * @return A boolean value. + */ + private boolean isValidUser() { + boolean valid = false; + String username = user.getUsername(); + if (username != null) { + if (userService.findUserByUsername(username) == null) { + valid = true; + } else { + FacesMessage msg = new FacesMessage(); + msg.setDetail("The username you have entered is already in use."); + msg.setSeverity(FacesMessage.SEVERITY_ERROR); + FacesContext.getCurrentInstance().addMessage(null, msg); + } + } + return valid; + } + + public void setCountryService(CountryService countryService) { + this.countryService = countryService; + } + + public void setUser(User user) { + this.user = user; + } + + public void setUserService(UserService userService) { + this.userService = userService; + } + + public String signup() { + if (isValidUser()) { + userService.saveUser(user); + return "login"; + } + return null; + } + + public String signupMobile() { + String outcome = signup(); + if (outcome != null) { + return "pm:main"; + } + return null; + } +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/controller/UserController.java b/primefaces-webapp/src/main/java/com/mycompany/controller/UserController.java new file mode 100644 index 0000000..8f79396 --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/controller/UserController.java @@ -0,0 +1,131 @@ +/* + * 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.controller; + +import java.util.ArrayList; +import java.util.List; + +import javax.faces.bean.ManagedBean; +import javax.faces.bean.ManagedProperty; +import javax.faces.bean.ViewScoped; +import javax.faces.event.ActionEvent; +import javax.faces.event.AjaxBehaviorEvent; + +import com.mycompany.model.ActiveUsers; +import com.mycompany.model.User; +import com.mycompany.service.UserService; + +/** + * Controller class for user-related functionality. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * @uml.dependency supplier="com.mycompany.util.UserSession" + */ +@ManagedBean +@ViewScoped +public class UserController extends AbstractController { + + /** + * + */ + private static final long serialVersionUID = 1140838618640961470L; + + @ManagedProperty(value = "#{activeUsers}") + private ActiveUsers activeUsers; + + private List themes; + + @ManagedProperty(value = "#{userService}") + private UserService userService; + + public User findUser(String username, String password) { + return userService.findUser(username, password); + } + + public List getThemes() { + if (themes == null) { + themes = new ArrayList(); + themes.add("aristo"); + themes.add("cupertino"); + themes.add("redmond"); + } + return themes; + } + + /** + * Returns the currently logged in user. + * + * @return A {@link User} object. + */ + public User getUser() { + return getLoggedInUser(); + } + + public String getUserTheme() { + String theme = null; + User user = getUser(); + if (user != null) { + theme = user.getTheme(); + } + if (theme == null) { + // use the default theme + theme = "aristo"; + } + return theme; + } + + public void handleClick(ActionEvent event) { + User user = getUser(); + if (user != null) { + Integer count = user.getClickCount(); + if (count == null) { + count = 0; + } + user.setClickCount(count + 1); + user = userService.saveUser(user); + userSession.setUser(user); + } + } + + public boolean isUserPresent(User user) { + return activeUsers.contains(user); + } + + public void setActiveUsers(ActiveUsers activeUsers) { + this.activeUsers = activeUsers; + } + + public void setUserService(UserService userService) { + this.userService = userService; + } + + public void updateUserTheme(AjaxBehaviorEvent event) { + User user = getUser(); + if (user != null) { + user = userService.saveUser(user); + } + } + +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/controller/VenueController.java b/primefaces-webapp/src/main/java/com/mycompany/controller/VenueController.java new file mode 100644 index 0000000..0f05286 --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/controller/VenueController.java @@ -0,0 +1,138 @@ +/* + * 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.controller; + +import java.util.List; + +import javax.faces.application.FacesMessage; +import javax.faces.bean.ManagedBean; +import javax.faces.bean.ManagedProperty; +import javax.faces.bean.ViewScoped; +import javax.faces.context.FacesContext; +import javax.faces.event.ActionEvent; +import javax.faces.event.ComponentSystemEvent; +import javax.faces.event.ValueChangeEvent; + +import com.mycompany.model.City; +import com.mycompany.model.Country; +import com.mycompany.model.ProvinceState; +import com.mycompany.model.Venue; +import com.mycompany.service.CountryService; +import com.mycompany.service.VenueService; + +/** + * Controller class for venue-related functionality. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +@ManagedBean +@ViewScoped +public class VenueController extends AbstractController { + + /** + * + */ + private static final long serialVersionUID = 1127963225862339644L; + + @ManagedProperty(value = "#{countryService}") + private CountryService countryService; + + private Venue venue; + + @ManagedProperty(value = "#{venueService}") + private VenueService venueService; + + public void deleteVenue(ActionEvent evt) { + venueService.deleteVenue(venue); + this.venue = null; + } + + public List findProvinceStatesByCountry(Country country) { + return countryService.findProvinceStatesByCountry(country); + } + + public List getCountries() { + return countryService.getCountries(); + } + + public Venue getVenue() { + return venue; + } + + public List getVenues() { + return venueService.findVenues(); + } + + public void init(ComponentSystemEvent evt) { + if (venue == null) { + venue = new Venue(); + venue.setCity(new City()); + } + } + + public void newVenue(ActionEvent event) { + this.venue = new Venue(); + this.venue.setCity(new City()); + } + + public void saveVenue(ActionEvent evt) { + try { + // lookup existing city + City city = countryService.findCity(venue.getCity().getName(), venue.getProvinceState()); + if (city == null) { + venue.getCity().setProvinceState(venue.getProvinceState()); + } else { + venue.setCity(city); + } + venueService.saveVenue(venue); + FacesMessage msg = new FacesMessage(); + msg.setDetail("The venue has been saved!"); + msg.setSeverity(FacesMessage.SEVERITY_INFO); + String id = evt.getComponent().getClientId(); + FacesContext.getCurrentInstance().addMessage(id, msg); + } catch (Exception e) { + FacesMessage msg = new FacesMessage(); + msg.setDetail("Failed to save venue: " + e.getMessage()); + msg.setSeverity(FacesMessage.SEVERITY_ERROR); + FacesContext.getCurrentInstance().addMessage(null, msg); + } + } + + public void setCountryService(CountryService countryService) { + this.countryService = countryService; + } + + public void setVenue(Venue venue) { + this.venue = venue; + } + + public void setVenueService(VenueService venueService) { + this.venueService = venueService; + } + + public void venueSelected(ValueChangeEvent evt) { + } +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/convert/CityConverter.java b/primefaces-webapp/src/main/java/com/mycompany/convert/CityConverter.java new file mode 100644 index 0000000..9d4378a --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/convert/CityConverter.java @@ -0,0 +1,64 @@ +/* + * 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.convert; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; +import javax.faces.convert.Converter; +import javax.faces.convert.FacesConverter; + +import com.mycompany.model.City; +import com.mycompany.service.CountryService; +import com.mycompany.util.FacesUtils; + +/** + * Converter for {@link City} objects. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +@FacesConverter(forClass = City.class) +public class CityConverter implements Converter { + + @Override + public Object getAsObject(FacesContext context, UIComponent component, String value) { + if (value == null) { + return null; + } + CountryService service = (CountryService) FacesUtils.getManagedBean("countryService"); + return service.findCityById(Integer.valueOf(value)); + } + + @Override + public String getAsString(FacesContext context, UIComponent component, Object value) { + if (value instanceof City) { + return String.valueOf(((City) value).getId()); + } else if (value instanceof String) { + return ((String) value); + } + return null; + } + +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/convert/CountryConverter.java b/primefaces-webapp/src/main/java/com/mycompany/convert/CountryConverter.java new file mode 100644 index 0000000..8f1a674 --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/convert/CountryConverter.java @@ -0,0 +1,64 @@ +/* + * 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.convert; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; +import javax.faces.convert.Converter; +import javax.faces.convert.FacesConverter; + +import com.mycompany.model.Country; +import com.mycompany.service.CountryService; +import com.mycompany.util.FacesUtils; + +/** + * Converter class for {@link Country} objects. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +@FacesConverter(forClass = Country.class) +public class CountryConverter implements Converter { + + @Override + public Object getAsObject(FacesContext context, UIComponent component, String value) { + if (value == null) { + return null; + } + CountryService service = (CountryService) FacesUtils.getManagedBean("countryService"); + return service.findCountryById(Integer.valueOf(value)); + } + + @Override + public String getAsString(FacesContext context, UIComponent component, Object value) { + if (value instanceof Country) { + return String.valueOf(((Country) value).getId()); + } else if (value instanceof String) { + return ((String) value); + } + return null; + } + +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/convert/EditableStateConverter.java b/primefaces-webapp/src/main/java/com/mycompany/convert/EditableStateConverter.java new file mode 100644 index 0000000..0d5f2bd --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/convert/EditableStateConverter.java @@ -0,0 +1,77 @@ +/* + * 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.convert; + +import javax.faces.component.UIComponent; +import javax.faces.component.UIParameter; +import javax.faces.context.FacesContext; +import javax.faces.convert.Converter; +import javax.faces.convert.FacesConverter; + +import com.mycompany.model.Country; +import com.mycompany.model.ProvinceState; +import com.mycompany.service.CountryService; +import com.mycompany.util.FacesUtils; + +/** + * Converter object for editable {@link ProvinceState} objects. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +@FacesConverter(forClass = ProvinceState.class, + value = "mycompany.EditableStateConverter") +public class EditableStateConverter implements Converter { + + @Override + public Object getAsObject(FacesContext context, UIComponent component, String value) { + if (value == null) { + return null; + } + ProvinceState state = null; + UIParameter param = (UIParameter) component.findComponent("countryParam"); + if (param != null) { + // lookup existing state by country and name + Country country = (Country) param.getValue(); + CountryService service = (CountryService) FacesUtils.getManagedBean("countryService"); + state = service.findStateByName(country, value); + if (state == null) { + // create new state if it does not exist + state = service.createProvinceState(country, value); + } + } + return state; + } + + @Override + public String getAsString(FacesContext context, UIComponent component, Object value) { + if (value instanceof ProvinceState) { + return ((ProvinceState) value).getName(); + } else if (value instanceof String) { + return ((String) value); + } + return null; + } +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/convert/StateConverter.java b/primefaces-webapp/src/main/java/com/mycompany/convert/StateConverter.java new file mode 100644 index 0000000..365eed7 --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/convert/StateConverter.java @@ -0,0 +1,63 @@ +/* + * 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.convert; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; +import javax.faces.convert.Converter; +import javax.faces.convert.FacesConverter; + +import com.mycompany.model.ProvinceState; +import com.mycompany.service.CountryService; +import com.mycompany.util.FacesUtils; + +/** + * Converter class for {@link ProvinceState} objects. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +@FacesConverter(forClass = ProvinceState.class) +public class StateConverter implements Converter { + + @Override + public Object getAsObject(FacesContext context, UIComponent component, String value) { + if (value == null) { + return null; + } + CountryService service = (CountryService) FacesUtils.getManagedBean("countryService"); + return service.findStateById(Integer.valueOf(value)); + } + + @Override + public String getAsString(FacesContext context, UIComponent component, Object value) { + if (value instanceof ProvinceState) { + return String.valueOf(((ProvinceState) value).getId()); + } else if (value instanceof String) { + return ((String) value); + } + return null; + } +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/convert/UserConverter.java b/primefaces-webapp/src/main/java/com/mycompany/convert/UserConverter.java new file mode 100644 index 0000000..2b483b4 --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/convert/UserConverter.java @@ -0,0 +1,64 @@ +/* + * 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.convert; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; +import javax.faces.convert.Converter; +import javax.faces.convert.FacesConverter; + +import com.mycompany.model.User; +import com.mycompany.service.UserService; +import com.mycompany.util.FacesUtils; + +/** + * Converter class for {@link User} objects. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +@FacesConverter(forClass = User.class) +public class UserConverter implements Converter { + + @Override + public Object getAsObject(FacesContext context, UIComponent component, String value) { + if (value == null) { + return null; + } + UserService service = (UserService) FacesUtils.getManagedBean("userService"); + return service.findUserById(Integer.valueOf(value)); + } + + @Override + public String getAsString(FacesContext context, UIComponent component, Object value) { + if (value instanceof User) { + return String.valueOf(((User) value).getId()); + } else if (value instanceof String) { + return ((String) value); + } + return null; + } + +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/convert/VenueConverter.java b/primefaces-webapp/src/main/java/com/mycompany/convert/VenueConverter.java new file mode 100644 index 0000000..9e0b5c2 --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/convert/VenueConverter.java @@ -0,0 +1,64 @@ +/* + * 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.convert; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; +import javax.faces.convert.Converter; +import javax.faces.convert.FacesConverter; + +import com.mycompany.model.Venue; +import com.mycompany.service.VenueService; +import com.mycompany.util.FacesUtils; + +/** + * Converter class for {@link Venue} objects. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +@FacesConverter(forClass = Venue.class) +public class VenueConverter implements Converter { + + @Override + public Object getAsObject(FacesContext context, UIComponent component, String value) { + if (value == null) { + return null; + } + VenueService service = (VenueService) FacesUtils.getManagedBean("venueService"); + return service.findVenueById(Integer.valueOf(value)); + } + + @Override + public String getAsString(FacesContext context, UIComponent component, Object value) { + if (value instanceof Venue) { + return String.valueOf(((Venue) value).getId()); + } else if (value instanceof String) { + return ((String) value); + } + return null; + } + +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/lifecycle/ConversationExceptionFilter.java b/primefaces-webapp/src/main/java/com/mycompany/lifecycle/ConversationExceptionFilter.java new file mode 100644 index 0000000..f728bb5 --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/lifecycle/ConversationExceptionFilter.java @@ -0,0 +1,111 @@ +/* + * 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.lifecycle; + +import java.io.IOException; +import java.util.Collections; +import java.util.Enumeration; +import java.util.Map; + +import javax.enterprise.context.NonexistentConversationException; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.annotation.WebFilter; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import javax.servlet.http.HttpServletResponse; + +/** + * + * This filter handles the {@link NonexistentConversationException) propagating + * from CDI for requests containing an invalid conversation ID (cid parameter). + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +@WebFilter("/*") +public class ConversationExceptionFilter implements Filter { + + private class ConversationAwareRequestWrapper extends HttpServletRequestWrapper { + + public ConversationAwareRequestWrapper(HttpServletRequest request) { + super(request); + } + + @Override + public String getParameter(String name) { + if ("cid".equals(name)) { + return null; + } + return super.getParameter(name); + } + + @Override + public Map getParameterMap() { + Map map = super.getParameterMap(); + map.remove("cid"); + return map; + } + + @Override + public Enumeration getParameterNames() { + return Collections.enumeration(getParameterMap().keySet()); + } + + } + + @Override + public void destroy() { + } + + @Override + public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) + throws IOException, ServletException { + HttpServletRequest request = (HttpServletRequest) req; + HttpServletResponse response = (HttpServletResponse) res; + try { + chain.doFilter(request, response); + } catch (ServletException e) { + if (e.getCause() instanceof NonexistentConversationException) { + HttpServletRequestWrapper wrapper = new ConversationAwareRequestWrapper(request); + String context = request.getContextPath(); + String viewId = request.getRequestURI(); + String path = viewId.replaceFirst(context, ""); + request.getRequestDispatcher(path).forward(wrapper, res); + } else { + throw e; + } + } + } + + @Override + public void init(FilterConfig arg0) throws ServletException { + } + +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/lifecycle/Destroyed.java b/primefaces-webapp/src/main/java/com/mycompany/lifecycle/Destroyed.java new file mode 100644 index 0000000..cc7325b --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/lifecycle/Destroyed.java @@ -0,0 +1,42 @@ +/* + * 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.lifecycle; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.inject.Qualifier; + +/** + * Thanks to Dan Allen for this useful code: https://gist.github.com/637959 + * + */ +@Qualifier +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.FIELD, ElementType.PARAMETER }) +public @interface Destroyed { +} \ No newline at end of file diff --git a/primefaces-webapp/src/main/java/com/mycompany/lifecycle/Initialized.java b/primefaces-webapp/src/main/java/com/mycompany/lifecycle/Initialized.java new file mode 100644 index 0000000..86226d3 --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/lifecycle/Initialized.java @@ -0,0 +1,42 @@ +/* + * 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.lifecycle; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.inject.Qualifier; + +/** + * Thanks to Dan Allen for this useful code: https://gist.github.com/637959 + * + */ +@Qualifier +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.FIELD, ElementType.PARAMETER }) +public @interface Initialized { +} \ No newline at end of file diff --git a/primefaces-webapp/src/main/java/com/mycompany/lifecycle/SecurityPhaseListener.java b/primefaces-webapp/src/main/java/com/mycompany/lifecycle/SecurityPhaseListener.java new file mode 100644 index 0000000..99b1a13 --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/lifecycle/SecurityPhaseListener.java @@ -0,0 +1,88 @@ +/* + * 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.lifecycle; + +import javax.faces.component.UIViewRoot; +import javax.faces.context.FacesContext; +import javax.faces.event.PhaseEvent; +import javax.faces.event.PhaseId; +import javax.faces.event.PhaseListener; + +import com.mycompany.controller.LoginController; + +/** + * PhaseListener class that handles authorization for protected views. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +public class SecurityPhaseListener implements PhaseListener { + + /** + * + */ + private static final long serialVersionUID = -1013239137374622294L; + + @Override + public void afterPhase(PhaseEvent event) { + + // eagerly create session due to JAVASERVERFACES-2215 + FacesContext context = FacesContext.getCurrentInstance(); + context.getExternalContext().getSession(true); + + // check if view is protected + UIViewRoot view = context.getViewRoot(); + if (view != null) { + String viewId = view.getViewId(); + boolean authenticationRequired = viewId.contains("/protected/"); + boolean loggedIn = isLoggedIn(); + if (authenticationRequired && !loggedIn) { + // send user to login page if not logged in + context.getApplication() + .getNavigationHandler() + .handleNavigation(context, null, "login"); + } + } + } + + @Override + public void beforePhase(PhaseEvent event) { + } + + @Override + public PhaseId getPhaseId() { + return PhaseId.RESTORE_VIEW; + } + + private boolean isLoggedIn() { + boolean loggedIn = false; + FacesContext ctx = FacesContext.getCurrentInstance(); + LoginController controller = (LoginController) ctx.getApplication().evaluateExpressionGet( + ctx, "#{loginController}", Object.class); + loggedIn = controller.isLoggedIn(); + return loggedIn; + } + +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/lifecycle/ServletContextLifecycleNotifier.java b/primefaces-webapp/src/main/java/com/mycompany/lifecycle/ServletContextLifecycleNotifier.java new file mode 100644 index 0000000..1b36259 --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/lifecycle/ServletContextLifecycleNotifier.java @@ -0,0 +1,58 @@ +/* + * 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.lifecycle; + +import javax.enterprise.event.Event; +import javax.enterprise.inject.Any; +import javax.enterprise.util.AnnotationLiteral; +import javax.inject.Inject; +import javax.servlet.ServletContext; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; +import javax.servlet.annotation.WebListener; + +/** + * Thanks to Dan Allen for this useful code: https://gist.github.com/637959 + * + */ +@WebListener +public class ServletContextLifecycleNotifier implements ServletContextListener { + + @Inject + @Any + private Event servletContextEvent; + + @Override + public void contextInitialized(ServletContextEvent sce) { + servletContextEvent.select(new AnnotationLiteral() { + }).fire(sce.getServletContext()); + } + + @Override + public void contextDestroyed(ServletContextEvent sce) { + servletContextEvent.select(new AnnotationLiteral() { + }).fire(sce.getServletContext()); + } +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/model/AbstractEntity.java b/primefaces-webapp/src/main/java/com/mycompany/model/AbstractEntity.java new file mode 100644 index 0000000..94a9803 --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/model/AbstractEntity.java @@ -0,0 +1,88 @@ +/* + * 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.model; + +import java.io.Serializable; + +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; +import javax.persistence.MappedSuperclass; +import javax.persistence.Version; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +/** + * Abstract class for JPA entities. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +@MappedSuperclass +@Inheritance(strategy = InheritanceType.JOINED) +public abstract class AbstractEntity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = -489637051819304520L; + + private Integer id; + + private Integer version; + + @Override + public boolean equals(Object object) { + return EqualsBuilder.reflectionEquals(this, object); + } + + @Id + @GeneratedValue(strategy = GenerationType.TABLE) + public Integer getId() { + return id; + } + + @Version + public Integer getVersion() { + return version; + } + + @Override + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this); + } + + public void setId(Integer id) { + this.id = id; + } + + public void setVersion(Integer version) { + this.version = version; + } + +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/model/AbstractEntity_.java b/primefaces-webapp/src/main/java/com/mycompany/model/AbstractEntity_.java new file mode 100644 index 0000000..f706cdf --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/model/AbstractEntity_.java @@ -0,0 +1,14 @@ +package com.mycompany.model; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; + +@StaticMetamodel(AbstractEntity.class) +public abstract class AbstractEntity_ { + + public static volatile SingularAttribute id; + public static volatile SingularAttribute hashCode; + public static volatile SingularAttribute version; + +} + diff --git a/primefaces-webapp/src/main/java/com/mycompany/model/ActiveUsers.java b/primefaces-webapp/src/main/java/com/mycompany/model/ActiveUsers.java new file mode 100644 index 0000000..2bc520c --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/model/ActiveUsers.java @@ -0,0 +1,48 @@ +/* + * 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.model; + +import java.util.ArrayList; + +import javax.faces.bean.ApplicationScoped; +import javax.faces.bean.ManagedBean; + +/** + * Application-scoped JSF managed bean storing {@link User} objects for presence + * purposes. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +@ManagedBean +@ApplicationScoped +public class ActiveUsers extends ArrayList { + + /** + * + */ + private static final long serialVersionUID = -3068333669859836249L; + +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/model/City.java b/primefaces-webapp/src/main/java/com/mycompany/model/City.java new file mode 100644 index 0000000..31471ce --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/model/City.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.model; + +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.ManyToOne; +import javax.persistence.NamedQueries; +import javax.persistence.NamedQuery; + +import com.mycompany.util.Queries; + +/** + * JPA entity class for city data. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +@Entity +@NamedQueries(@NamedQuery( name = Queries.CITY_FIND_BY_NAME_AND_PROVINCE_STATE, + query = "select c from City c where c.name = ?1 and c.provinceState = ?2")) +public class City extends AbstractEntity { + + /** + * + */ + private static final long serialVersionUID = -1124357744815785459L; + + private Double latitude; + + private Double longitude; + + private String name; + + private ProvinceState provinceState; + + public Double getLatitude() { + return latitude; + } + + public Double getLongitude() { + return longitude; + } + + public String getName() { + return name; + } + + @ManyToOne(fetch = FetchType.EAGER) + public ProvinceState getProvinceState() { + return provinceState; + } + + public void setLatitude(Double latitude) { + this.latitude = latitude; + } + + public void setLongitude(Double longitude) { + this.longitude = longitude; + } + + public void setName(String name) { + this.name = name; + } + + public void setProvinceState(ProvinceState state) { + this.provinceState = state; + } +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/model/City_.java b/primefaces-webapp/src/main/java/com/mycompany/model/City_.java new file mode 100644 index 0000000..506dc06 --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/model/City_.java @@ -0,0 +1,15 @@ +package com.mycompany.model; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; + +@StaticMetamodel(City.class) +public abstract class City_ extends com.mycompany.model.AbstractEntity_ { + + public static volatile SingularAttribute provinceState; + public static volatile SingularAttribute name; + public static volatile SingularAttribute longitude; + public static volatile SingularAttribute latitude; + +} + diff --git a/primefaces-webapp/src/main/java/com/mycompany/model/Content.java b/primefaces-webapp/src/main/java/com/mycompany/model/Content.java new file mode 100644 index 0000000..d8d580b --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/model/Content.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.model; + +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.ManyToOne; +import javax.persistence.NamedQueries; +import javax.persistence.NamedQuery; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.persistence.UniqueConstraint; + +import com.mycompany.util.Queries; + +/** + * JPA entity for content data. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +@Entity +@Table(uniqueConstraints = @UniqueConstraint(columnNames = "viewid")) +@NamedQueries(@NamedQuery( name = Queries.CONTENT_FIND_BY_NAME, + query = "select c from Content c where c.viewId=?1")) +public class Content extends AbstractEntity { + + /** + * + */ + private static final long serialVersionUID = 5714237132670562107L; + + private User createdBy; + + private Date createdDate; + + private String viewId; + + private String value; + + @ManyToOne + public User getCreatedBy() { + return createdBy; + } + + @Temporal(TemporalType.TIMESTAMP) + public Date getCreatedDate() { + return createdDate; + } + + public String getViewId() { + return viewId; + } + + @Column(columnDefinition = "TEXT") + public String getValue() { + return value; + } + + public void setCreatedBy(User createdBy) { + this.createdBy = createdBy; + } + + public void setCreatedDate(Date createdDate) { + this.createdDate = createdDate; + } + + public void setViewId(String name) { + this.viewId = name; + } + + public void setValue(String value) { + this.value = value; + } + +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/model/Content_.java b/primefaces-webapp/src/main/java/com/mycompany/model/Content_.java new file mode 100644 index 0000000..a8a845a --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/model/Content_.java @@ -0,0 +1,16 @@ +package com.mycompany.model; + +import java.util.Date; +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; + +@StaticMetamodel(Content.class) +public abstract class Content_ extends com.mycompany.model.AbstractEntity_ { + + public static volatile SingularAttribute createdBy; + public static volatile SingularAttribute value; + public static volatile SingularAttribute createdDate; + public static volatile SingularAttribute viewId; + +} + diff --git a/primefaces-webapp/src/main/java/com/mycompany/model/Country.java b/primefaces-webapp/src/main/java/com/mycompany/model/Country.java new file mode 100644 index 0000000..bd43e96 --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/model/Country.java @@ -0,0 +1,103 @@ +/* + * 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.model; + +import java.util.HashSet; +import java.util.Set; + +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.NamedQueries; +import javax.persistence.NamedQuery; +import javax.persistence.OneToMany; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +import com.mycompany.util.Queries; + +/** + * JPA entity for country data. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +@Entity +@NamedQueries({ @NamedQuery(name = Queries.COUNTRY_FIND_BY_CODE, + query = "select c from Country c where c.code = ?1"), + @NamedQuery(name = Queries.COUNTRY_FIND_ALL, + query = "select c from Country c order by c.name") }) +public class Country extends AbstractEntity { + + private static final String[] excludeFields = new String[] { "provinceStates" }; + + /** + * + */ + private static final long serialVersionUID = -4925972235656394450L; + + private String code; + + private String name; + + private Set provinceStates = new HashSet(); + + @Override + public boolean equals(Object object) { + return EqualsBuilder.reflectionEquals(this, object, excludeFields); + } + + public String getCode() { + return code; + } + + public String getName() { + return name; + } + + @OneToMany( mappedBy = "country", + fetch = FetchType.EAGER) + public Set getProvinceStates() { + return provinceStates; + } + + @Override + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this, excludeFields); + } + + public void setCode(String code) { + this.code = code; + } + + public void setName(String name) { + this.name = name; + } + + public void setProvinceStates(Set states) { + this.provinceStates = states; + } + +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/model/Country_.java b/primefaces-webapp/src/main/java/com/mycompany/model/Country_.java new file mode 100644 index 0000000..596c0de --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/model/Country_.java @@ -0,0 +1,16 @@ +package com.mycompany.model; + +import javax.persistence.metamodel.SetAttribute; +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; + +@StaticMetamodel(Country.class) +public abstract class Country_ extends com.mycompany.model.AbstractEntity_ { + + public static volatile SetAttribute provinceStates; + public static volatile SingularAttribute name; + public static volatile SingularAttribute hashCode; + public static volatile SingularAttribute code; + +} + diff --git a/primefaces-webapp/src/main/java/com/mycompany/model/Credentials.java b/primefaces-webapp/src/main/java/com/mycompany/model/Credentials.java new file mode 100644 index 0000000..030907f --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/model/Credentials.java @@ -0,0 +1,58 @@ +/* + * 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.model; + +import javax.enterprise.inject.Model; + +/** + * CDI-managed bean in request scope for user credentials. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +@Model +public class Credentials { + + private String password; + + private String username; + + public String getPassword() { + return password; + } + + public String getUsername() { + return username; + } + + public void setPassword(String password) { + this.password = password; + } + + public void setUsername(String username) { + this.username = username; + } + +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/model/Event.java b/primefaces-webapp/src/main/java/com/mycompany/model/Event.java new file mode 100644 index 0000000..c3274fc --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/model/Event.java @@ -0,0 +1,162 @@ +/* + * 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.model; + +import java.util.Date; +import java.util.HashSet; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.ManyToOne; +import javax.persistence.NamedQueries; +import javax.persistence.NamedQuery; +import javax.persistence.OneToMany; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +import com.mycompany.util.Queries; + +/** + * JPA entity for event data. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +@Entity +@NamedQueries(@NamedQuery( name = Queries.EVENT_FIND_ALL, + query = "select e from Event e order by e.startDate desc")) +public class Event extends AbstractEntity { + + private static final String[] excludedFields = new String[] { "attendance" }; + + /** + * + */ + private static final long serialVersionUID = 1853185041344918956L; + + private Set attendance = new HashSet(); + + private User createdBy; + + private String description; + + private Date endDate; + + private EventType eventType; + + private Date startDate; + + private String title; + + private Venue venue; + + @Override + public boolean equals(Object object) { + return EqualsBuilder.reflectionEquals(this, object, excludedFields); + } + + @OneToMany( cascade = CascadeType.REMOVE, + mappedBy = "event") + public Set getAttendance() { + return attendance; + } + + @ManyToOne + public User getCreatedBy() { + return createdBy; + } + + public String getDescription() { + return description; + } + + @Temporal(TemporalType.TIMESTAMP) + public Date getEndDate() { + return endDate; + } + + @Enumerated(EnumType.STRING) + public EventType getEventType() { + return eventType; + } + + @Temporal(TemporalType.TIMESTAMP) + public Date getStartDate() { + return startDate; + } + + public String getTitle() { + return title; + } + + @ManyToOne + public Venue getVenue() { + return venue; + } + + @Override + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this, excludedFields); + } + + public void setAttendance(Set usersAttended) { + this.attendance = usersAttended; + } + + public void setCreatedBy(User createdBy) { + this.createdBy = createdBy; + } + + public void setDescription(String description) { + this.description = description; + } + + public void setEndDate(Date endDate) { + this.endDate = endDate; + } + + public void setEventType(EventType eventType) { + this.eventType = eventType; + } + + public void setStartDate(Date startDate) { + this.startDate = startDate; + } + + public void setTitle(String title) { + this.title = title; + } + + public void setVenue(Venue venue) { + this.venue = venue; + } + +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/model/EventAttendance.java b/primefaces-webapp/src/main/java/com/mycompany/model/EventAttendance.java new file mode 100644 index 0000000..0b9304b --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/model/EventAttendance.java @@ -0,0 +1,100 @@ +/* + * 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.model; + +import javax.persistence.Entity; +import javax.persistence.ManyToOne; +import javax.persistence.NamedQueries; +import javax.persistence.NamedQuery; +import javax.persistence.Table; +import javax.persistence.UniqueConstraint; + +import com.mycompany.util.Queries; + +/** + * JPA entity for user event attendance data. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +@Entity +@Table(uniqueConstraints = @UniqueConstraint(columnNames = { "event", "user" })) +@NamedQueries({ + @NamedQuery(name = Queries.EVENT_ATTENDANCE_FIND_BY_USER_AND_EVENT, + query = "select e from EventAttendance e where e.user = ?1 and e.event = ?2"), + @NamedQuery(name = Queries.EVENT_ATTENDANCE_FIND_BY_USER, + query = "select e from EventAttendance e where e.user = ?1 order by e.event.startDate desc"), + @NamedQuery(name = Queries.EVENT_ATTENDANCE_FIND_GENDER_COUNT_BY_EVENT, + query = "select e.event.startDate, count(e.user.gender) from EventAttendance e where e.user.gender = ?1 and e.confirmed is true group by e.event order by e.event.startDate ") }) +public class EventAttendance extends AbstractEntity { + + /** + * + */ + private static final long serialVersionUID = -4351135973935030713L; + + private boolean confirmed; + + private Event event; + + private int rating; + + private User user; + + @ManyToOne + public Event getEvent() { + return event; + } + + public int getRating() { + return rating; + } + + @ManyToOne + public User getUser() { + return user; + } + + public boolean isConfirmed() { + return confirmed; + } + + public void setConfirmed(boolean attended) { + this.confirmed = attended; + } + + public void setEvent(Event event) { + this.event = event; + } + + public void setRating(int rating) { + this.rating = rating; + } + + public void setUser(User user) { + this.user = user; + } + +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/model/EventAttendance_.java b/primefaces-webapp/src/main/java/com/mycompany/model/EventAttendance_.java new file mode 100644 index 0000000..b3cbbc6 --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/model/EventAttendance_.java @@ -0,0 +1,15 @@ +package com.mycompany.model; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; + +@StaticMetamodel(EventAttendance.class) +public abstract class EventAttendance_ extends com.mycompany.model.AbstractEntity_ { + + public static volatile SingularAttribute confirmed; + public static volatile SingularAttribute event; + public static volatile SingularAttribute rating; + public static volatile SingularAttribute user; + +} + diff --git a/primefaces-webapp/src/main/java/com/mycompany/model/EventType.java b/primefaces-webapp/src/main/java/com/mycompany/model/EventType.java new file mode 100644 index 0000000..9ad4a29 --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/model/EventType.java @@ -0,0 +1,47 @@ +/* + * 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.model; + +/** + * Represents an event type. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +public enum EventType { + + CONCERT("Concert"), MOVIE("Movie"), OTHER("Other"); + + private String label; + + private EventType(String label) { + this.label = label; + } + + public String getLabel() { + return label; + } + +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/model/Event_.java b/primefaces-webapp/src/main/java/com/mycompany/model/Event_.java new file mode 100644 index 0000000..387da14 --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/model/Event_.java @@ -0,0 +1,22 @@ +package com.mycompany.model; + +import java.util.Date; +import javax.persistence.metamodel.SetAttribute; +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; + +@StaticMetamodel(Event.class) +public abstract class Event_ extends com.mycompany.model.AbstractEntity_ { + + public static volatile SingularAttribute startDate; + public static volatile SingularAttribute title; + public static volatile SingularAttribute createdBy; + public static volatile SingularAttribute description; + public static volatile SetAttribute attendance; + public static volatile SingularAttribute hashCode; + public static volatile SingularAttribute endDate; + public static volatile SingularAttribute eventType; + public static volatile SingularAttribute venue; + +} + diff --git a/primefaces-webapp/src/main/java/com/mycompany/model/Gender.java b/primefaces-webapp/src/main/java/com/mycompany/model/Gender.java new file mode 100644 index 0000000..10560e5 --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/model/Gender.java @@ -0,0 +1,47 @@ +/* + * 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.model; + +/** + * Represents a gender. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +public enum Gender { + + FEMALE("Female"), MALE("Male"); + + private String label; + + private Gender(String label) { + this.label = label; + } + + public String getLabel() { + return label; + } + +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/model/Idea.java b/primefaces-webapp/src/main/java/com/mycompany/model/Idea.java new file mode 100644 index 0000000..68a1140 --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/model/Idea.java @@ -0,0 +1,119 @@ +/* + * 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.model; + +import java.util.HashSet; +import java.util.Set; + +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +/** + * JPA entity for mind map data. This class is self-referencing and has a + * hierarchical parent-child relationship so an idea can have any number of + * sub-ideas. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +@Entity +public class Idea extends AbstractEntity { + + private static final String[] excludeFields = new String[] { "parent", "children" }; + + /** + * + */ + private static final long serialVersionUID = -5778367117092282684L; + + private User author; + + private Set children = new HashSet(); + + private String description; + + private String name; + + private Idea parent; + + @Override + public boolean equals(Object object) { + return EqualsBuilder.reflectionEquals(this, object, excludeFields); + } + + @ManyToOne + public User getAuthor() { + return author; + } + + @OneToMany( mappedBy = "parent", + fetch = FetchType.LAZY) + public Set getChildren() { + return children; + } + + public String getDescription() { + return description; + } + + public String getName() { + return name; + } + + @ManyToOne + public Idea getParent() { + return parent; + } + + @Override + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this, excludeFields); + } + + public void setAuthor(User author) { + this.author = author; + } + + public void setChildren(Set children) { + this.children = children; + } + + public void setDescription(String description) { + this.description = description; + } + + public void setName(String name) { + this.name = name; + } + + public void setParent(Idea parent) { + this.parent = parent; + } +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/model/Idea_.java b/primefaces-webapp/src/main/java/com/mycompany/model/Idea_.java new file mode 100644 index 0000000..a86f4f7 --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/model/Idea_.java @@ -0,0 +1,18 @@ +package com.mycompany.model; + +import javax.persistence.metamodel.SetAttribute; +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; + +@StaticMetamodel(Idea.class) +public abstract class Idea_ extends com.mycompany.model.AbstractEntity_ { + + public static volatile SingularAttribute author; + public static volatile SingularAttribute description; + public static volatile SingularAttribute name; + public static volatile SingularAttribute hashCode; + public static volatile SingularAttribute parent; + public static volatile SetAttribute children; + +} + diff --git a/primefaces-webapp/src/main/java/com/mycompany/model/ProvinceState.java b/primefaces-webapp/src/main/java/com/mycompany/model/ProvinceState.java new file mode 100644 index 0000000..24b008a --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/model/ProvinceState.java @@ -0,0 +1,94 @@ +/* + * 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.model; + +import java.util.HashSet; +import java.util.Set; + +import javax.persistence.Entity; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +/** + * JPA entity for province/state data. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +@Entity +public class ProvinceState extends AbstractEntity { + + private static final String[] excludeFields = new String[] { "cities" }; + + /** + * + */ + private static final long serialVersionUID = 5984616633801173028L; + + private Set cities = new HashSet(); + + private Country country; + + private String name; + + @Override + public boolean equals(Object object) { + return EqualsBuilder.reflectionEquals(this, object, excludeFields); + } + + @OneToMany(mappedBy = "provinceState") + public Set getCities() { + return cities; + } + + @ManyToOne + public Country getCountry() { + return country; + } + + public String getName() { + return name; + } + + @Override + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this, excludeFields); + } + + public void setCities(Set cities) { + this.cities = cities; + } + + public void setCountry(Country country) { + this.country = country; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/model/ProvinceState_.java b/primefaces-webapp/src/main/java/com/mycompany/model/ProvinceState_.java new file mode 100644 index 0000000..223ab66 --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/model/ProvinceState_.java @@ -0,0 +1,16 @@ +package com.mycompany.model; + +import javax.persistence.metamodel.SetAttribute; +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; + +@StaticMetamodel(ProvinceState.class) +public abstract class ProvinceState_ extends com.mycompany.model.AbstractEntity_ { + + public static volatile SetAttribute cities; + public static volatile SingularAttribute name; + public static volatile SingularAttribute hashCode; + public static volatile SingularAttribute country; + +} + diff --git a/primefaces-webapp/src/main/java/com/mycompany/model/RelationshipType.java b/primefaces-webapp/src/main/java/com/mycompany/model/RelationshipType.java new file mode 100644 index 0000000..b1ed719 --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/model/RelationshipType.java @@ -0,0 +1,47 @@ +/* + * 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.model; + +/** + * Represents a relationship type. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +public enum RelationshipType { + + FAMILY("Family"), FRIEND("Friend"), COLLEAGUE("Colleague"); + + private String label; + + private RelationshipType(String label) { + this.label = label; + } + + public String getLabel() { + return label; + } + +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/model/User.java b/primefaces-webapp/src/main/java/com/mycompany/model/User.java new file mode 100644 index 0000000..3fcc998 --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/model/User.java @@ -0,0 +1,243 @@ +/* + * 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.model; + +import java.util.Date; +import java.util.HashSet; +import java.util.Set; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.ManyToOne; +import javax.persistence.NamedQueries; +import javax.persistence.NamedQuery; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.persistence.UniqueConstraint; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +import com.mycompany.util.Queries; + +/** + * JPA entity for user data. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +@Entity +@Table( name = "USERS", + uniqueConstraints = { @UniqueConstraint(columnNames = "username"), + @UniqueConstraint(columnNames = "emailaddress") }) +@NamedQueries({ + @NamedQuery(name = Queries.USER_FIND_BY_USERNAME_PASSWORD, + query = "select u from User u where u.username=?1 and u.password=?2"), + @NamedQuery(name = Queries.USER_FIND_BY_RELATIONSHIP_TYPE, + query = "select r.toUser from UserRelationship r where r.relationshipType = ?1 and r.fromUser = ?2 order by r.toUser.lastName, r.toUser.firstName"), + @NamedQuery(name = Queries.USER_FIND_BY_PARTIAL_NAME, + query = "select u from User u where u.firstName like :name or u.lastName like :name order by u.firstName, u.lastName") }) +public class User extends AbstractEntity { + + private static final String[] excludedFields = new String[] { "fromRelationships", + "toRelationships", "eventsAttended" }; + + /** + * + */ + private static final long serialVersionUID = 8009394076089033693L; + + private boolean acceptedTerms; + + private Date birthdate; + + private Integer clickCount; + + private Country country; + + private String emailAddress; + + private Set eventsAttended = new HashSet(); + + private String firstName; + + private Set fromRelationships = new HashSet(); + + private Gender gender; + + private String lastName; + + private String password; + + private String phoneNumber; + + private String theme; + + private Set toRelationships = new HashSet(); + + private String username; + + @Override + public boolean equals(Object object) { + return EqualsBuilder.reflectionEquals(this, object, excludedFields); + } + + @Temporal(TemporalType.DATE) + public Date getBirthdate() { + return birthdate; + } + + public Integer getClickCount() { + return clickCount; + } + + @ManyToOne + public Country getCountry() { + return country; + } + + public String getEmailAddress() { + return emailAddress; + } + + @OneToMany(mappedBy = "user") + public Set getEventsAttended() { + return eventsAttended; + } + + public String getFirstName() { + return firstName; + } + + @OneToMany(mappedBy = "fromUser") + public Set getFromRelationships() { + return fromRelationships; + } + + @Enumerated(EnumType.STRING) + public Gender getGender() { + return gender; + } + + public String getLastName() { + return lastName; + } + + public String getPassword() { + return password; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public String getTheme() { + return theme; + } + + @OneToMany(mappedBy = "toUser") + public Set getToRelationships() { + return toRelationships; + } + + public String getUsername() { + return username; + } + + @Override + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this, excludedFields); + } + + @Column(columnDefinition = "smallint not null default 0") + public boolean isAcceptedTerms() { + return acceptedTerms; + } + + public void setAcceptedTerms(boolean acceptedTerms) { + this.acceptedTerms = acceptedTerms; + } + + public void setBirthdate(Date birthdate) { + this.birthdate = birthdate; + } + + public void setClickCount(Integer clicks) { + this.clickCount = clicks; + } + + public void setCountry(Country country) { + this.country = country; + } + + public void setEmailAddress(String emailAddress) { + this.emailAddress = emailAddress; + } + + public void setEventsAttended(Set eventsAttended) { + this.eventsAttended = eventsAttended; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public void setFromRelationships(Set fromRelationships) { + this.fromRelationships = fromRelationships; + } + + public void setGender(Gender gender) { + this.gender = gender; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public void setPassword(String password) { + this.password = password; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public void setTheme(String theme) { + this.theme = theme; + } + + public void setToRelationships(Set toRelationships) { + this.toRelationships = toRelationships; + } + + public void setUsername(String username) { + this.username = username; + } + +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/model/UserRelationship.java b/primefaces-webapp/src/main/java/com/mycompany/model/UserRelationship.java new file mode 100644 index 0000000..adcd9fc --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/model/UserRelationship.java @@ -0,0 +1,83 @@ +/* + * 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.model; + +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.UniqueConstraint; + +/** + * JPA entity for a relationship between two users. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +@Entity +@Table(uniqueConstraints = @UniqueConstraint(columnNames = { "from_user", "to_user", + "relationshipType" })) +public class UserRelationship extends AbstractEntity { + + /** + * + */ + private static final long serialVersionUID = -5157091586647676960L; + + private RelationshipType relationshipType; + + private User fromUser; + + private User toUser; + + @Enumerated(EnumType.STRING) + public RelationshipType getRelationshipType() { + return relationshipType; + } + + @ManyToOne + public User getFromUser() { + return fromUser; + } + + @ManyToOne + public User getToUser() { + return toUser; + } + + public void setRelationshipType(RelationshipType contactType) { + this.relationshipType = contactType; + } + + public void setFromUser(User firstUser) { + this.fromUser = firstUser; + } + + public void setToUser(User secondUser) { + this.toUser = secondUser; + } + +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/model/UserRelationship_.java b/primefaces-webapp/src/main/java/com/mycompany/model/UserRelationship_.java new file mode 100644 index 0000000..9780702 --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/model/UserRelationship_.java @@ -0,0 +1,14 @@ +package com.mycompany.model; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; + +@StaticMetamodel(UserRelationship.class) +public abstract class UserRelationship_ extends com.mycompany.model.AbstractEntity_ { + + public static volatile SingularAttribute relationshipType; + public static volatile SingularAttribute toUser; + public static volatile SingularAttribute fromUser; + +} + diff --git a/primefaces-webapp/src/main/java/com/mycompany/model/User_.java b/primefaces-webapp/src/main/java/com/mycompany/model/User_.java new file mode 100644 index 0000000..bd4eeb9 --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/model/User_.java @@ -0,0 +1,29 @@ +package com.mycompany.model; + +import java.util.Date; +import javax.persistence.metamodel.SetAttribute; +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; + +@StaticMetamodel(User.class) +public abstract class User_ extends com.mycompany.model.AbstractEntity_ { + + public static volatile SingularAttribute acceptedTerms; + public static volatile SingularAttribute lastName; + public static volatile SingularAttribute clickCount; + public static volatile SetAttribute fromRelationships; + public static volatile SingularAttribute theme; + public static volatile SingularAttribute hashCode; + public static volatile SingularAttribute emailAddress; + public static volatile SetAttribute toRelationships; + public static volatile SingularAttribute password; + public static volatile SingularAttribute country; + public static volatile SingularAttribute username; + public static volatile SetAttribute eventsAttended; + public static volatile SingularAttribute phoneNumber; + public static volatile SingularAttribute birthdate; + public static volatile SingularAttribute gender; + public static volatile SingularAttribute firstName; + +} + diff --git a/primefaces-webapp/src/main/java/com/mycompany/model/Venue.java b/primefaces-webapp/src/main/java/com/mycompany/model/Venue.java new file mode 100644 index 0000000..6bbd4ad --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/model/Venue.java @@ -0,0 +1,180 @@ +/* + * 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.model; + +import java.util.HashSet; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Transient; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +/** + * JPA entity for venue data. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +@Entity +public class Venue extends AbstractEntity { + + private static final String[] excludedFields = new String[] { "events" }; + + /** + * + */ + private static final long serialVersionUID = 5049478213946349124L; + + private City city; + + private Country country; + + private Set events = new HashSet(); + + private Double latitude; + + private Double longitude; + + private String name; + + private String phoneNumber; + + private ProvinceState provinceState; + + private String streetAddress; + + @Override + public boolean equals(Object object) { + return EqualsBuilder.reflectionEquals(this, object, excludedFields); + } + + @ManyToOne(cascade = CascadeType.PERSIST) + public City getCity() { + return city; + } + + /** + * This method returns the complete address of the venue. + * + * @return A string. + */ + @Transient + public String getCompleteAddress() { + StringBuilder sb = new StringBuilder(); + sb.append(streetAddress); + sb.append(", "); + sb.append(city.getName()); + sb.append(", "); + sb.append(provinceState.getName()); + sb.append(", "); + sb.append(country.getName()); + return sb.toString(); + } + + @ManyToOne + public Country getCountry() { + return country; + } + + @OneToMany( cascade = CascadeType.REMOVE, + mappedBy = "venue") + public Set getEvents() { + return events; + } + + @Transient + public Double getLatitude() { + return latitude; + } + + @Transient + public Double getLongitude() { + return longitude; + } + + public String getName() { + return name; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + @ManyToOne + public ProvinceState getProvinceState() { + return provinceState; + } + + public String getStreetAddress() { + return streetAddress; + } + + @Override + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this, excludedFields); + } + + public void setCity(City city) { + this.city = city; + } + + public void setCountry(Country country) { + this.country = country; + } + + public void setEvents(Set events) { + this.events = events; + } + + public void setLatitude(Double latitude) { + this.latitude = latitude; + } + + public void setLongitude(Double longitude) { + this.longitude = longitude; + } + + public void setName(String name) { + this.name = name; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public void setProvinceState(ProvinceState state) { + this.provinceState = state; + } + + public void setStreetAddress(String streetAddress) { + this.streetAddress = streetAddress; + } + +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/model/Venue_.java b/primefaces-webapp/src/main/java/com/mycompany/model/Venue_.java new file mode 100644 index 0000000..7ae5977 --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/model/Venue_.java @@ -0,0 +1,20 @@ +package com.mycompany.model; + +import javax.persistence.metamodel.SetAttribute; +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; + +@StaticMetamodel(Venue.class) +public abstract class Venue_ extends com.mycompany.model.AbstractEntity_ { + + public static volatile SingularAttribute streetAddress; + public static volatile SingularAttribute provinceState; + public static volatile SingularAttribute phoneNumber; + public static volatile SetAttribute events; + public static volatile SingularAttribute name; + public static volatile SingularAttribute hashCode; + public static volatile SingularAttribute country; + public static volatile SingularAttribute city; + +} + diff --git a/primefaces-webapp/src/main/java/com/mycompany/service/ChartService.java b/primefaces-webapp/src/main/java/com/mycompany/service/ChartService.java new file mode 100644 index 0000000..c257c9c --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/service/ChartService.java @@ -0,0 +1,50 @@ +/* + * 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; + +import java.util.List; + +import com.mycompany.model.Gender; + +/** + * Interface for a chart service. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +public interface ChartService { + + /** + * Finds all event attendance data by gender. + * + * @param gender + * The {@link Gender} enum. + * @return A List of Object arrays. First element is the event date, second + * element is the number of people by gender who attended this + * event. + */ + List findEventAttendanceByGender(Gender gender); + +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/service/ContentService.java b/primefaces-webapp/src/main/java/com/mycompany/service/ContentService.java new file mode 100644 index 0000000..1694619 --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/service/ContentService.java @@ -0,0 +1,55 @@ +/* + * 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; + +import com.mycompany.model.Content; + +/** + * Interface for a content service. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +public interface ContentService { + + /** + * Finds a {@link Content} object by name. + * + * @param name + * The name to find. + * @return A Content object. + */ + Content findContentByName(String name); + + /** + * Saves a {@link Content} object. + * + * @param content + * The object to save. + * @return The saved object. + */ + Content saveContent(Content content); + +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/service/CountryService.java b/primefaces-webapp/src/main/java/com/mycompany/service/CountryService.java new file mode 100644 index 0000000..d6b90b5 --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/service/CountryService.java @@ -0,0 +1,150 @@ +/* + * 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; + +import java.util.List; + +import javax.enterprise.event.Observes; +import javax.servlet.ServletContext; + +import com.mycompany.lifecycle.Initialized; +import com.mycompany.model.City; +import com.mycompany.model.Country; +import com.mycompany.model.ProvinceState; + +/** + * Service class for country-related operations. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +public interface CountryService { + + /** + * Creates a {@link ProvinceState} object for a particular {@link Country}. + * + * @param country + * The Country in which the ProvinceState is located. + * @param value + * The name of the ProvinceState. + * @return The newly created ProvinceState object. + */ + ProvinceState createProvinceState(Country country, String value); + + /** + * Finds a list of {@link City} objects for the given {@link ProvinceState}. + * + * @param provinceState + * The ProvinceState object for which to find cities. + * @return A List of City objects. + */ + List findCitiesByState(ProvinceState provinceState); + + /** + * Finds a {@link City} by name in the {@link ProvinceState}. + * + * @param name + * The name of the city. + * @param provinceState + * The province/state in which to find the city. + * @return A City object. + */ + City findCity(String name, ProvinceState provinceState); + + /** + * Finds a {@link City} object by ID. + * + * @param id + * The ID of the city. + * @return A City object. + */ + City findCityById(Integer id); + + /** + * Finds a {@link Country} object by ID. + * + * @param id + * The ID of the country. + * @return A Country object. + */ + Country findCountryById(Integer id); + + /** + * Finds a {@link List} of {@link ProvinceState} objects for a particular + * {@link Country}. + * + * @param country + * The Country object. + * @return A List of ProvinceState objects. + */ + List findProvinceStatesByCountry(Country country); + + /** + * Finds a {@link ProvinceState} object by ID. + * + * @param id + * The ID of the ProvinceState object. + * @return A ProvinceState object. + */ + ProvinceState findStateById(Integer id); + + /** + * Finds a {@link ProvinceState} object by name within a particular + * {@link Country}. + * + * @param country + * The Country object. + * @param name + * The name of the ProvinceState to find. + * @return A ProvinceState object. + */ + ProvinceState findStateByName(Country country, String name); + + /** + * Returns all {@link Country} objects. + * + * @return A List of Country objects. + */ + List getCountries(); + + /** + * Returns all {@link ProvinceState} objects. + * + * @return A List of ProvinceState objects. + */ + List getProvinceStates(); + + /** + * Invoked during the {@link ServletContext} initialization to populate the + * database with sample data. + * + * @param context + * The {@link ServletContext} object. + * @throws Exception + * If something goes wrong. + */ + void init(@Observes @Initialized ServletContext context) throws Exception; + +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/service/EventService.java b/primefaces-webapp/src/main/java/com/mycompany/service/EventService.java new file mode 100644 index 0000000..0fe35ed --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/service/EventService.java @@ -0,0 +1,131 @@ +/* + * 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; + +import java.util.Date; +import java.util.List; + +import com.mycompany.model.City; +import com.mycompany.model.Event; +import com.mycompany.model.EventAttendance; +import com.mycompany.model.EventType; +import com.mycompany.model.ProvinceState; +import com.mycompany.model.User; + +/** + * Interfaces for an event service. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +public interface EventService { + + /** + * Finds all {@link Event} objects. + * + * @return A List of Event objects. + */ + List findAllEvents(); + + /** + * Finds all {@link EventAttendance} objects for a particular {@link User}. + * + * @param user + * The User object. + * @return A List of EventAttendance objects. + */ + List findAllEventsAttendanceByUser(User user); + + /** + * Finds the {@link EventAttendance} object for a particular {@link Event} + * and {@link User}. + * + * @param event + * The Event object. + * @param user + * The User object. + * @return An EventAttendance object. + */ + EventAttendance findEventAttendance(Event event, User user); + + /** + * Finds an {@link Event} by ID. + * + * @param id + * The Event ID. + * @return An Event object. + */ + Event findEventById(Integer id); + + /** + * Finds a List of {@link Event} objects in a {@link City} and + * {@link ProvinceState} for a particular {@link EventType} and keyword. + * + * @param city + * The City object. + * @param provinceState + * The ProvinceState object. + * @param eventType + * The EventType object. + * @param keyword + * A keyword. + * @return A List of Event objects. + */ + List findEvents(City city, ProvinceState provinceState, EventType eventType, + String keyword); + + /** + * Finds a List of {@link Event} objects between a start and end date + * created by a particular {@link User}. + * + * @param start + * The start date. + * @param end + * The end date. + * @param user + * The User object. + * @return A List of Event objects. + */ + List findUserEvents(Date start, Date end, User user); + + /** + * Saves an {@link EventAttendance} object. + * + * @param attendance + * The EventAttendance object. + * @return The saved object. + */ + EventAttendance saveAttendance(EventAttendance attendance); + + /** + * Saves an {@link Event}. + * + * @param event + * The Event object. + * @return The saved object. + */ + Event saveEvent(Event event); + +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/service/IdeaService.java b/primefaces-webapp/src/main/java/com/mycompany/service/IdeaService.java new file mode 100644 index 0000000..1e1d817 --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/service/IdeaService.java @@ -0,0 +1,76 @@ +/* + * 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; + +import java.util.List; + +import org.primefaces.model.mindmap.MindmapNode; + +import com.mycompany.model.Idea; + +/** + * Interface for an idea service. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +public interface IdeaService { + + /** + * Populates a mind map data structure from an {@link Idea} using the + * {@link MindmapNode} interface. + * + * @param idea + * The {@link Idea} object. + * @param root + * The root of the mind map tree. + */ + void buildMindMap(Idea idea, MindmapNode root); + + /** + * Finds an {@link Idea} by ID. + * + * @param id + * The Idea object's ID. + * @return An Idea object. + */ + Idea findIdea(Integer id); + + /** + * Finds a list of {@link Idea} objects. + * + * @return + */ + List findIdeas(); + + /** + * Saves an {@link Idea} object. + * + * @param newIdea + * The Idea to save. + * @return The saved Idea. + */ + Idea saveIdea(Idea newIdea); +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/service/UserService.java b/primefaces-webapp/src/main/java/com/mycompany/service/UserService.java new file mode 100644 index 0000000..34cde9f --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/service/UserService.java @@ -0,0 +1,130 @@ +/* + * 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; + +import java.util.List; + +import com.mycompany.model.RelationshipType; +import com.mycompany.model.User; +import com.mycompany.model.UserRelationship; + +/** + * Interface for user service. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +public interface UserService { + + /** + * Finds a {@link UserRelationship} object representing a relationship + * between two {@link User} objects. + * + * @param user1 + * The first user. + * @param user2 + * The second user. + * @return A UserRelationship object. + */ + UserRelationship findRelationshipToUser(User user1, User user2); + + /** + * Finds a {@link User} with the given username and password. Used for + * authentication. + * + * @param username + * The username. + * @param password + * The password. + * @return A User object if found. + */ + User findUser(String username, String password); + + /** + * Finds a {@link User} by ID. + * + * @param id + * The user's ID. + * @return A User object. + */ + User findUserById(Integer id); + + /** + * Finds a {@link User} by username. + * + * @param username + * The username. + * @return A User object. + */ + User findUserByUsername(String username); + + /** + * Finds a List of all {@link User} objects. + * + * @return A List of User objects. + */ + List findUsers(); + + /** + * Finds a List of {@link User} objects that have a first name or last name + * that partially matches the suggestion string. + * + * @param suggest + * The partial string. + * @return A List of User objects. + */ + List findUsersByName(String suggest); + + /** + * Finds a List of {@link User} objects that are related to the {@link User} + * according to the specified {@link RelationshipType}. + * + * @param type + * The {@link RelationshipType} object. + * @param user + * The {@link User} object. + * @return A List of {@link User} objects. + */ + List findUsersByType(RelationshipType type, User user); + + /** + * Saves a {@link UserRelationship} object. + * + * @param relationship + * The UserRelationship to save. + * @return The saved object. + */ + UserRelationship saveRelationship(UserRelationship relationship); + + /** + * Saves a {@link User} object. + * + * @param user + * The user to save. + * @return The saved object. + */ + User saveUser(User user); + +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/service/VenueService.java b/primefaces-webapp/src/main/java/com/mycompany/service/VenueService.java new file mode 100644 index 0000000..8ebe3e5 --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/service/VenueService.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; + +import java.util.List; + +import com.mycompany.model.Venue; + +/** + * Interface for a venue service. + * + * @author Ian Hlavats (ian@tarantulaconsulting.com) + * + */ +public interface VenueService { + + /** + * Deletes a {@link Venue} object. + * + * @param venue + * The Venue to delete. + */ + void deleteVenue(Venue venue); + + /** + * Finds a {@link Venue} object by ID. + * + * @param id + * The ID of the Venue. + * @return The Venue object. + */ + Venue findVenueById(Integer id); + + /** + * Finds a {@link List} of all {@link Venue} objects. + * + * @return A List of Venue objects. + */ + List findVenues(); + + /** + * Saves a {@link Venue} object. + * + * @param venue + * The Venue to save. + * @return The saved object. + */ + Venue saveVenue(Venue venue); + +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/service/impl/AbstractService.java b/primefaces-webapp/src/main/java/com/mycompany/service/impl/AbstractService.java new file mode 100644 index 0000000..4d42834 --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/service/impl/AbstractService.java @@ -0,0 +1,39 @@ +/* + * 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 javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class AbstractService { + + @PersistenceContext + protected EntityManager em; + + protected Logger logger = LoggerFactory.getLogger(getClass()); +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/service/impl/ChartServiceImpl.java b/primefaces-webapp/src/main/java/com/mycompany/service/impl/ChartServiceImpl.java new file mode 100644 index 0000000..d5c5b17 --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/service/impl/ChartServiceImpl.java @@ -0,0 +1,48 @@ +/* + * 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.Query; + +import com.mycompany.model.Gender; +import com.mycompany.service.ChartService; +import com.mycompany.util.Queries; + +@Named("chartService") +@Stateless +public class ChartServiceImpl extends AbstractService implements ChartService { + + @Override + @SuppressWarnings("unchecked") + public List findEventAttendanceByGender(Gender gender) { + Query query = em.createNamedQuery(Queries.EVENT_ATTENDANCE_FIND_GENDER_COUNT_BY_EVENT); + List genderResults = query.setParameter(1, gender).getResultList(); + return genderResults; + } +} diff --git a/primefaces-webapp/src/main/java/com/mycompany/service/impl/ContentServiceImpl.java b/primefaces-webapp/src/main/java/com/mycompany/service/impl/ContentServiceImpl.java new file mode 100644 index 0000000..5d420fa --- /dev/null +++ b/primefaces-webapp/src/main/java/com/mycompany/service/impl/ContentServiceImpl.java @@ -0,0 +1,65 @@ +/* + * 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 javax.ejb.Stateless; +import javax.inject.Named; +import javax.persistence.NoResultException; +import javax.persistence.TypedQuery; + +import com.mycompany.model.Content; +import com.mycompany.service.ContentService; +import com.mycompany.util.Queries; + +@Named("contentService") +@Stateless +public class ContentServiceImpl extends AbstractService implements ContentService { + + @Override + public Content findContentByName(String name) { + Content found = null; + try { + TypedQuery 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 @@ + + + + + <ui:insert name="title" /> + + + + + + + + +
+ +
+
+ + + + + +
+ +
+
+ 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 + + +