├── .gitignore ├── LICENSE ├── README.md └── retwisj ├── README.md ├── build.gradle ├── docs └── src │ └── reference │ ├── docbook │ ├── index.xml │ └── retwisj.xml │ └── resources │ ├── css │ ├── highlight.css │ └── manual.css │ ├── images │ ├── admon │ │ ├── blank.png │ │ ├── caution.gif │ │ ├── caution.png │ │ ├── caution.tif │ │ ├── draft.png │ │ ├── home.gif │ │ ├── home.png │ │ ├── important.gif │ │ ├── important.png │ │ ├── important.tif │ │ ├── next.gif │ │ ├── next.png │ │ ├── note.gif │ │ ├── note.png │ │ ├── note.tif │ │ ├── prev.gif │ │ ├── prev.png │ │ ├── tip.gif │ │ ├── tip.png │ │ ├── tip.tif │ │ ├── toc-blank.png │ │ ├── toc-minus.png │ │ ├── toc-plus.png │ │ ├── up.gif │ │ ├── up.png │ │ ├── warning.gif │ │ ├── warning.png │ │ └── warning.tif │ ├── callouts │ │ ├── 1.png │ │ ├── 10.png │ │ ├── 11.png │ │ ├── 12.png │ │ ├── 13.png │ │ ├── 14.png │ │ ├── 15.png │ │ ├── 2.png │ │ ├── 3.png │ │ ├── 4.png │ │ ├── 5.png │ │ ├── 6.png │ │ ├── 7.png │ │ ├── 8.png │ │ └── 9.png │ ├── logo.png │ └── xdev-spring_logo.jpg │ └── xsl │ ├── fopdf.xsl │ ├── highlight-fo.xsl │ ├── highlight.xsl │ ├── html-custom.xsl │ ├── html-single-custom.xsl │ ├── html.xsl │ ├── html_chunk.xsl │ └── pdf-custom.xsl ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── src └── main ├── java └── org │ └── springframework │ └── data │ └── redis │ └── samples │ └── retwisj │ ├── Post.java │ ├── Range.java │ ├── RetwisSecurity.java │ ├── User.java │ ├── redis │ ├── KeyUtils.java │ └── RetwisRepository.java │ └── web │ ├── CookieInterceptor.java │ ├── NoSuchDataException.java │ ├── RetwisController.java │ ├── WebPost.java │ └── WebUtils.java ├── resources ├── log4j.properties ├── messages.properties ├── messages_cn.properties ├── messages_en.properties ├── messages_es.properties ├── messages_ro.properties └── redis.properties └── webapp ├── WEB-INF ├── jsp │ ├── home.jsp │ ├── mentions.jsp │ ├── nodata.jsp │ ├── oops.jsp │ ├── signin.jsp │ ├── status.jsp │ └── timeline.jsp ├── retwisj-servlet.xml ├── spring │ └── applicationContext-redis.xml ├── templates │ ├── footer.jspf │ ├── header.jspf │ ├── network.jspf │ ├── post.jspf │ ├── posts.jspf │ └── userFollow.jspf └── web.xml └── static ├── images ├── favicon.ico └── springsource-logo.png └── styles ├── custom.css ├── ie.css ├── print.css └── screen.css /.gitignore: -------------------------------------------------------------------------------- 1 | bin 2 | build 3 | target 4 | .settings 5 | .gradle 6 | .classpath 7 | .project 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright 2015-Present Pivotal Software Inc. 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | 204 | 205 | 206 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # spring-data-keyvalue-examples is no longer actively maintained by VMware, Inc. 2 | 3 | Spring Data - Key Value - Examples 4 | ================================== 5 | 6 | Examples featuring [Spring Data](https://www.springsource.org/spring-data) Key Value project. 7 | The primary goal of the [Spring Data](https://www.springsource.org/spring-data) project is to make it easier to build Spring-powered applications that use new data access technologies such as non-relational databases, map-reduce frameworks, and cloud based data services. 8 | As the name implies, the **Key Value** modules provides integration with key value stores such as [Redis](https://code.google.com/p/redis/) and [Riak](https://riak.com/Riak.html). 9 | 10 | Example List 11 | ------------ 12 | RetwisJ - A Java, Spring Data port of [Retwis](https://redis.io/topics/twitter-clone). Documentation available [here](https://docs.spring.io/spring-data/data-keyvalue/examples/retwisj/current/) and blog post [here](https://spring.io/blog/2011/04/27/getting-started-redis-spring-cloud-foundry/) 13 | 14 | Contributing 15 | ------------ 16 | 17 | Here are some ways for you to get involved in the community: 18 | 19 | * Get involved with the Spring community on the Spring Community Forums. Please help out on the [forum](https://forum.spring.io/forumdisplay.php?f=80) by responding to questions and joining the debate. 20 | * Create [JIRA](https://jira.springframework.org/browse/DATAKV) tickets for bugs and new features and comment and vote on the ones that you are interested in. 21 | * Github is for social coding: if you want to write code, we encourage contributions through pull requests from [forks of this repository](https://help.github.com/forking/). If you want to contribute code this way, please reference a JIRA ticket as well covering the specific issue you are addressing. 22 | * Watch for upcoming articles on Spring by [subscribing](https://www.springsource.org/node/feed) to springframework.org 23 | 24 | Before we accept a non-trivial patch or pull request we will need you to sign the [contributor's agreement](https://support.springsource.com/spring_committer_signup). Signing the contributor's agreement does not grant anyone commit rights to the main repository, but it does mean that we can accept your contributions, and you will get an author credit if we do. Active contributors might be asked to join the core team, and given the ability to merge pull requests. 25 | -------------------------------------------------------------------------------- /retwisj/README.md: -------------------------------------------------------------------------------- 1 | Spring Data - Redis Twitter Example 2 | =================================== 3 | 4 | An improved Java implementation of the [Redis Twitter Clone](https://redis.io/topics/twitter-clone) using Spring Data. Tutorial available [here](https://docs.spring.io/spring-data/data-keyvalue/examples/retwisj/current/) 5 | 6 | 7 | Build 8 | ----- 9 | The project creates a WAR file suitable for deployment in a Servlet 2.5 container (such as Tomcat). It uses [Gradle](https://gradle.org/) as a build system. 10 | Simply type: 11 | 12 | gradlew build 13 | 14 | or if you have gradle installed on your machine and in your classpath: 15 | 16 | gradle build 17 | 18 | Start up an instance of the redis server, deploy your WAR and point your browser to (for the typical setup) [http://localhost:8080/retwisj](http://localhost:8080/retwisj) -------------------------------------------------------------------------------- /retwisj/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | maven { url 'https://repo.springsource.org/plugins-release' } 4 | } 5 | dependencies { 6 | classpath 'org.springframework.build.gradle:bundlor-plugin:0.1.2' 7 | classpath 'org.springframework.build.gradle:docbook-reference-plugin:0.2.4' 8 | } 9 | } 10 | 11 | description = 'Retwis-J' 12 | group = 'org.springframework.data' 13 | 14 | apply plugin: "java" 15 | apply plugin: 'eclipse' 16 | apply plugin: 'eclipse-wtp' 17 | apply plugin: 'idea' 18 | apply plugin: 'docbook-reference' 19 | apply plugin: 'war' 20 | 21 | group = 'org.springframework.data' 22 | version = "$springDataRedisTwitterVersion" 23 | 24 | sourceCompatibility = 1.6 25 | archivesBaseName = "retwisj" 26 | 27 | 28 | repositories { 29 | maven { url "https://repo.springsource.org/libs-snapshot" } 30 | maven { url "https://repo.springsource.org/plugins-release" } 31 | } 32 | 33 | dependencies { 34 | compile "org.slf4j:slf4j-api:$slf4jVersion" 35 | compile "org.slf4j:jcl-over-slf4j:$slf4jVersion" 36 | runtime "org.slf4j:slf4j-log4j12:$slf4jVersion" 37 | runtime "log4j:log4j:$log4jVersion" 38 | compile "redis.clients:jedis:2.1.0" 39 | compile "org.codehaus.jackson:jackson-core-asl:$jacksonVersion" 40 | compile "org.codehaus.jackson:jackson-mapper-asl:$jacksonVersion" 41 | compile "javax.servlet:com.springsource.javax.servlet.jsp.jstl:1.2.0" 42 | compile ("org.springframework.data:spring-data-redis:$springRedisVersion") { 43 | exclude group: 'commons-logging' 44 | } 45 | compile "org.springframework:spring-webmvc:$springVersion" 46 | compile "javax.inject:com.springsource.javax.inject:1.0.0" 47 | providedCompile "javax.servlet:com.springsource.javax.servlet:2.4.0" 48 | providedCompile "javax.servlet:com.springsource.javax.servlet.jsp:2.1.0" 49 | compile "javax.servlet:com.springsource.javax.servlet.jsp.jstl:1.2.0" 50 | compile "org.apache.taglibs:com.springsource.org.apache.taglibs.standard:1.1.2" 51 | // Testing 52 | testCompile "junit:junit:$junitVersion" 53 | testCompile "org.springframework:spring-test:$springVersion" 54 | testCompile "org.mockito:mockito-all:$mockitoVersion" 55 | } 56 | 57 | task wrapper(type: Wrapper) { 58 | description = 'Generates gradlew[.bat] scripts' 59 | gradleVersion = '1.2' 60 | } 61 | 62 | war { 63 | archiveName = baseName + "." + extension 64 | } 65 | 66 | reference { 67 | sourceDir = file('docs/src/reference/docbook') 68 | } 69 | 70 | defaultTasks 'build' -------------------------------------------------------------------------------- /retwisj/docs/src/reference/docbook/index.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | Spring Data Redis - Retwis-J 9 | Retwis-J 10 | 13 | Retwis-J 14 | 15 | 16 | 17 | Costin 18 | Leau 19 | SpringSource 20 | 21 | 22 | 23 | 24 | 25 | Copies of this document may be made for your own use and for distribution 26 | to others, provided that you do not charge any fee for such copies and 27 | further provided that each copy contains this Copyright Notice, whether 28 | distributed in print or electronically. 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/css/highlight.css: -------------------------------------------------------------------------------- 1 | /* 2 | code highlight CSS resemblign the Eclipse IDE default color schema 3 | @author Costin Leau 4 | */ 5 | 6 | .hl-keyword { 7 | color: #7F0055; 8 | font-weight: bold; 9 | } 10 | 11 | .hl-comment { 12 | color: #3F5F5F; 13 | font-style: italic; 14 | } 15 | 16 | .hl-multiline-comment { 17 | color: #3F5FBF; 18 | font-style: italic; 19 | } 20 | 21 | .hl-tag { 22 | color: #3F7F7F; 23 | } 24 | 25 | .hl-attribute { 26 | color: #7F007F; 27 | } 28 | 29 | .hl-value { 30 | color: #2A00FF; 31 | } 32 | 33 | .hl-string { 34 | color: #2A00FF; 35 | } -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/css/manual.css: -------------------------------------------------------------------------------- 1 | @IMPORT url("highlight.css"); 2 | 3 | html { 4 | padding: 0pt; 5 | margin: 0pt; 6 | } 7 | 8 | body { 9 | margin-left: 10%; 10 | margin-right: 10%; 11 | font-family: Arial, Sans-serif; 12 | } 13 | 14 | div { 15 | margin: 0pt; 16 | } 17 | 18 | p { 19 | text-align: justify; 20 | } 21 | 22 | hr { 23 | border: 1px solid gray; 24 | background: gray; 25 | } 26 | 27 | h1,h2,h3,h4 { 28 | color: #234623; 29 | font-family: Arial, Sans-serif; 30 | } 31 | 32 | pre { 33 | line-height: 1.0; 34 | color: black; 35 | } 36 | 37 | pre.programlisting { 38 | font-size: 10pt; 39 | padding: 7pt 3pt; 40 | border: 1pt solid black; 41 | background: #eeeeee; 42 | clear: both; 43 | } 44 | 45 | div.table { 46 | margin: 1em; 47 | padding: 0.5em; 48 | text-align: center; 49 | } 50 | 51 | div.table table { 52 | display: table; 53 | width: 100%; 54 | } 55 | 56 | div.table td { 57 | padding-left: 7px; 58 | padding-right: 7px; 59 | } 60 | 61 | .sidebar { 62 | float: right; 63 | margin: 10px 0 10px 30px; 64 | padding: 10px 20px 20px 20px; 65 | width: 33%; 66 | border: 1px solid black; 67 | background-color: #F4F4F4; 68 | font-size: 14px; 69 | } 70 | 71 | .mediaobject { 72 | padding-top: 30px; 73 | padding-bottom: 30px; 74 | } 75 | 76 | .legalnotice { 77 | font-family: Verdana, Arial, helvetica, sans-serif; 78 | font-size: 12px; 79 | font-style: italic; 80 | } 81 | 82 | p.releaseinfo { 83 | font-size: 100%; 84 | font-weight: bold; 85 | font-family: Verdana, Arial, helvetica, sans-serif; 86 | padding-top: 10px; 87 | } 88 | 89 | p.pubdate { 90 | font-size: 120%; 91 | font-weight: bold; 92 | font-family: Verdana, Arial, helvetica, sans-serif; 93 | } 94 | 95 | span.productname { 96 | font-size: 200%; 97 | font-weight: bold; 98 | font-family: Verdana, Arial, helvetica, sans-serif; 99 | } 100 | -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/admon/blank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/admon/blank.png -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/admon/caution.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/admon/caution.gif -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/admon/caution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/admon/caution.png -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/admon/caution.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/admon/caution.tif -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/admon/draft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/admon/draft.png -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/admon/home.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/admon/home.gif -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/admon/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/admon/home.png -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/admon/important.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/admon/important.gif -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/admon/important.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/admon/important.png -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/admon/important.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/admon/important.tif -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/admon/next.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/admon/next.gif -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/admon/next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/admon/next.png -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/admon/note.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/admon/note.gif -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/admon/note.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/admon/note.png -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/admon/note.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/admon/note.tif -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/admon/prev.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/admon/prev.gif -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/admon/prev.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/admon/prev.png -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/admon/tip.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/admon/tip.gif -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/admon/tip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/admon/tip.png -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/admon/tip.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/admon/tip.tif -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/admon/toc-blank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/admon/toc-blank.png -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/admon/toc-minus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/admon/toc-minus.png -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/admon/toc-plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/admon/toc-plus.png -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/admon/up.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/admon/up.gif -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/admon/up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/admon/up.png -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/admon/warning.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/admon/warning.gif -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/admon/warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/admon/warning.png -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/admon/warning.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/admon/warning.tif -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/callouts/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/callouts/1.png -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/callouts/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/callouts/10.png -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/callouts/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/callouts/11.png -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/callouts/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/callouts/12.png -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/callouts/13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/callouts/13.png -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/callouts/14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/callouts/14.png -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/callouts/15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/callouts/15.png -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/callouts/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/callouts/2.png -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/callouts/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/callouts/3.png -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/callouts/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/callouts/4.png -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/callouts/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/callouts/5.png -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/callouts/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/callouts/6.png -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/callouts/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/callouts/7.png -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/callouts/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/callouts/8.png -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/callouts/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/callouts/9.png -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/logo.png -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/images/xdev-spring_logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/docs/src/reference/resources/images/xdev-spring_logo.jpg -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/xsl/fopdf.xsl: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 11 | 12 | 13 | 14 | 15 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | , 55 | 56 | 57 | 58 | 59 | ( 60 | 61 | ) 62 | 63 | 64 | 65 | Copyright © 2006-2009 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | -5em 96 | -5em 97 | 98 | 99 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | Spring Data Redis () 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 149 | 150 | 151 | 0 152 | 153 | 1 154 | 1 155 | 0 156 | 157 | 160 | 161 | 162 | 163 | book toc 164 | 165 | 166 | 167 | 2 168 | 169 | 170 | 171 | 172 | 173 | 176 | 177 | 178 | 179 | 0 180 | 0 181 | 0 182 | 183 | 184 | 5mm 185 | 10mm 186 | 10mm 187 | 188 | 15mm 189 | 10mm 190 | 0mm 191 | 192 | 18mm 193 | 18mm 194 | 195 | 196 | 0pc 197 | 198 | 201 | 202 | 203 | justify 204 | false 205 | 206 | 207 | 11 208 | 8 209 | 210 | 211 | 1.4 212 | 213 | 214 | 215 | 216 | 217 | 218 | 0.8em 219 | 220 | 221 | 224 | 225 | 226 | 17.4cm 227 | 228 | 229 | 230 | 4pt 231 | 4pt 232 | 4pt 233 | 4pt 234 | 235 | 236 | 237 | 0.1pt 238 | 0.1pt 239 | 240 | 243 | 244 | 245 | 1 246 | 247 | 248 | 249 | 252 | 253 | 254 | 255 | left 256 | bold 257 | 258 | 259 | pt 260 | 261 | 262 | 263 | 265 | 266 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 0.8em 277 | 0.8em 278 | 0.8em 279 | 280 | 281 | pt 282 | 283 | 0.1em 284 | 0.1em 285 | 0.1em 286 | 287 | 288 | 0.6em 289 | 0.6em 290 | 0.6em 291 | 292 | 293 | pt 294 | 295 | 0.1em 296 | 0.1em 297 | 0.1em 298 | 299 | 300 | 0.4em 301 | 0.4em 302 | 0.4em 303 | 304 | 305 | pt 306 | 307 | 0.1em 308 | 0.1em 309 | 0.1em 310 | 311 | 312 | 313 | 314 | bold 315 | 316 | 317 | pt 318 | 319 | false 320 | 0.4em 321 | 0.6em 322 | 0.8em 323 | 324 | 325 | 328 | 329 | 330 | 331 | 332 | 333 | pt 334 | 335 | 336 | 337 | 338 | 1em 339 | 1em 340 | 1em 341 | #444444 342 | solid 343 | 0.1pt 344 | 0.5em 345 | 0.5em 346 | 0.5em 347 | 0.5em 348 | 0.5em 349 | 0.5em 350 | 351 | 352 | 353 | 1 354 | 355 | #F0F0F0 356 | 357 | 358 | 361 | 362 | 363 | 0 364 | 1 365 | 366 | 367 | 90 368 | 369 | 372 | 373 | 374 | '1' 375 | src/docbkx/resources/images/admons/ 376 | 377 | 380 | 381 | 382 | 383 | figure after 384 | example before 385 | equation before 386 | table before 387 | procedure before 388 | 389 | 390 | 391 | 1 392 | 393 | 394 | 395 | 0.8em 396 | 0.8em 397 | 0.8em 398 | 0.1em 399 | 0.1em 400 | 0.1em 401 | 402 | 403 | 406 | 407 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 448 | 449 | 450 | -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/xsl/highlight-fo.xsl: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/xsl/highlight.xsl: -------------------------------------------------------------------------------- 1 | 2 | 5 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/xsl/html-custom.xsl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 21 | 22 | 26 | 27 | 28 | 29 | 30 | '5' 31 | '1' 32 | 33 | 34 | 1 35 | 36 | 37 | 1 38 | 39 | 40 | 1 41 | 0 42 | 1 43 | 44 | 45 | 46 | images/admon/ 47 | .png 48 | 49 | 120 50 | images/callouts/ 51 | .png 52 | 53 | 54 | css/manual.css 55 | text/css 56 | book toc,title 57 | 58 | text-align: left 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 3 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | Begin Google Analytics code 120 | 124 | 130 | End Google Analytics code 131 | 132 | 133 | 134 | 135 | Begin LoopFuse code 136 | 138 | 142 | End LoopFuse code 143 | 144 | 145 | -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/xsl/html-single-custom.xsl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 21 | 22 | 26 | 27 | 28 | 29 | 30 | 31 | 1 32 | 33 | 34 | 1 35 | 36 | 37 | 1 38 | 0 39 | 1 40 | 41 | 42 | 43 | images/admon/ 44 | .png 45 | 46 | 120 47 | images/callouts/ 48 | .png 49 | 50 | 51 | css/manual.css 52 | text/css 53 | book toc,title 54 | 55 | text-align: left 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 2 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | Begin Google Analytics code 117 | 121 | 127 | End Google Analytics code 128 | 129 | 130 | 131 | 132 | Begin LoopFuse code 133 | 135 | 139 | End LoopFuse code 140 | 141 | 142 | -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/xsl/html.xsl: -------------------------------------------------------------------------------- 1 | 2 | 6 | 11 | 12 | 13 | 14 | 15 | 18 | 19 | 20 | 0 21 | 0 22 | 1 23 | 24 | 27 | 28 | 29 | 30 | book toc 31 | 32 | 33 | 34 | 3 35 | 36 | 39 | 40 | 41 | 1 42 | 43 | 44 | 45 | 48 | 49 | 50 | 1 51 | 52 | 53 | 90 54 | 55 | 58 | 59 | 60 | 1 61 | images/admons/ 62 | 65 | 66 | 67 | figure after 68 | example before 69 | equation before 70 | table before 71 | procedure before 72 | 73 | 74 | 75 | , 76 | 77 | 78 | 79 | () 80 | 81 | 82 | 83 | 84 |
85 |

Authors

86 |

87 | 88 |

89 |
90 | 93 | 94 | 95 |
96 | 98 | 99 | 100 | 101 | 102 | 103 |
104 |
105 | 106 |
107 | 108 | -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/xsl/html_chunk.xsl: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | '5' 17 | '1' 18 | 0 19 | 0 20 | 1 21 | 24 | 25 | 26 | book toc 27 | qandaset toc 28 | 29 | 30 | 3 31 | 34 | 35 | 1 36 | 37 | 38 | 41 | 42 | 1 43 | 90 44 | 45 | 48 | 49 | 50 | 1 51 | images/admons/ 52 | 55 | 56 | 57 | figure after 58 | example before 59 | equation before 60 | table before 61 | procedure before 62 | 63 | 64 | 65 | , 66 | 67 | 68 | 69 | () 70 | 71 | 74 | 75 | 76 | 77 |
78 |

Authors

79 |

80 | 81 |

82 |
83 | 86 | 87 | 88 | 97 | 98 | 99 | 100 | 1 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 111 | 117 | 118 | 219 | 220 | 221 |
222 | -------------------------------------------------------------------------------- /retwisj/docs/src/reference/resources/xsl/pdf-custom.xsl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 21 | 22 | 27 | 28 | 29 | 30 | 31 | 32 | '1' 33 | images/admon/ 34 | .png 35 | 36 | 38 | 39 | 40 | 24pt 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -5em 63 | -5em 64 | 65 | 66 | 69 | 70 | 71 | book toc,title 72 | 73 | 74 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | please define productname in your docbook file! 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 202 | 203 | 204 | 1 205 | 0 206 | 1 207 | 1 208 | 209 | 212 | 213 | 214 | 0 215 | 0 216 | 0 217 | 218 | 221 | 222 | false 223 | 224 | 225 | 11 226 | 8 227 | 228 | 229 | 1.4 230 | 231 | 232 | 233 | left 234 | bold 235 | 236 | 237 | pt 238 | 239 | 240 | 241 | 243 | 244 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 0.8em 255 | 0.8em 256 | 0.8em 257 | 258 | 259 | pt 260 | 261 | 0.1em 262 | 0.1em 263 | 0.1em 264 | 265 | 266 | 0.6em 267 | 0.6em 268 | 0.6em 269 | 270 | 271 | pt 272 | 273 | 0.1em 274 | 0.1em 275 | 0.1em 276 | 277 | 278 | 0.4em 279 | 0.4em 280 | 0.4em 281 | 282 | 283 | pt 284 | 285 | 0.1em 286 | 0.1em 287 | 0.1em 288 | 289 | 290 | 0.3em 291 | 0.3em 292 | 0.3em 293 | 294 | 295 | pt 296 | 297 | 0.1em 298 | 0.1em 299 | 0.1em 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 342 | 343 | 344 | 345 | 4pt 346 | 4pt 347 | 4pt 348 | 4pt 349 | 350 | 351 | 352 | 0.1pt 353 | 0.1pt 354 | 355 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 370 | 371 | 372 | 373 | 374 | 375 | pt 376 | 377 | 378 | 379 | 380 | 1em 381 | 1em 382 | 1em 383 | 0.1em 384 | 0.1em 385 | 0.1em 386 | 387 | #444444 388 | solid 389 | 0.1pt 390 | 0.5em 391 | 0.5em 392 | 0.5em 393 | 0.5em 394 | 0.5em 395 | 0.5em 396 | 397 | 398 | 399 | 1 400 | 401 | #F0F0F0 402 | 403 | 404 | 405 | 0.1em 406 | 0.1em 407 | 0.1em 408 | 0.1em 409 | 0.1em 410 | 0.1em 411 | 412 | 413 | 414 | 0.5em 415 | 0.5em 416 | 0.5em 417 | 0.1em 418 | 0.1em 419 | 0.1em 420 | always 421 | 422 | 423 | 426 | 427 | 428 | normal 429 | italic 430 | 431 | 432 | pt 433 | 434 | false 435 | 0.1em 436 | 0.1em 437 | 0.1em 438 | 439 | 440 | 443 | 444 | 445 | 0 446 | 1 447 | 448 | 449 | 90 450 | 451 | 454 | 455 | 456 | 457 | figure after 458 | example after 459 | equation before 460 | table before 461 | procedure before 462 | 463 | 464 | 465 | 1 466 | 467 | 0pt 468 | 469 | 470 | 3 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 489 | 522 | 523 | -------------------------------------------------------------------------------- /retwisj/gradle.properties: -------------------------------------------------------------------------------- 1 | ## Dependecies Version 2 | 3 | # Logging 4 | log4jVersion = 1.2.17 5 | slf4jVersion = 1.6.6 6 | 7 | # Common libraries 8 | springVersion = 3.1.4.RELEASE 9 | springRedisVersion = 1.1.0.RELEASE 10 | jacksonVersion = 1.8.3 11 | 12 | # Testing 13 | junitVersion = 4.8.1 14 | mockitoVersion = 1.8.5 15 | 16 | springDataRedisTwitterVersion=1.0.0.BUILD-SNAPSHOT -------------------------------------------------------------------------------- /retwisj/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /retwisj/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Feb 08 11:31:50 EET 2013 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=http\://services.gradle.org/distributions/gradle-1.2-bin.zip 7 | -------------------------------------------------------------------------------- /retwisj/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # For Cygwin, ensure paths are in UNIX format before anything is touched. 46 | if $cygwin ; then 47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 48 | fi 49 | 50 | # Attempt to set APP_HOME 51 | # Resolve links: $0 may be a link 52 | PRG="$0" 53 | # Need this for relative symlinks. 54 | while [ -h "$PRG" ] ; do 55 | ls=`ls -ld "$PRG"` 56 | link=`expr "$ls" : '.*-> \(.*\)$'` 57 | if expr "$link" : '/.*' > /dev/null; then 58 | PRG="$link" 59 | else 60 | PRG=`dirname "$PRG"`"/$link" 61 | fi 62 | done 63 | SAVED="`pwd`" 64 | cd "`dirname \"$PRG\"`/" >&- 65 | APP_HOME="`pwd -P`" 66 | cd "$SAVED" >&- 67 | 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 69 | 70 | # Determine the Java command to use to start the JVM. 71 | if [ -n "$JAVA_HOME" ] ; then 72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 73 | # IBM's JDK on AIX uses strange locations for the executables 74 | JAVACMD="$JAVA_HOME/jre/sh/java" 75 | else 76 | JAVACMD="$JAVA_HOME/bin/java" 77 | fi 78 | if [ ! -x "$JAVACMD" ] ; then 79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | else 85 | JAVACMD="java" 86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 87 | 88 | Please set the JAVA_HOME variable in your environment to match the 89 | location of your Java installation." 90 | fi 91 | 92 | # Increase the maximum file descriptors if we can. 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 94 | MAX_FD_LIMIT=`ulimit -H -n` 95 | if [ $? -eq 0 ] ; then 96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 97 | MAX_FD="$MAX_FD_LIMIT" 98 | fi 99 | ulimit -n $MAX_FD 100 | if [ $? -ne 0 ] ; then 101 | warn "Could not set maximum file descriptor limit: $MAX_FD" 102 | fi 103 | else 104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 105 | fi 106 | fi 107 | 108 | # For Darwin, add options to specify how the application appears in the dock 109 | if $darwin; then 110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 111 | fi 112 | 113 | # For Cygwin, switch paths to Windows format before running java 114 | if $cygwin ; then 115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /retwisj/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /retwisj/src/main/java/org/springframework/data/redis/samples/retwisj/Post.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 the original uid or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.data.redis.samples.retwisj; 17 | 18 | 19 | /** 20 | * Class describing a post. 21 | * 22 | * @author Costin Leau 23 | */ 24 | public class Post { 25 | 26 | private String content; 27 | private String uid; 28 | private String time = String.valueOf(System.currentTimeMillis()); 29 | private String replyPid; 30 | private String replyUid; 31 | 32 | /** 33 | * Returns the content. 34 | * 35 | * @return Returns the content 36 | */ 37 | public String getContent() { 38 | return content; 39 | } 40 | 41 | /** 42 | * @param content The content to set. 43 | */ 44 | public void setContent(String content) { 45 | this.content = content; 46 | } 47 | 48 | 49 | /** 50 | * Returns the uid. 51 | * 52 | * @return Returns the uid 53 | */ 54 | public String getUid() { 55 | return uid; 56 | } 57 | 58 | /** 59 | * @param uid The uid to set. 60 | */ 61 | public void setUid(String author) { 62 | this.uid = author; 63 | } 64 | 65 | /** 66 | * Returns the time. 67 | * 68 | * @return Returns the time 69 | */ 70 | public String getTime() { 71 | return time; 72 | } 73 | 74 | /** 75 | * @param time The time to set. 76 | */ 77 | public void setTime(String time) { 78 | this.time = time; 79 | } 80 | 81 | /** 82 | * Returns the replyPid. 83 | * 84 | * @return Returns the replyPid 85 | */ 86 | public String getReplyPid() { 87 | return replyPid; 88 | } 89 | 90 | /** 91 | * @param replyPid The replyPid to set. 92 | */ 93 | public void setReplyPid(String replyPid) { 94 | this.replyPid = replyPid; 95 | } 96 | 97 | /** 98 | * Returns the replyUid. 99 | * 100 | * @return Returns the replyUid 101 | */ 102 | public String getReplyUid() { 103 | return replyUid; 104 | } 105 | 106 | /** 107 | * @param replyUid The replyUid to set. 108 | */ 109 | public void setReplyUid(String replyUid) { 110 | this.replyUid = replyUid; 111 | } 112 | 113 | @Override 114 | public String toString() { 115 | return "Post [content=" + content + ", replyPid=" + replyPid + ", replyUid=" + replyUid 116 | + ", time=" + time + ", uid=" + uid + "]"; 117 | } 118 | } -------------------------------------------------------------------------------- /retwisj/src/main/java/org/springframework/data/redis/samples/retwisj/Range.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.data.redis.samples.retwisj; 17 | 18 | /** 19 | * Basic object indicating a range of objects to retrieve. Default is 10 objects (starting at zero). 20 | * 21 | * @author Costin Leau 22 | */ 23 | public class Range { 24 | 25 | private static final int SIZE = 9; 26 | public int begin = 0; 27 | public int end = SIZE; 28 | 29 | public Range() { 30 | }; 31 | 32 | public Range(int begin, int end) { 33 | this.begin = begin; 34 | this.end = end; 35 | } 36 | 37 | public Range(int pageNumber) { 38 | this.begin = 0; 39 | this.end = pageNumber * SIZE; 40 | } 41 | 42 | public int getPages() { 43 | return (int) Math.round(Math.ceil(end / SIZE)); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /retwisj/src/main/java/org/springframework/data/redis/samples/retwisj/RetwisSecurity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.data.redis.samples.retwisj; 17 | 18 | import org.springframework.core.NamedThreadLocal; 19 | import org.springframework.util.StringUtils; 20 | 21 | /** 22 | * Simple security class that saves the local user info across each request. 23 | * 24 | * @author Costin Leau 25 | */ 26 | public abstract class RetwisSecurity { 27 | 28 | private static class UserInfo { 29 | String name; 30 | String uid; 31 | } 32 | 33 | private static final ThreadLocal user = new NamedThreadLocal("Retwis-id"); 34 | 35 | public static String getName() { 36 | UserInfo userInfo = user.get(); 37 | return (userInfo != null ? userInfo.name : null); 38 | } 39 | 40 | public static String getUid() { 41 | UserInfo userInfo = user.get(); 42 | return (userInfo != null ? userInfo.uid : null); 43 | } 44 | 45 | public static void setUser(String name, String uid) { 46 | UserInfo userInfo = new UserInfo(); 47 | userInfo.name = name; 48 | userInfo.uid = uid; 49 | user.set(userInfo); 50 | } 51 | 52 | public static boolean isUserSignedIn(String name) { 53 | UserInfo userInfo = user.get(); 54 | return userInfo != null && userInfo.name.equals(name); 55 | } 56 | 57 | public static boolean isSignedIn() { 58 | return StringUtils.hasText(getName()); 59 | } 60 | 61 | public static void clean() { 62 | user.set(null); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /retwisj/src/main/java/org/springframework/data/redis/samples/retwisj/User.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.data.redis.samples.retwisj; 17 | 18 | 19 | /** 20 | * Class describing a user. 21 | * 22 | * @author Costin Leau 23 | */ 24 | public class User { 25 | 26 | private Long id; 27 | private String name; 28 | private String pass; 29 | private String authKey; 30 | 31 | public User(String name, String pass) { 32 | this.name = name; 33 | this.pass = pass; 34 | } 35 | 36 | /** 37 | * Returns the id. 38 | * 39 | * @return Returns the id 40 | */ 41 | public Long getId() { 42 | return id; 43 | } 44 | 45 | /** 46 | * @param id The id to set. 47 | */ 48 | public void setId(Long id) { 49 | this.id = id; 50 | } 51 | 52 | /** 53 | * Returns the name. 54 | * 55 | * @return Returns the name 56 | */ 57 | public String getName() { 58 | return name; 59 | } 60 | 61 | /** 62 | * @param name The name to set. 63 | */ 64 | public void setName(String name) { 65 | this.name = name; 66 | } 67 | 68 | /** 69 | * Returns the pass. 70 | * 71 | * @return Returns the pass 72 | */ 73 | public String getPass() { 74 | return pass; 75 | } 76 | 77 | /** 78 | * @param pass The pass to set. 79 | */ 80 | public void setPass(String password) { 81 | this.pass = password; 82 | } 83 | 84 | /** 85 | * Returns the authKey. 86 | * 87 | * @return Returns the authKey 88 | */ 89 | public String getAuthKey() { 90 | return authKey; 91 | } 92 | 93 | /** 94 | * @param authKey The authKey to set. 95 | */ 96 | public void setAuthKey(String loginKey) { 97 | this.authKey = loginKey; 98 | } 99 | } -------------------------------------------------------------------------------- /retwisj/src/main/java/org/springframework/data/redis/samples/retwisj/redis/KeyUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.data.redis.samples.retwisj.redis; 17 | 18 | /** 19 | * Simple class keeping all the key patterns to avoid the proliferation of 20 | * Strings through the code. 21 | * 22 | * @author Costin Leau 23 | */ 24 | abstract class KeyUtils { 25 | static final String UID = "uid:"; 26 | 27 | static String following(String uid) { 28 | return UID + uid + ":following"; 29 | } 30 | 31 | static String followers(String uid) { 32 | return UID + uid + ":followers"; 33 | } 34 | 35 | static String timeline(String uid) { 36 | return UID + uid + ":timeline"; 37 | } 38 | 39 | static String mentions(String uid) { 40 | return UID + uid + ":mentions"; 41 | } 42 | 43 | static String posts(String uid) { 44 | return UID + uid + ":posts"; 45 | } 46 | 47 | static String auth(String uid) { 48 | return UID + uid + ":auth"; 49 | } 50 | 51 | static String uid(String uid) { 52 | return UID + uid; 53 | } 54 | 55 | static String post(String pid) { 56 | return "pid:" + pid; 57 | } 58 | 59 | static String authKey(String auth) { 60 | return "auth:" + auth; 61 | } 62 | 63 | public static String user(String name) { 64 | return "user:" + name + ":uid"; 65 | } 66 | 67 | static String users() { 68 | return "users"; 69 | } 70 | 71 | static String timeline() { 72 | return "timeline"; 73 | } 74 | 75 | static String globalUid() { 76 | return "global:uid"; 77 | } 78 | 79 | static String globalPid() { 80 | return "global:pid"; 81 | } 82 | 83 | static String alsoFollowed(String uid, String targetUid) { 84 | return UID + uid + ":also:uid:" + targetUid; 85 | } 86 | 87 | static String commonFollowers(String uid, String targetUid) { 88 | return UID + uid + ":common:uid:" + targetUid; 89 | } 90 | } -------------------------------------------------------------------------------- /retwisj/src/main/java/org/springframework/data/redis/samples/retwisj/redis/RetwisRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.data.redis.samples.retwisj.redis; 17 | 18 | import java.util.ArrayList; 19 | import java.util.Arrays; 20 | import java.util.Collection; 21 | import java.util.Collections; 22 | import java.util.Iterator; 23 | import java.util.LinkedHashMap; 24 | import java.util.List; 25 | import java.util.Map; 26 | import java.util.UUID; 27 | import java.util.concurrent.TimeUnit; 28 | import java.util.regex.Matcher; 29 | import java.util.regex.Pattern; 30 | 31 | import javax.inject.Inject; 32 | import javax.inject.Named; 33 | 34 | import org.springframework.data.redis.core.BoundHashOperations; 35 | import org.springframework.data.redis.core.BulkMapper; 36 | import org.springframework.data.redis.core.StringRedisTemplate; 37 | import org.springframework.data.redis.core.ValueOperations; 38 | import org.springframework.data.redis.core.query.SortQuery; 39 | import org.springframework.data.redis.core.query.SortQueryBuilder; 40 | import org.springframework.data.redis.hash.DecoratingStringHashMapper; 41 | import org.springframework.data.redis.hash.HashMapper; 42 | import org.springframework.data.redis.hash.JacksonHashMapper; 43 | import org.springframework.data.redis.samples.retwisj.Post; 44 | import org.springframework.data.redis.samples.retwisj.Range; 45 | import org.springframework.data.redis.samples.retwisj.RetwisSecurity; 46 | import org.springframework.data.redis.samples.retwisj.web.WebPost; 47 | import org.springframework.data.redis.support.atomic.RedisAtomicLong; 48 | import org.springframework.data.redis.support.collections.DefaultRedisList; 49 | import org.springframework.data.redis.support.collections.DefaultRedisMap; 50 | import org.springframework.data.redis.support.collections.DefaultRedisSet; 51 | import org.springframework.data.redis.support.collections.RedisList; 52 | import org.springframework.data.redis.support.collections.RedisMap; 53 | import org.springframework.data.redis.support.collections.RedisSet; 54 | import org.springframework.util.StringUtils; 55 | 56 | /** 57 | * Twitter-clone on top of Redis. 58 | * 59 | * @author Costin Leau 60 | */ 61 | @Named 62 | public class RetwisRepository { 63 | 64 | private static final Pattern MENTION_REGEX = Pattern.compile("@[\\w]+"); 65 | 66 | private final StringRedisTemplate template; 67 | private final ValueOperations valueOps; 68 | 69 | private final RedisAtomicLong postIdCounter; 70 | private final RedisAtomicLong userIdCounter; 71 | 72 | // global users 73 | private RedisList users; 74 | // global timeline 75 | private final RedisList timeline; 76 | 77 | private final HashMapper postMapper = new DecoratingStringHashMapper( 78 | new JacksonHashMapper(Post.class)); 79 | 80 | @Inject 81 | public RetwisRepository(StringRedisTemplate template) { 82 | this.template = template; 83 | valueOps = template.opsForValue(); 84 | 85 | users = new DefaultRedisList(KeyUtils.users(), template); 86 | timeline = new DefaultRedisList(KeyUtils.timeline(), template); 87 | userIdCounter = new RedisAtomicLong(KeyUtils.globalUid(), template.getConnectionFactory()); 88 | postIdCounter = new RedisAtomicLong(KeyUtils.globalPid(), template.getConnectionFactory()); 89 | } 90 | 91 | public String addUser(String name, String password) { 92 | String uid = String.valueOf(userIdCounter.incrementAndGet()); 93 | 94 | // save user as hash 95 | // uid -> user 96 | BoundHashOperations userOps = template.boundHashOps(KeyUtils.uid(uid)); 97 | userOps.put("name", name); 98 | userOps.put("pass", password); 99 | valueOps.set(KeyUtils.user(name), uid); 100 | 101 | users.addFirst(name); 102 | return addAuth(name); 103 | } 104 | 105 | public List getPost(String pid) { 106 | return Collections.singletonList(convertPost(pid, post(pid))); 107 | } 108 | 109 | public List getPosts(String uid, Range range) { 110 | return convertPidsToPosts(KeyUtils.posts(uid), range); 111 | } 112 | 113 | public List getTimeline(String uid, Range range) { 114 | return convertPidsToPosts(KeyUtils.timeline(uid), range); 115 | } 116 | 117 | public Collection getFollowers(String uid) { 118 | return covertUidsToNames(KeyUtils.followers(uid)); 119 | } 120 | 121 | public Collection getFollowing(String uid) { 122 | return covertUidsToNames(KeyUtils.following(uid)); 123 | } 124 | 125 | public List getMentions(String uid, Range range) { 126 | return convertPidsToPosts(KeyUtils.mentions(uid), range); 127 | } 128 | 129 | public Collection timeline(Range range) { 130 | return convertPidsToPosts(KeyUtils.timeline(), range); 131 | } 132 | 133 | public Collection newUsers(Range range) { 134 | return users.range(range.begin, range.end); 135 | } 136 | 137 | public void post(String username, WebPost post) { 138 | Post p = post.asPost(); 139 | 140 | String uid = findUid(username); 141 | p.setUid(uid); 142 | 143 | String pid = String.valueOf(postIdCounter.incrementAndGet()); 144 | 145 | String replyName = post.getReplyTo(); 146 | if (StringUtils.hasText(replyName)) { 147 | String mentionUid = findUid(replyName); 148 | p.setReplyUid(mentionUid); 149 | // handle mentions below 150 | p.setReplyPid(post.getReplyPid()); 151 | } 152 | 153 | // add post 154 | post(pid).putAll(postMapper.toHash(p)); 155 | 156 | // add links 157 | posts(uid).addFirst(pid); 158 | timeline(uid).addFirst(pid); 159 | 160 | // update followers 161 | for (String follower : followers(uid)) { 162 | timeline(follower).addFirst(pid); 163 | } 164 | 165 | timeline.addFirst(pid); 166 | handleMentions(p, pid, replyName); 167 | } 168 | 169 | private void handleMentions(Post post, String pid, String name) { 170 | // find mentions 171 | Collection mentions = findMentions(post.getContent()); 172 | 173 | for (String mention : mentions) { 174 | String uid = findUid(mention); 175 | if (uid != null) { 176 | mentions(uid).addFirst(pid); 177 | } 178 | } 179 | } 180 | 181 | public String findUid(String name) { 182 | return valueOps.get(KeyUtils.user(name)); 183 | } 184 | 185 | public boolean isUserValid(String name) { 186 | return template.hasKey(KeyUtils.user(name)); 187 | } 188 | 189 | public boolean isPostValid(String pid) { 190 | return template.hasKey(KeyUtils.post(pid)); 191 | } 192 | 193 | 194 | private String findName(String uid) { 195 | if (!StringUtils.hasText(uid)) { 196 | return ""; 197 | } 198 | BoundHashOperations userOps = template.boundHashOps(KeyUtils.uid(uid)); 199 | return userOps.get("name"); 200 | } 201 | 202 | public boolean auth(String user, String pass) { 203 | // find uid 204 | String uid = findUid(user); 205 | if (StringUtils.hasText(uid)) { 206 | BoundHashOperations userOps = template.boundHashOps(KeyUtils.uid(uid)); 207 | return userOps.get("pass").equals(pass); 208 | } 209 | 210 | return false; 211 | } 212 | 213 | public String findNameForAuth(String value) { 214 | String uid = valueOps.get(KeyUtils.authKey(value)); 215 | return findName(uid); 216 | } 217 | 218 | public String addAuth(String name) { 219 | String uid = findUid(name); 220 | // add random auth key relation 221 | String auth = UUID.randomUUID().toString(); 222 | valueOps.set(KeyUtils.auth(uid), auth); 223 | valueOps.set(KeyUtils.authKey(auth), uid); 224 | return auth; 225 | } 226 | 227 | public void deleteAuth(String user) { 228 | String uid = findUid(user); 229 | 230 | String authKey = KeyUtils.auth(uid); 231 | String auth = valueOps.get(authKey); 232 | 233 | template.delete(Arrays.asList(authKey, KeyUtils.authKey(auth))); 234 | } 235 | 236 | public boolean hasMorePosts(String targetUid, Range range) { 237 | return posts(targetUid).size() > range.end + 1; 238 | } 239 | 240 | public boolean hasMoreTimeline(String targetUid, Range range) { 241 | return timeline(targetUid).size() > range.end + 1; 242 | } 243 | 244 | 245 | public boolean hasMoreTimeline(Range range) { 246 | return timeline.size() > range.end + 1; 247 | } 248 | 249 | public boolean isFollowing(String uid, String targetUid) { 250 | return following(uid).contains(targetUid); 251 | } 252 | 253 | public void follow(String targetUser) { 254 | String targetUid = findUid(targetUser); 255 | 256 | following(RetwisSecurity.getUid()).add(targetUid); 257 | followers(targetUid).add(RetwisSecurity.getUid()); 258 | } 259 | 260 | public void stopFollowing(String targetUser) { 261 | String targetUid = findUid(targetUser); 262 | 263 | following(RetwisSecurity.getUid()).remove(targetUid); 264 | followers(targetUid).remove(RetwisSecurity.getUid()); 265 | } 266 | 267 | public List alsoFollowed(String uid, String targetUid) { 268 | RedisSet tempSet = following(uid).intersectAndStore(followers(targetUid), 269 | KeyUtils.alsoFollowed(uid, targetUid)); 270 | 271 | String key = tempSet.getKey(); 272 | template.expire(key, 5, TimeUnit.SECONDS); 273 | 274 | return covertUidsToNames(key); 275 | } 276 | 277 | public List commonFollowers(String uid, String targetUid) { 278 | RedisSet tempSet = following(uid).intersectAndStore(following(targetUid), 279 | KeyUtils.commonFollowers(uid, targetUid)); 280 | 281 | tempSet.expire(5, TimeUnit.SECONDS); 282 | 283 | return covertUidsToNames(tempSet.getKey()); 284 | } 285 | 286 | // collections mapping the core data structures 287 | 288 | private RedisList timeline(String uid) { 289 | return new DefaultRedisList(KeyUtils.timeline(uid), template); 290 | } 291 | 292 | private RedisSet following(String uid) { 293 | return new DefaultRedisSet(KeyUtils.following(uid), template); 294 | } 295 | 296 | private RedisSet followers(String uid) { 297 | return new DefaultRedisSet(KeyUtils.followers(uid), template); 298 | } 299 | 300 | private RedisList mentions(String uid) { 301 | return new DefaultRedisList(KeyUtils.mentions(uid), template); 302 | } 303 | 304 | private RedisMap post(String pid) { 305 | return new DefaultRedisMap(KeyUtils.post(pid), template); 306 | } 307 | 308 | private RedisList posts(String uid) { 309 | return new DefaultRedisList(KeyUtils.posts(uid), template); 310 | } 311 | 312 | // various util methods 313 | 314 | private String replaceReplies(String content) { 315 | Matcher regexMatcher = MENTION_REGEX.matcher(content); 316 | while (regexMatcher.find()) { 317 | String match = regexMatcher.group(); 318 | int start = regexMatcher.start(); 319 | int stop = regexMatcher.end(); 320 | 321 | String uName = match.substring(1); 322 | if (isUserValid(uName)) { 323 | content = content.substring(0, start) + "" + match + "" 324 | + content.substring(stop); 325 | } 326 | } 327 | return content; 328 | } 329 | 330 | private List covertUidsToNames(String key) { 331 | return template.sort(SortQueryBuilder.sort(key).noSort().get("uid:*->name").build()); 332 | } 333 | 334 | private List convertPidsToPosts(String key, Range range) { 335 | String pid = "pid:*->"; 336 | final String pidKey = "#"; 337 | final String uid = "uid"; 338 | final String content = "content"; 339 | final String replyPid = "replyPid"; 340 | final String replyUid = "replyUid"; 341 | final String time = "time"; 342 | 343 | SortQuery query = SortQueryBuilder.sort(key).noSort().get(pidKey).get(pid + uid).get(pid + content).get( 344 | pid + replyPid).get(pid + replyUid).get(pid + time).limit(range.begin, range.end).build(); 345 | BulkMapper hm = new BulkMapper() { 346 | @Override 347 | public WebPost mapBulk(List bulk) { 348 | Map map = new LinkedHashMap(); 349 | Iterator iterator = bulk.iterator(); 350 | 351 | String pid = iterator.next(); 352 | map.put(uid, iterator.next()); 353 | map.put(content, iterator.next()); 354 | map.put(replyPid, iterator.next()); 355 | map.put(replyUid, iterator.next()); 356 | map.put(time, iterator.next()); 357 | 358 | return convertPost(pid, map); 359 | } 360 | }; 361 | List sort = template.sort(query, hm); 362 | 363 | return sort; 364 | } 365 | 366 | private WebPost convertPost(String pid, Map hash) { 367 | Post post = postMapper.fromHash(hash); 368 | WebPost wPost = new WebPost(post); 369 | wPost.setPid(pid); 370 | wPost.setName(findName(post.getUid())); 371 | wPost.setReplyTo(findName(post.getReplyUid())); 372 | wPost.setContent(replaceReplies(post.getContent())); 373 | return wPost; 374 | } 375 | 376 | public static Collection findMentions(String content) { 377 | Matcher regexMatcher = MENTION_REGEX.matcher(content); 378 | List mentions = new ArrayList(4); 379 | 380 | while (regexMatcher.find()) { 381 | mentions.add(regexMatcher.group().substring(1)); 382 | } 383 | 384 | return mentions; 385 | } 386 | } -------------------------------------------------------------------------------- /retwisj/src/main/java/org/springframework/data/redis/samples/retwisj/web/CookieInterceptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.data.redis.samples.retwisj.web; 17 | 18 | import javax.inject.Inject; 19 | import javax.servlet.http.Cookie; 20 | import javax.servlet.http.HttpServletRequest; 21 | import javax.servlet.http.HttpServletResponse; 22 | 23 | import org.springframework.data.redis.samples.retwisj.RetwisSecurity; 24 | import org.springframework.data.redis.samples.retwisj.redis.RetwisRepository; 25 | import org.springframework.util.ObjectUtils; 26 | import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; 27 | 28 | /** 29 | * Basic interceptor that checks that each request has been authenticated against Redis. 30 | * 31 | * @author Costin Leau 32 | */ 33 | public class CookieInterceptor extends HandlerInterceptorAdapter { 34 | 35 | public static final String RETWIS_COOKIE = "retwisauth"; 36 | 37 | @Inject 38 | private RetwisRepository twitter; 39 | 40 | @Override 41 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 42 | // all non-root requests get analyzed 43 | Cookie[] cookies = request.getCookies(); 44 | 45 | if (!ObjectUtils.isEmpty(cookies)) { 46 | for (Cookie cookie : cookies) { 47 | if (RETWIS_COOKIE.equals(cookie.getName())) { 48 | String auth = cookie.getValue(); 49 | String name = twitter.findNameForAuth(auth); 50 | if (name != null) { 51 | String uid = twitter.findUid(name); 52 | RetwisSecurity.setUser(name, uid); 53 | } 54 | } 55 | } 56 | } 57 | return true; 58 | } 59 | 60 | @Override 61 | public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) 62 | throws Exception { 63 | RetwisSecurity.clean(); 64 | } 65 | } -------------------------------------------------------------------------------- /retwisj/src/main/java/org/springframework/data/redis/samples/retwisj/web/NoSuchDataException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.data.redis.samples.retwisj.web; 17 | 18 | /** 19 | * Exception thrown when the controller is invoked with invalid data. 20 | * 21 | * @author Costin Leau 22 | */ 23 | public class NoSuchDataException extends RuntimeException { 24 | 25 | private final String data; 26 | private final boolean userRelated; 27 | 28 | public NoSuchDataException(String data, boolean userRelated) { 29 | 30 | super("Invalid data " + data); 31 | this.data = data; 32 | this.userRelated = userRelated; 33 | } 34 | 35 | /** 36 | * Returns the name. 37 | * 38 | * @return Returns the name 39 | */ 40 | public String getData() { 41 | return data; 42 | } 43 | 44 | public boolean isPost() { 45 | return !userRelated; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /retwisj/src/main/java/org/springframework/data/redis/samples/retwisj/web/RetwisController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.data.redis.samples.retwisj.web; 17 | 18 | import javax.servlet.http.Cookie; 19 | import javax.servlet.http.HttpServletRequest; 20 | import javax.servlet.http.HttpServletResponse; 21 | 22 | import org.springframework.beans.factory.annotation.Autowired; 23 | import org.springframework.data.redis.samples.retwisj.Post; 24 | import org.springframework.data.redis.samples.retwisj.Range; 25 | import org.springframework.data.redis.samples.retwisj.RetwisSecurity; 26 | import org.springframework.data.redis.samples.retwisj.redis.RetwisRepository; 27 | import org.springframework.stereotype.Controller; 28 | import org.springframework.ui.Model; 29 | import org.springframework.util.StringUtils; 30 | import org.springframework.web.bind.annotation.ExceptionHandler; 31 | import org.springframework.web.bind.annotation.PathVariable; 32 | import org.springframework.web.bind.annotation.RequestMapping; 33 | import org.springframework.web.bind.annotation.RequestMethod; 34 | import org.springframework.web.bind.annotation.RequestParam; 35 | 36 | /** 37 | * Annotation-driven controller for Retwis. 38 | * 39 | * @author Costin Leau 40 | */ 41 | @Controller 42 | public class RetwisController { 43 | 44 | @Autowired 45 | private final RetwisRepository retwis; 46 | 47 | @Autowired 48 | public RetwisController(RetwisRepository twitter) { 49 | this.retwis = twitter; 50 | } 51 | 52 | @RequestMapping("/") 53 | public String root(@RequestParam(required = false) Integer page, Model model) { 54 | if (RetwisSecurity.isSignedIn()) { 55 | return "redirect:/!" + RetwisSecurity.getName(); 56 | } 57 | return timeline(page, model); 58 | } 59 | 60 | @RequestMapping("/signUp") 61 | public String signUp(String name, String pass, String pass2, Model model, HttpServletResponse response) { 62 | if (retwis.isUserValid(name)) { 63 | model.addAttribute("errorduplicateuser", Boolean.TRUE); 64 | return "signin"; 65 | } 66 | 67 | if (!StringUtils.hasText(pass) || !StringUtils.hasText(pass2) || !pass.equals(pass2)) { 68 | model.addAttribute("errormatch", Boolean.TRUE); 69 | return "signin"; 70 | } 71 | 72 | String auth = retwis.addUser(name, pass); 73 | addAuthCookie(auth, name, response); 74 | 75 | return "redirect:/!" + name; 76 | } 77 | 78 | @RequestMapping("/signIn") 79 | public String signIn(@RequestParam(required = false) String name, @RequestParam(required = false) String pass, Model model, HttpServletResponse response) { 80 | // add tracing cookie 81 | if (retwis.auth(name, pass)) { 82 | addAuthCookie(retwis.addAuth(name), name, response); 83 | return "redirect:/!" + name; 84 | } 85 | else if (StringUtils.hasText(name) || StringUtils.hasText(pass)) { 86 | model.addAttribute("errorpass", Boolean.TRUE); 87 | } 88 | // go back to sign in screen 89 | return "signin"; 90 | } 91 | 92 | private void addAuthCookie(String auth, String name, HttpServletResponse response) { 93 | RetwisSecurity.setUser(name, retwis.findUid(name)); 94 | 95 | Cookie cookie = new Cookie(CookieInterceptor.RETWIS_COOKIE, auth); 96 | cookie.setComment("Retwis-J demo"); 97 | // cookie valid for up to 1 week 98 | cookie.setMaxAge(60 * 60 * 24 * 7); 99 | response.addCookie(cookie); 100 | } 101 | 102 | @RequestMapping(value = "/!{name}", method = RequestMethod.GET) 103 | public String posts(@PathVariable String name, @RequestParam(required = false) String replyto, @RequestParam(required = false) String replypid, @RequestParam(required = false) Integer page, Model model) { 104 | checkUser(name); 105 | String targetUid = retwis.findUid(name); 106 | model.addAttribute("post", new Post()); 107 | model.addAttribute("name", name); 108 | model.addAttribute("followers", retwis.getFollowers(targetUid)); 109 | model.addAttribute("following", retwis.getFollowing(targetUid)); 110 | 111 | if (RetwisSecurity.isSignedIn()) { 112 | model.addAttribute("replyTo", replyto); 113 | model.addAttribute("replyPid", replypid); 114 | 115 | if (!targetUid.equals(RetwisSecurity.getUid())) { 116 | model.addAttribute("also_followed", retwis.alsoFollowed(RetwisSecurity.getUid(), targetUid)); 117 | model.addAttribute("common_followers", retwis.commonFollowers(RetwisSecurity.getUid(), targetUid)); 118 | model.addAttribute("follows", retwis.isFollowing(RetwisSecurity.getUid(), targetUid)); 119 | } 120 | } 121 | // sanitize page attribute 122 | page = (page != null ? Math.abs(page) : 1); 123 | model.addAttribute("page", page + 1); 124 | Range range = new Range(page); 125 | model.addAttribute("moreposts", (RetwisSecurity.isUserSignedIn(targetUid) ? retwis.hasMoreTimeline(targetUid, 126 | range) : retwis.hasMorePosts(targetUid, range))); 127 | model.addAttribute("posts", (RetwisSecurity.isUserSignedIn(targetUid) ? retwis.getTimeline(targetUid, range) 128 | : retwis.getPosts(targetUid, range))); 129 | 130 | return "home"; 131 | } 132 | 133 | @RequestMapping(value = "/!{name}", method = RequestMethod.POST) 134 | public String posts(@PathVariable String name, WebPost post, Model model, HttpServletRequest request) { 135 | checkUser(name); 136 | retwis.post(name, post); 137 | return "redirect:/!" + name; 138 | } 139 | 140 | @RequestMapping("/!{name}/follow") 141 | public String follow(@PathVariable String name) { 142 | checkUser(name); 143 | retwis.follow(name); 144 | return "redirect:/!" + name; 145 | } 146 | 147 | @RequestMapping("/!{name}/stopfollowing") 148 | public String stopFollowing(@PathVariable String name) { 149 | checkUser(name); 150 | retwis.stopFollowing(name); 151 | return "redirect:/!" + name; 152 | } 153 | 154 | @RequestMapping("/!{name}/mentions") 155 | public String mentions(@PathVariable String name, Model model) { 156 | checkUser(name); 157 | model.addAttribute("name", name); 158 | String targetUid = retwis.findUid(name); 159 | 160 | model.addAttribute("posts", retwis.getMentions(targetUid, new Range())); 161 | model.addAttribute("followers", retwis.getFollowers(targetUid)); 162 | model.addAttribute("following", retwis.getFollowing(targetUid)); 163 | 164 | if (RetwisSecurity.isSignedIn() && !targetUid.equals(RetwisSecurity.getUid())) { 165 | model.addAttribute("also_followed", retwis.alsoFollowed(RetwisSecurity.getUid(), targetUid)); 166 | model.addAttribute("common_followers", retwis.commonFollowers(RetwisSecurity.getUid(), targetUid)); 167 | model.addAttribute("follows", retwis.isFollowing(RetwisSecurity.getUid(), targetUid)); 168 | } 169 | 170 | return "mentions"; 171 | } 172 | 173 | @RequestMapping("/timeline") 174 | public String timeline(@RequestParam(required = false) Integer page, Model model) { 175 | // sanitize page attribute 176 | page = (page != null ? Math.abs(page) : 1); 177 | model.addAttribute("page", page + 1); 178 | Range range = new Range(page); 179 | model.addAttribute("moreposts", retwis.hasMoreTimeline(range)); 180 | model.addAttribute("posts", retwis.timeline(range)); 181 | model.addAttribute("users", retwis.newUsers(new Range())); 182 | return "timeline"; 183 | } 184 | 185 | @RequestMapping("/logout") 186 | public String logout() { 187 | String user = RetwisSecurity.getName(); 188 | // invalidate auth 189 | retwis.deleteAuth(user); 190 | return "redirect:/"; 191 | } 192 | 193 | @RequestMapping("/status") 194 | public String status(String pid, Model model) { 195 | checkPost(pid); 196 | model.addAttribute("posts", retwis.getPost(pid)); 197 | return "status"; 198 | } 199 | 200 | private void checkUser(String username) { 201 | if (!retwis.isUserValid(username)) { 202 | throw new NoSuchDataException(username, true); 203 | } 204 | } 205 | 206 | private void checkPost(String pid) { 207 | if (!retwis.isPostValid(pid)) { 208 | throw new NoSuchDataException(pid, false); 209 | } 210 | } 211 | 212 | @ExceptionHandler(NoSuchDataException.class) 213 | public String handleNoUserException(NoSuchDataException ex) { 214 | // model.addAttribute("data", ex.getData()); 215 | // model.addAttribute("nodatatype", ex.isPost() ? "nodata.post" : "nodata.user"); 216 | return "nodata"; 217 | } 218 | } -------------------------------------------------------------------------------- /retwisj/src/main/java/org/springframework/data/redis/samples/retwisj/web/WebPost.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.data.redis.samples.retwisj.web; 17 | 18 | import org.springframework.data.redis.samples.retwisj.Post; 19 | 20 | /** 21 | * DTO suitable for presenting a Post through the Web UI. 22 | * 23 | * @author Costin Leau 24 | */ 25 | public class WebPost { 26 | 27 | private String content; 28 | private String name; 29 | private String replyTo; 30 | private String replyPid; 31 | private String pid; 32 | private String time; 33 | private String timeArg; 34 | 35 | public WebPost() { 36 | } 37 | 38 | public WebPost(Post post) { 39 | 40 | String tempTime = WebUtils.timeInWords(Long.valueOf(post.getTime())); 41 | int lastIndexOf = tempTime.lastIndexOf("#"); 42 | if (lastIndexOf > 0) { 43 | this.time = tempTime.substring(0, lastIndexOf); 44 | this.timeArg = tempTime.substring(lastIndexOf + 1); 45 | } 46 | else { 47 | this.time = tempTime; 48 | this.timeArg = ""; 49 | } 50 | this.replyPid = post.getReplyPid(); 51 | this.content = post.getContent(); 52 | } 53 | 54 | /** 55 | * Returns the replyPid. 56 | * 57 | * @return Returns the replyPid 58 | */ 59 | public String getReplyPid() { 60 | return replyPid; 61 | } 62 | 63 | /** 64 | * @param replyPid The replyPid to set. 65 | */ 66 | public void setReplyPid(String replyPid) { 67 | this.replyPid = replyPid; 68 | } 69 | 70 | /** 71 | * Returns the name. 72 | * 73 | * @return Returns the name 74 | */ 75 | public String getName() { 76 | return name; 77 | } 78 | 79 | /** 80 | * @param name The name to set. 81 | */ 82 | public void setName(String name) { 83 | this.name = name; 84 | } 85 | 86 | /** 87 | * Returns the replyTo. 88 | * 89 | * @return Returns the replyTo 90 | */ 91 | public String getReplyTo() { 92 | return replyTo; 93 | } 94 | 95 | /** 96 | * Returns the content. 97 | * 98 | * @return Returns the content 99 | */ 100 | public String getContent() { 101 | return content; 102 | } 103 | 104 | /** 105 | * @param content The content to set. 106 | */ 107 | public void setContent(String content) { 108 | this.content = content; 109 | } 110 | 111 | /** 112 | * Returns the pid. 113 | * 114 | * @return Returns the pid 115 | */ 116 | public String getPid() { 117 | return pid; 118 | } 119 | 120 | /** 121 | * @param pid The pid to set. 122 | */ 123 | public void setPid(String pid) { 124 | this.pid = pid; 125 | } 126 | 127 | /** 128 | * Returns the time. 129 | * 130 | * @return Returns the time 131 | */ 132 | public String getTime() { 133 | return time; 134 | } 135 | 136 | public void setTime(String time) { 137 | this.time = time; 138 | } 139 | 140 | public String getTimeArg() { 141 | return timeArg; 142 | } 143 | 144 | /** 145 | * @param replyTo The replyTo to set. 146 | */ 147 | public void setReplyTo(String replyName) { 148 | this.replyTo = replyName; 149 | } 150 | 151 | public Post asPost() { 152 | Post post = new Post(); 153 | post.setReplyPid(replyPid); 154 | post.setContent(content); 155 | return post; 156 | } 157 | 158 | @Override 159 | public String toString() { 160 | return "WebPost [content=" + content + ", name=" + name + ", pid=" + pid + ", replyTo=" + replyTo 161 | + ", replyPid=" + replyPid + ", time=" + time + "]"; 162 | } 163 | } -------------------------------------------------------------------------------- /retwisj/src/main/java/org/springframework/data/redis/samples/retwisj/web/WebUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.data.redis.samples.retwisj.web; 17 | 18 | 19 | /** 20 | * Utility converting the date (stored as long) into human-friendly message. 21 | * 22 | * @author Costin Leau 23 | */ 24 | public class WebUtils { 25 | 26 | public static String timeInWords(long time) { 27 | long elapsed = System.currentTimeMillis() - time; 28 | 29 | // seconds 30 | elapsed /= 1000; 31 | 32 | if (elapsed < 10) { 33 | return "time.now"; 34 | } 35 | if (elapsed < 60) { 36 | return "time.minute.less"; 37 | } 38 | 39 | // minutes 40 | elapsed /= 60; 41 | 42 | if (elapsed < 2) { 43 | return "time.minute"; 44 | } 45 | 46 | if (elapsed < 45) { 47 | return "time.minutes#" + elapsed; 48 | } 49 | 50 | if (elapsed < 90) { 51 | return "time.hour"; 52 | } 53 | 54 | if (elapsed < 1440) { 55 | return "time.hours#" + elapsed / 60; 56 | } 57 | 58 | if (elapsed < 2880) { 59 | return "time.day"; 60 | } 61 | 62 | if (elapsed < 43200) { 63 | return "time.days#" + (elapsed / 1440); 64 | } 65 | 66 | if (elapsed < 86400) { 67 | return "time.month"; 68 | } 69 | 70 | if (elapsed < 525600) { 71 | return "time.months#" + (elapsed / 43200); 72 | } 73 | 74 | if (elapsed < 1051199) { 75 | return "time.year"; 76 | } 77 | 78 | return "time.years#" + (elapsed / 525600); 79 | } 80 | } -------------------------------------------------------------------------------- /retwisj/src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | # For JBoss: Avoid to setup Log4J outside $JBOSS_HOME/server/default/deploy/log4j.xml! 2 | # For all other servers: Comment out the Log4J listener in web.xml to activate Log4J. 3 | log4j.rootLogger=INFO, stdout 4 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 5 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 6 | log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n 7 | 8 | log4j.appender.logfile=org.apache.log4j.RollingFileAppender 9 | log4j.appender.logfile.File=${retwis.root}/WEB-INF/retwis.log 10 | log4j.appender.logfile.MaxFileSize=512KB 11 | # Keep three backup files. 12 | log4j.appender.logfile.MaxBackupIndex=3 13 | # Pattern to output: date priority [category] - message 14 | log4j.appender.logfile.layout=org.apache.log4j.PatternLayout 15 | log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n 16 | #log4j.logger.org.springframework.web=DEBUG -------------------------------------------------------------------------------- /retwisj/src/main/resources/messages.properties: -------------------------------------------------------------------------------- 1 | home=Home 2 | lang=Language 3 | docs=Docs 4 | update=Post 5 | mentions=mentions 6 | follower=Follower 7 | followers=Followers 8 | following=Following 9 | follow.both=You both follow 10 | follow=Follow 11 | follow.stop=Stop following 12 | follow.also=Also followed by 13 | timeline=Timeline 14 | logout=logout 15 | signin=Sign In 16 | signup=Sign Up 17 | welcome=Welcome 18 | username=Username 19 | password=Password 20 | password.again=Repeat password 21 | required=is required 22 | wazza=what's happening ? 23 | itsyou = That's you! 24 | notFound=User has not been found 25 | duplicate=is already in use 26 | reply=Reply 27 | replyto=Reply to 28 | inreplyto=in reply to 29 | Mentions=Mentions of 30 | error.pass =Incorrect username or password 31 | error.match =Passwords do not match 32 | error.duplicateuser =User name already in use 33 | nodata =The requested data does not exist 34 | nodata.post =post 35 | nodata.user =user 36 | all.posts =Posts from all users 37 | newusers =New Users 38 | nopost =No posts 39 | nopost.note =You have no posts. Why not say hi to 40 | oops = Oops! Something went wrong... 41 | and.more=and more... 42 | more=More 43 | # time messages 44 | time.now=just now 45 | time.minute.less=less than a minute ago 46 | time.minute=one minute ago 47 | time.minutes={0} minutes ago 48 | time.hour=about an hour ago 49 | time.hours={0} hours ago 50 | time.day=about a day ago 51 | time.days={0} days ago 52 | time.month=about a month ago 53 | time.months={0} months ago 54 | time.year=about a year ago 55 | time.years=over {0} years ago -------------------------------------------------------------------------------- /retwisj/src/main/resources/messages_cn.properties: -------------------------------------------------------------------------------- 1 | home=首页 2 | lang=语言 3 | docs=文档 4 | update=邮政 5 | mentions=提到 6 | follower=信徒 7 | followers=信徒 8 | following=以下 9 | follow.both=你们都遵循 10 | follow=按照 11 | follow.stop=停止跟踪 12 | follow.also=也跟着 13 | timeline=时间轴 14 | logout=注销 15 | signin=登录 16 | signup=注册 17 | welcome=欢迎 18 | username=用户名 19 | password=密码 20 | password.again=重复密码 21 | required=需要 22 | wazza=发生了什么? 23 | itsyou = 就是你! 24 | notFound=用户没有被发现 25 | duplicate=已在使用 26 | reply=答复 27 | replyto=回复 28 | inreplyto =在回答 29 | Mentions=提到 30 | error.pass =用户名或密码不正确 31 | error.match =密码不匹配 32 | error.duplicateuser =用户名已在使用 33 | nodata =请求的数据不存在 34 | nodata.post =文章 35 | nodata.user =用户 36 | all.posts =员额从所有用户 37 | newusers =新用户 38 | nopost =没有帖子 39 | nopost.note =你有没有文章。为什么不打招呼 40 | oops = 哎呀!出事了... 41 | and.more=和更多... 42 | more=更多 43 | # time messages 44 | time.now=刚才 45 | time.minute.less=不到一分钟前 46 | time.minute=一分钟前 47 | time.minutes={0}分钟前 48 | time.hour=大约一个小时前 49 | time.hours={0}小时前 50 | time.day=大约一小时前 51 | time.days={0}天前 52 | time.month=大约一个月前 53 | time.months={0}个月前 54 | time.year=大约一年前 55 | time.years=超过{0}年前 -------------------------------------------------------------------------------- /retwisj/src/main/resources/messages_en.properties: -------------------------------------------------------------------------------- 1 | # This file is intentionally empty. Message look-ups will fall back to the default "messages.properties" file. -------------------------------------------------------------------------------- /retwisj/src/main/resources/messages_es.properties: -------------------------------------------------------------------------------- 1 | home=Casa 2 | lang=Lenguaje 3 | docs=Documentación 4 | update=Mensaje 5 | mentions=menciona 6 | follower=Seguidor 7 | followers=Seguidores 8 | following=Partidarios 9 | follow.both=Los dos siguen 10 | follow=Seguir 11 | follow.stop=Dejar de seguir 12 | follow.also=También seguido por 13 | timeline=Historia 14 | logout=Salida 15 | signin=Registrarse 16 | signup=Registrarse 17 | welcome=¡Bienvenido 18 | username=Nombre 19 | password=Contraseña 20 | password.again=Repita password 21 | required=se requiere 22 | wazza=¿Qué pasa 23 | itsyou = Eso eres tú! 24 | notFound=El usuario no se ha encontrado 25 | duplicate=ya está en uso 26 | reply=Responder 27 | replyto=Responder a 28 | inreplyto =en respuesta a 29 | Mentions=Menciones de 30 | error.pass =Incorrecto nombre o contraseña 31 | error.match =Las contraseñas no coinciden 32 | error.duplicateuser =Nombre ya está en uso 33 | nodata =Los datos solicitados no existe 34 | nodata.post =puesto 35 | nodata.user =usuario 36 | all.posts =Mensajes de todos los usuarios 37 | newusers =Nuevo usuario 38 | nopost =No hay mensajes 39 | nopost.note =Usted no tiene mensajes. ¿Por qué no saludar a 40 | oops = ¡Uy! Algo salió mal ... 41 | and.more=y mucho más ... 42 | more=Más 43 | # time messages 44 | time.now=en este momento 45 | time.minute.less=less than a minute ago 46 | time.minute=hace menos de un minuto 47 | time.minutes=hace {0} minutos 48 | time.hour=hace de una hora 49 | time.hours=hace {0} horas 50 | time.day=hace alrededor de un día 51 | time.days=hace {0} días 52 | time.month=hace aproximadamente un mes 53 | time.months=hace {0} meses 54 | time.year=hace un año 55 | time.years=más de {0} años -------------------------------------------------------------------------------- /retwisj/src/main/resources/messages_ro.properties: -------------------------------------------------------------------------------- 1 | home=Acasă 2 | lang=Limbă 3 | docs=Documentaţie 4 | update=Postează 5 | mentions=Meniţuni 6 | follower=Urmărit de 7 | followers=Urmărit de 8 | following=Urmăreşte pe 9 | follow.both=Amândoi urmăriţi pe 10 | follow=Urmăreşte 11 | follow.stop=Nu mai urmări 12 | follow.also=Urmărit şi de 13 | timeline=Scurt istoric 14 | logout=Ieşire 15 | signin=Înscriere 16 | signup=Autentificare 17 | welcome=Bine ai venit 18 | username=Utilizator 19 | password=Parolă 20 | password.again=Repetă parola 21 | required=este necesar 22 | wazza =Ce mai faci? 23 | itsyou =Esti chiar tu! 24 | notFound=Utilizatorul nu a fost găsit 25 | duplicate=este deja folosit 26 | reply=Răspunde 27 | replyto=Răspunde lui 28 | inreplyto =răspuns către 29 | Mentions=Menţiuni 30 | error.pass = Utilizator sau parolă incorectă 31 | error.match = Parolele nu sunt identice 32 | error.duplicateuser = Utilizatorul deja există 33 | nodata = Nu există informaţia cerută 34 | nodata.post = mesajul 35 | nodata.user = utilizatorul 36 | all.posts = Postările tuturor utilizatorilor 37 | newusers =Utilizatori noi 38 | nopost = Nici o postare 39 | nopost.note = Nu ai nici o postare. De ce nu îl saluţi pe 40 | oops = Oops! Ceva nu merge... 41 | and.more=şi alţii... 42 | more=Mai mult 43 | # time messages 44 | time.now=chiar acum 45 | time.minute.less=sub un minut 46 | time.minute=un minut 47 | time.minutes=acum {0} minute 48 | time.hour=cam de o oră 49 | time.hours=acum {0} ore 50 | time.day=cam de o zi 51 | time.days=acum {0} zile 52 | time.month=cam de o lună 53 | time.months=acum {0} luni 54 | time.year=cam de un an 55 | time.years=acum mai bine {0} ani -------------------------------------------------------------------------------- /retwisj/src/main/resources/redis.properties: -------------------------------------------------------------------------------- 1 | # Redis settings 2 | 3 | redis.host=localhost 4 | redis.port=6379 5 | redis.pass= -------------------------------------------------------------------------------- /retwisj/src/main/webapp/WEB-INF/jsp/home.jsp: -------------------------------------------------------------------------------- 1 |
2 |

${name}

3 |
4 |
5 | 6 | 7 |
8 |
9 | 10 | 11 | ${replyTo}: 12 | 13 | 14 | ${name}, 15 | 16 | 17 |
18 | 19 | 20 | "/> 21 |
22 |
23 |
24 | 25 | 26 | <%@ include file="/WEB-INF/templates/userFollow.jspf" %> 27 | 28 | 29 |
30 |
31 | 32 | <%@ include file="/WEB-INF/templates/posts.jspf" %> 33 | <%@ include file="/WEB-INF/templates/network.jspf" %> 34 | 35 | 36 | -------------------------------------------------------------------------------- /retwisj/src/main/webapp/WEB-INF/jsp/mentions.jsp: -------------------------------------------------------------------------------- 1 |
2 |

${name}

3 |
4 | 5 |
6 |
7 | 8 | 9 | 10 | 11 | 12 | 13 | <%@ include file="/WEB-INF/templates/userFollow.jspf" %> 14 | 15 | 16 |
17 |
18 | <%@ include file="/WEB-INF/templates/network.jspf" %> 19 | <%@ include file="/WEB-INF/templates/posts.jspf" %> 20 | -------------------------------------------------------------------------------- /retwisj/src/main/webapp/WEB-INF/jsp/nodata.jsp: -------------------------------------------------------------------------------- 1 |

: ${name}

-------------------------------------------------------------------------------- /retwisj/src/main/webapp/WEB-INF/jsp/oops.jsp: -------------------------------------------------------------------------------- 1 |

Oops - something went wrong

-------------------------------------------------------------------------------- /retwisj/src/main/webapp/WEB-INF/jsp/signin.jsp: -------------------------------------------------------------------------------- 1 |

2 | 3 |
4 |

5 | 6 |
7 | 8 |
9 | 10 |
11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | " /> 24 | 25 |
26 |
27 | 28 |
29 |

30 | 31 | 32 |
33 | 34 |
35 |
36 | 37 | 38 |
39 | 40 |
41 |
42 | 43 |
44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 |
58 | "> 59 |
60 |
61 | 62 |

 

63 |

 

-------------------------------------------------------------------------------- /retwisj/src/main/webapp/WEB-INF/jsp/status.jsp: -------------------------------------------------------------------------------- 1 |
2 | <%@ include file="/WEB-INF/templates/posts.jspf" %> 3 |
4 | -------------------------------------------------------------------------------- /retwisj/src/main/webapp/WEB-INF/jsp/timeline.jsp: -------------------------------------------------------------------------------- 1 |
2 |

3 |
4 |
5 | 6 |
7 |
8 | 9 | <%@ include file="/WEB-INF/templates/posts.jspf" %> 10 | 11 | 12 |
13 |
14 |

15 | 16 | 17 | ${u} 18 | 19 |
20 |
-------------------------------------------------------------------------------- /retwisj/src/main/webapp/WEB-INF/retwisj-servlet.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 31 | 33 | 34 | 39 | 41 | -------------------------------------------------------------------------------- /retwisj/src/main/webapp/WEB-INF/spring/applicationContext-redis.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 20 | 21 | -------------------------------------------------------------------------------- /retwisj/src/main/webapp/WEB-INF/templates/footer.jspf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /retwisj/src/main/webapp/WEB-INF/templates/header.jspf: -------------------------------------------------------------------------------- 1 | <%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> 2 | <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> 3 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 4 | <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> 5 | <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> 6 | 7 | <%@page import="org.springframework.data.redis.samples.retwisj.RetwisSecurity"%> 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | " type="text/css" media="screen, projection"/> 16 | " type="text/css" media="print"/> 17 | 20 | " type="text/css" media="screen, projection"/> 21 | "> 22 | Retwis-J :: a Spring Data Redis demonstration 23 | 24 | 25 | 26 |
27 |
28 |
29 |

"">Retwis-J

30 |
31 |
32 | <% 33 | pageContext.setAttribute("loggedIn", RetwisSecurity.isSignedIn(), PageContext.PAGE_SCOPE); 34 | pageContext.setAttribute("loggedUser", RetwisSecurity.getName(), PageContext.PAGE_SCOPE); 35 | %> 36 | 37 | "> | 38 | ">@${loggedUser} | 39 | "> | 40 | "> 41 | 42 | 43 | 44 | 45 | 46 | 47 |
48 |
49 |
50 |
51 | 52 | -------------------------------------------------------------------------------- /retwisj/src/main/webapp/WEB-INF/templates/network.jspf: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |

:

5 | 6 | 9 | 10 |
11 |
12 |
13 |

14 | : ${fn:length(followers)} 15 |

16 | 17 |
    18 | 19 |
  • ${f}
  • 20 |
    21 |
22 | 23 |
24 |
25 |

: ${fn:length(following)}

26 | 27 |
    28 | 29 |
  • ${f}
  • 30 |
    31 |
32 | 33 |
34 |
35 | -------------------------------------------------------------------------------- /retwisj/src/main/webapp/WEB-INF/templates/post.jspf: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |

5 | ">${p.name} ${p.content} 6 |
7 | 8 | "> 9 | 10 | 11 | "> ${p.replyTo} 12 | 13 |     14 | 15 | "> 16 | 17 |

18 |
19 |
20 | -------------------------------------------------------------------------------- /retwisj/src/main/webapp/WEB-INF/templates/posts.jspf: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 5 | 6 | ">@costinl ? 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | <%@ include file="/WEB-INF/templates/post.jspf" %> 15 | 16 | 17 | 18 |
19 | 20 |
21 |
22 |
23 | -------------------------------------------------------------------------------- /retwisj/src/main/webapp/WEB-INF/templates/userFollow.jspf: -------------------------------------------------------------------------------- 1 |
2 | 3 | "> 4 | "> 5 | 6 | | "> 7 |
8 | 9 | 10 |
11 | : ">${f} 12 |
13 |
14 | -------------------------------------------------------------------------------- /retwisj/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | Spring Data RetwisJ 6 | 7 | Spring Data Redis-based Twitter-clone sample application 8 | 9 | 10 | webAppRootKey 11 | retwisj.root 12 | 13 | 14 | 15 | log4jConfigLocation 16 | /WEB-INF/classes/log4j.properties 17 | 18 | 19 | 23 | 24 | contextConfigLocation 25 | /WEB-INF/spring/applicationContext-redis.xml 26 | 27 | 28 | 40 | 41 | 42 | org.springframework.web.util.Log4jConfigListener 43 | 44 | 45 | 46 | org.springframework.web.context.ContextLoaderListener 47 | 48 | 49 | 58 | 59 | retwisj 60 | org.springframework.web.servlet.DispatcherServlet 61 | 2 62 | 63 | 64 | 65 | retwisj 66 | / 67 | 68 | 69 | 70 | httpMethodFilter 71 | org.springframework.web.filter.HiddenHttpMethodFilter 72 | 73 | 74 | 75 | httpMethodFilter 76 | retwisj 77 | 78 | 79 | 80 | 10 81 | 82 | 83 | 84 | java.lang.Exception 85 | 86 | /WEB-INF/jsp/oops.jsp 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | Basic header/footer templating 98 | *.jsp 99 | false 100 | /WEB-INF/templates/header.jspf 101 | /WEB-INF/templates/footer.jspf 102 | 103 | 104 | -------------------------------------------------------------------------------- /retwisj/src/main/webapp/static/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/src/main/webapp/static/images/favicon.ico -------------------------------------------------------------------------------- /retwisj/src/main/webapp/static/images/springsource-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/spring-data-keyvalue-examples/3b65310485c801ee179de05fa8cfaf7c96727f81/retwisj/src/main/webapp/static/images/springsource-logo.png -------------------------------------------------------------------------------- /retwisj/src/main/webapp/static/styles/custom.css: -------------------------------------------------------------------------------- 1 | a { 2 | color: #D02B55; 3 | } 4 | 5 | body { 6 | color: #555; 7 | } 8 | 9 | div.post p { 10 | margin: 2px; 11 | } 12 | 13 | .box { 14 | padding: 10px; 15 | background: rgba(208,43,85,0.15); 16 | -moz-border-radius-bottomleft:5px;scr 17 | -moz-border-radius-bottomright:5px; 18 | -moz-border-radius-topleft:5px; 19 | -moz-border-radius-topright:5px; 20 | } 21 | 22 | textarea { 23 | height: 5em; 24 | width: 500px; 25 | } 26 | 27 | .footer { 28 | text-align: center; 29 | } 30 | 31 | -------------------------------------------------------------------------------- /retwisj/src/main/webapp/static/styles/ie.css: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------- 2 | 3 | 4 | Blueprint CSS Framework 0.9 5 | http://blueprintcss.org 6 | 7 | * Copyright (c) 2007-Present. See LICENSE for more info. 8 | * See README for instructions on how to use Blueprint. 9 | * For credits and origins, see AUTHORS. 10 | * This is a compressed file. See the sources in the 'src' directory. 11 | 12 | ----------------------------------------------------------------------- */ 13 | 14 | /* ie.css */ 15 | body {text-align:center;} 16 | .container {text-align:left;} 17 | * html .column, * html div.span-1, * html div.span-2, * html div.span-3, * html div.span-4, * html div.span-5, * html div.span-6, * html div.span-7, * html div.span-8, * html div.span-9, * html div.span-10, * html div.span-11, * html div.span-12, * html div.span-13, * html div.span-14, * html div.span-15, * html div.span-16, * html div.span-17, * html div.span-18, * html div.span-19, * html div.span-20, * html div.span-21, * html div.span-22, * html div.span-23, * html div.span-24 {display:inline;overflow-x:hidden;} 18 | * html legend {margin:0px -8px 16px 0;padding:0;} 19 | ol {margin-left:2em;} 20 | sup {vertical-align:text-top;} 21 | sub {vertical-align:text-bottom;} 22 | html>body p code {*white-space:normal;} 23 | hr {margin:-8px auto 11px;} 24 | img {-ms-interpolation-mode:bicubic;} 25 | .clearfix, .container {display:inline-block;} 26 | * html .clearfix, * html .container {height:1%;} 27 | fieldset {padding-top:0;} 28 | textarea {overflow:auto;} 29 | input.text, input.title, textarea {background-color:#fff;border:1px solid #bbb;} 30 | input.text:focus, input.title:focus {border-color:#666;} 31 | input.text, input.title, textarea, select {margin:0.5em 0;} 32 | input.checkbox, input.radio {position:relative;top:.25em;} 33 | form.inline div, form.inline p {vertical-align:middle;} 34 | form.inline label {position:relative;top:-0.25em;} 35 | form.inline input.checkbox, form.inline input.radio, form.inline input.button, form.inline button {margin:0.5em 0;} 36 | button, input.button {position:relative;top:0.25em;} -------------------------------------------------------------------------------- /retwisj/src/main/webapp/static/styles/print.css: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------- 2 | 3 | 4 | Blueprint CSS Framework 0.9 5 | http://blueprintcss.org 6 | 7 | * Copyright (c) 2007-Present. See LICENSE for more info. 8 | * See README for instructions on how to use Blueprint. 9 | * For credits and origins, see AUTHORS. 10 | * This is a compressed file. See the sources in the 'src' directory. 11 | 12 | ----------------------------------------------------------------------- */ 13 | 14 | /* print.css */ 15 | body {line-height:1.5;font-family:"Helvetica Neue", Arial, Helvetica, sans-serif;color:#000;background:none;font-size:10pt;} 16 | .container {background:none;} 17 | hr {background:#ccc;color:#ccc;width:100%;height:2px;margin:2em 0;padding:0;border:none;} 18 | hr.space {background:#fff;color:#fff;visibility:hidden;} 19 | h1, h2, h3, h4, h5, h6 {font-family:"Helvetica Neue", Arial, "Lucida Grande", sans-serif;} 20 | code {font:.9em "Courier New", Monaco, Courier, monospace;} 21 | a img {border:none;} 22 | p img.top {margin-top:0;} 23 | blockquote {margin:1.5em;padding:1em;font-style:italic;font-size:.9em;} 24 | .small {font-size:.9em;} 25 | .large {font-size:1.1em;} 26 | .quiet {color:#999;} 27 | .hide {display:none;} 28 | a:link, a:visited {background:transparent;font-weight:700;text-decoration:underline;} 29 | a:link:after, a:visited:after {content:" (" attr(href) ")";font-size:90%;} -------------------------------------------------------------------------------- /retwisj/src/main/webapp/static/styles/screen.css: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------- 2 | 3 | 4 | Blueprint CSS Framework 0.9 5 | http://blueprintcss.org 6 | 7 | * Copyright (c) 2007-Present. See LICENSE for more info. 8 | * See README for instructions on how to use Blueprint. 9 | * For credits and origins, see AUTHORS. 10 | * This is a compressed file. See the sources in the 'src' directory. 11 | 12 | ----------------------------------------------------------------------- */ 13 | 14 | /* reset.css */ 15 | html, body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, code, del, dfn, em, img, q, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td {margin:0;padding:0;border:0;font-weight:inherit;font-style:inherit;font-size:100%;font-family:inherit;vertical-align:baseline;} 16 | body {line-height:1.5;} 17 | table {border-collapse:separate;border-spacing:0;} 18 | caption, th, td {text-align:left;font-weight:normal;} 19 | table, td, th {vertical-align:middle;} 20 | blockquote:before, blockquote:after, q:before, q:after {content:"";} 21 | blockquote, q {quotes:"" "";} 22 | a img {border:none;} 23 | 24 | /* typography.css */ 25 | html {font-size:100.01%;} 26 | body {font-size:75%;color:#222;background:#fff;font-family:"Helvetica Neue", Arial, Helvetica, sans-serif;} 27 | h1, h2, h3, h4, h5, h6 {font-weight:normal;color:#111;} 28 | h1 {font-size:3em;line-height:1;margin-bottom:0.5em;} 29 | h2 {font-size:2em;margin-bottom:0.75em;} 30 | h3 {font-size:1.5em;line-height:1;margin-bottom:1em;} 31 | h4 {font-size:1.2em;line-height:1.25;margin-bottom:1.25em;} 32 | h5 {font-size:1em;font-weight:bold;margin-bottom:1.5em;} 33 | h6 {font-size:1em;font-weight:bold;} 34 | h1 img, h2 img, h3 img, h4 img, h5 img, h6 img {margin:0;} 35 | p {margin:0 0 1.5em;} 36 | p img.left {float:left;margin:1.5em 1.5em 1.5em 0;padding:0;} 37 | p img.right {float:right;margin:1.5em 0 1.5em 1.5em;} 38 | a:focus, a:hover {color:#000;} 39 | a {color:#009;text-decoration:underline;} 40 | blockquote {margin:1.5em;color:#666;font-style:italic;} 41 | strong {font-weight:bold;} 42 | em, dfn {font-style:italic;} 43 | dfn {font-weight:bold;} 44 | sup, sub {line-height:0;} 45 | abbr, acronym {border-bottom:1px dotted #666;} 46 | address {margin:0 0 1.5em;font-style:italic;} 47 | del {color:#666;} 48 | pre {margin:1.5em 0;white-space:pre;} 49 | pre, code, tt {font:1em 'andale mono', 'lucida console', monospace;line-height:1.5;} 50 | li ul, li ol {margin:0 1.5em;} 51 | ul, ol {margin:0 1.5em 1.5em 1.5em;} 52 | ul {list-style-type:disc;} 53 | ol {list-style-type:decimal;} 54 | dl {margin:0 0 1.5em 0;} 55 | dl dt {font-weight:bold;} 56 | dd {margin-left:1.5em;} 57 | table {margin-bottom:1.4em;width:100%;} 58 | th {font-weight:bold;} 59 | thead th {background:#c3d9ff;} 60 | th, td, caption {padding:4px 10px 4px 5px;} 61 | tr.even td {background:#e5ecf9;} 62 | tfoot {font-style:italic;} 63 | caption {background:#eee;} 64 | .small {font-size:.8em;margin-bottom:1.875em;line-height:1.875em;} 65 | .large {font-size:1.2em;line-height:2.5em;margin-bottom:1.25em;} 66 | .hide {display:none;} 67 | .quiet {color:#666;} 68 | .loud {color:#000;} 69 | .highlight {background:#ff0;} 70 | .added {background:#060;color:#fff;} 71 | .removed {background:#900;color:#fff;} 72 | .first {margin-left:0;padding-left:0;} 73 | .last {margin-right:0;padding-right:0;} 74 | .top {margin-top:0;padding-top:0;} 75 | .bottom {margin-bottom:0;padding-bottom:0;} 76 | 77 | /* forms.css */ 78 | label {font-weight:bold;} 79 | fieldset {padding:1.4em;margin:0 0 1.5em 0;border:1px solid #ccc;} 80 | legend {font-weight:bold;font-size:1.2em;} 81 | input[type=text], input[type=password], input.text, input.title, textarea, select {background-color:#fff;border:1px solid #bbb;} 82 | input[type=text]:focus, input[type=password]:focus, input.text:focus, input.title:focus, textarea:focus, select:focus {border-color:#666;} 83 | input[type=text], input[type=password], input.text, input.title, textarea, select {margin:0.5em 0;} 84 | input.text, input.title {width:300px;padding:5px;} 85 | input.title {font-size:1.5em;} 86 | textarea {width:390px;height:250px;padding:5px;} 87 | input[type=checkbox], input[type=radio], input.checkbox, input.radio {position:relative;top:.25em;} 88 | form.inline {line-height:3;} 89 | form.inline p {margin-bottom:0;} 90 | .error, .notice, .success {padding:.8em;margin-bottom:1em;border:2px solid #ddd;} 91 | .error {background:#FBE3E4;color:#8a1f11;border-color:#FBC2C4;} 92 | .notice {background:#FFF6BF;color:#514721;border-color:#FFD324;} 93 | .success {background:#E6EFC2;color:#264409;border-color:#C6D880;} 94 | .error a {color:#8a1f11;} 95 | .notice a {color:#514721;} 96 | .success a {color:#264409;} 97 | 98 | /* grid.css */ 99 | .container {width:950px;margin:0 auto;} 100 | .showgrid {background:url(src/grid.png);} 101 | .column, div.span-1, div.span-2, div.span-3, div.span-4, div.span-5, div.span-6, div.span-7, div.span-8, div.span-9, div.span-10, div.span-11, div.span-12, div.span-13, div.span-14, div.span-15, div.span-16, div.span-17, div.span-18, div.span-19, div.span-20, div.span-21, div.span-22, div.span-23, div.span-24 {float:left;margin-right:10px;} 102 | .last, div.last {margin-right:0;} 103 | .span-1 {width:30px;} 104 | .span-2 {width:70px;} 105 | .span-3 {width:110px;} 106 | .span-4 {width:150px;} 107 | .span-5 {width:190px;} 108 | .span-6 {width:230px;} 109 | .span-7 {width:270px;} 110 | .span-8 {width:310px;} 111 | .span-9 {width:350px;} 112 | .span-10 {width:390px;} 113 | .span-11 {width:430px;} 114 | .span-12 {width:470px;} 115 | .span-13 {width:510px;} 116 | .span-14 {width:550px;} 117 | .span-15 {width:590px;} 118 | .span-16 {width:630px;} 119 | .span-17 {width:670px;} 120 | .span-18 {width:710px;} 121 | .span-19 {width:750px;} 122 | .span-20 {width:790px;} 123 | .span-21 {width:830px;} 124 | .span-22 {width:870px;} 125 | .span-23 {width:910px;} 126 | .span-24, div.span-24 {width:950px;margin-right:0;} 127 | input.span-1, textarea.span-1, input.span-2, textarea.span-2, input.span-3, textarea.span-3, input.span-4, textarea.span-4, input.span-5, textarea.span-5, input.span-6, textarea.span-6, input.span-7, textarea.span-7, input.span-8, textarea.span-8, input.span-9, textarea.span-9, input.span-10, textarea.span-10, input.span-11, textarea.span-11, input.span-12, textarea.span-12, input.span-13, textarea.span-13, input.span-14, textarea.span-14, input.span-15, textarea.span-15, input.span-16, textarea.span-16, input.span-17, textarea.span-17, input.span-18, textarea.span-18, input.span-19, textarea.span-19, input.span-20, textarea.span-20, input.span-21, textarea.span-21, input.span-22, textarea.span-22, input.span-23, textarea.span-23, input.span-24, textarea.span-24 {border-left-width:1px!important;border-right-width:1px!important;padding-left:5px!important;padding-right:5px!important;} 128 | input.span-1, textarea.span-1 {width:18px!important;} 129 | input.span-2, textarea.span-2 {width:58px!important;} 130 | input.span-3, textarea.span-3 {width:98px!important;} 131 | input.span-4, textarea.span-4 {width:138px!important;} 132 | input.span-5, textarea.span-5 {width:178px!important;} 133 | input.span-6, textarea.span-6 {width:218px!important;} 134 | input.span-7, textarea.span-7 {width:258px!important;} 135 | input.span-8, textarea.span-8 {width:298px!important;} 136 | input.span-9, textarea.span-9 {width:338px!important;} 137 | input.span-10, textarea.span-10 {width:378px!important;} 138 | input.span-11, textarea.span-11 {width:418px!important;} 139 | input.span-12, textarea.span-12 {width:458px!important;} 140 | input.span-13, textarea.span-13 {width:498px!important;} 141 | input.span-14, textarea.span-14 {width:538px!important;} 142 | input.span-15, textarea.span-15 {width:578px!important;} 143 | input.span-16, textarea.span-16 {width:618px!important;} 144 | input.span-17, textarea.span-17 {width:658px!important;} 145 | input.span-18, textarea.span-18 {width:698px!important;} 146 | input.span-19, textarea.span-19 {width:738px!important;} 147 | input.span-20, textarea.span-20 {width:778px!important;} 148 | input.span-21, textarea.span-21 {width:818px!important;} 149 | input.span-22, textarea.span-22 {width:858px!important;} 150 | input.span-23, textarea.span-23 {width:898px!important;} 151 | input.span-24, textarea.span-24 {width:938px!important;} 152 | .append-1 {padding-right:40px;} 153 | .append-2 {padding-right:80px;} 154 | .append-3 {padding-right:120px;} 155 | .append-4 {padding-right:160px;} 156 | .append-5 {padding-right:200px;} 157 | .append-6 {padding-right:240px;} 158 | .append-7 {padding-right:280px;} 159 | .append-8 {padding-right:320px;} 160 | .append-9 {padding-right:360px;} 161 | .append-10 {padding-right:400px;} 162 | .append-11 {padding-right:440px;} 163 | .append-12 {padding-right:480px;} 164 | .append-13 {padding-right:520px;} 165 | .append-14 {padding-right:560px;} 166 | .append-15 {padding-right:600px;} 167 | .append-16 {padding-right:640px;} 168 | .append-17 {padding-right:680px;} 169 | .append-18 {padding-right:720px;} 170 | .append-19 {padding-right:760px;} 171 | .append-20 {padding-right:800px;} 172 | .append-21 {padding-right:840px;} 173 | .append-22 {padding-right:880px;} 174 | .append-23 {padding-right:920px;} 175 | .prepend-1 {padding-left:40px;} 176 | .prepend-2 {padding-left:80px;} 177 | .prepend-3 {padding-left:120px;} 178 | .prepend-4 {padding-left:160px;} 179 | .prepend-5 {padding-left:200px;} 180 | .prepend-6 {padding-left:240px;} 181 | .prepend-7 {padding-left:280px;} 182 | .prepend-8 {padding-left:320px;} 183 | .prepend-9 {padding-left:360px;} 184 | .prepend-10 {padding-left:400px;} 185 | .prepend-11 {padding-left:440px;} 186 | .prepend-12 {padding-left:480px;} 187 | .prepend-13 {padding-left:520px;} 188 | .prepend-14 {padding-left:560px;} 189 | .prepend-15 {padding-left:600px;} 190 | .prepend-16 {padding-left:640px;} 191 | .prepend-17 {padding-left:680px;} 192 | .prepend-18 {padding-left:720px;} 193 | .prepend-19 {padding-left:760px;} 194 | .prepend-20 {padding-left:800px;} 195 | .prepend-21 {padding-left:840px;} 196 | .prepend-22 {padding-left:880px;} 197 | .prepend-23 {padding-left:920px;} 198 | div.border {padding-right:4px;margin-right:5px;border-right:1px solid #eee;} 199 | div.colborder {padding-right:24px;margin-right:25px;border-right:1px solid #eee;} 200 | .pull-1 {margin-left:-40px;} 201 | .pull-2 {margin-left:-80px;} 202 | .pull-3 {margin-left:-120px;} 203 | .pull-4 {margin-left:-160px;} 204 | .pull-5 {margin-left:-200px;} 205 | .pull-6 {margin-left:-240px;} 206 | .pull-7 {margin-left:-280px;} 207 | .pull-8 {margin-left:-320px;} 208 | .pull-9 {margin-left:-360px;} 209 | .pull-10 {margin-left:-400px;} 210 | .pull-11 {margin-left:-440px;} 211 | .pull-12 {margin-left:-480px;} 212 | .pull-13 {margin-left:-520px;} 213 | .pull-14 {margin-left:-560px;} 214 | .pull-15 {margin-left:-600px;} 215 | .pull-16 {margin-left:-640px;} 216 | .pull-17 {margin-left:-680px;} 217 | .pull-18 {margin-left:-720px;} 218 | .pull-19 {margin-left:-760px;} 219 | .pull-20 {margin-left:-800px;} 220 | .pull-21 {margin-left:-840px;} 221 | .pull-22 {margin-left:-880px;} 222 | .pull-23 {margin-left:-920px;} 223 | .pull-24 {margin-left:-960px;} 224 | .pull-1, .pull-2, .pull-3, .pull-4, .pull-5, .pull-6, .pull-7, .pull-8, .pull-9, .pull-10, .pull-11, .pull-12, .pull-13, .pull-14, .pull-15, .pull-16, .pull-17, .pull-18, .pull-19, .pull-20, .pull-21, .pull-22, .pull-23, .pull-24 {float:left;position:relative;} 225 | .push-1 {margin:0 -40px 1.5em 40px;} 226 | .push-2 {margin:0 -80px 1.5em 80px;} 227 | .push-3 {margin:0 -120px 1.5em 120px;} 228 | .push-4 {margin:0 -160px 1.5em 160px;} 229 | .push-5 {margin:0 -200px 1.5em 200px;} 230 | .push-6 {margin:0 -240px 1.5em 240px;} 231 | .push-7 {margin:0 -280px 1.5em 280px;} 232 | .push-8 {margin:0 -320px 1.5em 320px;} 233 | .push-9 {margin:0 -360px 1.5em 360px;} 234 | .push-10 {margin:0 -400px 1.5em 400px;} 235 | .push-11 {margin:0 -440px 1.5em 440px;} 236 | .push-12 {margin:0 -480px 1.5em 480px;} 237 | .push-13 {margin:0 -520px 1.5em 520px;} 238 | .push-14 {margin:0 -560px 1.5em 560px;} 239 | .push-15 {margin:0 -600px 1.5em 600px;} 240 | .push-16 {margin:0 -640px 1.5em 640px;} 241 | .push-17 {margin:0 -680px 1.5em 680px;} 242 | .push-18 {margin:0 -720px 1.5em 720px;} 243 | .push-19 {margin:0 -760px 1.5em 760px;} 244 | .push-20 {margin:0 -800px 1.5em 800px;} 245 | .push-21 {margin:0 -840px 1.5em 840px;} 246 | .push-22 {margin:0 -880px 1.5em 880px;} 247 | .push-23 {margin:0 -920px 1.5em 920px;} 248 | .push-24 {margin:0 -960px 1.5em 960px;} 249 | .push-1, .push-2, .push-3, .push-4, .push-5, .push-6, .push-7, .push-8, .push-9, .push-10, .push-11, .push-12, .push-13, .push-14, .push-15, .push-16, .push-17, .push-18, .push-19, .push-20, .push-21, .push-22, .push-23, .push-24 {float:right;position:relative;} 250 | .prepend-top {margin-top:1.5em;} 251 | .append-bottom {margin-bottom:1.5em;} 252 | .box {padding:1.5em;margin-bottom:1.5em;background:#E5ECF9;} 253 | hr {background:#ddd;color:#ddd;clear:both;float:none;width:100%;height:.1em;margin:0 0 1.45em;border:none;} 254 | hr.space {background:#fff;color:#fff;visibility:hidden;} 255 | .clearfix:after, .container:after {content:"\0020";display:block;height:0;clear:both;visibility:hidden;overflow:hidden;} 256 | .clearfix, .container {display:block;} 257 | .clear {clear:both;} 258 | 259 | /* fancy-type */ 260 | p + p {text-indent:2em;margin-top:-1.5em;} 261 | form p + p {text-indent:0;} 262 | .alt {color:#666;font-family:"Warnock Pro", "Goudy Old Style","Palatino","Book Antiqua", Georgia, serif;font-style:italic;font-weight:normal;} 263 | .dquo {margin-left:-.5em;} 264 | p.incr, .incr p {font-size:10px;line-height:1.44em;margin-bottom:1.5em;} 265 | .caps {font-variant:small-caps;letter-spacing:1px;text-transform:lowercase;font-size:1.2em;line-height:1%;font-weight:bold;padding:0 2px;} 266 | 267 | /* buttons */ 268 | a.button, button {display:block;float:left;margin:0.7em 0.5em 0.7em 0;padding:5px 10px 5px 7px;border:1px solid #dedede;border-top:1px solid #eee;border-left:1px solid #eee;background-color:#f5f5f5;font-family:"Lucida Grande", Tahoma, Arial, Verdana, sans-serif;font-size:100%;line-height:130%;text-decoration:none;font-weight:bold;color:#565656;cursor:pointer;} 269 | button {width:auto;overflow:visible;padding:4px 10px 3px 7px;} 270 | button[type] {padding:4px 10px 4px 7px;line-height:17px;} 271 | *:first-child+html button[type] {padding:4px 10px 3px 7px;} 272 | button img, a.button img {margin:0 3px -3px 0 !important;padding:0;border:none;width:16px;height:16px;float:none;} 273 | button:hover, a.button:hover {background-color:#dff4ff;border:1px solid #c2e1ef;color:#336699;} 274 | a.button:active {background-color:#6299c5;border:1px solid #6299c5;color:#fff;} 275 | body .positive {color:#529214;} 276 | a.positive:hover, button.positive:hover {background-color:#E6EFC2;border:1px solid #C6D880;color:#529214;} 277 | a.positive:active {background-color:#529214;border:1px solid #529214;color:#fff;} 278 | body .negative {color:#d12f19;} 279 | a.negative:hover, button.negative:hover {background-color:#fbe3e4;border:1px solid #fbc2c4;color:#d12f19;} 280 | a.negative:active {background-color:#d12f19;border:1px solid #d12f19;color:#fff;} --------------------------------------------------------------------------------