mirror of
https://github.com/Athou/commafeed.git
synced 2026-03-21 21:37:29 +00:00
initial commit
This commit is contained in:
12
.gitignore
vendored
Normal file
12
.gitignore
vendored
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#log files
|
||||||
|
commafeed.log
|
||||||
|
derby.log
|
||||||
|
|
||||||
|
# Maven build directory
|
||||||
|
target
|
||||||
|
|
||||||
|
# Eclipse files
|
||||||
|
.project
|
||||||
|
.classpath
|
||||||
|
.settings
|
||||||
|
.factorypath
|
||||||
5
.openshift/action_hooks/build
Normal file
5
.openshift/action_hooks/build
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# This is a simple build script and will be executed on your CI system if
|
||||||
|
# available. Otherwise it will execute while your application is stopped
|
||||||
|
# before the deploy step. This script gets executed directly, so it
|
||||||
|
# could be python, php, ruby, etc.
|
||||||
5
.openshift/action_hooks/deploy
Normal file
5
.openshift/action_hooks/deploy
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# This deploy hook gets executed after dependencies are resolved and the
|
||||||
|
# build hook has been run but before the application has been started back
|
||||||
|
# up again. This script gets executed directly, so it could be python, php,
|
||||||
|
# ruby, etc.
|
||||||
4
.openshift/action_hooks/post_deploy
Normal file
4
.openshift/action_hooks/post_deploy
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# This is a simple post deploy hook executed after your application
|
||||||
|
# is deployed and started. This script gets executed directly, so
|
||||||
|
# it could be python, php, ruby, etc.
|
||||||
14
.openshift/action_hooks/post_start_jbosseap-6.0
Normal file
14
.openshift/action_hooks/post_start_jbosseap-6.0
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# The pre_start_cartridge and pre_stop_cartridge hooks are *SOURCED*
|
||||||
|
# immediately before (re)starting or stopping the specified cartridge.
|
||||||
|
# They are able to make any desired environment variable changes as
|
||||||
|
# well as other adjustments to the application environment.
|
||||||
|
|
||||||
|
# The post_start_cartridge and post_stop_cartridge hooks are executed
|
||||||
|
# immediately after (re)starting or stopping the specified cartridge.
|
||||||
|
|
||||||
|
# Exercise caution when adding commands to these hooks. They can
|
||||||
|
# prevent your application from stopping cleanly or starting at all.
|
||||||
|
# Application start and stop is subject to different timeouts
|
||||||
|
# throughout the system.
|
||||||
14
.openshift/action_hooks/post_stop_jbosseap-6.0
Normal file
14
.openshift/action_hooks/post_stop_jbosseap-6.0
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# The pre_start_cartridge and pre_stop_cartridge hooks are *SOURCED*
|
||||||
|
# immediately before (re)starting or stopping the specified cartridge.
|
||||||
|
# They are able to make any desired environment variable changes as
|
||||||
|
# well as other adjustments to the application environment.
|
||||||
|
|
||||||
|
# The post_start_cartridge and post_stop_cartridge hooks are executed
|
||||||
|
# immediately after (re)starting or stopping the specified cartridge.
|
||||||
|
|
||||||
|
# Exercise caution when adding commands to these hooks. They can
|
||||||
|
# prevent your application from stopping cleanly or starting at all.
|
||||||
|
# Application start and stop is subject to different timeouts
|
||||||
|
# throughout the system.
|
||||||
5
.openshift/action_hooks/pre_build
Normal file
5
.openshift/action_hooks/pre_build
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# This is a simple script and will be executed on your CI system if
|
||||||
|
# available. Otherwise it will execute while your application is stopped
|
||||||
|
# before the build step. This script gets executed directly, so it
|
||||||
|
# could be python, php, ruby, etc.
|
||||||
5
.openshift/action_hooks/pre_build_jbosseap-6.0
Normal file
5
.openshift/action_hooks/pre_build_jbosseap-6.0
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# This is a simple bash script and will be sourced prior to building
|
||||||
|
# your application. This script can be used to modify the Maven build
|
||||||
|
# arguments for non-CI/Jenkins builds by exporting MAVEN_ARGS. The default
|
||||||
|
# is "clean package -Popenshift -DskipTests"
|
||||||
14
.openshift/action_hooks/pre_start_jbosseap-6.0
Normal file
14
.openshift/action_hooks/pre_start_jbosseap-6.0
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# The pre_start_cartridge and pre_stop_cartridge hooks are *SOURCED*
|
||||||
|
# immediately before (re)starting or stopping the specified cartridge.
|
||||||
|
# They are able to make any desired environment variable changes as
|
||||||
|
# well as other adjustments to the application environment.
|
||||||
|
|
||||||
|
# The post_start_cartridge and post_stop_cartridge hooks are executed
|
||||||
|
# immediately after (re)starting or stopping the specified cartridge.
|
||||||
|
|
||||||
|
# Exercise caution when adding commands to these hooks. They can
|
||||||
|
# prevent your application from stopping cleanly or starting at all.
|
||||||
|
# Application start and stop is subject to different timeouts
|
||||||
|
# throughout the system.
|
||||||
14
.openshift/action_hooks/pre_stop_jbosseap-6.0
Normal file
14
.openshift/action_hooks/pre_stop_jbosseap-6.0
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# The pre_start_cartridge and pre_stop_cartridge hooks are *SOURCED*
|
||||||
|
# immediately before (re)starting or stopping the specified cartridge.
|
||||||
|
# They are able to make any desired environment variable changes as
|
||||||
|
# well as other adjustments to the application environment.
|
||||||
|
|
||||||
|
# The post_start_cartridge and post_stop_cartridge hooks are executed
|
||||||
|
# immediately after (re)starting or stopping the specified cartridge.
|
||||||
|
|
||||||
|
# Exercise caution when adding commands to these hooks. They can
|
||||||
|
# prevent your application from stopping cleanly or starting at all.
|
||||||
|
# Application start and stop is subject to different timeouts
|
||||||
|
# throughout the system.
|
||||||
3
.openshift/config/modules/README
Normal file
3
.openshift/config/modules/README
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
Place your jboss-as7 modules in this directory. This directory is added to the
|
||||||
|
module path of the jboss-as7 server associated with your application. It has the
|
||||||
|
same structure as the jboss-as7/modules directory.
|
||||||
519
.openshift/config/standalone.xml
Normal file
519
.openshift/config/standalone.xml
Normal file
@@ -0,0 +1,519 @@
|
|||||||
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
|
|
||||||
|
<server xmlns="urn:jboss:domain:1.3">
|
||||||
|
|
||||||
|
<extensions>
|
||||||
|
<extension module="org.jboss.as.clustering.infinispan" />
|
||||||
|
<extension module="org.jboss.as.clustering.jgroups" />
|
||||||
|
<extension module="org.jboss.as.cmp" />
|
||||||
|
<extension module="org.jboss.as.configadmin" />
|
||||||
|
<extension module="org.jboss.as.connector" />
|
||||||
|
<extension module="org.jboss.as.deployment-scanner" />
|
||||||
|
<extension module="org.jboss.as.ee" />
|
||||||
|
<extension module="org.jboss.as.ejb3" />
|
||||||
|
<extension module="org.jboss.as.jacorb" />
|
||||||
|
<extension module="org.jboss.as.jaxr" />
|
||||||
|
<extension module="org.jboss.as.jaxrs" />
|
||||||
|
<extension module="org.jboss.as.jdr" />
|
||||||
|
<extension module="org.jboss.as.jmx" />
|
||||||
|
<extension module="org.jboss.as.jpa" />
|
||||||
|
<extension module="org.jboss.as.jsr77" />
|
||||||
|
<extension module="org.jboss.as.logging" />
|
||||||
|
<extension module="org.jboss.as.mail" />
|
||||||
|
<extension module="org.jboss.as.messaging" />
|
||||||
|
<extension module="org.jboss.as.naming" />
|
||||||
|
<extension module="org.jboss.as.osgi" />
|
||||||
|
<extension module="org.jboss.as.pojo" />
|
||||||
|
<extension module="org.jboss.as.remoting" />
|
||||||
|
<extension module="org.jboss.as.sar" />
|
||||||
|
<extension module="org.jboss.as.security" />
|
||||||
|
<extension module="org.jboss.as.threads" />
|
||||||
|
<extension module="org.jboss.as.transactions" />
|
||||||
|
<extension module="org.jboss.as.web" />
|
||||||
|
<extension module="org.jboss.as.webservices" />
|
||||||
|
<extension module="org.jboss.as.weld" />
|
||||||
|
</extensions>
|
||||||
|
|
||||||
|
<system-properties>
|
||||||
|
<property name="org.apache.coyote.http11.Http11Protocol.COMPRESSION" value="on"/>
|
||||||
|
</system-properties>
|
||||||
|
|
||||||
|
<management>
|
||||||
|
<management-interfaces>
|
||||||
|
<native-interface>
|
||||||
|
<socket-binding native="management-native"/>
|
||||||
|
</native-interface>
|
||||||
|
<http-interface>
|
||||||
|
<socket-binding http="management-http"/>
|
||||||
|
</http-interface>
|
||||||
|
</management-interfaces>
|
||||||
|
</management>
|
||||||
|
|
||||||
|
<profile>
|
||||||
|
<subsystem xmlns="urn:jboss:domain:logging:1.1">
|
||||||
|
<!--console-handler name="CONSOLE"> <level name="INFO"/> <formatter> <pattern-formatter
|
||||||
|
pattern="%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n"/> </formatter> </console-handler -->
|
||||||
|
<periodic-rotating-file-handler name="FILE">
|
||||||
|
<formatter>
|
||||||
|
<pattern-formatter
|
||||||
|
pattern="%d{yyyy/MM/dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n" />
|
||||||
|
</formatter>
|
||||||
|
<file relative-to="jboss.server.log.dir" path="server.log" />
|
||||||
|
<suffix value=".yyyy-MM-dd" />
|
||||||
|
<append value="true" />
|
||||||
|
</periodic-rotating-file-handler>
|
||||||
|
<logger category="com.arjuna">
|
||||||
|
<level name="WARN" />
|
||||||
|
</logger>
|
||||||
|
<logger category="org.apache.tomcat.util.modeler">
|
||||||
|
<level name="WARN" />
|
||||||
|
</logger>
|
||||||
|
<logger category="sun.rmi">
|
||||||
|
<level name="WARN" />
|
||||||
|
</logger>
|
||||||
|
<logger category="jacorb">
|
||||||
|
<level name="WARN" />
|
||||||
|
</logger>
|
||||||
|
<logger category="jacorb.config">
|
||||||
|
<level name="ERROR" />
|
||||||
|
</logger>
|
||||||
|
<root-logger>
|
||||||
|
<level name="INFO" />
|
||||||
|
<handlers>
|
||||||
|
<!--handler name="CONSOLE"/ -->
|
||||||
|
<handler name="FILE" />
|
||||||
|
</handlers>
|
||||||
|
</root-logger>
|
||||||
|
</subsystem>
|
||||||
|
<subsystem xmlns="urn:jboss:domain:cmp:1.0" />
|
||||||
|
<subsystem xmlns="urn:jboss:domain:configadmin:1.0" />
|
||||||
|
<subsystem xmlns="urn:jboss:domain:datasources:1.1">
|
||||||
|
<datasources>
|
||||||
|
<datasource jndi-name="java:/jdbc/commafeedDS"
|
||||||
|
enabled="${postgresql.enabled}" use-java-context="true" pool-name="PostgreSQLDS"
|
||||||
|
use-ccm="true">
|
||||||
|
<connection-url>jdbc:postgresql://${env.OPENSHIFT_POSTGRESQL_DB_HOST}:${env.OPENSHIFT_POSTGRESQL_DB_PORT}/${env.OPENSHIFT_APP_NAME}
|
||||||
|
</connection-url>
|
||||||
|
<driver>postgresql</driver>
|
||||||
|
<security>
|
||||||
|
<user-name>${env.OPENSHIFT_POSTGRESQL_DB_USERNAME}</user-name>
|
||||||
|
<password>${env.OPENSHIFT_POSTGRESQL_DB_PASSWORD}</password>
|
||||||
|
</security>
|
||||||
|
<validation>
|
||||||
|
<check-valid-connection-sql>SELECT 1</check-valid-connection-sql>
|
||||||
|
<background-validation>true</background-validation>
|
||||||
|
</validation>
|
||||||
|
<pool>
|
||||||
|
<flush-strategy>IdleConnections</flush-strategy>
|
||||||
|
<allow-multiple-users/>
|
||||||
|
</pool>
|
||||||
|
</datasource>
|
||||||
|
<drivers>
|
||||||
|
<driver name="postgresql" module="org.postgresql.jdbc">
|
||||||
|
<xa-datasource-class>org.postgresql.xa.PGXADataSource
|
||||||
|
</xa-datasource-class>
|
||||||
|
</driver>
|
||||||
|
</drivers>
|
||||||
|
</datasources>
|
||||||
|
</subsystem>
|
||||||
|
<subsystem xmlns="urn:jboss:domain:deployment-scanner:1.1">
|
||||||
|
<deployment-scanner path="deployments"
|
||||||
|
relative-to="jboss.server.base.dir" scan-interval="5000"
|
||||||
|
deployment-timeout="300" />
|
||||||
|
</subsystem>
|
||||||
|
<subsystem xmlns="urn:jboss:domain:ee:1.1">
|
||||||
|
<spec-descriptor-property-replacement>false
|
||||||
|
</spec-descriptor-property-replacement>
|
||||||
|
<jboss-descriptor-property-replacement>true
|
||||||
|
</jboss-descriptor-property-replacement>
|
||||||
|
</subsystem>
|
||||||
|
<subsystem xmlns="urn:jboss:domain:ejb3:1.3">
|
||||||
|
<session-bean>
|
||||||
|
<stateless>
|
||||||
|
<bean-instance-pool-ref pool-name="slsb-strict-max-pool" />
|
||||||
|
</stateless>
|
||||||
|
<stateful default-access-timeout="5000" cache-ref="simple"
|
||||||
|
clustered-cache-ref="clustered" />
|
||||||
|
<singleton default-access-timeout="5000" />
|
||||||
|
</session-bean>
|
||||||
|
<mdb>
|
||||||
|
<resource-adapter-ref resource-adapter-name="hornetq-ra" />
|
||||||
|
<bean-instance-pool-ref pool-name="mdb-strict-max-pool" />
|
||||||
|
</mdb>
|
||||||
|
<pools>
|
||||||
|
<bean-instance-pools>
|
||||||
|
<strict-max-pool name="slsb-strict-max-pool"
|
||||||
|
max-pool-size="20" instance-acquisition-timeout="5"
|
||||||
|
instance-acquisition-timeout-unit="MINUTES" />
|
||||||
|
<strict-max-pool name="mdb-strict-max-pool"
|
||||||
|
max-pool-size="20" instance-acquisition-timeout="5"
|
||||||
|
instance-acquisition-timeout-unit="MINUTES" />
|
||||||
|
</bean-instance-pools>
|
||||||
|
</pools>
|
||||||
|
<caches>
|
||||||
|
<cache name="simple" aliases="NoPassivationCache" />
|
||||||
|
<cache name="passivating" passivation-store-ref="file"
|
||||||
|
aliases="SimpleStatefulCache" />
|
||||||
|
<cache name="clustered" passivation-store-ref="infinispan"
|
||||||
|
aliases="StatefulTreeCache" />
|
||||||
|
</caches>
|
||||||
|
<passivation-stores>
|
||||||
|
<file-passivation-store name="file" />
|
||||||
|
<cluster-passivation-store name="infinispan"
|
||||||
|
cache-container="ejb" />
|
||||||
|
</passivation-stores>
|
||||||
|
<async thread-pool-name="default" />
|
||||||
|
<timer-service thread-pool-name="default">
|
||||||
|
<data-store path="timer-service-data" relative-to="jboss.server.data.dir" />
|
||||||
|
</timer-service>
|
||||||
|
<remote connector-ref="remoting-connector" thread-pool-name="default" />
|
||||||
|
<thread-pools>
|
||||||
|
<thread-pool name="default">
|
||||||
|
<max-threads count="10" />
|
||||||
|
<keepalive-time time="100" unit="milliseconds" />
|
||||||
|
</thread-pool>
|
||||||
|
</thread-pools>
|
||||||
|
<iiop enable-by-default="false" use-qualified-name="false" />
|
||||||
|
</subsystem>
|
||||||
|
<subsystem xmlns="urn:jboss:domain:infinispan:1.3">
|
||||||
|
<cache-container name="cluster" aliases="ha-partition"
|
||||||
|
default-cache="default">
|
||||||
|
<transport lock-timeout="60000" />
|
||||||
|
<replicated-cache name="default" mode="SYNC"
|
||||||
|
batching="true">
|
||||||
|
<locking isolation="REPEATABLE_READ" />
|
||||||
|
</replicated-cache>
|
||||||
|
</cache-container>
|
||||||
|
<cache-container name="web" aliases="standard-session-cache"
|
||||||
|
default-cache="repl">
|
||||||
|
<transport lock-timeout="60000" />
|
||||||
|
<replicated-cache name="repl" mode="ASYNC"
|
||||||
|
batching="true">
|
||||||
|
<file-store />
|
||||||
|
</replicated-cache>
|
||||||
|
<replicated-cache name="sso" mode="SYNC" batching="true" />
|
||||||
|
<distributed-cache name="dist" mode="ASYNC"
|
||||||
|
batching="true" l1-lifespan="0">
|
||||||
|
<file-store />
|
||||||
|
</distributed-cache>
|
||||||
|
</cache-container>
|
||||||
|
<cache-container name="ejb" aliases="sfsb sfsb-cache"
|
||||||
|
default-cache="repl">
|
||||||
|
<transport lock-timeout="60000" />
|
||||||
|
<replicated-cache name="repl" mode="ASYNC"
|
||||||
|
batching="true">
|
||||||
|
<eviction strategy="LRU" max-entries="10000" />
|
||||||
|
<file-store />
|
||||||
|
</replicated-cache>
|
||||||
|
<!-- ~ Clustered cache used internally by EJB subsytem for managing the
|
||||||
|
client-mapping(s) of ~ the socketbinding referenced by the EJB remoting connector -->
|
||||||
|
<replicated-cache name="remote-connector-client-mappings"
|
||||||
|
mode="SYNC" batching="true" />
|
||||||
|
<distributed-cache name="dist" mode="ASYNC"
|
||||||
|
batching="true" l1-lifespan="0">
|
||||||
|
<eviction strategy="LRU" max-entries="10000" />
|
||||||
|
<file-store />
|
||||||
|
</distributed-cache>
|
||||||
|
</cache-container>
|
||||||
|
<cache-container name="hibernate" default-cache="local-query"
|
||||||
|
module="org.jboss.as.jpa.hibernate:4">
|
||||||
|
<transport lock-timeout="60000" />
|
||||||
|
<local-cache name="local-query">
|
||||||
|
<transaction mode="NONE" />
|
||||||
|
<eviction strategy="LRU" max-entries="10000" />
|
||||||
|
<expiration max-idle="100000" />
|
||||||
|
</local-cache>
|
||||||
|
<invalidation-cache name="entity" mode="SYNC">
|
||||||
|
<transaction mode="NON_XA" />
|
||||||
|
<eviction strategy="LRU" max-entries="10000" />
|
||||||
|
<expiration max-idle="100000" />
|
||||||
|
</invalidation-cache>
|
||||||
|
<replicated-cache name="timestamps" mode="ASYNC">
|
||||||
|
<transaction mode="NONE" />
|
||||||
|
<eviction strategy="NONE" />
|
||||||
|
</replicated-cache>
|
||||||
|
</cache-container>
|
||||||
|
</subsystem>
|
||||||
|
<subsystem xmlns="urn:jboss:domain:jacorb:1.2">
|
||||||
|
<orb>
|
||||||
|
<initializers transactions="spec" security="on" />
|
||||||
|
</orb>
|
||||||
|
</subsystem>
|
||||||
|
<subsystem xmlns="urn:jboss:domain:jaxr:1.1">
|
||||||
|
<connection-factory jndi-name="java:jboss/jaxr/ConnectionFactory" />
|
||||||
|
</subsystem>
|
||||||
|
<subsystem xmlns="urn:jboss:domain:jaxrs:1.0" />
|
||||||
|
<subsystem xmlns="urn:jboss:domain:jca:1.1">
|
||||||
|
<archive-validation enabled="true" fail-on-error="true" fail-on-warn="false"/>
|
||||||
|
<bean-validation enabled="true"/>
|
||||||
|
<default-workmanager>
|
||||||
|
<short-running-threads>
|
||||||
|
<core-threads count="50" />
|
||||||
|
<queue-length count="50" />
|
||||||
|
<max-threads count="50" />
|
||||||
|
<keepalive-time time="10" unit="seconds" />
|
||||||
|
</short-running-threads>
|
||||||
|
<long-running-threads>
|
||||||
|
<core-threads count="50" />
|
||||||
|
<queue-length count="50" />
|
||||||
|
<max-threads count="50" />
|
||||||
|
<keepalive-time time="10" unit="seconds" />
|
||||||
|
</long-running-threads>
|
||||||
|
</default-workmanager>
|
||||||
|
<cached-connection-manager />
|
||||||
|
</subsystem>
|
||||||
|
<subsystem xmlns="urn:jboss:domain:jdr:1.0" />
|
||||||
|
<subsystem xmlns="urn:jboss:domain:jgroups:1.1"
|
||||||
|
default-stack="tcp">
|
||||||
|
<stack name="tcp">
|
||||||
|
<transport type="TCP" socket-binding="jgroups-tcp">
|
||||||
|
<property name="external_addr">${env.OPENSHIFT_GEAR_DNS}</property>
|
||||||
|
<property name="external_port">${env.OPENSHIFT_JBOSSEAP_CLUSTER_PROXY_PORT}
|
||||||
|
</property>
|
||||||
|
<property name="bind_port">7600</property>
|
||||||
|
<property name="bind_addr">${env.OPENSHIFT_INTERNAL_IP}</property>
|
||||||
|
</transport>
|
||||||
|
<protocol type="TCPPING">
|
||||||
|
<property name="timeout">3000</property>
|
||||||
|
<property name="initial_hosts">${env.OPENSHIFT_JBOSSEAP_CLUSTER}</property>
|
||||||
|
<property name="port_range">0</property>
|
||||||
|
<property name="num_initial_members">1</property>
|
||||||
|
</protocol>
|
||||||
|
<protocol type="MERGE2" />
|
||||||
|
<protocol type="FD" />
|
||||||
|
<protocol type="VERIFY_SUSPECT" />
|
||||||
|
<protocol type="BARRIER" />
|
||||||
|
<protocol type="pbcast.NAKACK" />
|
||||||
|
<protocol type="UNICAST2" />
|
||||||
|
<protocol type="pbcast.STABLE" />
|
||||||
|
<protocol type="AUTH">
|
||||||
|
<property name="auth_class">org.jgroups.auth.MD5Token</property>
|
||||||
|
<property name="token_hash">SHA</property>
|
||||||
|
<property name="auth_value">${env.OPENSHIFT_APP_UUID}</property>
|
||||||
|
</protocol>
|
||||||
|
<protocol type="pbcast.GMS" />
|
||||||
|
<protocol type="UFC" />
|
||||||
|
<protocol type="MFC" />
|
||||||
|
<protocol type="FRAG2" />
|
||||||
|
<!--protocol type="pbcast.STATE_TRANSFER"/> <protocol type="pbcast.FLUSH"/ -->
|
||||||
|
</stack>
|
||||||
|
</subsystem>
|
||||||
|
<subsystem xmlns="urn:jboss:domain:jmx:1.1">
|
||||||
|
<show-model value="true" />
|
||||||
|
<remoting-connector />
|
||||||
|
</subsystem>
|
||||||
|
<subsystem xmlns="urn:jboss:domain:jpa:1.0">
|
||||||
|
<jpa default-datasource="" />
|
||||||
|
</subsystem>
|
||||||
|
<subsystem xmlns="urn:jboss:domain:jsr77:1.0" />
|
||||||
|
<subsystem xmlns="urn:jboss:domain:mail:1.0">
|
||||||
|
<mail-session jndi-name="java:jboss/mail/Default">
|
||||||
|
<smtp-server outbound-socket-binding-ref="mail-smtp" />
|
||||||
|
</mail-session>
|
||||||
|
</subsystem>
|
||||||
|
<subsystem xmlns="urn:jboss:domain:messaging:1.2">
|
||||||
|
<hornetq-server>
|
||||||
|
<clustered>true</clustered>
|
||||||
|
<persistence-enabled>true</persistence-enabled>
|
||||||
|
<security-enabled>false</security-enabled>
|
||||||
|
<journal-file-size>102400</journal-file-size>
|
||||||
|
<journal-min-files>2</journal-min-files>
|
||||||
|
|
||||||
|
<thread-pool-max-size>${messaging.thread.pool.max.size}</thread-pool-max-size>
|
||||||
|
<scheduled-thread-pool-max-size>${messaging.scheduled.thread.pool.max.size}</scheduled-thread-pool-max-size>
|
||||||
|
|
||||||
|
<connectors>
|
||||||
|
<netty-connector name="netty" socket-binding="messaging" />
|
||||||
|
<netty-connector name="netty-throughput"
|
||||||
|
socket-binding="messaging-throughput">
|
||||||
|
<param key="batch-delay" value="50" />
|
||||||
|
</netty-connector>
|
||||||
|
<in-vm-connector name="in-vm" server-id="0" />
|
||||||
|
</connectors>
|
||||||
|
<acceptors>
|
||||||
|
<netty-acceptor name="netty" socket-binding="messaging" />
|
||||||
|
<netty-acceptor name="netty-throughput"
|
||||||
|
socket-binding="messaging-throughput">
|
||||||
|
<param key="batch-delay" value="50" />
|
||||||
|
<param key="direct-deliver" value="false" />
|
||||||
|
</netty-acceptor>
|
||||||
|
<in-vm-acceptor name="in-vm" server-id="0" />
|
||||||
|
</acceptors>
|
||||||
|
<!--broadcast-groups> <broadcast-group name="bg-group1"> <socket-binding>messaging-group</socket-binding>
|
||||||
|
<broadcast-period>5000</broadcast-period> <connector-ref>netty</connector-ref>
|
||||||
|
</broadcast-group> </broadcast-groups> <discovery-groups> <discovery-group
|
||||||
|
name="dg-group1"> <socket-binding>messaging-group</socket-binding> <refresh-timeout>10000</refresh-timeout>
|
||||||
|
</discovery-group> </discovery-groups> <cluster-connections> <cluster-connection
|
||||||
|
name="my-cluster"> <address>jms</address> <connector-ref>netty</connector-ref>
|
||||||
|
<discovery-group-ref discovery-group-name="dg-group1"/> </cluster-connection>
|
||||||
|
</cluster-connections -->
|
||||||
|
<address-settings>
|
||||||
|
<!--default for catch all -->
|
||||||
|
<address-setting match="#">
|
||||||
|
<dead-letter-address>jms.queue.DLQ</dead-letter-address>
|
||||||
|
<expiry-address>jms.queue.ExpiryQueue</expiry-address>
|
||||||
|
<redelivery-delay>0</redelivery-delay>
|
||||||
|
<redistribution-delay>1000</redistribution-delay>
|
||||||
|
<max-size-bytes>10485760</max-size-bytes>
|
||||||
|
<address-full-policy>BLOCK</address-full-policy>
|
||||||
|
<message-counter-history-day-limit>10
|
||||||
|
</message-counter-history-day-limit>
|
||||||
|
</address-setting>
|
||||||
|
</address-settings>
|
||||||
|
<jms-connection-factories>
|
||||||
|
<connection-factory name="InVmConnectionFactory">
|
||||||
|
<connectors>
|
||||||
|
<connector-ref connector-name="in-vm" />
|
||||||
|
</connectors>
|
||||||
|
<entries>
|
||||||
|
<entry name="java:/ConnectionFactory" />
|
||||||
|
</entries>
|
||||||
|
</connection-factory>
|
||||||
|
<connection-factory name="RemoteConnectionFactory">
|
||||||
|
<connectors>
|
||||||
|
<connector-ref connector-name="netty" />
|
||||||
|
</connectors>
|
||||||
|
<entries>
|
||||||
|
<entry name="java:jboss/exported/jms/RemoteConnectionFactory" />
|
||||||
|
</entries>
|
||||||
|
</connection-factory>
|
||||||
|
<pooled-connection-factory name="hornetq-ra">
|
||||||
|
<transaction mode="xa" />
|
||||||
|
<connectors>
|
||||||
|
<connector-ref connector-name="in-vm" />
|
||||||
|
</connectors>
|
||||||
|
<entries>
|
||||||
|
<entry name="java:/JmsXA" />
|
||||||
|
</entries>
|
||||||
|
</pooled-connection-factory>
|
||||||
|
</jms-connection-factories>
|
||||||
|
</hornetq-server>
|
||||||
|
</subsystem>
|
||||||
|
<subsystem xmlns="urn:jboss:domain:naming:1.2">
|
||||||
|
<remote-naming />
|
||||||
|
</subsystem>
|
||||||
|
<subsystem xmlns="urn:jboss:domain:osgi:1.2" activation="lazy">
|
||||||
|
<properties>
|
||||||
|
<!-- Specifies the beginning start level of the framework -->
|
||||||
|
<property name="org.osgi.framework.startlevel.beginning">1</property>
|
||||||
|
</properties>
|
||||||
|
<capabilities>
|
||||||
|
<!-- modules registered with the OSGi layer on startup -->
|
||||||
|
<capability name="javax.servlet.api:v25" />
|
||||||
|
<capability name="javax.transaction.api" />
|
||||||
|
<!-- bundles started in startlevel 1 -->
|
||||||
|
<capability name="org.apache.felix.log" startlevel="1" />
|
||||||
|
<capability name="org.jboss.osgi.logging" startlevel="1" />
|
||||||
|
<capability name="org.apache.felix.configadmin"
|
||||||
|
startlevel="1" />
|
||||||
|
<capability name="org.jboss.as.osgi.configadmin"
|
||||||
|
startlevel="1" />
|
||||||
|
</capabilities>
|
||||||
|
</subsystem>
|
||||||
|
<subsystem xmlns="urn:jboss:domain:pojo:1.0" />
|
||||||
|
<subsystem xmlns="urn:jboss:domain:remoting:1.1">
|
||||||
|
<connector name="remoting-connector" socket-binding="remoting" />
|
||||||
|
</subsystem>
|
||||||
|
<subsystem xmlns="urn:jboss:domain:resource-adapters:1.0" />
|
||||||
|
<subsystem xmlns="urn:jboss:domain:sar:1.0" />
|
||||||
|
<subsystem xmlns="urn:jboss:domain:security:1.2">
|
||||||
|
<security-domains>
|
||||||
|
<security-domain name="other" cache-type="default">
|
||||||
|
<authentication>
|
||||||
|
<login-module code="Remoting" flag="optional">
|
||||||
|
<module-option name="password-stacking" value="useFirstPass"/>
|
||||||
|
</login-module>
|
||||||
|
<login-module code="RealmDirect" flag="required">
|
||||||
|
<module-option name="password-stacking" value="useFirstPass"/>
|
||||||
|
</login-module>
|
||||||
|
</authentication>
|
||||||
|
</security-domain>
|
||||||
|
<security-domain name="jboss-web-policy" cache-type="default">
|
||||||
|
<authorization>
|
||||||
|
<policy-module code="Delegating" flag="required"/>
|
||||||
|
</authorization>
|
||||||
|
</security-domain>
|
||||||
|
<security-domain name="jboss-ejb-policy" cache-type="default">
|
||||||
|
<authorization>
|
||||||
|
<policy-module code="Delegating" flag="required"/>
|
||||||
|
</authorization>
|
||||||
|
</security-domain>
|
||||||
|
</security-domains>
|
||||||
|
</subsystem>
|
||||||
|
<subsystem xmlns="urn:jboss:domain:threads:1.1" />
|
||||||
|
<subsystem xmlns="urn:jboss:domain:transactions:1.2">
|
||||||
|
<core-environment>
|
||||||
|
<process-id>
|
||||||
|
<uuid />
|
||||||
|
</process-id>
|
||||||
|
</core-environment>
|
||||||
|
<recovery-environment socket-binding="txn-recovery-environment"
|
||||||
|
status-socket-binding="txn-status-manager" />
|
||||||
|
<coordinator-environment default-timeout="300" />
|
||||||
|
</subsystem>
|
||||||
|
<subsystem xmlns="urn:jboss:domain:web:1.1"
|
||||||
|
default-virtual-server="default-host" native="false">
|
||||||
|
<connector name="http" protocol="HTTP/1.1" scheme="http"
|
||||||
|
socket-binding="http" />
|
||||||
|
<virtual-server name="default-host"
|
||||||
|
enable-welcome-root="false">
|
||||||
|
<alias name="localhost" />
|
||||||
|
</virtual-server>
|
||||||
|
</subsystem>
|
||||||
|
<subsystem xmlns="urn:jboss:domain:webservices:1.1">
|
||||||
|
<modify-wsdl-address>true</modify-wsdl-address>
|
||||||
|
<wsdl-host>${env.OPENSHIFT_GEAR_DNS}</wsdl-host>
|
||||||
|
<wsdl-port>80</wsdl-port>
|
||||||
|
<endpoint-config name="Standard-Endpoint-Config" />
|
||||||
|
<endpoint-config name="Recording-Endpoint-Config">
|
||||||
|
<pre-handler-chain name="recording-handlers"
|
||||||
|
protocol-bindings="##SOAP11_HTTP ##SOAP11_HTTP_MTOM ##SOAP12_HTTP ##SOAP12_HTTP_MTOM">
|
||||||
|
<handler name="RecordingHandler"
|
||||||
|
class="org.jboss.ws.common.invocation.RecordingServerHandler" />
|
||||||
|
</pre-handler-chain>
|
||||||
|
</endpoint-config>
|
||||||
|
</subsystem>
|
||||||
|
<subsystem xmlns="urn:jboss:domain:weld:1.0" />
|
||||||
|
</profile>
|
||||||
|
|
||||||
|
<interfaces>
|
||||||
|
<interface name="management">
|
||||||
|
<loopback-address value="${env.OPENSHIFT_INTERNAL_IP}" />
|
||||||
|
</interface>
|
||||||
|
<interface name="public">
|
||||||
|
<loopback-address value="${env.OPENSHIFT_INTERNAL_IP}" />
|
||||||
|
</interface>
|
||||||
|
<interface name="unsecure">
|
||||||
|
<!-- Used for IIOP sockets in the standarad configuration. To secure JacORB
|
||||||
|
you need to setup SSL -->
|
||||||
|
<loopback-address value="${env.OPENSHIFT_INTERNAL_IP}" />
|
||||||
|
</interface>
|
||||||
|
</interfaces>
|
||||||
|
|
||||||
|
<socket-binding-group name="standard-sockets"
|
||||||
|
default-interface="public" port-offset="0">
|
||||||
|
<socket-binding name="management-native" interface="management"
|
||||||
|
port="9999" />
|
||||||
|
<socket-binding name="management-http" interface="management"
|
||||||
|
port="9990" />
|
||||||
|
|
||||||
|
<socket-binding name="http" port="8080" />
|
||||||
|
<socket-binding name="jacorb" interface="unsecure"
|
||||||
|
port="3528" />
|
||||||
|
<socket-binding name="jacorb-ssl" interface="unsecure"
|
||||||
|
port="3529" />
|
||||||
|
<socket-binding name="jgroups-tcp" port="7600" />
|
||||||
|
<socket-binding name="messaging" port="5445" />
|
||||||
|
<!--socket-binding name="messaging-group" multicast-address="${jboss.messaging.group.address:231.7.7.7}"
|
||||||
|
multicast-port="${jboss.messaging.group.port:9876}"/ -->
|
||||||
|
<socket-binding name="messaging-throughput" port="5455" />
|
||||||
|
<socket-binding name="osgi-http" interface="management"
|
||||||
|
port="8090" />
|
||||||
|
<socket-binding name="remoting" port="4447" />
|
||||||
|
<socket-binding name="txn-recovery-environment" port="4712" />
|
||||||
|
<socket-binding name="txn-status-manager" port="4713" />
|
||||||
|
<outbound-socket-binding name="mail-smtp">
|
||||||
|
<remote-destination host="localhost" port="25" />
|
||||||
|
</outbound-socket-binding>
|
||||||
|
</socket-binding-group>
|
||||||
|
</server>
|
||||||
22
.openshift/cron/README.cron
Normal file
22
.openshift/cron/README.cron
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
Run scripts or jobs on a periodic basis
|
||||||
|
=======================================
|
||||||
|
Any scripts or jobs added to the minutely, hourly, daily, weekly or monthly
|
||||||
|
directories will be run on a scheduled basis (frequency is as indicated by the
|
||||||
|
name of the directory) using run-parts.
|
||||||
|
|
||||||
|
run-parts ignores any files that are hidden or dotfiles (.*) or backup
|
||||||
|
files (*~ or *,) or named *.{rpmsave,rpmorig,rpmnew,swp,cfsaved}
|
||||||
|
|
||||||
|
The presence of two specially named files jobs.deny and jobs.allow controls
|
||||||
|
how run-parts executes your scripts/jobs.
|
||||||
|
jobs.deny ===> Prevents specific scripts or jobs from being executed.
|
||||||
|
jobs.allow ===> Only execute the named scripts or jobs (all other/non-named
|
||||||
|
scripts that exist in this directory are ignored).
|
||||||
|
|
||||||
|
The principles of jobs.deny and jobs.allow are the same as those of cron.deny
|
||||||
|
and cron.allow and are described in detail at:
|
||||||
|
http://docs.redhat.com/docs/en-US/Red_Hat_Enterprise_Linux/6/html/Deployment_Guide/ch-Automating_System_Tasks.html#s2-autotasks-cron-access
|
||||||
|
|
||||||
|
See: man crontab or above link for more details and see the the weekly/
|
||||||
|
directory for an example.
|
||||||
|
|
||||||
0
.openshift/cron/daily/.gitignore
vendored
Normal file
0
.openshift/cron/daily/.gitignore
vendored
Normal file
1
.openshift/cron/daily/log-cleanup.sh
Normal file
1
.openshift/cron/daily/log-cleanup.sh
Normal file
@@ -0,0 +1 @@
|
|||||||
|
rm -rf $OPENSHIFT_JBOSSAS_LOG_DIR\*.log.*
|
||||||
0
.openshift/cron/hourly/.gitignore
vendored
Normal file
0
.openshift/cron/hourly/.gitignore
vendored
Normal file
0
.openshift/cron/minutely/.gitignore
vendored
Normal file
0
.openshift/cron/minutely/.gitignore
vendored
Normal file
0
.openshift/cron/monthly/.gitignore
vendored
Normal file
0
.openshift/cron/monthly/.gitignore
vendored
Normal file
16
.openshift/cron/weekly/README
Normal file
16
.openshift/cron/weekly/README
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
Run scripts or jobs on a weekly basis
|
||||||
|
=====================================
|
||||||
|
Any scripts or jobs added to this directory will be run on a scheduled basis
|
||||||
|
(weekly) using run-parts.
|
||||||
|
|
||||||
|
run-parts ignores any files that are hidden or dotfiles (.*) or backup
|
||||||
|
files (*~ or *,) or named *.{rpmsave,rpmorig,rpmnew,swp,cfsaved} and handles
|
||||||
|
the files named jobs.deny and jobs.allow specially.
|
||||||
|
|
||||||
|
In this specific example, the chronograph script is the only script or job file
|
||||||
|
executed on a weekly basis (due to white-listing it in jobs.allow). And the
|
||||||
|
README and chrono.dat file are ignored either as a result of being black-listed
|
||||||
|
in jobs.deny or because they are NOT white-listed in the jobs.allow file.
|
||||||
|
|
||||||
|
For more details, please see ../README.cron file.
|
||||||
|
|
||||||
1
.openshift/cron/weekly/chrono.dat
Normal file
1
.openshift/cron/weekly/chrono.dat
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Time And Relative D...n In Execution (Open)Shift!
|
||||||
3
.openshift/cron/weekly/chronograph
Normal file
3
.openshift/cron/weekly/chronograph
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
echo "`date`: `cat $(dirname \"$0\")/chrono.dat`"
|
||||||
12
.openshift/cron/weekly/jobs.allow
Normal file
12
.openshift/cron/weekly/jobs.allow
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#
|
||||||
|
# Script or job files listed in here (one entry per line) will be
|
||||||
|
# executed on a weekly-basis.
|
||||||
|
#
|
||||||
|
# Example: The chronograph script will be executed weekly but the README
|
||||||
|
# and chrono.dat files in this directory will be ignored.
|
||||||
|
#
|
||||||
|
# The README file is actually ignored due to the entry in the
|
||||||
|
# jobs.deny which is checked before jobs.allow (this file).
|
||||||
|
#
|
||||||
|
chronograph
|
||||||
|
|
||||||
7
.openshift/cron/weekly/jobs.deny
Normal file
7
.openshift/cron/weekly/jobs.deny
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
# Any script or job files listed in here (one entry per line) will NOT be
|
||||||
|
# executed (read as ignored by run-parts).
|
||||||
|
#
|
||||||
|
|
||||||
|
README
|
||||||
|
|
||||||
22
.openshift/markers/README
Normal file
22
.openshift/markers/README
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
Markers
|
||||||
|
===========
|
||||||
|
|
||||||
|
Adding marker files to this directory will have the following effects:
|
||||||
|
|
||||||
|
enable_jpda - Will enable the JPDA socket based transport on the java virtual
|
||||||
|
machine running the JBoss AS 7 application server. This enables
|
||||||
|
you to remotely debug code running inside the JBoss AS 7
|
||||||
|
application server.
|
||||||
|
|
||||||
|
skip_maven_build - Maven build step will be skipped
|
||||||
|
|
||||||
|
force_clean_build - Will start the build process by removing all non
|
||||||
|
essential Maven dependencies. Any current dependencies specified in
|
||||||
|
your pom.xml file will then be re-downloaded.
|
||||||
|
|
||||||
|
hot_deploy - Will prevent a JBoss container restart during build/deployment.
|
||||||
|
Newly build archives will be re-deployed automatically by the
|
||||||
|
JBoss HDScanner component.
|
||||||
|
|
||||||
|
java7 - Will run JBoss AS7 with Java7 if present. If no marker is present then the
|
||||||
|
baseline Java version will be used (currently Java6)
|
||||||
0
.openshift/markers/java7
Normal file
0
.openshift/markers/java7
Normal file
5
README.md
Normal file
5
README.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
CommaFeed
|
||||||
|
=========
|
||||||
|
Google Reader inspired self-hosted RSS reader.
|
||||||
|
|
||||||
|
Deploy on any JavaEE6 container or better yet on OpenShift.
|
||||||
0
deployments/.gitkeep
Normal file
0
deployments/.gitkeep
Normal file
225
pom.xml
Normal file
225
pom.xml
Normal file
@@ -0,0 +1,225 @@
|
|||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>com.commafeed</groupId>
|
||||||
|
<artifactId>commafeed</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<packaging>war</packaging>
|
||||||
|
<name>CommaFeed</name>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>src/main/resources</directory>
|
||||||
|
</resource>
|
||||||
|
<resource>
|
||||||
|
<directory>src/main/java</directory>
|
||||||
|
<includes>
|
||||||
|
<include>**/*</include>
|
||||||
|
</includes>
|
||||||
|
<excludes>
|
||||||
|
<exclude>**/*.java</exclude>
|
||||||
|
</excludes>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.0</version>
|
||||||
|
<configuration>
|
||||||
|
<source>1.6</source>
|
||||||
|
<target>1.6</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-war-plugin</artifactId>
|
||||||
|
<version>2.1.1</version>
|
||||||
|
<configuration>
|
||||||
|
<failOnMissingWebXml>false</failOnMissingWebXml>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.zeroturnaround</groupId>
|
||||||
|
<artifactId>jrebel-maven-plugin</artifactId>
|
||||||
|
<version>1.1.3</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>generate-rebel-xml</id>
|
||||||
|
<phase>process-resources</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>generate</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jboss.spec</groupId>
|
||||||
|
<artifactId>jboss-javaee-6.0</artifactId>
|
||||||
|
<version>1.0.0.Final</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>uaihebert.com</groupId>
|
||||||
|
<artifactId>EasyCriteria</artifactId>
|
||||||
|
<version>2.1.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-log4j12</artifactId>
|
||||||
|
<version>1.7.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>log4j</groupId>
|
||||||
|
<artifactId>log4j</artifactId>
|
||||||
|
<version>1.2.17</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.guava</groupId>
|
||||||
|
<artifactId>guava</artifactId>
|
||||||
|
<version>14.0.1</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-beanutils</groupId>
|
||||||
|
<artifactId>commons-beanutils</artifactId>
|
||||||
|
<version>1.8.3</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-codec</groupId>
|
||||||
|
<artifactId>commons-codec</artifactId>
|
||||||
|
<version>1.7</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-collections</groupId>
|
||||||
|
<artifactId>commons-collections</artifactId>
|
||||||
|
<version>3.2.1</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-io</groupId>
|
||||||
|
<artifactId>commons-io</artifactId>
|
||||||
|
<version>2.4</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-lang</groupId>
|
||||||
|
<artifactId>commons-lang</artifactId>
|
||||||
|
<version>2.6</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.java.dev.rome</groupId>
|
||||||
|
<artifactId>rome</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.httpcomponents</groupId>
|
||||||
|
<artifactId>httpclient</artifactId>
|
||||||
|
<version>4.2.3</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>joda-time</groupId>
|
||||||
|
<artifactId>joda-time</artifactId>
|
||||||
|
<version>2.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.googlecode.lambdaj</groupId>
|
||||||
|
<artifactId>lambdaj</artifactId>
|
||||||
|
<version>2.3.3</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.wicket</groupId>
|
||||||
|
<artifactId>wicket-core</artifactId>
|
||||||
|
<version>6.6.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.wicket</groupId>
|
||||||
|
<artifactId>wicket-auth-roles</artifactId>
|
||||||
|
<version>6.6.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.wicket</groupId>
|
||||||
|
<artifactId>wicket-extensions</artifactId>
|
||||||
|
<version>6.6.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.wicket</groupId>
|
||||||
|
<artifactId>wicket-datetime</artifactId>
|
||||||
|
<version>6.6.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.odlabs.wiquery</groupId>
|
||||||
|
<artifactId>wiquery-jquery-ui</artifactId>
|
||||||
|
<version>6.6.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.wicket</groupId>
|
||||||
|
<artifactId>wicket-cdi</artifactId>
|
||||||
|
<version>6.6.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>de.agilecoders.wicket</groupId>
|
||||||
|
<artifactId>wicket-bootstrap-core</artifactId>
|
||||||
|
<version>0.8.1</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>de.agilecoders.wicket</groupId>
|
||||||
|
<artifactId>wicket-bootstrap-extensions</artifactId>
|
||||||
|
<version>0.8.1</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>de.agilecoders.wicket</groupId>
|
||||||
|
<artifactId>wicket-bootstrap-themes</artifactId>
|
||||||
|
<version>0.8.1</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.vaynberg.wicket.select2</groupId>
|
||||||
|
<artifactId>wicket-select2</artifactId>
|
||||||
|
<version>2.1</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>de.agilecoders.wicket.webjars</groupId>
|
||||||
|
<artifactId>wicket-webjars</artifactId>
|
||||||
|
<version>0.2.0</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<id>openshift</id>
|
||||||
|
<build>
|
||||||
|
<finalName>commafeed</finalName>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>2.12</version>
|
||||||
|
<configuration>
|
||||||
|
<skip>true</skip>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-war-plugin</artifactId>
|
||||||
|
<version>2.1.1</version>
|
||||||
|
<configuration>
|
||||||
|
<outputDirectory>deployments</outputDirectory>
|
||||||
|
<warName>ROOT</warName>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
|
</project>
|
||||||
0
src/main/java/.gitkeep
Normal file
0
src/main/java/.gitkeep
Normal file
74
src/main/java/com/commafeed/backend/StartupBean.java
Normal file
74
src/main/java/com/commafeed/backend/StartupBean.java
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
package com.commafeed.backend;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
import javax.ejb.Singleton;
|
||||||
|
import javax.ejb.Startup;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import com.commafeed.backend.dao.FeedCategoryService;
|
||||||
|
import com.commafeed.backend.dao.FeedService;
|
||||||
|
import com.commafeed.backend.dao.FeedSubscriptionService;
|
||||||
|
import com.commafeed.backend.dao.UserService;
|
||||||
|
import com.commafeed.backend.security.PasswordEncryptionService;
|
||||||
|
import com.commafeed.model.Feed;
|
||||||
|
import com.commafeed.model.FeedCategory;
|
||||||
|
import com.commafeed.model.FeedSubscription;
|
||||||
|
import com.commafeed.model.User;
|
||||||
|
|
||||||
|
@Startup
|
||||||
|
@Singleton
|
||||||
|
public class StartupBean {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
FeedService feedService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
FeedCategoryService feedCategoryService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
FeedSubscriptionService feedSubscriptionService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
UserService userService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
PasswordEncryptionService encryptionService;
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
private void init() {
|
||||||
|
|
||||||
|
if (userService.getCount() == 0) {
|
||||||
|
User user = new User();
|
||||||
|
byte[] salt = encryptionService.generateSalt();
|
||||||
|
user.setName("admin");
|
||||||
|
user.setSalt(salt);
|
||||||
|
user.setPassword(encryptionService.getEncryptedPassword("admin",
|
||||||
|
salt));
|
||||||
|
userService.save(user);
|
||||||
|
|
||||||
|
Feed feed = new Feed("http://feed.dilbert.com/dilbert/daily_strip");
|
||||||
|
feedService.save(feed);
|
||||||
|
|
||||||
|
FeedCategory newsCategory = new FeedCategory();
|
||||||
|
newsCategory.setName("News");
|
||||||
|
newsCategory.setUser(user);
|
||||||
|
feedCategoryService.save(newsCategory);
|
||||||
|
|
||||||
|
FeedCategory comicsCategory = new FeedCategory();
|
||||||
|
comicsCategory.setName("Comics");
|
||||||
|
comicsCategory.setUser(user);
|
||||||
|
comicsCategory.setParent(newsCategory);
|
||||||
|
feedCategoryService.save(comicsCategory);
|
||||||
|
|
||||||
|
FeedSubscription sub = new FeedSubscription();
|
||||||
|
sub.setCategory(comicsCategory);
|
||||||
|
sub.setFeed(feed);
|
||||||
|
sub.setTitle("Dilbert - Strips");
|
||||||
|
sub.setUser(user);
|
||||||
|
feedSubscriptionService.save(sub);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package com.commafeed.backend.dao;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.ejb.Stateless;
|
||||||
|
|
||||||
|
import com.commafeed.frontend.utils.ModelFactory.MF;
|
||||||
|
import com.commafeed.model.FeedCategory;
|
||||||
|
import com.commafeed.model.User;
|
||||||
|
|
||||||
|
@Stateless
|
||||||
|
public class FeedCategoryService extends GenericDAO<FeedCategory, Long> {
|
||||||
|
|
||||||
|
public List<FeedCategory> findAll(User user) {
|
||||||
|
return findByField(MF.i(MF.p(FeedCategory.class).getUser()), user);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package com.commafeed.backend.dao;
|
||||||
|
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import javax.ejb.Stateless;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import com.commafeed.model.Feed;
|
||||||
|
import com.commafeed.model.FeedEntry;
|
||||||
|
|
||||||
|
@Stateless
|
||||||
|
public class FeedEntryService extends GenericDAO<FeedEntry, String> {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
FeedService feedService;
|
||||||
|
|
||||||
|
public void updateEntries(String url, Collection<FeedEntry> entries) {
|
||||||
|
Feed feed = feedService.findById(url);
|
||||||
|
for (FeedEntry entry : entries) {
|
||||||
|
FeedEntry existing = findById(entry.getGuid());
|
||||||
|
if (existing == null) {
|
||||||
|
entry.setFeed(feed);
|
||||||
|
save(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
feed.setLastUpdated(Calendar.getInstance().getTime());
|
||||||
|
em.merge(feed);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
10
src/main/java/com/commafeed/backend/dao/FeedService.java
Normal file
10
src/main/java/com/commafeed/backend/dao/FeedService.java
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package com.commafeed.backend.dao;
|
||||||
|
|
||||||
|
import javax.ejb.Stateless;
|
||||||
|
|
||||||
|
import com.commafeed.model.Feed;
|
||||||
|
|
||||||
|
@Stateless
|
||||||
|
public class FeedService extends GenericDAO<Feed, String> {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.commafeed.backend.dao;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.ejb.Stateless;
|
||||||
|
|
||||||
|
import com.commafeed.frontend.utils.ModelFactory.MF;
|
||||||
|
import com.commafeed.model.FeedCategory;
|
||||||
|
import com.commafeed.model.FeedSubscription;
|
||||||
|
import com.commafeed.model.User;
|
||||||
|
|
||||||
|
@Stateless
|
||||||
|
public class FeedSubscriptionService extends GenericDAO<FeedSubscription, Long> {
|
||||||
|
|
||||||
|
public List<FeedSubscription> findAll(User user) {
|
||||||
|
return findByField(MF.i(MF.p(FeedCategory.class).getUser()), user);
|
||||||
|
}
|
||||||
|
}
|
||||||
89
src/main/java/com/commafeed/backend/dao/GenericDAO.java
Normal file
89
src/main/java/com/commafeed/backend/dao/GenericDAO.java
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
package com.commafeed.backend.dao;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.PersistenceContext;
|
||||||
|
import javax.persistence.criteria.CriteriaBuilder;
|
||||||
|
import javax.persistence.criteria.CriteriaQuery;
|
||||||
|
import javax.persistence.criteria.Root;
|
||||||
|
|
||||||
|
import com.google.common.reflect.TypeToken;
|
||||||
|
import com.uaihebert.factory.EasyCriteriaFactory;
|
||||||
|
import com.uaihebert.model.EasyCriteria;
|
||||||
|
|
||||||
|
public abstract class GenericDAO<T, K> {
|
||||||
|
|
||||||
|
private TypeToken<T> type = new TypeToken<T>(getClass()) {
|
||||||
|
};
|
||||||
|
|
||||||
|
@PersistenceContext
|
||||||
|
protected EntityManager em;
|
||||||
|
|
||||||
|
protected CriteriaBuilder builder;
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void init() {
|
||||||
|
builder = em.getCriteriaBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void save(T object) {
|
||||||
|
em.persist(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(T... objects) {
|
||||||
|
for (Object object : objects) {
|
||||||
|
em.merge(object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete(T object) {
|
||||||
|
object = em.merge(object);
|
||||||
|
em.remove(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteById(Object id) {
|
||||||
|
Object ref = em.getReference(getType(), id);
|
||||||
|
em.remove(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T findById(K id) {
|
||||||
|
T t = em.find(getType(), id);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<T> findAll() {
|
||||||
|
return EasyCriteriaFactory.createQueryCriteria(em, getType())
|
||||||
|
.getResultList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<T> findAll(int startIndex, int count) {
|
||||||
|
EasyCriteria<T> criteria = EasyCriteriaFactory.createQueryCriteria(em,
|
||||||
|
getType());
|
||||||
|
criteria.setMaxResults(count);
|
||||||
|
criteria.setFirstResult(startIndex);
|
||||||
|
return criteria.getResultList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getCount() {
|
||||||
|
CriteriaBuilder builder = em.getCriteriaBuilder();
|
||||||
|
CriteriaQuery<Long> query = builder.createQuery(Long.class);
|
||||||
|
Root<T> root = query.from(getType());
|
||||||
|
query.select(builder.count(root));
|
||||||
|
return em.createQuery(query).getSingleResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<T> findByField(String field, Object value) {
|
||||||
|
EasyCriteria<T> criteria = EasyCriteriaFactory.createQueryCriteria(em,
|
||||||
|
getType());
|
||||||
|
criteria.andEquals(field, value);
|
||||||
|
return criteria.getResultList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
protected Class<T> getType() {
|
||||||
|
return (Class<T>) type.getRawType();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
30
src/main/java/com/commafeed/backend/dao/UserService.java
Normal file
30
src/main/java/com/commafeed/backend/dao/UserService.java
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
package com.commafeed.backend.dao;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import com.commafeed.backend.security.PasswordEncryptionService;
|
||||||
|
import com.commafeed.frontend.utils.ModelFactory.MF;
|
||||||
|
import com.commafeed.model.User;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
|
||||||
|
public class UserService extends GenericDAO<User, Long> {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
PasswordEncryptionService encryptionService;
|
||||||
|
|
||||||
|
public User login(String name, String password) {
|
||||||
|
List<User> users = findByField(MF.i(MF.p(User.class).getName()), name);
|
||||||
|
User user = Iterables.getFirst(users, null);
|
||||||
|
if (user != null) {
|
||||||
|
boolean authenticated = encryptionService.authenticate(password,
|
||||||
|
user.getPassword(), user.getSalt());
|
||||||
|
if (authenticated) {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
53
src/main/java/com/commafeed/backend/feeds/FeedFetcher.java
Normal file
53
src/main/java/com/commafeed/backend/feeds/FeedFetcher.java
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
package com.commafeed.backend.feeds;
|
||||||
|
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import javax.ejb.AccessTimeout;
|
||||||
|
import javax.ejb.AsyncResult;
|
||||||
|
import javax.ejb.Asynchronous;
|
||||||
|
import javax.ejb.Lock;
|
||||||
|
import javax.ejb.LockType;
|
||||||
|
import javax.ejb.Singleton;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import org.apache.http.client.HttpClient;
|
||||||
|
import org.apache.http.client.ResponseHandler;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.impl.client.BasicResponseHandler;
|
||||||
|
import org.apache.http.impl.client.DefaultHttpClient;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.commafeed.model.Feed;
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public class FeedFetcher {
|
||||||
|
|
||||||
|
private static Logger log = LoggerFactory.getLogger(FeedFetcher.class);
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
FeedParser parser;
|
||||||
|
|
||||||
|
@Asynchronous
|
||||||
|
@Lock(LockType.READ)
|
||||||
|
@AccessTimeout(value = 15, unit = TimeUnit.SECONDS)
|
||||||
|
public Future<Feed> fetch(String feedUrl) {
|
||||||
|
log.debug("Fetching feed {}", feedUrl);
|
||||||
|
Feed feed = null;
|
||||||
|
|
||||||
|
HttpClient httpclient = new DefaultHttpClient();
|
||||||
|
try {
|
||||||
|
HttpGet httpget = new HttpGet(feedUrl);
|
||||||
|
ResponseHandler<String> responseHandler = new BasicResponseHandler();
|
||||||
|
String responseBody = httpclient.execute(httpget, responseHandler);
|
||||||
|
feed = parser.parse(feedUrl, responseBody);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
httpclient.getConnectionManager().shutdown();
|
||||||
|
}
|
||||||
|
return new AsyncResult<Feed>(feed);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
49
src/main/java/com/commafeed/backend/feeds/FeedParser.java
Normal file
49
src/main/java/com/commafeed/backend/feeds/FeedParser.java
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
package com.commafeed.backend.feeds;
|
||||||
|
|
||||||
|
import java.io.StringReader;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.ejb.Stateless;
|
||||||
|
|
||||||
|
import com.commafeed.model.Feed;
|
||||||
|
import com.commafeed.model.FeedEntry;
|
||||||
|
import com.sun.syndication.feed.synd.SyndEntry;
|
||||||
|
import com.sun.syndication.feed.synd.SyndFeed;
|
||||||
|
import com.sun.syndication.io.FeedException;
|
||||||
|
import com.sun.syndication.io.SyndFeedInput;
|
||||||
|
|
||||||
|
@Stateless
|
||||||
|
public class FeedParser {
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public Feed parse(String feedUrl, String xml) throws FeedException {
|
||||||
|
|
||||||
|
Feed feed = new Feed();
|
||||||
|
feed.setUrl(feedUrl);
|
||||||
|
feed.setLastUpdated(Calendar.getInstance().getTime());
|
||||||
|
|
||||||
|
try {
|
||||||
|
SyndFeed rss = new SyndFeedInput().build(new StringReader(xml));
|
||||||
|
|
||||||
|
List<SyndEntry> items = rss.getEntries();
|
||||||
|
for (SyndEntry item : items) {
|
||||||
|
FeedEntry entry = new FeedEntry();
|
||||||
|
entry.setGuid(item.getUri());
|
||||||
|
entry.setTitle(item.getTitle());
|
||||||
|
entry.setContent(item.getDescription() == null ? null : item
|
||||||
|
.getDescription().getValue());
|
||||||
|
entry.setUrl(item.getLink());
|
||||||
|
entry.setUpdated(item.getUpdatedDate() != null ? item
|
||||||
|
.getUpdatedDate() : item.getPublishedDate());
|
||||||
|
|
||||||
|
feed.getEntries().add(entry);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new FeedException("Could not parse feed : " + e.getMessage(),
|
||||||
|
e);
|
||||||
|
}
|
||||||
|
return feed;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
48
src/main/java/com/commafeed/backend/feeds/FeedTimer.java
Normal file
48
src/main/java/com/commafeed/backend/feeds/FeedTimer.java
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
package com.commafeed.backend.feeds;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
|
import javax.ejb.Schedule;
|
||||||
|
import javax.ejb.Singleton;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import com.commafeed.backend.dao.FeedEntryService;
|
||||||
|
import com.commafeed.backend.dao.FeedService;
|
||||||
|
import com.commafeed.model.Feed;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public class FeedTimer {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
FeedService feedService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
FeedEntryService feedEntryService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
FeedFetcher fetcher;
|
||||||
|
|
||||||
|
@Schedule(hour = "*", minute = "*", persistent = false)
|
||||||
|
private void timeout() {
|
||||||
|
List<Feed> feeds = feedService.findAll();
|
||||||
|
|
||||||
|
List<Future<Feed>> futures = Lists.newArrayList();
|
||||||
|
for (Feed feed : feeds) {
|
||||||
|
Future<Feed> future = fetcher.fetch(feed.getUrl());
|
||||||
|
futures.add(future);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Future<Feed> future : futures) {
|
||||||
|
try {
|
||||||
|
Feed feed = future.get();
|
||||||
|
feedEntryService
|
||||||
|
.updateEntries(feed.getUrl(), feed.getEntries());
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
package com.commafeed.backend.security;
|
||||||
|
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
import java.security.spec.KeySpec;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import javax.crypto.SecretKey;
|
||||||
|
import javax.crypto.SecretKeyFactory;
|
||||||
|
import javax.crypto.spec.PBEKeySpec;
|
||||||
|
import javax.ejb.Singleton;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.commafeed.backend.dao.UserService;
|
||||||
|
|
||||||
|
// http://www.javacodegeeks.com/2012/05/secure-password-storage-donts-dos-and.html
|
||||||
|
@Singleton
|
||||||
|
public class PasswordEncryptionService {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory
|
||||||
|
.getLogger(UserService.class);
|
||||||
|
|
||||||
|
public boolean authenticate(String attemptedPassword,
|
||||||
|
byte[] encryptedPassword, byte[] salt) {
|
||||||
|
// Encrypt the clear-text password using the same salt that was used to
|
||||||
|
// encrypt the original password
|
||||||
|
byte[] encryptedAttemptedPassword = null;
|
||||||
|
try {
|
||||||
|
encryptedAttemptedPassword = getEncryptedPassword(
|
||||||
|
attemptedPassword, salt);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// should never happen
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Authentication succeeds if encrypted password that the user entered
|
||||||
|
// is equal to the stored hash
|
||||||
|
return Arrays.equals(encryptedPassword, encryptedAttemptedPassword);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getEncryptedPassword(String password, byte[] salt) {
|
||||||
|
// PBKDF2 with SHA-1 as the hashing algorithm. Note that the NIST
|
||||||
|
// specifically names SHA-1 as an acceptable hashing algorithm for
|
||||||
|
// PBKDF2
|
||||||
|
String algorithm = "PBKDF2WithHmacSHA1";
|
||||||
|
// SHA-1 generates 160 bit hashes, so that's what makes sense here
|
||||||
|
int derivedKeyLength = 160;
|
||||||
|
// Pick an iteration count that works for you. The NIST recommends at
|
||||||
|
// least 1,000 iterations:
|
||||||
|
// http://csrc.nist.gov/publications/nistpubs/800-132/nist-sp800-132.pdf
|
||||||
|
// iOS 4.x reportedly uses 10,000:
|
||||||
|
// http://blog.crackpassword.com/2010/09/smartphone-forensics-cracking-blackberry-backup-passwords/
|
||||||
|
int iterations = 20000;
|
||||||
|
|
||||||
|
KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, iterations,
|
||||||
|
derivedKeyLength);
|
||||||
|
|
||||||
|
SecretKey key = null;
|
||||||
|
try {
|
||||||
|
SecretKeyFactory f = SecretKeyFactory.getInstance(algorithm);
|
||||||
|
key = f.generateSecret(spec);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// should never happen
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return key.getEncoded();
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] generateSalt() {
|
||||||
|
// VERY important to use SecureRandom instead of just Random
|
||||||
|
SecureRandom random = null;
|
||||||
|
try {
|
||||||
|
random = SecureRandom.getInstance("SHA1PRNG");
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
// should never happen
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate a 8 byte (64 bit) salt as recommended by RSA PKCS5
|
||||||
|
byte[] salt = new byte[8];
|
||||||
|
random.nextBytes(salt);
|
||||||
|
|
||||||
|
return salt;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
116
src/main/java/com/commafeed/frontend/CommaFeedApplication.java
Normal file
116
src/main/java/com/commafeed/frontend/CommaFeedApplication.java
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
package com.commafeed.frontend;
|
||||||
|
|
||||||
|
import javax.enterprise.inject.spi.BeanManager;
|
||||||
|
import javax.naming.InitialContext;
|
||||||
|
import javax.naming.NamingException;
|
||||||
|
|
||||||
|
import org.apache.wicket.Application;
|
||||||
|
import org.apache.wicket.Page;
|
||||||
|
import org.apache.wicket.Session;
|
||||||
|
import org.apache.wicket.ajax.AjaxRequestTarget;
|
||||||
|
import org.apache.wicket.authroles.authentication.AbstractAuthenticatedWebSession;
|
||||||
|
import org.apache.wicket.authroles.authentication.AuthenticatedWebApplication;
|
||||||
|
import org.apache.wicket.authroles.authorization.strategies.role.IRoleCheckingStrategy;
|
||||||
|
import org.apache.wicket.authroles.authorization.strategies.role.Roles;
|
||||||
|
import org.apache.wicket.authroles.authorization.strategies.role.annotations.AnnotationsRoleAuthorizationStrategy;
|
||||||
|
import org.apache.wicket.cdi.CdiConfiguration;
|
||||||
|
import org.apache.wicket.cdi.ConversationPropagation;
|
||||||
|
import org.apache.wicket.core.request.handler.PageProvider;
|
||||||
|
import org.apache.wicket.core.request.handler.RenderPageRequestHandler;
|
||||||
|
import org.apache.wicket.core.request.handler.RenderPageRequestHandler.RedirectPolicy;
|
||||||
|
import org.apache.wicket.markup.html.WebPage;
|
||||||
|
import org.apache.wicket.request.IRequestHandler;
|
||||||
|
import org.apache.wicket.request.Request;
|
||||||
|
import org.apache.wicket.request.Response;
|
||||||
|
import org.apache.wicket.request.cycle.AbstractRequestCycleListener;
|
||||||
|
import org.apache.wicket.request.cycle.RequestCycle;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.commafeed.frontend.components.auth.LoginPage;
|
||||||
|
import com.commafeed.frontend.pages.feed.FeedViewPage;
|
||||||
|
import com.commafeed.frontend.utils.exception.DisplayExceptionPage;
|
||||||
|
|
||||||
|
import de.agilecoders.wicket.Bootstrap;
|
||||||
|
import de.agilecoders.wicket.settings.BootstrapSettings;
|
||||||
|
import de.agilecoders.wicket.webjars.util.WicketWebjars;
|
||||||
|
|
||||||
|
public class CommaFeedApplication extends AuthenticatedWebApplication {
|
||||||
|
|
||||||
|
private Logger log = LoggerFactory.getLogger(CommaFeedApplication.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void init() {
|
||||||
|
super.init();
|
||||||
|
|
||||||
|
mountPage("login", LoginPage.class);
|
||||||
|
mountPage("feeds", FeedViewPage.class);
|
||||||
|
|
||||||
|
setupInjection();
|
||||||
|
|
||||||
|
getMarkupSettings().setStripWicketTags(true);
|
||||||
|
getMarkupSettings().setCompressWhitespace(true);
|
||||||
|
getMarkupSettings().setDefaultMarkupEncoding("UTF-8");
|
||||||
|
|
||||||
|
getSecuritySettings().setAuthorizationStrategy(
|
||||||
|
new AnnotationsRoleAuthorizationStrategy(
|
||||||
|
new IRoleCheckingStrategy() {
|
||||||
|
@Override
|
||||||
|
public boolean hasAnyRole(Roles roles) {
|
||||||
|
return CommaFeedSession.get().getRoles()
|
||||||
|
.hasAnyRole(roles);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
getRequestCycleListeners().add(new AbstractRequestCycleListener() {
|
||||||
|
@Override
|
||||||
|
public IRequestHandler onException(RequestCycle cycle, Exception ex) {
|
||||||
|
AjaxRequestTarget target = cycle.find(AjaxRequestTarget.class);
|
||||||
|
// redirect to the error page if ajax request, render error on
|
||||||
|
// current page otherwise
|
||||||
|
RedirectPolicy policy = target == null ? RedirectPolicy.NEVER_REDIRECT
|
||||||
|
: RedirectPolicy.AUTO_REDIRECT;
|
||||||
|
return new RenderPageRequestHandler(new PageProvider(
|
||||||
|
new DisplayExceptionPage(ex)), policy);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
mountPage("/error", DisplayExceptionPage.class);
|
||||||
|
|
||||||
|
BootstrapSettings settings = new BootstrapSettings();
|
||||||
|
Bootstrap.install(Application.get(), settings);
|
||||||
|
|
||||||
|
WicketWebjars.install(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<? extends Page> getHomePage() {
|
||||||
|
return FeedViewPage.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setupInjection() {
|
||||||
|
try {
|
||||||
|
BeanManager beanManager = (BeanManager) new InitialContext()
|
||||||
|
.lookup("java:comp/BeanManager");
|
||||||
|
new CdiConfiguration(beanManager).setPropagation(
|
||||||
|
ConversationPropagation.NONE).configure(this);
|
||||||
|
} catch (NamingException e) {
|
||||||
|
log.warn("Could not locate bean manager. CDI is disabled.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Session newSession(Request request, Response response) {
|
||||||
|
return new CommaFeedSession(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<? extends WebPage> getSignInPageClass() {
|
||||||
|
return LoginPage.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<? extends AbstractAuthenticatedWebSession> getWebSessionClass() {
|
||||||
|
return CommaFeedSession.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
51
src/main/java/com/commafeed/frontend/CommaFeedSession.java
Normal file
51
src/main/java/com/commafeed/frontend/CommaFeedSession.java
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
package com.commafeed.frontend;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import org.apache.wicket.Session;
|
||||||
|
import org.apache.wicket.authroles.authentication.AuthenticatedWebSession;
|
||||||
|
import org.apache.wicket.authroles.authorization.strategies.role.Roles;
|
||||||
|
import org.apache.wicket.request.Request;
|
||||||
|
|
||||||
|
import com.commafeed.backend.dao.UserService;
|
||||||
|
import com.commafeed.frontend.components.auth.Role;
|
||||||
|
import com.commafeed.model.User;
|
||||||
|
|
||||||
|
public class CommaFeedSession extends AuthenticatedWebSession {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
UserService userService;
|
||||||
|
|
||||||
|
private User user;
|
||||||
|
|
||||||
|
public CommaFeedSession(Request request) {
|
||||||
|
super(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public User getUser() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUser(User user) {
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CommaFeedSession get() {
|
||||||
|
return (CommaFeedSession) Session.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Roles getRoles() {
|
||||||
|
// TODO change this
|
||||||
|
return isSignedIn() ? new Roles(new String[] { Role.USER, Role.ADMIN })
|
||||||
|
: new Roles();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean authenticate(String userName, String password) {
|
||||||
|
User user = userService.login(userName, password);
|
||||||
|
setUser(user);
|
||||||
|
return user != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns:wicket="http://wicket.apache.org">
|
||||||
|
<body>
|
||||||
|
<wicket:panel>
|
||||||
|
<div class="css-treeview">
|
||||||
|
<ul>
|
||||||
|
<li wicket:id="tree"></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<wicket:fragment wicket:id="node">
|
||||||
|
<input type="checkbox" wicket:id="checkbox" />
|
||||||
|
<label wicket:id="label">
|
||||||
|
<span wicket:id="content"></span>
|
||||||
|
</label>
|
||||||
|
<ul>
|
||||||
|
<li wicket:id="node"></li>
|
||||||
|
</ul>
|
||||||
|
</wicket:fragment>
|
||||||
|
<wicket:fragment wicket:id="leaf">
|
||||||
|
<a wicket:id="link"></a>
|
||||||
|
</wicket:fragment>
|
||||||
|
</wicket:panel>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
package com.commafeed.frontend.components;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.apache.wicket.AttributeModifier;
|
||||||
|
import org.apache.wicket.Component;
|
||||||
|
import org.apache.wicket.markup.head.IHeaderResponse;
|
||||||
|
import org.apache.wicket.markup.html.basic.Label;
|
||||||
|
import org.apache.wicket.markup.html.form.CheckBox;
|
||||||
|
import org.apache.wicket.markup.html.form.FormComponentLabel;
|
||||||
|
import org.apache.wicket.markup.html.panel.Fragment;
|
||||||
|
import org.apache.wicket.markup.html.panel.Panel;
|
||||||
|
import org.apache.wicket.markup.repeater.RepeatingView;
|
||||||
|
import org.apache.wicket.model.IDetachable;
|
||||||
|
import org.apache.wicket.model.IModel;
|
||||||
|
|
||||||
|
import com.commafeed.frontend.references.csstree.CssTreeViewReference;
|
||||||
|
|
||||||
|
public abstract class CssTreeView<T, V> extends Panel {
|
||||||
|
|
||||||
|
private ITreeProvider<T, V> provider;
|
||||||
|
|
||||||
|
public CssTreeView(String id, final ITreeProvider<T, V> provider) {
|
||||||
|
super(id);
|
||||||
|
setRenderBodyOnly(true);
|
||||||
|
this.provider = provider;
|
||||||
|
|
||||||
|
RepeatingView view = new RepeatingView("tree");
|
||||||
|
addNode(null, view);
|
||||||
|
add(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addNode(T node, RepeatingView view) {
|
||||||
|
for (T child : provider.getChildren(node)) {
|
||||||
|
Fragment fragment = new Fragment(view.newChildId(), "node",
|
||||||
|
CssTreeView.this);
|
||||||
|
CheckBox checkBox = new CheckBox("checkbox");
|
||||||
|
checkBox.add(new AttributeModifier("checked", "checked"));
|
||||||
|
fragment.add(checkBox);
|
||||||
|
fragment.add(new FormComponentLabel("label", checkBox)
|
||||||
|
.add(new Label("content", provider.getChildLabel(child))
|
||||||
|
.setRenderBodyOnly(true)));
|
||||||
|
|
||||||
|
RepeatingView viewChild = new RepeatingView("node");
|
||||||
|
addNode(child, viewChild);
|
||||||
|
fragment.add(viewChild);
|
||||||
|
view.add(fragment);
|
||||||
|
}
|
||||||
|
for (V leaf : provider.getLeaves(node)) {
|
||||||
|
Fragment fragment = new Fragment(view.newChildId(), "leaf",
|
||||||
|
CssTreeView.this);
|
||||||
|
fragment.add(newLink("link", provider.model(leaf)));
|
||||||
|
view.add(fragment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDetach() {
|
||||||
|
super.onDetach();
|
||||||
|
provider.detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract Component newLink(String markupId, IModel<V> model);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void renderHead(IHeaderResponse response) {
|
||||||
|
super.renderHead(response);
|
||||||
|
CssTreeViewReference.render(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static interface ITreeProvider<T, V> extends IDetachable {
|
||||||
|
|
||||||
|
Collection<T> getChildren(T node);
|
||||||
|
|
||||||
|
IModel<String> getChildLabel(T node);
|
||||||
|
|
||||||
|
Collection<V> getLeaves(T node);
|
||||||
|
|
||||||
|
IModel<V> model(V object);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns:wicket="http://wicket.apache.org">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div class="page-header">
|
||||||
|
<h1>Login</h1>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<span wicket:id="login"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package com.commafeed.frontend.components.auth;
|
||||||
|
|
||||||
|
import org.apache.wicket.markup.head.IHeaderResponse;
|
||||||
|
import org.apache.wicket.markup.html.WebPage;
|
||||||
|
|
||||||
|
import de.agilecoders.wicket.Bootstrap;
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class LoginPage extends WebPage {
|
||||||
|
|
||||||
|
public LoginPage() {
|
||||||
|
add(new LoginPanel("login"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void renderHead(IHeaderResponse response) {
|
||||||
|
super.renderHead(response);
|
||||||
|
Bootstrap.renderHead(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns:wicket="http://wicket.apache.org">
|
||||||
|
<body>
|
||||||
|
<wicket:panel>
|
||||||
|
<span wicket:id="feedback"></span>
|
||||||
|
<form wicket:id="signInForm">
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label" for="username">User Name</label>
|
||||||
|
<div class="controls">
|
||||||
|
<input type="text" id="username" wicket:id="username"></input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label" for="password">Password</label>
|
||||||
|
<div class="controls">
|
||||||
|
<input type="password" id="password" wicket:id="password"></input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p class="help-block" wicket:id="rememberMeRow">
|
||||||
|
<input wicket:id="rememberMe" type="checkbox" /> Remember me
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<input type="submit" class="btn btn-primary" value="Log in" />
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</wicket:panel>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package com.commafeed.frontend.components.auth;
|
||||||
|
|
||||||
|
import org.apache.wicket.authroles.authentication.panel.SignInPanel;
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class LoginPanel extends SignInPanel {
|
||||||
|
|
||||||
|
public LoginPanel(String id) {
|
||||||
|
super(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package com.commafeed.frontend.components.auth;
|
||||||
|
|
||||||
|
public class Role {
|
||||||
|
public static final String USER = "user";
|
||||||
|
public static final String ADMIN = "admin";
|
||||||
|
}
|
||||||
10
src/main/java/com/commafeed/frontend/pages/BasePage.html
Normal file
10
src/main/java/com/commafeed/frontend/pages/BasePage.html
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns:wicket="http://wicket.apache.org">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<wicket:child />
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
19
src/main/java/com/commafeed/frontend/pages/BasePage.java
Normal file
19
src/main/java/com/commafeed/frontend/pages/BasePage.java
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package com.commafeed.frontend.pages;
|
||||||
|
|
||||||
|
import org.apache.wicket.authroles.authorization.strategies.role.annotations.AuthorizeInstantiation;
|
||||||
|
import org.apache.wicket.markup.head.IHeaderResponse;
|
||||||
|
import org.apache.wicket.markup.html.WebPage;
|
||||||
|
|
||||||
|
import com.commafeed.frontend.components.auth.Role;
|
||||||
|
|
||||||
|
import de.agilecoders.wicket.Bootstrap;
|
||||||
|
|
||||||
|
@AuthorizeInstantiation(Role.USER)
|
||||||
|
public abstract class BasePage extends WebPage {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void renderHead(IHeaderResponse response) {
|
||||||
|
super.renderHead(response);
|
||||||
|
Bootstrap.renderHead(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns:wicket="http://wicket.apache.org">
|
||||||
|
<body>
|
||||||
|
<wicket:extend>
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row-fluid">
|
||||||
|
<div class="span2">
|
||||||
|
<div wicket:id="tree"></div>
|
||||||
|
</div>
|
||||||
|
<div class="span10">
|
||||||
|
<div wicket:id="entries"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</wicket:extend>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
package com.commafeed.frontend.pages.feed;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import org.apache.wicket.Component;
|
||||||
|
import org.apache.wicket.ajax.AjaxRequestTarget;
|
||||||
|
import org.apache.wicket.markup.html.basic.Label;
|
||||||
|
import org.apache.wicket.model.IModel;
|
||||||
|
import org.apache.wicket.model.Model;
|
||||||
|
|
||||||
|
import com.commafeed.backend.dao.FeedCategoryService;
|
||||||
|
import com.commafeed.backend.dao.FeedSubscriptionService;
|
||||||
|
import com.commafeed.frontend.CommaFeedSession;
|
||||||
|
import com.commafeed.frontend.components.CssTreeView;
|
||||||
|
import com.commafeed.frontend.components.CssTreeView.ITreeProvider;
|
||||||
|
import com.commafeed.frontend.pages.BasePage;
|
||||||
|
import com.commafeed.frontend.utils.ModelFactory.MF;
|
||||||
|
import com.commafeed.frontend.utils.stateless.StatelessAjaxLink;
|
||||||
|
import com.commafeed.model.FeedCategory;
|
||||||
|
import com.commafeed.model.FeedSubscription;
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.collect.Collections2;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
public class FeedViewPage extends BasePage {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
FeedSubscriptionService feedSubscriptionService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
FeedCategoryService feedCategoryService;
|
||||||
|
|
||||||
|
public FeedViewPage() {
|
||||||
|
add(newTree("tree"));
|
||||||
|
add(new Label("entries", Model.of("")));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Component newTree(String markupId) {
|
||||||
|
ITreeProvider<FeedCategory, FeedSubscription> provider = new ITreeProvider<FeedCategory, FeedSubscription>() {
|
||||||
|
|
||||||
|
private List<FeedCategory> cats;
|
||||||
|
private List<FeedSubscription> subsWithoutCategory;
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
if (cats == null) {
|
||||||
|
cats = feedCategoryService.findAll(CommaFeedSession.get()
|
||||||
|
.getUser());
|
||||||
|
}
|
||||||
|
if (subsWithoutCategory == null) {
|
||||||
|
subsWithoutCategory = feedSubscriptionService.findByField(
|
||||||
|
MF.i(MF.p(FeedSubscription.class).getCategory()),
|
||||||
|
null);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<FeedCategory> getChildren(final FeedCategory node) {
|
||||||
|
init();
|
||||||
|
return Lists.newArrayList(Collections2.filter(cats,
|
||||||
|
new Predicate<FeedCategory>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(FeedCategory cat) {
|
||||||
|
return (node == null && cat.getParent() == null)
|
||||||
|
|| (cat.getParent() != null
|
||||||
|
&& node != null && cat
|
||||||
|
.getParent().getId() == node
|
||||||
|
.getId());
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<FeedSubscription> getLeaves(FeedCategory node) {
|
||||||
|
init();
|
||||||
|
if (node == null) {
|
||||||
|
return subsWithoutCategory;
|
||||||
|
}
|
||||||
|
return node.getSubscriptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IModel<String> getChildLabel(FeedCategory node) {
|
||||||
|
return Model.of(node.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IModel<FeedSubscription> model(FeedSubscription object) {
|
||||||
|
return Model.of(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void detach() {
|
||||||
|
cats = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
return new CssTreeView<FeedCategory, FeedSubscription>(markupId,
|
||||||
|
provider) {
|
||||||
|
@Override
|
||||||
|
protected Component newLink(String markupId,
|
||||||
|
final IModel<FeedSubscription> model) {
|
||||||
|
return new StatelessAjaxLink<Void>(markupId) {
|
||||||
|
@Override
|
||||||
|
public void onClick(AjaxRequestTarget target) {
|
||||||
|
System.out.println(model.getObject().getId());
|
||||||
|
}
|
||||||
|
}.setBody(Model.of(model.getObject().getTitle()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package com.commafeed.frontend.pages.home;
|
||||||
|
|
||||||
|
import com.commafeed.frontend.pages.BasePage;
|
||||||
|
|
||||||
|
public class HomePage extends BasePage {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package com.commafeed.frontend.references.csstree;
|
||||||
|
|
||||||
|
import org.apache.wicket.markup.head.CssHeaderItem;
|
||||||
|
import org.apache.wicket.markup.head.IHeaderResponse;
|
||||||
|
import org.apache.wicket.request.resource.CssResourceReference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* http://experiments.wemakesites.net/css3-treeview.html
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class CssTreeViewReference extends CssResourceReference {
|
||||||
|
private static CssTreeViewReference instance = new CssTreeViewReference();
|
||||||
|
|
||||||
|
public CssTreeViewReference() {
|
||||||
|
super(CssTreeViewReference.class, "css3-treeview.css");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void render(IHeaderResponse response) {
|
||||||
|
response.render(CssHeaderItem.forReference(instance));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CssTreeViewReference get() {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
.css-treeview ul,
|
||||||
|
.css-treeview li
|
||||||
|
{
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.css-treeview input
|
||||||
|
{
|
||||||
|
position: absolute;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.css-treeview
|
||||||
|
{
|
||||||
|
font: normal 11px "Segoe UI", Arial, Sans-serif;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.css-treeview a
|
||||||
|
{
|
||||||
|
color: #00f;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.css-treeview a:hover
|
||||||
|
{
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.css-treeview input + label + ul
|
||||||
|
{
|
||||||
|
margin: 0 0 0 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.css-treeview input ~ ul
|
||||||
|
{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.css-treeview label,
|
||||||
|
.css-treeview label::before
|
||||||
|
{
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.css-treeview input:disabled + label
|
||||||
|
{
|
||||||
|
cursor: default;
|
||||||
|
opacity: .6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.css-treeview input:checked:not(:disabled) ~ ul
|
||||||
|
{
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.css-treeview label,
|
||||||
|
.css-treeview label::before
|
||||||
|
{
|
||||||
|
background: url("icons.png") no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
.css-treeview label,
|
||||||
|
.css-treeview a,
|
||||||
|
.css-treeview label::before
|
||||||
|
{
|
||||||
|
display: inline-block;
|
||||||
|
height: 16px;
|
||||||
|
line-height: 16px;,
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.css-treeview label
|
||||||
|
{
|
||||||
|
background-position: 18px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.css-treeview label::before
|
||||||
|
{
|
||||||
|
content: "";
|
||||||
|
width: 16px;
|
||||||
|
margin: 0 22px 0 0;
|
||||||
|
vertical-align: middle;
|
||||||
|
background-position: 0 -32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.css-treeview input:checked + label::before
|
||||||
|
{
|
||||||
|
background-position: 0 -16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* webkit adjacent element selector bugfix */
|
||||||
|
@media screen and (-webkit-min-device-pixel-ratio:0)
|
||||||
|
{
|
||||||
|
.css-treeview
|
||||||
|
{
|
||||||
|
-webkit-animation: webkit-adjacent-element-selector-bugfix infinite 1s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@-webkit-keyframes webkit-adjacent-element-selector-bugfix
|
||||||
|
{
|
||||||
|
from
|
||||||
|
{
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
to
|
||||||
|
{
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 762 B |
@@ -0,0 +1,40 @@
|
|||||||
|
package com.commafeed.frontend.utils;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import org.apache.wicket.model.IModel;
|
||||||
|
import org.apache.wicket.model.LoadableDetachableModel;
|
||||||
|
import org.apache.wicket.model.Model;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
public class MapToListModel<K, V> extends
|
||||||
|
LoadableDetachableModel<List<Map.Entry<K, V>>> {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private IModel<Map<K, V>> model;
|
||||||
|
|
||||||
|
public MapToListModel(Map<K, V> map) {
|
||||||
|
this.model = Model.ofMap(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MapToListModel(IModel<Map<K, V>> model) {
|
||||||
|
this.model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<Entry<K, V>> load() {
|
||||||
|
Map<K, V> map = model.getObject();
|
||||||
|
return map == null ? null : Lists.newArrayList(map.entrySet());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void detach() {
|
||||||
|
super.detach();
|
||||||
|
model.detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
58
src/main/java/com/commafeed/frontend/utils/ModelFactory.java
Normal file
58
src/main/java/com/commafeed/frontend/utils/ModelFactory.java
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
package com.commafeed.frontend.utils;
|
||||||
|
|
||||||
|
import org.apache.wicket.model.PropertyModel;
|
||||||
|
|
||||||
|
import ch.lambdaj.Lambda;
|
||||||
|
import ch.lambdaj.function.argument.Argument;
|
||||||
|
import ch.lambdaj.function.argument.ArgumentsFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class to generate PropertyModels in a type-safe way
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ModelFactory {
|
||||||
|
|
||||||
|
public static <T> String invokedProperty(T proxiedValue) {
|
||||||
|
Argument<T> a = ArgumentsFactory.actualArgument(proxiedValue);
|
||||||
|
return a.getInkvokedPropertyName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> PropertyModel<T> model(Object value, T proxiedValue) {
|
||||||
|
String invokedPN = invokedProperty(proxiedValue);
|
||||||
|
PropertyModel<T> m = new PropertyModel<T>(value, invokedPN);
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static <T> T proxy(T t) {
|
||||||
|
Object object = Lambda.on(t.getClass());
|
||||||
|
return (T) object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T proxy(Class<T> clazz) {
|
||||||
|
return Lambda.on(clazz);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* shortcuts to ModelFactory
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static class MF {
|
||||||
|
|
||||||
|
public static <T> String i(T proxiedValue) {
|
||||||
|
return ModelFactory.invokedProperty(proxiedValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> PropertyModel<T> m(Object value, T proxiedValue) {
|
||||||
|
return ModelFactory.model(value, proxiedValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T p(T t) {
|
||||||
|
return ModelFactory.proxy(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T p(Class<T> clazz) {
|
||||||
|
return ModelFactory.proxy(clazz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
135
src/main/java/com/commafeed/frontend/utils/WicketUtils.java
Normal file
135
src/main/java/com/commafeed/frontend/utils/WicketUtils.java
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
package com.commafeed.frontend.utils;
|
||||||
|
|
||||||
|
import java.security.Principal;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.apache.wicket.ajax.WicketEventJQueryResourceReference;
|
||||||
|
import org.apache.wicket.markup.head.CssHeaderItem;
|
||||||
|
import org.apache.wicket.markup.head.IHeaderResponse;
|
||||||
|
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
|
||||||
|
import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
|
||||||
|
import org.apache.wicket.protocol.http.servlet.ServletWebRequest;
|
||||||
|
import org.apache.wicket.request.cycle.RequestCycle;
|
||||||
|
import org.apache.wicket.request.http.WebResponse;
|
||||||
|
import org.apache.wicket.request.resource.CssResourceReference;
|
||||||
|
import org.apache.wicket.request.resource.JavaScriptResourceReference;
|
||||||
|
import org.apache.wicket.util.io.IOUtils;
|
||||||
|
import org.apache.wicket.util.template.PackageTextTemplate;
|
||||||
|
|
||||||
|
import de.agilecoders.wicket.webjars.request.resource.WebjarsCssResourceReference;
|
||||||
|
import de.agilecoders.wicket.webjars.request.resource.WebjarsJavaScriptResourceReference;
|
||||||
|
|
||||||
|
public class WicketUtils {
|
||||||
|
|
||||||
|
public static void loadJQuery(IHeaderResponse response) {
|
||||||
|
response.render(JavaScriptHeaderItem
|
||||||
|
.forReference(WicketEventJQueryResourceReference.get()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JavaScriptHeaderItem buildJavaScriptHeaderItem(Class<?> klass) {
|
||||||
|
return JavaScriptHeaderItem
|
||||||
|
.forReference(new JavaScriptResourceReference(klass, klass
|
||||||
|
.getSimpleName() + ".js"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JavaScriptHeaderItem buildJavaScriptWebJarHeaderItem(
|
||||||
|
String name) {
|
||||||
|
return JavaScriptHeaderItem
|
||||||
|
.forReference(new WebjarsJavaScriptResourceReference(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void loadJS(IHeaderResponse response, Class<?> klass) {
|
||||||
|
response.render(buildJavaScriptHeaderItem(klass));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void loadJS(IHeaderResponse response, Class<?> klass,
|
||||||
|
Map<String, ? extends Object> variables) {
|
||||||
|
OnDomReadyHeaderItem result = null;
|
||||||
|
PackageTextTemplate template = null;
|
||||||
|
try {
|
||||||
|
template = new PackageTextTemplate(klass, klass.getSimpleName()
|
||||||
|
+ ".js");
|
||||||
|
String script = template.asString(variables);
|
||||||
|
result = OnDomReadyHeaderItem.forScript(script);
|
||||||
|
} finally {
|
||||||
|
IOUtils.closeQuietly(template);
|
||||||
|
}
|
||||||
|
response.render(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void loadWebJarJS(IHeaderResponse response, String name) {
|
||||||
|
response.render(buildJavaScriptWebJarHeaderItem(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CssHeaderItem buildCssHeaderItem(Class<?> klass) {
|
||||||
|
return CssHeaderItem.forReference(new CssResourceReference(klass, klass
|
||||||
|
.getSimpleName() + ".css"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CssHeaderItem buildCssWebJarHeaderItem(String name) {
|
||||||
|
return CssHeaderItem
|
||||||
|
.forReference(new WebjarsCssResourceReference(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void loadCSS(IHeaderResponse response, Class<?> klass) {
|
||||||
|
response.render(buildCssHeaderItem(klass));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void loadCSS(IHeaderResponse response, Class<?> klass,
|
||||||
|
Map<String, ? extends Object> variables) {
|
||||||
|
CssHeaderItem result = null;
|
||||||
|
PackageTextTemplate template = null;
|
||||||
|
try {
|
||||||
|
template = new PackageTextTemplate(klass, klass.getSimpleName()
|
||||||
|
+ ".js");
|
||||||
|
String css = template.asString(variables);
|
||||||
|
result = CssHeaderItem.forCSS(css, null);
|
||||||
|
} finally {
|
||||||
|
IOUtils.closeQuietly(template);
|
||||||
|
}
|
||||||
|
response.render(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void loadWebJarCSS(IHeaderResponse response, String name) {
|
||||||
|
response.render(buildCssWebJarHeaderItem(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HttpServletRequest getHttpServletRequest() {
|
||||||
|
ServletWebRequest servletWebRequest = (ServletWebRequest) RequestCycle
|
||||||
|
.get().getRequest();
|
||||||
|
return servletWebRequest.getContainerRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HttpServletResponse getHttpServletResponse() {
|
||||||
|
WebResponse webResponse = (WebResponse) RequestCycle.get()
|
||||||
|
.getResponse();
|
||||||
|
return (HttpServletResponse) webResponse.getContainerResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Principal getPrincipal() {
|
||||||
|
return getHttpServletRequest().getUserPrincipal();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getPrincipalName() {
|
||||||
|
Principal principal = getPrincipal();
|
||||||
|
return principal == null ? null : principal.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isUserInRole(String role) {
|
||||||
|
return getHttpServletRequest().isUserInRole(role);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isUserInRoles(String... roles) {
|
||||||
|
boolean inRoles = true;
|
||||||
|
for (String role : roles) {
|
||||||
|
if (!isUserInRole(role)) {
|
||||||
|
inRoles = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return inRoles;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package com.commafeed.frontend.utils.exception;
|
||||||
|
|
||||||
|
public class DisplayException extends RuntimeException {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private DisplayException() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public DisplayException(String message) {
|
||||||
|
super(message, new DisplayException());
|
||||||
|
}
|
||||||
|
|
||||||
|
public DisplayException(Throwable t) {
|
||||||
|
super(t.getMessage(), t);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DisplayException(String message, Throwable t) {
|
||||||
|
super(message, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en"
|
||||||
|
xmlns:wicket="http://git-wip-us.apache.org/repos/asf/wicket/repo?p=wicket.git;a=blob_plain;f=wicket-core/src/main/resources/META-INF/wicket-1.5.xsd;hb=master">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Error</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div class="page-header">
|
||||||
|
<h1>An unexpected error occured</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="alert alert-error" style="cursor: pointer"
|
||||||
|
data-toggle="collapse" data-target="#stacktrace">
|
||||||
|
<ul class="feedbackPanel unstyled" style="margin-bottom: 0px;">
|
||||||
|
<li class="feedbackPanelERROR">
|
||||||
|
<span class="feedbackPanelERROR" wicket:id="message"></span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
Go back to the <a href="javascript:window.history.back()">previous page</a> or to the <a wicket:id="homepage">home page.</a>
|
||||||
|
|
||||||
|
<div id="stacktrace" class="collapse">
|
||||||
|
<pre wicket:id="stacktrace"></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package com.commafeed.frontend.utils.exception;
|
||||||
|
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
|
||||||
|
import org.apache.wicket.markup.html.basic.Label;
|
||||||
|
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
|
||||||
|
|
||||||
|
import com.commafeed.frontend.pages.BasePage;
|
||||||
|
|
||||||
|
public class DisplayExceptionPage extends BasePage {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public DisplayExceptionPage(Throwable t) {
|
||||||
|
Throwable de = findDisplayException(t);
|
||||||
|
if (de != null) {
|
||||||
|
t = de;
|
||||||
|
}
|
||||||
|
|
||||||
|
add(new Label("message", t.getMessage()));
|
||||||
|
|
||||||
|
add(new BookmarkablePageLink<Void>("homepage", getApplication()
|
||||||
|
.getHomePage()));
|
||||||
|
|
||||||
|
StringWriter stringWriter = new StringWriter();
|
||||||
|
t.printStackTrace(new PrintWriter(stringWriter));
|
||||||
|
t.printStackTrace();
|
||||||
|
add(new Label("stacktrace", stringWriter.toString()));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private Throwable findDisplayException(Throwable t) {
|
||||||
|
while (t != null && !(t instanceof DisplayException)) {
|
||||||
|
t = t.getCause();
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
package com.commafeed.frontend.utils.stateless;
|
||||||
|
|
||||||
|
import org.apache.wicket.ajax.AjaxRequestTarget;
|
||||||
|
import org.apache.wicket.ajax.attributes.AjaxRequestAttributes;
|
||||||
|
import org.apache.wicket.ajax.form.AjaxFormSubmitBehavior;
|
||||||
|
import org.apache.wicket.markup.html.form.Form;
|
||||||
|
import org.apache.wicket.model.IModel;
|
||||||
|
import org.apache.wicket.request.mapper.parameter.PageParameters;
|
||||||
|
|
||||||
|
import de.agilecoders.wicket.markup.html.bootstrap.button.BootstrapAjaxButton;
|
||||||
|
import de.agilecoders.wicket.markup.html.bootstrap.button.Buttons;
|
||||||
|
|
||||||
|
public abstract class BootstrapStatelessAjaxButton extends BootstrapAjaxButton {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private PageParameters parameters;
|
||||||
|
|
||||||
|
public BootstrapStatelessAjaxButton(final String componentId,
|
||||||
|
final Buttons.Type buttonType) {
|
||||||
|
super(componentId, buttonType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BootstrapStatelessAjaxButton(final String componentId,
|
||||||
|
final IModel<String> model, final Buttons.Type buttonType) {
|
||||||
|
super(componentId, model, buttonType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BootstrapStatelessAjaxButton(final String componentId,
|
||||||
|
final IModel<String> model, final Buttons.Type buttonType,
|
||||||
|
PageParameters parameters) {
|
||||||
|
super(componentId, model, buttonType);
|
||||||
|
this.parameters = parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BootstrapStatelessAjaxButton(String id, Form<?> form,
|
||||||
|
Buttons.Type buttonType) {
|
||||||
|
super(id, form, buttonType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BootstrapStatelessAjaxButton(String id, IModel<String> model,
|
||||||
|
Form<?> form, Buttons.Type buttonType) {
|
||||||
|
super(id, model, form, buttonType);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public BootstrapStatelessAjaxButton(String id, IModel<String> model,
|
||||||
|
Form<?> form, Buttons.Type buttonType, PageParameters parameters) {
|
||||||
|
super(id, model, form, buttonType);
|
||||||
|
this.parameters = parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected AjaxFormSubmitBehavior newAjaxFormSubmitBehavior(String event) {
|
||||||
|
return new StatelessAjaxFormSubmitBehavior(getForm(), event) {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onSubmit(AjaxRequestTarget target) {
|
||||||
|
BootstrapStatelessAjaxButton.this.onSubmit(target,
|
||||||
|
BootstrapStatelessAjaxButton.this.getForm());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onAfterSubmit(AjaxRequestTarget target) {
|
||||||
|
BootstrapStatelessAjaxButton.this.onAfterSubmit(target,
|
||||||
|
BootstrapStatelessAjaxButton.this.getForm());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onError(AjaxRequestTarget target) {
|
||||||
|
BootstrapStatelessAjaxButton.this.onError(target,
|
||||||
|
BootstrapStatelessAjaxButton.this.getForm());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void updateAjaxAttributes(AjaxRequestAttributes attributes) {
|
||||||
|
super.updateAjaxAttributes(attributes);
|
||||||
|
BootstrapStatelessAjaxButton.this.updateAjaxAttributes(attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getDefaultProcessing() {
|
||||||
|
return BootstrapStatelessAjaxButton.this.getDefaultFormProcessing();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected PageParameters getPageParameters() {
|
||||||
|
return parameters;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
package com.commafeed.frontend.utils.stateless;
|
||||||
|
|
||||||
|
import org.apache.wicket.ajax.AjaxEventBehavior;
|
||||||
|
import org.apache.wicket.ajax.AjaxRequestTarget;
|
||||||
|
import org.apache.wicket.ajax.attributes.AjaxRequestAttributes;
|
||||||
|
import org.apache.wicket.model.IModel;
|
||||||
|
import org.apache.wicket.request.mapper.parameter.PageParameters;
|
||||||
|
|
||||||
|
import de.agilecoders.wicket.markup.html.bootstrap.button.BootstrapAjaxLink;
|
||||||
|
import de.agilecoders.wicket.markup.html.bootstrap.button.Buttons;
|
||||||
|
|
||||||
|
public abstract class BootstrapStatelessAjaxLink<T> extends BootstrapAjaxLink<T> {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private PageParameters parameters;
|
||||||
|
|
||||||
|
public BootstrapStatelessAjaxLink(final String id, final Buttons.Type buttonType) {
|
||||||
|
super(id, buttonType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BootstrapStatelessAjaxLink(String id, IModel<T> model,
|
||||||
|
Buttons.Type buttonType) {
|
||||||
|
super(id, model, buttonType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BootstrapStatelessAjaxLink(String id, IModel<T> model,
|
||||||
|
Buttons.Type buttonType, PageParameters parameters) {
|
||||||
|
super(id, model, buttonType);
|
||||||
|
this.parameters = parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected AjaxEventBehavior newAjaxEventBehavior(String event) {
|
||||||
|
return new StatelessAjaxEventBehavior(event) {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onEvent(AjaxRequestTarget target) {
|
||||||
|
BootstrapStatelessAjaxLink.this.onClick(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void updateAjaxAttributes(AjaxRequestAttributes attributes) {
|
||||||
|
super.updateAjaxAttributes(attributes);
|
||||||
|
BootstrapStatelessAjaxLink.this.updateAjaxAttributes(attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected PageParameters getPageParameters() {
|
||||||
|
return parameters;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package com.commafeed.frontend.utils.stateless;
|
||||||
|
|
||||||
|
import org.apache.wicket.Component;
|
||||||
|
import org.apache.wicket.ajax.AjaxEventBehavior;
|
||||||
|
import org.apache.wicket.request.Url;
|
||||||
|
import org.apache.wicket.request.mapper.parameter.PageParameters;
|
||||||
|
|
||||||
|
public abstract class StatelessAjaxEventBehavior extends AjaxEventBehavior {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public StatelessAjaxEventBehavior(final String event) {
|
||||||
|
super(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CharSequence getCallbackUrl() {
|
||||||
|
final Url url = Url.parse(super.getCallbackUrl().toString());
|
||||||
|
final PageParameters params = getPageParameters();
|
||||||
|
return StatelessEncoder.mergeParameters(url, params).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getStatelessHint(final Component component) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override this to pass the context of the current page to the behavior,
|
||||||
|
* allowing it to recreate the context for the ajax request.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
protected PageParameters getPageParameters() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package com.commafeed.frontend.utils.stateless;
|
||||||
|
|
||||||
|
import org.apache.wicket.Component;
|
||||||
|
import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
|
||||||
|
import org.apache.wicket.request.Url;
|
||||||
|
import org.apache.wicket.request.mapper.parameter.PageParameters;
|
||||||
|
|
||||||
|
public abstract class StatelessAjaxFormComponentUpdatingBehavior extends
|
||||||
|
AjaxFormComponentUpdatingBehavior {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -286307141298283926L;
|
||||||
|
|
||||||
|
public StatelessAjaxFormComponentUpdatingBehavior(final String event) {
|
||||||
|
super(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CharSequence getCallbackUrl() {
|
||||||
|
final Url url = Url.parse(super.getCallbackUrl().toString());
|
||||||
|
final PageParameters params = getPageParameters();
|
||||||
|
return StatelessEncoder.mergeParameters(url, params).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getStatelessHint(final Component component) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override this to pass the context of the current page to the behavior,
|
||||||
|
* allowing it to recreate the context for the ajax request.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
protected PageParameters getPageParameters() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package com.commafeed.frontend.utils.stateless;
|
||||||
|
|
||||||
|
import org.apache.wicket.Component;
|
||||||
|
import org.apache.wicket.ajax.form.AjaxFormSubmitBehavior;
|
||||||
|
import org.apache.wicket.markup.html.form.Form;
|
||||||
|
import org.apache.wicket.request.Url;
|
||||||
|
import org.apache.wicket.request.mapper.parameter.PageParameters;
|
||||||
|
|
||||||
|
public abstract class StatelessAjaxFormSubmitBehavior extends
|
||||||
|
AjaxFormSubmitBehavior {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public StatelessAjaxFormSubmitBehavior(final String event) {
|
||||||
|
super(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
public StatelessAjaxFormSubmitBehavior(Form<?> form, String event) {
|
||||||
|
super(form, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CharSequence getCallbackUrl() {
|
||||||
|
final Url url = Url.parse(super.getCallbackUrl().toString());
|
||||||
|
final PageParameters params = getPageParameters();
|
||||||
|
return StatelessEncoder.mergeParameters(url, params).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getStatelessHint(final Component component) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override this to pass the context of the current page to the behavior,
|
||||||
|
* allowing it to recreate the context for the ajax request.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
protected PageParameters getPageParameters() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
package com.commafeed.frontend.utils.stateless;
|
||||||
|
|
||||||
|
import org.apache.wicket.ajax.AjaxRequestTarget;
|
||||||
|
import org.apache.wicket.ajax.attributes.AjaxRequestAttributes;
|
||||||
|
import org.apache.wicket.ajax.markup.html.IAjaxLink;
|
||||||
|
import org.apache.wicket.markup.ComponentTag;
|
||||||
|
import org.apache.wicket.model.IModel;
|
||||||
|
import org.apache.wicket.request.mapper.parameter.PageParameters;
|
||||||
|
|
||||||
|
public abstract class StatelessAjaxLink<T> extends StatelessLink<T>
|
||||||
|
implements IAjaxLink {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -133600842398684777L;
|
||||||
|
|
||||||
|
public StatelessAjaxLink(final String id) {
|
||||||
|
this(id, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public StatelessAjaxLink(final String id,
|
||||||
|
final PageParameters params) {
|
||||||
|
this(id, null, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
public StatelessAjaxLink(final String id, final IModel<T> model) {
|
||||||
|
this(id, model, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public StatelessAjaxLink(final String id, final IModel<T> model,
|
||||||
|
final PageParameters params) {
|
||||||
|
super(id, model, params);
|
||||||
|
|
||||||
|
add(new StatelessAjaxEventBehavior("click") {
|
||||||
|
private static final long serialVersionUID = -8445395501430605953L;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void updateAjaxAttributes(AjaxRequestAttributes attributes) {
|
||||||
|
super.updateAjaxAttributes(attributes);
|
||||||
|
StatelessAjaxLink.this.updateAjaxAttributes(attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected PageParameters getPageParameters() {
|
||||||
|
return StatelessAjaxLink.this.getPageParameters();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onComponentTag(final ComponentTag tag) {
|
||||||
|
if (isLinkEnabled()) {
|
||||||
|
super.onComponentTag(tag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onEvent(final AjaxRequestTarget target) {
|
||||||
|
onClick(target);
|
||||||
|
target.add(StatelessAjaxLink.this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void updateAjaxAttributes(AjaxRequestAttributes attributes) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void onClick() {
|
||||||
|
onClick(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void onClick(final AjaxRequestTarget target);
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package com.commafeed.frontend.utils.stateless;
|
||||||
|
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.apache.wicket.request.Url;
|
||||||
|
import org.apache.wicket.request.mapper.parameter.INamedParameters;
|
||||||
|
import org.apache.wicket.request.mapper.parameter.PageParameters;
|
||||||
|
import org.apache.wicket.util.encoding.UrlEncoder;
|
||||||
|
|
||||||
|
final class StatelessEncoder {
|
||||||
|
|
||||||
|
static Url mergeParameters(final Url url, final PageParameters params) {
|
||||||
|
if (params == null) {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
Charset charset = url.getCharset();
|
||||||
|
Url mergedUrl = Url.parse(url.toString(), charset);
|
||||||
|
UrlEncoder urlEncoder = UrlEncoder.QUERY_INSTANCE;
|
||||||
|
Set<String> setParameters = new HashSet<String>();
|
||||||
|
|
||||||
|
for (INamedParameters.NamedPair pair : params.getAllNamed()) {
|
||||||
|
String key = urlEncoder.encode(pair.getKey(), charset);
|
||||||
|
String value = urlEncoder.encode(pair.getValue(), charset);
|
||||||
|
|
||||||
|
if (setParameters.contains(key)) {
|
||||||
|
mergedUrl.addQueryParameter(key, value);
|
||||||
|
} else {
|
||||||
|
mergedUrl.setQueryParameter(key, value);
|
||||||
|
setParameters.add(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mergedUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
private StatelessEncoder() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package com.commafeed.frontend.utils.stateless;
|
||||||
|
|
||||||
|
import org.apache.wicket.markup.html.link.Link;
|
||||||
|
import org.apache.wicket.model.IModel;
|
||||||
|
import org.apache.wicket.request.Url;
|
||||||
|
import org.apache.wicket.request.mapper.parameter.PageParameters;
|
||||||
|
|
||||||
|
public abstract class StatelessLink<T> extends Link<T> {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private final PageParameters parameters;
|
||||||
|
|
||||||
|
public StatelessLink(final String id) {
|
||||||
|
this(id, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public StatelessLink(final String id, final IModel<T> model) {
|
||||||
|
this(id, model, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public StatelessLink(final String id, final IModel<T> model,
|
||||||
|
final PageParameters params) {
|
||||||
|
super(id, model);
|
||||||
|
setMarkupId(id);
|
||||||
|
this.parameters = params;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final PageParameters getPageParameters() {
|
||||||
|
return parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean getStatelessHint() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected CharSequence getURL() {
|
||||||
|
final Url url = Url.parse(super.getURL().toString());
|
||||||
|
Url mergedUrl = StatelessEncoder.mergeParameters(url, parameters);
|
||||||
|
return mergedUrl.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
64
src/main/java/com/commafeed/model/Feed.java
Normal file
64
src/main/java/com/commafeed/model/Feed.java
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
package com.commafeed.model;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.FetchType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.OneToMany;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
import javax.persistence.Temporal;
|
||||||
|
import javax.persistence.TemporalType;
|
||||||
|
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "FEEDS")
|
||||||
|
public class Feed implements Serializable {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@Column(length = 2048)
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
@Temporal(TemporalType.TIMESTAMP)
|
||||||
|
private Date lastUpdated;
|
||||||
|
|
||||||
|
@OneToMany(mappedBy = "feed", fetch = FetchType.EAGER)
|
||||||
|
private Set<FeedEntry> entries = Sets.newHashSet();
|
||||||
|
|
||||||
|
public Feed() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Feed(String url) {
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUrl() {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUrl(String url) {
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getLastUpdated() {
|
||||||
|
return lastUpdated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastUpdated(Date lastUpdated) {
|
||||||
|
this.lastUpdated = lastUpdated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<FeedEntry> getEntries() {
|
||||||
|
return entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEntries(Set<FeedEntry> entries) {
|
||||||
|
this.entries = entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
78
src/main/java/com/commafeed/model/FeedCategory.java
Normal file
78
src/main/java/com/commafeed/model/FeedCategory.java
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
package com.commafeed.model;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.FetchType;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.OneToMany;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "FEEDCATEGORIES")
|
||||||
|
public class FeedCategory implements Serializable {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Column(length = 128)
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
private User user;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
private FeedCategory parent;
|
||||||
|
|
||||||
|
@OneToMany(mappedBy = "category", fetch = FetchType.EAGER)
|
||||||
|
private Set<FeedSubscription> subscriptions = Sets.newHashSet();
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public User getUser() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUser(User user) {
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FeedCategory getParent() {
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParent(FeedCategory parent) {
|
||||||
|
this.parent = parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<FeedSubscription> getSubscriptions() {
|
||||||
|
return subscriptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSubscriptions(Set<FeedSubscription> subscriptions) {
|
||||||
|
this.subscriptions = subscriptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
86
src/main/java/com/commafeed/model/FeedEntry.java
Normal file
86
src/main/java/com/commafeed/model/FeedEntry.java
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
package com.commafeed.model;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Lob;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
import javax.persistence.Temporal;
|
||||||
|
import javax.persistence.TemporalType;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "FEEDENTRIES")
|
||||||
|
public class FeedEntry implements Serializable {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@Column(length = 2048)
|
||||||
|
private String guid;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
private Feed feed;
|
||||||
|
|
||||||
|
@Column(length = 256)
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
@Lob
|
||||||
|
private String content;
|
||||||
|
|
||||||
|
@Column(length = 2048)
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
@Temporal(TemporalType.TIMESTAMP)
|
||||||
|
private Date updated;
|
||||||
|
|
||||||
|
public String getGuid() {
|
||||||
|
return guid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGuid(String guid) {
|
||||||
|
this.guid = guid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTitle(String title) {
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getContent() {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContent(String content) {
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUrl() {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUrl(String url) {
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getUpdated() {
|
||||||
|
return updated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUpdated(Date updated) {
|
||||||
|
this.updated = updated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Feed getFeed() {
|
||||||
|
return feed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFeed(Feed feed) {
|
||||||
|
this.feed = feed;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
71
src/main/java/com/commafeed/model/FeedEntryStatus.java
Normal file
71
src/main/java/com/commafeed/model/FeedEntryStatus.java
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
package com.commafeed.model;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "FEEDENTRYSTATUSES")
|
||||||
|
public class FeedEntryStatus implements Serializable {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
private User user;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
private FeedEntry entry;
|
||||||
|
|
||||||
|
@Column(name = "read_status")
|
||||||
|
private boolean read;
|
||||||
|
private boolean starred;
|
||||||
|
|
||||||
|
public User getUser() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUser(User user) {
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FeedEntry getEntry() {
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEntry(FeedEntry entry) {
|
||||||
|
this.entry = entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRead() {
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRead(boolean read) {
|
||||||
|
this.read = read;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isStarred() {
|
||||||
|
return starred;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStarred(boolean starred) {
|
||||||
|
this.starred = starred;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
73
src/main/java/com/commafeed/model/FeedSubscription.java
Normal file
73
src/main/java/com/commafeed/model/FeedSubscription.java
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
package com.commafeed.model;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "FEEDSUBSCRIPTIONS")
|
||||||
|
public class FeedSubscription implements Serializable {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
private User user;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
private Feed feed;
|
||||||
|
|
||||||
|
@Column(length = 128)
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
private FeedCategory category;
|
||||||
|
|
||||||
|
public Feed getFeed() {
|
||||||
|
return feed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFeed(Feed feed) {
|
||||||
|
this.feed = feed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public User getUser() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUser(User user) {
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTitle(String title) {
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FeedCategory getCategory() {
|
||||||
|
return category;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCategory(FeedCategory category) {
|
||||||
|
this.category = category;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
61
src/main/java/com/commafeed/model/User.java
Normal file
61
src/main/java/com/commafeed/model/User.java
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
package com.commafeed.model;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "USERS")
|
||||||
|
public class User implements Serializable {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Column(length = 32)
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Column(length = 256)
|
||||||
|
private byte[] password;
|
||||||
|
|
||||||
|
@Column(length = 8)
|
||||||
|
private byte[] salt;
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassword(byte[] password) {
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getSalt() {
|
||||||
|
return salt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSalt(byte[] salt) {
|
||||||
|
this.salt = salt;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
0
src/main/resources/.gitkeep
Normal file
0
src/main/resources/.gitkeep
Normal file
18
src/main/resources/META-INF/persistence.xml
Normal file
18
src/main/resources/META-INF/persistence.xml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<persistence version="2.0"
|
||||||
|
xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="
|
||||||
|
http://java.sun.com/xml/ns/persistence
|
||||||
|
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
|
||||||
|
<persistence-unit name="primary">
|
||||||
|
<jta-data-source>java:/jdbc/commafeedDS</jta-data-source>
|
||||||
|
<properties>
|
||||||
|
<property name="hibernate.hbm2ddl.auto" value="update" />
|
||||||
|
<property name="hibernate.show_sql" value="false" />
|
||||||
|
<property name="toplink.ddl-generation" value="drop-and-create-tables"/>
|
||||||
|
<property name="toplink.ddl-generation" value="create-tables"/>
|
||||||
|
<property name="toplink.cache.shared.default" value="false" />
|
||||||
|
<property name="eclipselink.weaving" value="false" />
|
||||||
|
</properties>
|
||||||
|
</persistence-unit>
|
||||||
|
</persistence>
|
||||||
16
src/main/resources/log4j.properties
Normal file
16
src/main/resources/log4j.properties
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
log4j.logger.com.commafeed=DEBUG, CONSOLE, FILE
|
||||||
|
log4j.logger.org=WARN, CONSOLE
|
||||||
|
log4j.logger.java=WARN, CONSOLE
|
||||||
|
log4j.logger.de=WARN, CONSOLE
|
||||||
|
|
||||||
|
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
|
||||||
|
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
|
||||||
|
log4j.appender.CONSOLE.layout.ConversionPattern=%-5p %d{ISO8601} [%c{1}\:%L] %m%n
|
||||||
|
|
||||||
|
log4j.appender.FILE=org.apache.log4j.RollingFileAppender
|
||||||
|
log4j.appender.FILE.File=${env.OPENSHIFT_LOG_DIR}commafeed.log
|
||||||
|
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
|
||||||
|
log4j.appender.FILE.layout.ConversionPattern=%-5p %d{ISO8601} [%c{1}\:%L/%t] %m%n
|
||||||
|
log4j.appender.FILE.MaxFileSize=100KB
|
||||||
|
log4j.appender.FILE.MaxBackupIndex=5
|
||||||
|
log4j.appender.FILE.Append=false
|
||||||
11
src/main/webapp/WEB-INF/beans.xml
Normal file
11
src/main/webapp/WEB-INF/beans.xml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:weld="http://jboss.org/schema/weld/beans"
|
||||||
|
xsi:schemaLocation="
|
||||||
|
http://java.sun.com/xml/ns/javaee http://docs.jboss.org/cdi/beans_1_0.xsd
|
||||||
|
http://jboss.org/schema/weld/beans http://jboss.org/schema/weld/beans_1_1.xsd">
|
||||||
|
|
||||||
|
<weld:scan>
|
||||||
|
<weld:include name="**" />
|
||||||
|
</weld:scan>
|
||||||
|
</beans>
|
||||||
22
src/main/webapp/WEB-INF/web.xml
Normal file
22
src/main/webapp/WEB-INF/web.xml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
|
||||||
|
|
||||||
|
<filter>
|
||||||
|
<filter-name>Wicket</filter-name>
|
||||||
|
<filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
|
||||||
|
<init-param>
|
||||||
|
<param-name>applicationClassName</param-name>
|
||||||
|
<param-value>com.commafeed.frontend.CommaFeedApplication</param-value>
|
||||||
|
</init-param>
|
||||||
|
<init-param>
|
||||||
|
<param-name>configuration</param-name>
|
||||||
|
<param-value>deployment</param-value>
|
||||||
|
</init-param>
|
||||||
|
</filter>
|
||||||
|
<filter-mapping>
|
||||||
|
<filter-name>Wicket</filter-name>
|
||||||
|
<url-pattern>/*</url-pattern>
|
||||||
|
</filter-mapping>
|
||||||
|
</web-app>
|
||||||
Reference in New Issue
Block a user