├── .gitignore ├── Dockerfile ├── LICENSE ├── README.md ├── cf.sh ├── docker-compose.yml ├── eclipse ├── eclipse-code-formatter.xml ├── org.eclipse.jdt.core.prefs └── org.eclipse.jdt.ui.prefs ├── manifest.yml ├── monitor ├── monitor.groovy └── sound.wav ├── pom.xml ├── spring-doge-photo ├── pom.xml └── src │ ├── main │ ├── java │ │ └── doge │ │ │ └── photo │ │ │ ├── DogePhotoManipulator.java │ │ │ ├── Photo.java │ │ │ ├── PhotoManipulator.java │ │ │ └── PhotoResource.java │ └── resources │ │ └── doge-logo.png │ └── test │ ├── java │ └── doge │ │ └── photo │ │ └── DogePhotoManipulatorTest.java │ └── resources │ └── thehoff.jpg ├── spring-doge-web ├── .bowerrc ├── bower.json ├── pom.xml └── src │ └── main │ └── resources │ ├── public │ ├── clientApp.js │ ├── css │ │ ├── animations.css │ │ └── doge.css │ ├── doge.js │ ├── lib │ │ ├── angular │ │ │ ├── .bower.json │ │ │ ├── README.md │ │ │ ├── angular-csp.css │ │ │ ├── angular.js │ │ │ ├── angular.min.js │ │ │ ├── angular.min.js.gzip │ │ │ ├── angular.min.js.map │ │ │ └── bower.json │ │ ├── ng-file-upload │ │ │ ├── .bower.json │ │ │ ├── FileAPI.flash.swf │ │ │ ├── FileAPI.min.js │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── angular-file-upload-html5-shim.js │ │ │ ├── angular-file-upload-html5-shim.min.js │ │ │ ├── angular-file-upload-shim.js │ │ │ ├── angular-file-upload-shim.min.js │ │ │ ├── angular-file-upload.js │ │ │ ├── angular-file-upload.min.js │ │ │ └── bower.json │ │ ├── requirejs-domready │ │ │ ├── .bower.json │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── domReady.js │ │ │ └── package.json │ │ ├── requirejs │ │ │ ├── .bower.json │ │ │ ├── README.md │ │ │ ├── bower.json │ │ │ └── require.js │ │ ├── sockjs │ │ │ ├── .bower.json │ │ │ ├── component.json │ │ │ ├── sockjs.js │ │ │ └── sockjs.min.js │ │ └── stomp-websocket │ │ │ ├── .bower.json │ │ │ ├── .gitignore │ │ │ ├── .travis.yml │ │ │ ├── Cakefile │ │ │ ├── LICENSE.txt │ │ │ ├── README.md │ │ │ ├── RELEASE_NOTES.md │ │ │ ├── browsertests │ │ │ ├── index.html │ │ │ ├── integration │ │ │ │ ├── integration.html │ │ │ │ └── integration.js │ │ │ ├── qunit.css │ │ │ ├── qunit.js │ │ │ ├── test.css │ │ │ └── unit │ │ │ │ ├── ack.js │ │ │ │ ├── config.js │ │ │ │ ├── connection.js │ │ │ │ ├── frame.js │ │ │ │ ├── message.js │ │ │ │ ├── parse_connect.js │ │ │ │ ├── subscription.js │ │ │ │ ├── transaction.js │ │ │ │ └── websocket.js │ │ │ ├── coffeelint.json │ │ │ ├── doc │ │ │ ├── .gitignore │ │ │ ├── i │ │ │ │ └── johnny_automatic │ │ │ │ │ ├── johnny_automatic_advise_from_the_doctor.svg │ │ │ │ │ ├── johnny_automatic_elephant_climbing.svg │ │ │ │ │ ├── johnny_automatic_follow_the_leader.svg │ │ │ │ │ └── johnny_automatic_the_dynamometer_test.svg │ │ │ ├── index.html │ │ │ ├── j │ │ │ │ └── doc.js │ │ │ └── screen.css │ │ │ ├── example │ │ │ ├── README.md │ │ │ ├── chat │ │ │ │ └── index.html │ │ │ ├── css │ │ │ │ ├── bootstrap.min.css │ │ │ │ └── bootstrap.min.responsive.css │ │ │ ├── index.html │ │ │ ├── server.js │ │ │ └── webworker │ │ │ │ ├── README.md │ │ │ │ ├── index.html │ │ │ │ └── webworker.js │ │ │ ├── index.js │ │ │ ├── lib │ │ │ ├── stomp-node.js │ │ │ ├── stomp.js │ │ │ └── stomp.min.js │ │ │ ├── package.json │ │ │ ├── src │ │ │ ├── stomp-node.coffee │ │ │ ├── stomp-node.orig.js │ │ │ ├── stomp.coffee │ │ │ └── stomp.orig.js │ │ │ └── test │ │ │ ├── server.mock.coffee │ │ │ ├── stomp.spec.coffee │ │ │ └── websocket.mock.coffee │ └── monitorApp.js │ └── templates │ ├── client.html │ └── monitor.html └── spring-doge ├── .springBeans ├── pom.xml └── src ├── main ├── java │ └── doge │ │ ├── Application.java │ │ ├── ServletInitializer.java │ │ ├── controller │ │ └── UsersRestController.java │ │ ├── domain │ │ ├── DogePhoto.java │ │ ├── DogePhotoRepository.java │ │ ├── User.java │ │ └── UserRepository.java │ │ └── service │ │ └── DogeService.java └── resources │ └── application.properties └── test └── java └── doge └── controller └── UsersRestControllerTest.java /.gitignore: -------------------------------------------------------------------------------- 1 | .classpath 2 | *iml 3 | .idea 4 | .gitignore~ 5 | .project 6 | .settings 7 | target 8 | bin 9 | target 10 | .DS_Store 11 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM java:8 2 | 3 | MAINTAINER Patrick Chanezon 4 | 5 | EXPOSE 8080 6 | 7 | COPY spring-doge/target/*.jar /usr/src/spring-doge/spring-doge.jar 8 | WORKDIR /usr/src/spring-doge 9 | CMD java -Dserver.port=8080 -Dspring.data.mongodb.uri=$MONGODB_URI -jar spring-doge.jar -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Spring Doge - Such Boot! 2 | 3 | ``` 4 | cf push -p target/demo-0.0.1-SNAPSHOT.jar -b https://github.com/cloudfoundry/java-buildpack.git doge 5 | 6 | http://www.java-allandsundry.com/2014/08/deploying-spring-boot-application-to.html 7 | ``` 8 | 9 | Interesting introduction [to deploying Spring Boot applications using Spring Cloud](http://www.java-allandsundry.com/2014/08/deploying-spring-boot-application-to.html) 10 | https://gist.github.com/relaxdiego/7539911 11 | 12 | https://github.com/pivotal-cf/java-8-buildpack/blob/master/docs/example-java_main.md 13 | 14 | ## Building and running with Docker 15 | 16 | You can use STS or a locally installation of maven to build spring-doge. However, if you need to build that on a new machine where you don't have all your development environment setup, you can build it with the maven Docker container. 17 | 18 | ``` 19 | docker run -v ~/.m2:/root/.m2 -v "$PWD":/usr/src -w /usr/src maven:3-jdk-8 mvn install 20 | ``` 21 | 22 | This will create the spring-doge jar file in target. 23 | Then, you can build a container for the app and run the app and a Mongodb database in containers with the following commands: 24 | 25 | ``` 26 | docker build -t chanezon/spring-doge . 27 | docker-compose up 28 | ``` 29 | 30 | Change chanezon to your docker hub username (change it also in the docker-compose.yml file) if you want to push a modification to this image to your repository in Docker hub. 31 | -------------------------------------------------------------------------------- /cf.sh: -------------------------------------------------------------------------------- 1 | #/bin/zsh 2 | 3 | 4 | ## Deploy the Doge application to Cloud Foundry 5 | 6 | cf d doge 7 | 8 | # setup the MongoLabs Mongo service 9 | cf cs mongolab sandbox doge-mongo 10 | 11 | # push the application and defer to the manifest.yml to handle the rest 12 | cf push 13 | 14 | # make sure that - if we're assinging random-word based URIs - we don't accrue unused routes. 15 | cf delete-orphaned-routes -f 16 | 17 | # list all the apps 18 | cf apps 19 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | web: 2 | image: chanezon/spring-doge 3 | ports: 4 | - "8080:8080" 5 | links: ["mongo"] 6 | environment: 7 | - MONGODB_URI=mongodb://mongo:27017/test 8 | mongo: 9 | image: mongo 10 | -------------------------------------------------------------------------------- /eclipse/org.eclipse.jdt.ui.prefs: -------------------------------------------------------------------------------- 1 | cleanup.add_default_serial_version_id=true 2 | cleanup.add_generated_serial_version_id=false 3 | cleanup.add_missing_annotations=true 4 | cleanup.add_missing_deprecated_annotations=true 5 | cleanup.add_missing_methods=false 6 | cleanup.add_missing_nls_tags=false 7 | cleanup.add_missing_override_annotations=true 8 | cleanup.add_missing_override_annotations_interface_methods=true 9 | cleanup.add_serial_version_id=false 10 | cleanup.always_use_blocks=true 11 | cleanup.always_use_parentheses_in_expressions=false 12 | cleanup.always_use_this_for_non_static_field_access=true 13 | cleanup.always_use_this_for_non_static_method_access=false 14 | cleanup.convert_to_enhanced_for_loop=false 15 | cleanup.correct_indentation=true 16 | cleanup.format_source_code=true 17 | cleanup.format_source_code_changes_only=false 18 | cleanup.make_local_variable_final=false 19 | cleanup.make_parameters_final=false 20 | cleanup.make_private_fields_final=false 21 | cleanup.make_type_abstract_if_missing_method=false 22 | cleanup.make_variable_declarations_final=false 23 | cleanup.never_use_blocks=false 24 | cleanup.never_use_parentheses_in_expressions=true 25 | cleanup.organize_imports=true 26 | cleanup.qualify_static_field_accesses_with_declaring_class=false 27 | cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true 28 | cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true 29 | cleanup.qualify_static_member_accesses_with_declaring_class=true 30 | cleanup.qualify_static_method_accesses_with_declaring_class=false 31 | cleanup.remove_private_constructors=true 32 | cleanup.remove_trailing_whitespaces=true 33 | cleanup.remove_trailing_whitespaces_all=true 34 | cleanup.remove_trailing_whitespaces_ignore_empty=false 35 | cleanup.remove_unnecessary_casts=true 36 | cleanup.remove_unnecessary_nls_tags=false 37 | cleanup.remove_unused_imports=true 38 | cleanup.remove_unused_local_variables=false 39 | cleanup.remove_unused_private_fields=true 40 | cleanup.remove_unused_private_members=false 41 | cleanup.remove_unused_private_methods=true 42 | cleanup.remove_unused_private_types=true 43 | cleanup.sort_members=false 44 | cleanup.sort_members_all=false 45 | cleanup.use_blocks=true 46 | cleanup.use_blocks_only_for_return_and_throw=false 47 | cleanup.use_parentheses_in_expressions=false 48 | cleanup.use_this_for_non_static_field_access=false 49 | cleanup.use_this_for_non_static_field_access_only_if_necessary=false 50 | cleanup.use_this_for_non_static_method_access=false 51 | cleanup.use_this_for_non_static_method_access_only_if_necessary=true 52 | cleanup_profile=_Spring Cleanup Conventions 53 | cleanup_settings_version=2 54 | eclipse.preferences.version=1 55 | editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true 56 | formatter_profile=_Spring Java Conventions 57 | formatter_settings_version=12 58 | org.eclipse.jdt.ui.exception.name=e 59 | org.eclipse.jdt.ui.gettersetter.use.is=false 60 | org.eclipse.jdt.ui.ignorelowercasenames=true 61 | org.eclipse.jdt.ui.importorder=java;javax;org;com;\#; 62 | org.eclipse.jdt.ui.javadoc=true 63 | org.eclipse.jdt.ui.keywordthis=false 64 | org.eclipse.jdt.ui.ondemandthreshold=9999 65 | org.eclipse.jdt.ui.overrideannotation=true 66 | org.eclipse.jdt.ui.staticondemandthreshold=9999 67 | org.eclipse.jdt.ui.text.custom_code_templates= 68 | sp_cleanup.add_default_serial_version_id=true 69 | sp_cleanup.add_generated_serial_version_id=false 70 | sp_cleanup.add_missing_annotations=true 71 | sp_cleanup.add_missing_deprecated_annotations=true 72 | sp_cleanup.add_missing_methods=false 73 | sp_cleanup.add_missing_nls_tags=false 74 | sp_cleanup.add_missing_override_annotations=true 75 | sp_cleanup.add_missing_override_annotations_interface_methods=true 76 | sp_cleanup.add_serial_version_id=false 77 | sp_cleanup.always_use_blocks=true 78 | sp_cleanup.always_use_parentheses_in_expressions=true 79 | sp_cleanup.always_use_this_for_non_static_field_access=true 80 | sp_cleanup.always_use_this_for_non_static_method_access=false 81 | sp_cleanup.convert_functional_interfaces=false 82 | sp_cleanup.convert_to_enhanced_for_loop=false 83 | sp_cleanup.correct_indentation=false 84 | sp_cleanup.format_source_code=true 85 | sp_cleanup.format_source_code_changes_only=false 86 | sp_cleanup.make_local_variable_final=false 87 | sp_cleanup.make_parameters_final=false 88 | sp_cleanup.make_private_fields_final=false 89 | sp_cleanup.make_type_abstract_if_missing_method=false 90 | sp_cleanup.make_variable_declarations_final=false 91 | sp_cleanup.never_use_blocks=false 92 | sp_cleanup.never_use_parentheses_in_expressions=false 93 | sp_cleanup.on_save_use_additional_actions=true 94 | sp_cleanup.organize_imports=true 95 | sp_cleanup.qualify_static_field_accesses_with_declaring_class=false 96 | sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true 97 | sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true 98 | sp_cleanup.qualify_static_member_accesses_with_declaring_class=true 99 | sp_cleanup.qualify_static_method_accesses_with_declaring_class=false 100 | sp_cleanup.remove_private_constructors=true 101 | sp_cleanup.remove_trailing_whitespaces=true 102 | sp_cleanup.remove_trailing_whitespaces_all=true 103 | sp_cleanup.remove_trailing_whitespaces_ignore_empty=false 104 | sp_cleanup.remove_unnecessary_casts=true 105 | sp_cleanup.remove_unnecessary_nls_tags=false 106 | sp_cleanup.remove_unused_imports=true 107 | sp_cleanup.remove_unused_local_variables=false 108 | sp_cleanup.remove_unused_private_fields=true 109 | sp_cleanup.remove_unused_private_members=false 110 | sp_cleanup.remove_unused_private_methods=true 111 | sp_cleanup.remove_unused_private_types=true 112 | sp_cleanup.sort_members=false 113 | sp_cleanup.sort_members_all=false 114 | sp_cleanup.use_anonymous_class_creation=false 115 | sp_cleanup.use_blocks=false 116 | sp_cleanup.use_blocks_only_for_return_and_throw=false 117 | sp_cleanup.use_lambda=false 118 | sp_cleanup.use_parentheses_in_expressions=false 119 | sp_cleanup.use_this_for_non_static_field_access=true 120 | sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=false 121 | sp_cleanup.use_this_for_non_static_method_access=false 122 | sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true 123 | -------------------------------------------------------------------------------- /manifest.yml: -------------------------------------------------------------------------------- 1 | --- 2 | applications: 3 | - name: doge 4 | memory: 512M 5 | instances: 1 6 | host: doge-${random-word} 7 | domain: cfapps.io 8 | path: spring-doge/target/spring-doge.jar 9 | buildpack: https://github.com/cloudfoundry/java-buildpack.git 10 | services: 11 | - doge-mongo 12 | env: 13 | SPRING_PROFILES_DEFAULT: cloud 14 | DEBUG: "true" 15 | debug: "true" 16 | 17 | 18 | -------------------------------------------------------------------------------- /monitor/monitor.groovy: -------------------------------------------------------------------------------- 1 | import com.pi4j.io.gpio.* 2 | import org.springframework.web.client.* 3 | 4 | @Configuration 5 | @EnableScheduling 6 | @Grab("com.pi4j:pi4j-core:0.0.5") 7 | @Grab("spring-web") 8 | class EverySecond { 9 | 10 | GpioPinDigitalOutput pin1 = GpioFactory.getInstance() 11 | .provisionDigitalOutputPin(RaspiPin.GPIO_01) 12 | 13 | RestTemplate rest = new RestTemplate() 14 | 15 | @Value('${url}') String url 16 | 17 | @PostConstruct 18 | void setup() { 19 | pin1.low() 20 | } 21 | 22 | @Scheduled(fixedRate=1000l) 23 | void check() { 24 | try { 25 | def status = rest.getForObject(url, String).toString() 26 | if (!status.contains("UP")) raiseAlert() 27 | } catch (Exception ex) { 28 | ex.printStackTrace() 29 | raiseAlert() 30 | } 31 | } 32 | 33 | void raiseAlert() { 34 | """aplay sound.wav""".execute() 35 | for(int i=0;i<20;i++) { 36 | pin1.high() 37 | Thread.sleep(500) 38 | pin1.low() 39 | Thread.sleep(500) 40 | } 41 | System.exit(0) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /monitor/sound.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshlong/spring-doge/85ca53c3f5719c5fd964b19e8fb83e448ae6db3a/monitor/sound.wav -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 1.3.0.M2 9 | 10 | io.spring.doge 11 | spring-doge-parent 12 | 0.0.1-SNAPSHOT 13 | pom 14 | 15 | 1.8 16 | 17 | 18 | spring-doge 19 | spring-doge-photo 20 | spring-doge-web 21 | 22 | 23 | 24 | 25 | maven-eclipse-plugin 26 | 27 | false 28 | 29 | 30 | .settings/org.eclipse.jdt.ui.prefs 31 | ${main.basedir}/eclipse/org.eclipse.jdt.ui.prefs 32 | 33 | 34 | .settings/org.eclipse.jdt.core.prefs 35 | ${main.basedir}/eclipse/org.eclipse.jdt.core.prefs 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | spring-milestone 45 | http://repo.springsource.org/milestone 46 | 47 | 48 | 49 | 50 | spring-milestone 51 | http://repo.springsource.org/milestone 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /spring-doge-photo/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | io.spring.doge 7 | spring-doge-parent 8 | 0.0.1-SNAPSHOT 9 | 10 | spring-doge-photo 11 | 12 | ${basedir}/.. 13 | 14 | 15 | 16 | org.springframework.boot 17 | test 18 | spring-boot-starter-test 19 | 20 | 21 | org.springframework 22 | spring-core 23 | 24 | 25 | org.springframework 26 | spring-web 27 | true 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /spring-doge-photo/src/main/java/doge/photo/DogePhotoManipulator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012-2014 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 | * http://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 | 17 | package doge.photo; 18 | 19 | import java.awt.BasicStroke; 20 | import java.awt.Color; 21 | import java.awt.Font; 22 | import java.awt.Graphics2D; 23 | import java.awt.Paint; 24 | import java.awt.RenderingHints; 25 | import java.awt.Shape; 26 | import java.awt.font.GlyphVector; 27 | import java.awt.image.BufferedImage; 28 | import java.io.ByteArrayInputStream; 29 | import java.io.ByteArrayOutputStream; 30 | import java.io.IOException; 31 | import java.io.InputStream; 32 | import java.util.ArrayList; 33 | import java.util.List; 34 | import java.util.Random; 35 | 36 | import javax.imageio.IIOImage; 37 | import javax.imageio.ImageIO; 38 | import javax.imageio.ImageWriteParam; 39 | import javax.imageio.ImageWriter; 40 | import javax.imageio.stream.ImageOutputStream; 41 | 42 | import org.springframework.core.io.ClassPathResource; 43 | import org.springframework.util.Assert; 44 | 45 | /** 46 | * A {@link PhotoManipulator} to add Doge images. 47 | * 48 | * @author Josh Long 49 | * @author Phillip Webb 50 | */ 51 | public class DogePhotoManipulator implements PhotoManipulator { 52 | 53 | private static final int IMAGE_WIDTH = 300; 54 | 55 | private final Random random = new Random(); 56 | 57 | private BufferedImage dogeLogo; 58 | 59 | private final List textOverlays = new ArrayList<>(); 60 | 61 | public DogePhotoManipulator() { 62 | this(readClassImage("/doge-logo.png")); 63 | } 64 | 65 | public DogePhotoManipulator(BufferedImage dogeLogo) { 66 | Assert.notNull(dogeLogo, "DogeLogo must not be null"); 67 | this.dogeLogo = dogeLogo; 68 | } 69 | 70 | public void addTextOverlay(String very, String so, String what) { 71 | this.textOverlays.add(new TextOverlay(very, so, what)); 72 | } 73 | 74 | @Override 75 | public Photo manipulate(Photo photo) throws IOException { 76 | BufferedImage sourceImage = readImage(photo); 77 | BufferedImage destinationImage = manipulate(sourceImage); 78 | Photo resultPhoto = () -> { 79 | ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 80 | ImageOutputStream ios = ImageIO.createImageOutputStream(outputStream); 81 | ImageWriter writer = ImageIO.getImageWritersByFormatName("jpeg").next(); 82 | ImageWriteParam param = writer.getDefaultWriteParam(); 83 | param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); 84 | param.setCompressionQuality(0.85f); 85 | writer.setOutput(ios); 86 | writer.write(null, new IIOImage(destinationImage, null, null), param); 87 | ImageIO.write(destinationImage, "jpeg", outputStream); 88 | return new ByteArrayInputStream(outputStream.toByteArray()); 89 | }; 90 | return resultPhoto; 91 | } 92 | 93 | private BufferedImage readImage(Photo photo) throws IOException { 94 | try (InputStream inputStream = photo.getInputStream()) { 95 | return ImageIO.read(inputStream); 96 | } 97 | } 98 | 99 | private BufferedImage manipulate(BufferedImage sourceImage) { 100 | double aspectRatio = sourceImage.getHeight() / (double) sourceImage.getWidth(); 101 | int height = (int) Math.floor(IMAGE_WIDTH * aspectRatio); 102 | BufferedImage destinationImage = new BufferedImage(IMAGE_WIDTH, height, 103 | BufferedImage.TYPE_INT_RGB); 104 | render(sourceImage, destinationImage); 105 | return destinationImage; 106 | } 107 | 108 | private void render(BufferedImage sourceImage, BufferedImage destinationImage) { 109 | Graphics2D destinationGraphics = destinationImage.createGraphics(); 110 | try { 111 | setGraphicsHints(destinationGraphics); 112 | renderBackground(sourceImage, destinationImage, destinationGraphics); 113 | renderOverlay(destinationImage, destinationGraphics); 114 | } 115 | finally { 116 | destinationGraphics.dispose(); 117 | } 118 | } 119 | 120 | private void renderBackground(BufferedImage sourceImage, 121 | BufferedImage destinationImage, Graphics2D destinationGraphics) { 122 | destinationGraphics.drawImage(sourceImage, 0, 0, IMAGE_WIDTH, 123 | destinationImage.getHeight(), null); 124 | } 125 | 126 | private void renderOverlay(BufferedImage image, Graphics2D graphics) { 127 | getRandomText().render(image, graphics); 128 | int y = image.getHeight() - this.dogeLogo.getHeight(); 129 | graphics.drawImage(this.dogeLogo, 0, y, null); 130 | } 131 | 132 | private TextOverlay getRandomText() { 133 | return this.textOverlays.get(this.random.nextInt(this.textOverlays.size())); 134 | } 135 | 136 | private void setGraphicsHints(Graphics2D graphics) { 137 | graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, 138 | RenderingHints.VALUE_INTERPOLATION_BILINEAR); 139 | graphics.setRenderingHint(RenderingHints.KEY_RENDERING, 140 | RenderingHints.VALUE_RENDER_QUALITY); 141 | graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 142 | RenderingHints.VALUE_ANTIALIAS_ON); 143 | graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, 144 | RenderingHints.VALUE_TEXT_ANTIALIAS_ON); 145 | graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, 146 | RenderingHints.VALUE_TEXT_ANTIALIAS_GASP); 147 | } 148 | 149 | private static BufferedImage readClassImage(String name) { 150 | try (InputStream imgInputStream = new ClassPathResource(name).getInputStream()) { 151 | return ImageIO.read(imgInputStream); 152 | } 153 | catch (IOException e) { 154 | throw new RuntimeException(e); 155 | } 156 | 157 | } 158 | 159 | /** 160 | * Text overlay 161 | */ 162 | private static class TextOverlay { 163 | 164 | private final String very; 165 | 166 | private final String so; 167 | 168 | private final String such; 169 | 170 | public TextOverlay(String very, String so, String such) { 171 | this.very = very; 172 | this.so = so; 173 | this.such = such; 174 | } 175 | 176 | public void render(BufferedImage image, Graphics2D g) { 177 | double r = image.getHeight() / 448.0; 178 | renderText(g, "wow", 32, Color.MAGENTA, 25, r * 43); 179 | renderText(g, "very " + this.very, 29, Color.GREEN, 105, r * 115); 180 | renderText(g, "so " + this.so, 20, Color.MAGENTA, 25, r * 330); 181 | renderText(g, "such " + this.such, 30, Color.ORANGE, 125, r * 385); 182 | } 183 | 184 | private void renderText(Graphics2D g, String text, int fontSize, Paint paint, 185 | double x, double y) { 186 | Font font = new Font("Comic Sans MS", Font.BOLD, fontSize); 187 | GlyphVector vector = font.createGlyphVector(g.getFontRenderContext(), 188 | text.toCharArray()); 189 | Shape shape = vector.getOutline((int) x, (int) y); 190 | g.setStroke(new BasicStroke(0.5f)); 191 | g.setPaint(paint); 192 | g.fill(shape); 193 | g.setColor(Color.BLACK); 194 | g.draw(shape); 195 | } 196 | } 197 | } 198 | -------------------------------------------------------------------------------- /spring-doge-photo/src/main/java/doge/photo/Photo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012-2014 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 | * http://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 | 17 | package doge.photo; 18 | 19 | import java.io.IOException; 20 | import java.io.InputStream; 21 | 22 | /** 23 | * Encapsulation of a photo. 24 | * 25 | * @author Josh Long 26 | * @author Phillip Webb 27 | */ 28 | public interface Photo { 29 | 30 | /** 31 | * @return a new {@link InputStream} containing photo data as a JPEG. The caller is 32 | * responsible for closing the stream. 33 | * @throws IOException 34 | */ 35 | public InputStream getInputStream() throws IOException; 36 | 37 | } 38 | -------------------------------------------------------------------------------- /spring-doge-photo/src/main/java/doge/photo/PhotoManipulator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012-2014 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 | * http://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 | 17 | package doge.photo; 18 | 19 | import java.io.IOException; 20 | 21 | /** 22 | * Service to manipulate a {@link Photo} in some way. 23 | * 24 | * @author Josh Long 25 | * @author Phillip Webb 26 | */ 27 | public interface PhotoManipulator { 28 | 29 | /** 30 | * Manipulates a photo. 31 | * @param photo the source photo 32 | * @return the manipulated photo 33 | * @throws IOException 34 | */ 35 | Photo manipulate(Photo photo) throws IOException; 36 | 37 | } 38 | -------------------------------------------------------------------------------- /spring-doge-photo/src/main/java/doge/photo/PhotoResource.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012-2014 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 | * http://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 | 17 | package doge.photo; 18 | 19 | import java.io.IOException; 20 | import java.io.InputStream; 21 | 22 | import org.springframework.core.io.AbstractResource; 23 | import org.springframework.core.io.Resource; 24 | import org.springframework.util.Assert; 25 | 26 | /** 27 | * Adapter class to convert a {@link Photo} to a Spring {@link Resource}. 28 | * 29 | * @author Josh Long 30 | * @author Phillip Webb 31 | */ 32 | public class PhotoResource extends AbstractResource { 33 | 34 | private final Photo photo; 35 | 36 | public PhotoResource(Photo photo) { 37 | Assert.notNull(photo, "Photo must not be null"); 38 | this.photo = photo; 39 | } 40 | 41 | @Override 42 | public String getDescription() { 43 | return null; 44 | } 45 | 46 | @Override 47 | public InputStream getInputStream() throws IOException { 48 | return this.photo.getInputStream(); 49 | } 50 | 51 | @Override 52 | public long contentLength() throws IOException { 53 | return -1; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /spring-doge-photo/src/main/resources/doge-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshlong/spring-doge/85ca53c3f5719c5fd964b19e8fb83e448ae6db3a/spring-doge-photo/src/main/resources/doge-logo.png -------------------------------------------------------------------------------- /spring-doge-photo/src/test/java/doge/photo/DogePhotoManipulatorTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012-2014 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 | * http://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 | 17 | package doge.photo; 18 | 19 | import java.io.File; 20 | import java.io.FileOutputStream; 21 | 22 | import org.junit.Before; 23 | import org.junit.Test; 24 | import org.springframework.core.io.ClassPathResource; 25 | import org.springframework.util.FileCopyUtils; 26 | 27 | /** 28 | * Tests for {@link DogePhotoManipulator}. 29 | * 30 | * @author Phillip Webb 31 | * @author Josh Long 32 | */ 33 | public class DogePhotoManipulatorTest { 34 | 35 | private PhotoManipulator manipulator = new DogePhotoManipulator() { 36 | { 37 | addTextOverlay("very1", "so1", "what1"); 38 | addTextOverlay("very2", "so2", "what2"); 39 | } 40 | }; 41 | 42 | private File file; 43 | 44 | @Before 45 | public void clean() { 46 | File target = new File(System.getProperty("java.io.tmpdir")); 47 | this.file = new File(target, "manipulatedhoff.jpg"); 48 | this.file.delete(); 49 | System.out.println(this.file); 50 | } 51 | 52 | @Test 53 | public void testDogePhotoManipulatorService() throws Exception { 54 | Photo photo = () -> new ClassPathResource("thehoff.jpg").getInputStream(); 55 | Photo manipulated = this.manipulator.manipulate(photo); 56 | FileCopyUtils.copy(manipulated.getInputStream(), new FileOutputStream(this.file)); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /spring-doge-photo/src/test/resources/thehoff.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshlong/spring-doge/85ca53c3f5719c5fd964b19e8fb83e448ae6db3a/spring-doge-photo/src/test/resources/thehoff.jpg -------------------------------------------------------------------------------- /spring-doge-web/.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory" : "src/main/resources/public/lib" 3 | } -------------------------------------------------------------------------------- /spring-doge-web/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "doge", 3 | "version": "1.0.0-SNAPSHOT", 4 | "dependencies": { 5 | 6 | "sockjs": "~0.3", 7 | "stomp-websocket": "~2.2", 8 | "requirejs": "~2.1.11", 9 | "angular": "~1.2.16", 10 | "ng-file-upload": "~1.3.1", 11 | "requirejs-domready": "~2.0.1" 12 | }, 13 | 14 | "ignore": [ 15 | "test" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /spring-doge-web/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | io.spring.doge 7 | spring-doge-parent 8 | 0.0.1-SNAPSHOT 9 | 10 | spring-doge-web 11 | 12 | ${basedir}/.. 13 | 14 | 15 | 16 | org.springframework.boot 17 | spring-boot-starter-web 18 | 19 | 20 | org.springframework.boot 21 | spring-boot-starter-thymeleaf 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/clientApp.js: -------------------------------------------------------------------------------- 1 | var appName = 'client'; 2 | 3 | /******************************************************************************* 4 | * Uploads images to made doge-tastic 5 | */ 6 | require.config({ 7 | paths : { 8 | doge : 'doge', 9 | stomp : doge.jsUrl('stomp-websocket/lib/stomp'), 10 | sockjs : doge.jsUrl('sockjs/sockjs'), 11 | angular : doge.jsUrl('angular/angular'), 12 | angularFileUpload : doge.jsUrl('ng-file-upload/angular-file-upload'), 13 | domReady : doge.jsUrl('requirejs-domready/domReady') 14 | }, 15 | shim : { 16 | angular : { 17 | exports : 'angular' 18 | } 19 | } 20 | }); 21 | 22 | define([ 'require', 'angular' ], function(require, angular) { 23 | 24 | 'use strict'; 25 | 26 | require([ 'angular', 'angularFileUpload', 'sockjs', 'stomp', 'domReady!' ], 27 | function(angular) { 28 | angular.bootstrap(document, [ appName ]); 29 | }); 30 | 31 | angular.module(appName, [ 'angularFileUpload' ]).controller('ClientController', 32 | [ '$scope', '$http', '$upload', '$log', function($scope, $http, $upload, $log) { 33 | 34 | $scope.users = []; 35 | $scope.dogeUploads = []; 36 | 37 | $http.get('/users').success(function(data) { 38 | $scope.users = data; 39 | if ($scope.users != null && $scope.users.length > 0) { 40 | $scope.selectedUser = $scope.users[0]; 41 | } 42 | }); 43 | 44 | $scope.onFileSelect = function($files) { 45 | for (var i = 0; i < $files.length; i++) { 46 | $scope.upload = $upload.upload({ 47 | url : '/users/' + $scope.selectedUser.id + '/doge', 48 | method : 'POST', 49 | file : $files[i], 50 | fileFormDataName: 'file' 51 | }).success(function(data, status, headers, config) { 52 | $scope.dogeUploads.splice(0, 0, headers('location')); 53 | }); 54 | } 55 | } 56 | 57 | } ]); 58 | }); 59 | -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/css/doge.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: sans-serif; 3 | } 4 | 5 | .drop-box { 6 | background: none repeat scroll 0 0 #F8F8F8; 7 | border: 5px dashed #DDDDDD; 8 | height: 150px; 9 | line-height: 150px; 10 | width: 250px; 11 | text-align: center; 12 | vertical-align: middle; 13 | } 14 | 15 | .drop-box.dragover { 16 | border: 5px dashed blue; 17 | } 18 | 19 | .ng-cloak { 20 | visibility: hidden !important; 21 | } 22 | 23 | ul#uploads { 24 | padding: 0; 25 | list-style: none; 26 | font-size: 14px; 27 | } 28 | 29 | ul#uploads img { 30 | width: 40px; 31 | height: auto; 32 | vertical-align: middle; 33 | padding: 2px 10px 2px 10px; 34 | } 35 | -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/doge.js: -------------------------------------------------------------------------------- 1 | var doge = { 2 | jsUrl : function(p) { 3 | return 'lib/' + p; 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/angular/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular", 3 | "version": "1.2.16", 4 | "main": "./angular.js", 5 | "dependencies": {}, 6 | "homepage": "https://github.com/angular/bower-angular", 7 | "_release": "1.2.16", 8 | "_resolution": { 9 | "type": "version", 10 | "tag": "v1.2.16", 11 | "commit": "7ae38b4a0cfced157e3486a0d6e2d299601723bb" 12 | }, 13 | "_source": "git://github.com/angular/bower-angular.git", 14 | "_target": "~1.2.16", 15 | "_originalSource": "angular", 16 | "_direct": true 17 | } -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/angular/README.md: -------------------------------------------------------------------------------- 1 | # bower-angular 2 | 3 | This repo is for distribution on `bower`. The source for this module is in the 4 | [main AngularJS repo](https://github.com/angular/angular.js). 5 | Please file issues and pull requests against that repo. 6 | 7 | ## Install 8 | 9 | Install with `bower`: 10 | 11 | ```shell 12 | bower install angular 13 | ``` 14 | 15 | Add a ` 19 | ``` 20 | 21 | ## Documentation 22 | 23 | Documentation is available on the 24 | [AngularJS docs site](http://docs.angularjs.org/). 25 | 26 | ## License 27 | 28 | The MIT License 29 | 30 | Copyright (c) 2010-2012 Google, Inc. http://angularjs.org 31 | 32 | Permission is hereby granted, free of charge, to any person obtaining a copy 33 | of this software and associated documentation files (the "Software"), to deal 34 | in the Software without restriction, including without limitation the rights 35 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 36 | copies of the Software, and to permit persons to whom the Software is 37 | furnished to do so, subject to the following conditions: 38 | 39 | The above copyright notice and this permission notice shall be included in 40 | all copies or substantial portions of the Software. 41 | 42 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 43 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 44 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 45 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 46 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 47 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 48 | THE SOFTWARE. 49 | -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/angular/angular-csp.css: -------------------------------------------------------------------------------- 1 | /* Include this file in your html if you are using the CSP mode. */ 2 | 3 | @charset "UTF-8"; 4 | 5 | [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], 6 | .ng-cloak, .x-ng-cloak, 7 | .ng-hide { 8 | display: none !important; 9 | } 10 | 11 | ng\:form { 12 | display: block; 13 | } 14 | 15 | .ng-animate-block-transitions { 16 | transition:0s all!important; 17 | -webkit-transition:0s all!important; 18 | } 19 | -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/angular/angular.min.js.gzip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshlong/spring-doge/85ca53c3f5719c5fd964b19e8fb83e448ae6db3a/spring-doge-web/src/main/resources/public/lib/angular/angular.min.js.gzip -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/angular/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular", 3 | "version": "1.2.16", 4 | "main": "./angular.js", 5 | "dependencies": { 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/ng-file-upload/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-file-upload", 3 | "main": [ 4 | "angular-file-upload-shim.js", 5 | "angular-file-upload.js" 6 | ], 7 | "version": "1.3.1", 8 | "homepage": "https://github.com/danialfarid/angular-file-upload", 9 | "authors": [ 10 | "danialf " 11 | ], 12 | "description": "Lightweight Angular JS directive to upload files. Support drag&drop, progress and abort", 13 | "license": "MIT", 14 | "_release": "1.3.1", 15 | "_resolution": { 16 | "type": "version", 17 | "tag": "1.3.1", 18 | "commit": "bf6ad8767175e1ea62cb58f36e4692cf5b4cf892" 19 | }, 20 | "_source": "git://github.com/danialfarid/angular-file-upload-bower.git", 21 | "_target": "~1.3.1", 22 | "_originalSource": "ng-file-upload" 23 | } -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/ng-file-upload/FileAPI.flash.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshlong/spring-doge/85ca53c3f5719c5fd964b19e8fb83e448ae6db3a/spring-doge-web/src/main/resources/public/lib/ng-file-upload/FileAPI.flash.swf -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/ng-file-upload/FileAPI.min.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshlong/spring-doge/85ca53c3f5719c5fd964b19e8fb83e448ae6db3a/spring-doge-web/src/main/resources/public/lib/ng-file-upload/FileAPI.min.js -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/ng-file-upload/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 danialfarid 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/ng-file-upload/README.md: -------------------------------------------------------------------------------- 1 | # angular-file-upload-bower 2 | 3 | bower distribution of [angular-file-upload](https://github.com/danialfarid/angular-file-upload). 4 | All issues and pull request must be sumbitted to [angular-file-upload](https://github.com/danialfarid/angular-file-upload) 5 | 6 | ## Install 7 | 8 | Install with `bower`: 9 | 10 | ```shell 11 | bower install ng-file-upload 12 | ``` 13 | 14 | Add a ` 18 | 19 | 20 | 21 | 22 | ``` 23 | -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/ng-file-upload/angular-file-upload-html5-shim.js: -------------------------------------------------------------------------------- 1 | /**! 2 | * AngularJS file upload shim for angular XHR HTML5 browsers 3 | * @author Danial 4 | * @version 1.3.1 5 | */ 6 | if (window.XMLHttpRequest) { 7 | if (window.FormData) { 8 | // allow access to Angular XHR private field: https://github.com/angular/angular.js/issues/1934 9 | XMLHttpRequest = (function(origXHR) { 10 | return function() { 11 | var xhr = new origXHR(); 12 | xhr.setRequestHeader = (function(orig) { 13 | return function(header, value) { 14 | if (header === '__setXHR_') { 15 | var val = value(xhr); 16 | // fix for angular < 1.2.0 17 | if (val instanceof Function) { 18 | val(xhr); 19 | } 20 | } else { 21 | orig.apply(xhr, arguments); 22 | } 23 | } 24 | })(xhr.setRequestHeader); 25 | return xhr; 26 | } 27 | })(XMLHttpRequest); 28 | window.XMLHttpRequest.__isShim = true; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/ng-file-upload/angular-file-upload-html5-shim.min.js: -------------------------------------------------------------------------------- 1 | /*! 1.3.1 */ 2 | window.XMLHttpRequest&&window.FormData&&(XMLHttpRequest=function(a){return function(){var b=new a;return b.setRequestHeader=function(a){return function(c,d){if("__setXHR_"===c){var e=d(b);e instanceof Function&&e(b)}else a.apply(b,arguments)}}(b.setRequestHeader),b}}(XMLHttpRequest),window.XMLHttpRequest.__isShim=!0); -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/ng-file-upload/angular-file-upload-shim.js: -------------------------------------------------------------------------------- 1 | /**! 2 | * AngularJS file upload shim for HTML5 FormData 3 | * @author Danial 4 | * @version 1.3.1 5 | */ 6 | (function() { 7 | 8 | var hasFlash = function() { 9 | try { 10 | var fo = new ActiveXObject('ShockwaveFlash.ShockwaveFlash'); 11 | if (fo) return true; 12 | } catch(e) { 13 | if (navigator.mimeTypes["application/x-shockwave-flash"] != undefined) return true; 14 | } 15 | return false; 16 | } 17 | 18 | if (window.XMLHttpRequest) { 19 | if (window.FormData) { 20 | // allow access to Angular XHR private field: https://github.com/angular/angular.js/issues/1934 21 | window.XMLHttpRequest = (function(origXHR) { 22 | return function() { 23 | var xhr = new origXHR(); 24 | xhr.setRequestHeader = (function(orig) { 25 | return function(header, value) { 26 | if (header === '__setXHR_') { 27 | var val = value(xhr); 28 | // fix for angular < 1.2.0 29 | if (val instanceof Function) { 30 | val(xhr); 31 | } 32 | } else { 33 | orig.apply(xhr, arguments); 34 | } 35 | } 36 | })(xhr.setRequestHeader); 37 | return xhr; 38 | } 39 | })(window.XMLHttpRequest); 40 | } else { 41 | window.XMLHttpRequest = (function(origXHR) { 42 | return function() { 43 | var xhr = new origXHR(); 44 | var origSend = xhr.send; 45 | xhr.__requestHeaders = []; 46 | xhr.open = (function(orig) { 47 | if (!xhr.upload) xhr.upload = {}; 48 | xhr.__listeners = []; 49 | xhr.upload.addEventListener = function(t, fn, b) { 50 | xhr.__listeners[t] = fn; 51 | }; 52 | return function(m, url, b) { 53 | orig.apply(xhr, [m, url, b]); 54 | xhr.__url = url; 55 | } 56 | })(xhr.open); 57 | xhr.getResponseHeader = (function(orig) { 58 | return function(h) { 59 | return xhr.__fileApiXHR ? xhr.__fileApiXHR.getResponseHeader(h) : orig.apply(xhr, [h]); 60 | } 61 | })(xhr.getResponseHeader); 62 | xhr.getAllResponseHeaders = (function(orig) { 63 | return function() { 64 | return xhr.__fileApiXHR ? xhr.__fileApiXHR.getAllResponseHeaders() : orig.apply(xhr); 65 | } 66 | })(xhr.getAllResponseHeaders); 67 | xhr.abort = (function(orig) { 68 | return function() { 69 | return xhr.__fileApiXHR ? xhr.__fileApiXHR.abort() : (orig == null ? null : orig.apply(xhr)); 70 | } 71 | })(xhr.abort); 72 | xhr.setRequestHeader = (function(orig) { 73 | return function(header, value) { 74 | if (header === '__setXHR_') { 75 | var val = value(xhr); 76 | // fix for angular < 1.2.0 77 | if (val instanceof Function) { 78 | val(xhr); 79 | } 80 | } else { 81 | orig.apply(xhr, arguments); 82 | } 83 | } 84 | })(xhr.setRequestHeader); 85 | 86 | xhr.send = function() { 87 | if (arguments[0] && arguments[0].__isShim) { 88 | var formData = arguments[0]; 89 | var config = { 90 | url: xhr.__url, 91 | complete: function(err, fileApiXHR) { 92 | if (!err && xhr.__listeners['load']) 93 | xhr.__listeners['load']({type: 'load', loaded: xhr.__loaded, total: xhr.__total, target: xhr, lengthComputable: true}); 94 | if (!err && xhr.__listeners['loadend']) 95 | xhr.__listeners['loadend']({type: 'loadend', loaded: xhr.__loaded, total: xhr.__total, target: xhr, lengthComputable: true}); 96 | if (err === 'abort' && xhr.__listeners['abort']) 97 | xhr.__listeners['abort']({type: 'abort', loaded: xhr.__loaded, total: xhr.__total, target: xhr, lengthComputable: true}); 98 | if (fileApiXHR.status !== undefined) Object.defineProperty(xhr, 'status', {get: function() {return fileApiXHR.status}}); 99 | if (fileApiXHR.statusText !== undefined) Object.defineProperty(xhr, 'statusText', {get: function() {return fileApiXHR.statusText}}); 100 | Object.defineProperty(xhr, 'readyState', {get: function() {return 4}}); 101 | if (fileApiXHR.response !== undefined) Object.defineProperty(xhr, 'response', {get: function() {return fileApiXHR.response}}); 102 | Object.defineProperty(xhr, 'responseText', {get: function() {return fileApiXHR.responseText}}); 103 | xhr.__fileApiXHR = fileApiXHR; 104 | xhr.onreadystatechange(); 105 | }, 106 | progress: function(e) { 107 | e.target = xhr; 108 | xhr.__listeners['progress'] && xhr.__listeners['progress'](e); 109 | xhr.__total = e.total; 110 | xhr.__loaded = e.loaded; 111 | }, 112 | headers: xhr.__requestHeaders 113 | } 114 | config.data = {}; 115 | config.files = {} 116 | for (var i = 0; i < formData.data.length; i++) { 117 | var item = formData.data[i]; 118 | if (item.val != null && item.val.name != null && item.val.size != null && item.val.type != null) { 119 | config.files[item.key] = item.val; 120 | } else { 121 | config.data[item.key] = item.val; 122 | } 123 | } 124 | 125 | setTimeout(function() { 126 | if (!hasFlash()) { 127 | throw 'Adode Flash Player need to be installed. To check ahead use "FileAPI.hasFlash"'; 128 | } 129 | xhr.__fileApiXHR = FileAPI.upload(config); 130 | }, 1); 131 | } else { 132 | origSend.apply(xhr, arguments); 133 | } 134 | } 135 | return xhr; 136 | } 137 | })(window.XMLHttpRequest); 138 | window.XMLHttpRequest.__hasFlash = hasFlash(); 139 | } 140 | window.XMLHttpRequest.__isShim = true; 141 | } 142 | 143 | if (!window.FormData) { 144 | var wrapFileApi = function(elem) { 145 | if (!hasFlash()) { 146 | throw 'Adode Flash Player need to be installed. To check ahead use "FileAPI.hasFlash"'; 147 | } 148 | if (!elem.__isWrapped && (elem.getAttribute('ng-file-select') != null || elem.getAttribute('data-ng-file-select') != null)) { 149 | var wrap = document.createElement('div'); 150 | wrap.innerHTML = '
'; 151 | wrap = wrap.firstChild; 152 | var parent = elem.parentNode; 153 | parent.insertBefore(wrap, elem); 154 | parent.removeChild(elem); 155 | wrap.appendChild(elem); 156 | elem.__isWrapped = true; 157 | } 158 | }; 159 | var changeFnWrapper = function(fn) { 160 | return function(evt) { 161 | var files = FileAPI.getFiles(evt); 162 | if (!evt.target) { 163 | evt.target = {}; 164 | } 165 | evt.target.files = files; 166 | evt.target.files.item = function(i) { 167 | return evt.target.files[i] || null; 168 | } 169 | fn(evt); 170 | }; 171 | }; 172 | var isFileChange = function(elem, e) { 173 | return (e.toLowerCase() === 'change' || e.toLowerCase() === 'onchange') && elem.getAttribute('type') == 'file'; 174 | } 175 | if (HTMLInputElement.prototype.addEventListener) { 176 | HTMLInputElement.prototype.addEventListener = (function(origAddEventListener) { 177 | return function(e, fn, b, d) { 178 | if (isFileChange(this, e)) { 179 | wrapFileApi(this); 180 | origAddEventListener.apply(this, [e, changeFnWrapper(fn), b, d]); 181 | } else { 182 | origAddEventListener.apply(this, [e, fn, b, d]); 183 | } 184 | } 185 | })(HTMLInputElement.prototype.addEventListener); 186 | } 187 | if (HTMLInputElement.prototype.attachEvent) { 188 | HTMLInputElement.prototype.attachEvent = (function(origAttachEvent) { 189 | return function(e, fn) { 190 | if (isFileChange(this, e)) { 191 | wrapFileApi(this); 192 | origAttachEvent.apply(this, [e, changeFnWrapper(fn)]); 193 | } else { 194 | origAttachEvent.apply(this, [e, fn]); 195 | } 196 | } 197 | })(HTMLInputElement.prototype.attachEvent); 198 | } 199 | 200 | window.FormData = FormData = function() { 201 | return { 202 | append: function(key, val, name) { 203 | this.data.push({ 204 | key: key, 205 | val: val, 206 | name: name 207 | }); 208 | }, 209 | data: [], 210 | __isShim: true 211 | }; 212 | }; 213 | 214 | (function () { 215 | //load FileAPI 216 | if (!window.FileAPI) { 217 | window.FileAPI = {}; 218 | } 219 | if (!FileAPI.upload) { 220 | var jsUrl, basePath, script = document.createElement('script'), allScripts = document.getElementsByTagName('script'), i, index, src; 221 | if (window.FileAPI.jsUrl) { 222 | jsUrl = window.FileAPI.jsUrl; 223 | } else if (window.FileAPI.jsPath) { 224 | basePath = window.FileAPI.jsPath; 225 | } else { 226 | for (i = 0; i < allScripts.length; i++) { 227 | src = allScripts[i].src; 228 | index = src.indexOf('angular-file-upload-shim.js') 229 | if (index == -1) { 230 | index = src.indexOf('angular-file-upload-shim.min.js'); 231 | } 232 | if (index > -1) { 233 | basePath = src.substring(0, index); 234 | break; 235 | } 236 | } 237 | } 238 | 239 | if (FileAPI.staticPath == null) FileAPI.staticPath = basePath; 240 | script.setAttribute('src', jsUrl || basePath + "FileAPI.min.js"); 241 | document.getElementsByTagName('head')[0].appendChild(script); 242 | FileAPI.hasFlash = hasFlash(); 243 | } 244 | })(); 245 | } 246 | 247 | 248 | if (!window.FileReader) { 249 | window.FileReader = function() { 250 | var _this = this, loadStarted = false; 251 | this.listeners = {}; 252 | this.addEventListener = function(type, fn) { 253 | _this.listeners[type] = _this.listeners[type] || []; 254 | _this.listeners[type].push(fn); 255 | }; 256 | this.removeEventListener = function(type, fn) { 257 | _this.listeners[type] && _this.listeners[type].splice(_this.listeners[type].indexOf(fn), 1); 258 | }; 259 | this.dispatchEvent = function(evt) { 260 | var list = _this.listeners[evt.type]; 261 | if (list) { 262 | for (var i = 0; i < list.length; i++) { 263 | list[i].call(_this, evt); 264 | } 265 | } 266 | }; 267 | this.onabort = this.onerror = this.onload = this.onloadstart = this.onloadend = this.onprogress = null; 268 | 269 | function constructEvent(type, evt) { 270 | var e = {type: type, target: _this, loaded: evt.loaded, total: evt.total, error: evt.error}; 271 | if (evt.result != null) e.target.result = evt.result; 272 | return e; 273 | }; 274 | var listener = function(evt) { 275 | if (!loadStarted) { 276 | loadStarted = true; 277 | _this.onloadstart && this.onloadstart(constructEvent('loadstart', evt)); 278 | } 279 | if (evt.type === 'load') { 280 | _this.onloadend && _this.onloadend(constructEvent('loadend', evt)); 281 | var e = constructEvent('load', evt); 282 | _this.onload && _this.onload(e); 283 | _this.dispatchEvent(e); 284 | } else if (evt.type === 'progress') { 285 | var e = constructEvent('progress', evt); 286 | _this.onprogress && _this.onprogress(e); 287 | _this.dispatchEvent(e); 288 | } else { 289 | var e = constructEvent('error', evt); 290 | _this.onerror && _this.onerror(e); 291 | _this.dispatchEvent(e); 292 | } 293 | }; 294 | this.readAsArrayBuffer = function(file) { 295 | FileAPI.readAsBinaryString(file, listener); 296 | } 297 | this.readAsBinaryString = function(file) { 298 | FileAPI.readAsBinaryString(file, listener); 299 | } 300 | this.readAsDataURL = function(file) { 301 | FileAPI.readAsDataURL(file, listener); 302 | } 303 | this.readAsText = function(file) { 304 | FileAPI.readAsText(file, listener); 305 | } 306 | } 307 | } 308 | 309 | })(); 310 | -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/ng-file-upload/angular-file-upload-shim.min.js: -------------------------------------------------------------------------------- 1 | /*! 1.3.1 */ 2 | !function(){var a=function(){try{var a=new ActiveXObject("ShockwaveFlash.ShockwaveFlash");if(a)return!0}catch(b){if(void 0!=navigator.mimeTypes["application/x-shockwave-flash"])return!0}return!1};if(window.XMLHttpRequest&&(window.FormData?window.XMLHttpRequest=function(a){return function(){var b=new a;return b.setRequestHeader=function(a){return function(c,d){if("__setXHR_"===c){var e=d(b);e instanceof Function&&e(b)}else a.apply(b,arguments)}}(b.setRequestHeader),b}}(window.XMLHttpRequest):(window.XMLHttpRequest=function(b){return function(){var c=new b,d=c.send;return c.__requestHeaders=[],c.open=function(a){return c.upload||(c.upload={}),c.__listeners=[],c.upload.addEventListener=function(a,b){c.__listeners[a]=b},function(b,d,e){a.apply(c,[b,d,e]),c.__url=d}}(c.open),c.getResponseHeader=function(a){return function(b){return c.__fileApiXHR?c.__fileApiXHR.getResponseHeader(b):a.apply(c,[b])}}(c.getResponseHeader),c.getAllResponseHeaders=function(a){return function(){return c.__fileApiXHR?c.__fileApiXHR.getAllResponseHeaders():a.apply(c)}}(c.getAllResponseHeaders),c.abort=function(a){return function(){return c.__fileApiXHR?c.__fileApiXHR.abort():null==a?null:a.apply(c)}}(c.abort),c.setRequestHeader=function(a){return function(b,d){if("__setXHR_"===b){var e=d(c);e instanceof Function&&e(c)}else a.apply(c,arguments)}}(c.setRequestHeader),c.send=function(){if(arguments[0]&&arguments[0].__isShim){var b=arguments[0],e={url:c.__url,complete:function(a,b){!a&&c.__listeners.load&&c.__listeners.load({type:"load",loaded:c.__loaded,total:c.__total,target:c,lengthComputable:!0}),!a&&c.__listeners.loadend&&c.__listeners.loadend({type:"loadend",loaded:c.__loaded,total:c.__total,target:c,lengthComputable:!0}),"abort"===a&&c.__listeners.abort&&c.__listeners.abort({type:"abort",loaded:c.__loaded,total:c.__total,target:c,lengthComputable:!0}),void 0!==b.status&&Object.defineProperty(c,"status",{get:function(){return b.status}}),void 0!==b.statusText&&Object.defineProperty(c,"statusText",{get:function(){return b.statusText}}),Object.defineProperty(c,"readyState",{get:function(){return 4}}),void 0!==b.response&&Object.defineProperty(c,"response",{get:function(){return b.response}}),Object.defineProperty(c,"responseText",{get:function(){return b.responseText}}),c.__fileApiXHR=b,c.onreadystatechange()},progress:function(a){a.target=c,c.__listeners.progress&&c.__listeners.progress(a),c.__total=a.total,c.__loaded=a.loaded},headers:c.__requestHeaders};e.data={},e.files={};for(var f=0;f',c=c.firstChild;var d=b.parentNode;d.insertBefore(c,b),d.removeChild(b),c.appendChild(b),b.__isWrapped=!0}},c=function(a){return function(b){var c=FileAPI.getFiles(b);b.target||(b.target={}),b.target.files=c,b.target.files.item=function(a){return b.target.files[a]||null},a(b)}},d=function(a,b){return("change"===b.toLowerCase()||"onchange"===b.toLowerCase())&&"file"==a.getAttribute("type")};HTMLInputElement.prototype.addEventListener&&(HTMLInputElement.prototype.addEventListener=function(a){return function(e,f,g,h){d(this,e)?(b(this),a.apply(this,[e,c(f),g,h])):a.apply(this,[e,f,g,h])}}(HTMLInputElement.prototype.addEventListener)),HTMLInputElement.prototype.attachEvent&&(HTMLInputElement.prototype.attachEvent=function(a){return function(e,f){d(this,e)?(b(this),a.apply(this,[e,c(f)])):a.apply(this,[e,f])}}(HTMLInputElement.prototype.attachEvent)),window.FormData=FormData=function(){return{append:function(a,b,c){this.data.push({key:a,val:b,name:c})},data:[],__isShim:!0}},function(){if(window.FileAPI||(window.FileAPI={}),!FileAPI.upload){var b,c,d,e,f,g=document.createElement("script"),h=document.getElementsByTagName("script");if(window.FileAPI.jsUrl)b=window.FileAPI.jsUrl;else if(window.FileAPI.jsPath)c=window.FileAPI.jsPath;else for(d=0;d-1){c=f.substring(0,e);break}null==FileAPI.staticPath&&(FileAPI.staticPath=c),g.setAttribute("src",b||c+"FileAPI.min.js"),document.getElementsByTagName("head")[0].appendChild(g),FileAPI.hasFlash=a()}}()}window.FileReader||(window.FileReader=function(){function a(a,c){var d={type:a,target:b,loaded:c.loaded,total:c.total,error:c.error};return null!=c.result&&(d.target.result=c.result),d}var b=this,c=!1;this.listeners={},this.addEventListener=function(a,c){b.listeners[a]=b.listeners[a]||[],b.listeners[a].push(c)},this.removeEventListener=function(a,c){b.listeners[a]&&b.listeners[a].splice(b.listeners[a].indexOf(c),1)},this.dispatchEvent=function(a){var c=b.listeners[a.type];if(c)for(var d=0;d 4 | * @version 1.3.1 5 | */ 6 | (function() { 7 | 8 | var angularFileUpload = angular.module('angularFileUpload', []); 9 | 10 | angularFileUpload.service('$upload', ['$http', '$timeout', function($http, $timeout) { 11 | function sendHttp(config) { 12 | config.method = config.method || 'POST'; 13 | config.headers = config.headers || {}; 14 | config.transformRequest = config.transformRequest || function(data, headersGetter) { 15 | if (window.ArrayBuffer && data instanceof window.ArrayBuffer) { 16 | return data; 17 | } 18 | return $http.defaults.transformRequest[0](data, headersGetter); 19 | }; 20 | 21 | if (window.XMLHttpRequest.__isShim) { 22 | config.headers['__setXHR_'] = function() { 23 | return function(xhr) { 24 | config.__XHR = xhr; 25 | config.xhrFn && config.xhrFn(xhr); 26 | xhr.upload.addEventListener('progress', function(e) { 27 | if (config.progress) { 28 | $timeout(function() { 29 | if(config.progress) config.progress(e); 30 | }); 31 | } 32 | }, false); 33 | //fix for firefox not firing upload progress end, also IE8-9 34 | xhr.upload.addEventListener('load', function(e) { 35 | if (e.lengthComputable) { 36 | $timeout(function() { 37 | if(config.progress) config.progress(e); 38 | }); 39 | } 40 | }, false); 41 | } 42 | }; 43 | } 44 | 45 | var promise = $http(config); 46 | 47 | promise.progress = function(fn) { 48 | config.progress = fn; 49 | return promise; 50 | }; 51 | promise.abort = function() { 52 | if (config.__XHR) { 53 | $timeout(function() { 54 | config.__XHR.abort(); 55 | }); 56 | } 57 | return promise; 58 | }; 59 | promise.xhr = function(fn) { 60 | config.xhrFn = fn; 61 | return promise; 62 | }; 63 | promise.then = (function(promise, origThen) { 64 | return function(s, e, p) { 65 | config.progress = p || config.progress; 66 | var result = origThen.apply(promise, [s, e, p]); 67 | result.abort = promise.abort; 68 | result.progress = promise.progress; 69 | result.xhr = promise.xhr; 70 | return result; 71 | }; 72 | })(promise, promise.then); 73 | 74 | return promise; 75 | } 76 | 77 | this.upload = function(config) { 78 | config.headers = config.headers || {}; 79 | config.headers['Content-Type'] = undefined; 80 | config.transformRequest = config.transformRequest || $http.defaults.transformRequest; 81 | var formData = new FormData(); 82 | var origTransformRequest = config.transformRequest; 83 | var origData = config.data; 84 | config.transformRequest = function(formData, headerGetter) { 85 | if (origData) { 86 | if (config.formDataAppender) { 87 | for (var key in origData) { 88 | var val = origData[key]; 89 | config.formDataAppender(formData, key, val); 90 | } 91 | } else { 92 | for (var key in origData) { 93 | var val = origData[key]; 94 | if (typeof origTransformRequest == 'function') { 95 | val = origTransformRequest(val, headerGetter); 96 | } else { 97 | for (var i = 0; i < origTransformRequest.length; i++) { 98 | var transformFn = origTransformRequest[i]; 99 | if (typeof transformFn == 'function') { 100 | val = transformFn(val, headerGetter); 101 | } 102 | } 103 | } 104 | formData.append(key, val); 105 | } 106 | } 107 | } 108 | 109 | if (config.file != null) { 110 | var fileFormName = config.fileFormDataName || 'file'; 111 | 112 | if (Object.prototype.toString.call(config.file) === '[object Array]') { 113 | var isFileFormNameString = Object.prototype.toString.call(fileFormName) === '[object String]'; 114 | for (var i = 0; i < config.file.length; i++) { 115 | formData.append(isFileFormNameString ? fileFormName + i : fileFormName[i], config.file[i], config.file[i].name); 116 | } 117 | } else { 118 | formData.append(fileFormName, config.file, config.file.name); 119 | } 120 | } 121 | return formData; 122 | }; 123 | 124 | config.data = formData; 125 | 126 | return sendHttp(config); 127 | }; 128 | 129 | this.http = function(config) { 130 | return sendHttp(config); 131 | } 132 | }]); 133 | 134 | angularFileUpload.directive('ngFileSelect', [ '$parse', '$timeout', function($parse, $timeout) { 135 | return function(scope, elem, attr) { 136 | var fn = $parse(attr['ngFileSelect']); 137 | elem.bind('change', function(evt) { 138 | var files = [], fileList, i; 139 | fileList = evt.target.files; 140 | if (fileList != null) { 141 | for (i = 0; i < fileList.length; i++) { 142 | files.push(fileList.item(i)); 143 | } 144 | } 145 | $timeout(function() { 146 | fn(scope, { 147 | $files : files, 148 | $event : evt 149 | }); 150 | }); 151 | }); 152 | elem.bind('click', function(){ 153 | this.value = null; 154 | }); 155 | }; 156 | } ]); 157 | 158 | angularFileUpload.directive('ngFileDropAvailable', [ '$parse', '$timeout', function($parse, $timeout) { 159 | return function(scope, elem, attr) { 160 | if ('draggable' in document.createElement('span')) { 161 | var fn = $parse(attr['ngFileDropAvailable']); 162 | $timeout(function() { 163 | fn(scope); 164 | }); 165 | } 166 | }; 167 | } ]); 168 | 169 | angularFileUpload.directive('ngFileDrop', [ '$parse', '$timeout', function($parse, $timeout) { 170 | return function(scope, elem, attr) { 171 | if ('draggable' in document.createElement('span')) { 172 | var cancel = null; 173 | var fn = $parse(attr['ngFileDrop']); 174 | elem[0].addEventListener("dragover", function(evt) { 175 | $timeout.cancel(cancel); 176 | evt.stopPropagation(); 177 | evt.preventDefault(); 178 | elem.addClass(attr['ngFileDragOverClass'] || "dragover"); 179 | }, false); 180 | elem[0].addEventListener("dragleave", function(evt) { 181 | cancel = $timeout(function() { 182 | elem.removeClass(attr['ngFileDragOverClass'] || "dragover"); 183 | }); 184 | }, false); 185 | 186 | var processing = 0; 187 | function traverseFileTree(files, item) { 188 | if (item.isDirectory) { 189 | var dirReader = item.createReader(); 190 | processing++; 191 | dirReader.readEntries(function(entries) { 192 | for (var i = 0; i < entries.length; i++) { 193 | traverseFileTree(files, entries[i]); 194 | } 195 | processing--; 196 | }); 197 | } else { 198 | processing++; 199 | item.file(function(file) { 200 | processing--; 201 | files.push(file); 202 | }); 203 | } 204 | } 205 | 206 | elem[0].addEventListener("drop", function(evt) { 207 | evt.stopPropagation(); 208 | evt.preventDefault(); 209 | elem.removeClass(attr['ngFileDragOverClass'] || "dragover"); 210 | var files = [], items = evt.dataTransfer.items; 211 | if (items && items.length > 0 && items[0].webkitGetAsEntry) { 212 | for (var i = 0; i < items.length; i++) { 213 | traverseFileTree(files, items[i].webkitGetAsEntry()); 214 | } 215 | } else { 216 | var fileList = evt.dataTransfer.files; 217 | if (fileList != null) { 218 | for (var i = 0; i < fileList.length; i++) { 219 | files.push(fileList.item(i)); 220 | } 221 | } 222 | } 223 | (function callback(delay) { 224 | $timeout(function() { 225 | if (!processing) { 226 | fn(scope, { 227 | $files : files, 228 | $event : evt 229 | }); 230 | } else { 231 | callback(10); 232 | } 233 | }, delay || 0) 234 | })(); 235 | }, false); 236 | } 237 | }; 238 | } ]); 239 | 240 | })(); 241 | -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/ng-file-upload/angular-file-upload.min.js: -------------------------------------------------------------------------------- 1 | /*! 1.3.1 */ 2 | !function(){var a=angular.module("angularFileUpload",[]);a.service("$upload",["$http","$timeout",function(a,b){function c(c){c.method=c.method||"POST",c.headers=c.headers||{},c.transformRequest=c.transformRequest||function(b,c){return window.ArrayBuffer&&b instanceof window.ArrayBuffer?b:a.defaults.transformRequest[0](b,c)},window.XMLHttpRequest.__isShim&&(c.headers.__setXHR_=function(){return function(a){c.__XHR=a,c.xhrFn&&c.xhrFn(a),a.upload.addEventListener("progress",function(a){c.progress&&b(function(){c.progress&&c.progress(a)})},!1),a.upload.addEventListener("load",function(a){a.lengthComputable&&b(function(){c.progress&&c.progress(a)})},!1)}});var d=a(c);return d.progress=function(a){return c.progress=a,d},d.abort=function(){return c.__XHR&&b(function(){c.__XHR.abort()}),d},d.xhr=function(a){return c.xhrFn=a,d},d.then=function(a,b){return function(d,e,f){c.progress=f||c.progress;var g=b.apply(a,[d,e,f]);return g.abort=a.abort,g.progress=a.progress,g.xhr=a.xhr,g}}(d,d.then),d}this.upload=function(b){b.headers=b.headers||{},b.headers["Content-Type"]=void 0,b.transformRequest=b.transformRequest||a.defaults.transformRequest;var d=new FormData,e=b.transformRequest,f=b.data;return b.transformRequest=function(a,c){if(f)if(b.formDataAppender)for(var d in f){var g=f[d];b.formDataAppender(a,d,g)}else for(var d in f){var g=f[d];if("function"==typeof e)g=e(g,c);else for(var h=0;h0&&j[0].webkitGetAsEntry)for(var k=0;k" 8 | ], 9 | "description": "Lightweight Angular JS directive to upload files. Support drag&drop, progress and abort", 10 | "license": "MIT" 11 | } 12 | -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/requirejs-domready/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "requirejs-domready", 3 | "homepage": "https://github.com/requirejs/domReady", 4 | "version": "2.0.1", 5 | "_release": "2.0.1", 6 | "_resolution": { 7 | "type": "version", 8 | "tag": "2.0.1", 9 | "commit": "850d9c92541afac5d9c64506736272cdbf7a3ae5" 10 | }, 11 | "_source": "git://github.com/requirejs/domReady.git", 12 | "_target": "~2.0.1", 13 | "_originalSource": "requirejs-domready", 14 | "_direct": true 15 | } -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/requirejs-domready/LICENSE: -------------------------------------------------------------------------------- 1 | RequireJS is released under two licenses: new BSD, and MIT. You may pick the 2 | license that best suits your development needs. The text of both licenses are 3 | provided below. 4 | 5 | 6 | The "New" BSD License: 7 | ---------------------- 8 | 9 | Copyright (c) 2010-2011, The Dojo Foundation 10 | All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without 13 | modification, are permitted provided that the following conditions are met: 14 | 15 | * Redistributions of source code must retain the above copyright notice, this 16 | list of conditions and the following disclaimer. 17 | * Redistributions in binary form must reproduce the above copyright notice, 18 | this list of conditions and the following disclaimer in the documentation 19 | and/or other materials provided with the distribution. 20 | * Neither the name of the Dojo Foundation nor the names of its contributors 21 | may be used to endorse or promote products derived from this software 22 | without specific prior written permission. 23 | 24 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 25 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 26 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 27 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 28 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 30 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 31 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 32 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 33 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | 35 | 36 | 37 | MIT License 38 | ----------- 39 | 40 | Copyright (c) 2010-2011, The Dojo Foundation 41 | 42 | Permission is hereby granted, free of charge, to any person obtaining a copy 43 | of this software and associated documentation files (the "Software"), to deal 44 | in the Software without restriction, including without limitation the rights 45 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 46 | copies of the Software, and to permit persons to whom the Software is 47 | furnished to do so, subject to the following conditions: 48 | 49 | The above copyright notice and this permission notice shall be included in 50 | all copies or substantial portions of the Software. 51 | 52 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 53 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 54 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 55 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 56 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 57 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 58 | THE SOFTWARE. 59 | -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/requirejs-domready/README.md: -------------------------------------------------------------------------------- 1 | # text 2 | 3 | An AMD loader plugin for detecting DOM ready. 4 | 5 | Known to work in RequireJS, but should work in other 6 | AMD loaders that support the same loader plugin API. 7 | 8 | ## Docs 9 | 10 | See the [RequireJS API text section](http://requirejs.org/docs/api.html#pageload). 11 | 12 | ## Latest release 13 | 14 | The latest release will be available from the "latest" tag. 15 | 16 | ## License 17 | 18 | Dual-licensed -- new BSD or MIT. 19 | 20 | ## Where are the tests? 21 | 22 | They are in the [requirejs](https://github.com/jrburke/requirejs) and 23 | [r.js](https://github.com/jrburke/r.js) repos. 24 | 25 | ## History 26 | 27 | This plugin was in the [requirejs repo](https://github.com/jrburke/requirejs) 28 | up until the requirejs 2.0 release. 29 | -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/requirejs-domready/domReady.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license RequireJS domReady 2.0.1 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved. 3 | * Available via the MIT or new BSD license. 4 | * see: http://github.com/requirejs/domReady for details 5 | */ 6 | /*jslint */ 7 | /*global require: false, define: false, requirejs: false, 8 | window: false, clearInterval: false, document: false, 9 | self: false, setInterval: false */ 10 | 11 | 12 | define(function () { 13 | 'use strict'; 14 | 15 | var isTop, testDiv, scrollIntervalId, 16 | isBrowser = typeof window !== "undefined" && window.document, 17 | isPageLoaded = !isBrowser, 18 | doc = isBrowser ? document : null, 19 | readyCalls = []; 20 | 21 | function runCallbacks(callbacks) { 22 | var i; 23 | for (i = 0; i < callbacks.length; i += 1) { 24 | callbacks[i](doc); 25 | } 26 | } 27 | 28 | function callReady() { 29 | var callbacks = readyCalls; 30 | 31 | if (isPageLoaded) { 32 | //Call the DOM ready callbacks 33 | if (callbacks.length) { 34 | readyCalls = []; 35 | runCallbacks(callbacks); 36 | } 37 | } 38 | } 39 | 40 | /** 41 | * Sets the page as loaded. 42 | */ 43 | function pageLoaded() { 44 | if (!isPageLoaded) { 45 | isPageLoaded = true; 46 | if (scrollIntervalId) { 47 | clearInterval(scrollIntervalId); 48 | } 49 | 50 | callReady(); 51 | } 52 | } 53 | 54 | if (isBrowser) { 55 | if (document.addEventListener) { 56 | //Standards. Hooray! Assumption here that if standards based, 57 | //it knows about DOMContentLoaded. 58 | document.addEventListener("DOMContentLoaded", pageLoaded, false); 59 | window.addEventListener("load", pageLoaded, false); 60 | } else if (window.attachEvent) { 61 | window.attachEvent("onload", pageLoaded); 62 | 63 | testDiv = document.createElement('div'); 64 | try { 65 | isTop = window.frameElement === null; 66 | } catch (e) {} 67 | 68 | //DOMContentLoaded approximation that uses a doScroll, as found by 69 | //Diego Perini: http://javascript.nwbox.com/IEContentLoaded/, 70 | //but modified by other contributors, including jdalton 71 | if (testDiv.doScroll && isTop && window.external) { 72 | scrollIntervalId = setInterval(function () { 73 | try { 74 | testDiv.doScroll(); 75 | pageLoaded(); 76 | } catch (e) {} 77 | }, 30); 78 | } 79 | } 80 | 81 | //Check if document already complete, and if so, just trigger page load 82 | //listeners. Latest webkit browsers also use "interactive", and 83 | //will fire the onDOMContentLoaded before "interactive" but not after 84 | //entering "interactive" or "complete". More details: 85 | //http://dev.w3.org/html5/spec/the-end.html#the-end 86 | //http://stackoverflow.com/questions/3665561/document-readystate-of-interactive-vs-ondomcontentloaded 87 | //Hmm, this is more complicated on further use, see "firing too early" 88 | //bug: https://github.com/requirejs/domReady/issues/1 89 | //so removing the || document.readyState === "interactive" test. 90 | //There is still a window.onload binding that should get fired if 91 | //DOMContentLoaded is missed. 92 | if (document.readyState === "complete") { 93 | pageLoaded(); 94 | } 95 | } 96 | 97 | /** START OF PUBLIC API **/ 98 | 99 | /** 100 | * Registers a callback for DOM ready. If DOM is already ready, the 101 | * callback is called immediately. 102 | * @param {Function} callback 103 | */ 104 | function domReady(callback) { 105 | if (isPageLoaded) { 106 | callback(doc); 107 | } else { 108 | readyCalls.push(callback); 109 | } 110 | return domReady; 111 | } 112 | 113 | domReady.version = '2.0.1'; 114 | 115 | /** 116 | * Loader Plugin API method 117 | */ 118 | domReady.load = function (name, req, onLoad, config) { 119 | if (config.isBuild) { 120 | onLoad(null); 121 | } else { 122 | domReady(onLoad); 123 | } 124 | }; 125 | 126 | /** END OF PUBLIC API **/ 127 | 128 | return domReady; 129 | }); 130 | -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/requirejs-domready/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "volo": { 3 | "url": "https://raw.github.com/requirejs/domReady/{version}/domReady.js" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/requirejs/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "requirejs", 3 | "version": "2.1.11", 4 | "homepage": "http://requirejs.org", 5 | "authors": [ 6 | "jrburke.com" 7 | ], 8 | "description": "A file and module loader for JavaScript", 9 | "main": "require.js", 10 | "keywords": [ 11 | "AMD" 12 | ], 13 | "license": "new BSD, and MIT", 14 | "_release": "2.1.11", 15 | "_resolution": { 16 | "type": "version", 17 | "tag": "2.1.11", 18 | "commit": "fc97e49f1ec9fb2f204bef2b60ed21a32d6a2e05" 19 | }, 20 | "_source": "git://github.com/jrburke/requirejs-bower.git", 21 | "_target": "~2.1.11", 22 | "_originalSource": "requirejs" 23 | } -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/requirejs/README.md: -------------------------------------------------------------------------------- 1 | # requirejs-bower 2 | 3 | Bower packaging for [RequireJS](http://requirejs.org). 4 | 5 | -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/requirejs/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "requirejs", 3 | "version": "2.1.11", 4 | "homepage": "http://requirejs.org", 5 | "authors": [ 6 | "jrburke.com" 7 | ], 8 | "description": "A file and module loader for JavaScript", 9 | "main": "require.js", 10 | "keywords": [ 11 | "AMD" 12 | ], 13 | "license": "new BSD, and MIT" 14 | } 15 | -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/sockjs/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sockjs", 3 | "version": "0.3.4", 4 | "main": "sockjs.js", 5 | "ignore": [ 6 | "**/.*", 7 | "node_modules", 8 | "components" 9 | ], 10 | "homepage": "https://github.com/myguidingstar/bower-sockjs", 11 | "_release": "0.3.4", 12 | "_resolution": { 13 | "type": "version", 14 | "tag": "0.3.4", 15 | "commit": "ae96e770ab85caf9073a8806a9dcd7c0ce316623" 16 | }, 17 | "_source": "git://github.com/myguidingstar/bower-sockjs.git", 18 | "_target": "~0.3", 19 | "_originalSource": "sockjs" 20 | } -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/sockjs/component.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sockjs", 3 | "version": "0.3.4", 4 | "main": "sockjs.js", 5 | "ignore": [ 6 | "**/.*", 7 | "node_modules", 8 | "components" 9 | ] 10 | } -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/stomp-websocket/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "stomp-websocket", 3 | "homepage": "https://github.com/jmesnil/stomp-websocket", 4 | "version": "2.2.0", 5 | "_release": "2.2.0", 6 | "_resolution": { 7 | "type": "version", 8 | "tag": "v2.2.0", 9 | "commit": "d099bd69fd6cf1f96227c30ed7d8f474a173332d" 10 | }, 11 | "_source": "git://github.com/jmesnil/stomp-websocket.git", 12 | "_target": "~2.2", 13 | "_originalSource": "stomp-websocket" 14 | } -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/stomp-websocket/.gitignore: -------------------------------------------------------------------------------- 1 | pkg 2 | .settings 3 | bin 4 | data 5 | dist/test 6 | TODO.txt 7 | node_modules 8 | doc/public 9 | -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/stomp-websocket/.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 0.6.19 4 | 5 | before_script: 6 | - ./node_modules/.bin/cake build 7 | 8 | script: 9 | - npm test 10 | -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/stomp-websocket/Cakefile: -------------------------------------------------------------------------------- 1 | fs = require 'fs' 2 | {exec} = require 'child_process' 3 | util = require 'util' 4 | 5 | binDir = "./node_modules/.bin/" 6 | 7 | task 'watch', 'Watch for changes in coffee files to build and test', -> 8 | util.log "Watching for changes in src and test" 9 | lastTest = 0 10 | watchDir 'src', -> 11 | invoke 'build:src' 12 | invoke 'build:min' 13 | invoke 'build:doc' 14 | invoke 'build:test' 15 | watchDir 'test', -> 16 | invoke 'build:test' 17 | watchDir 'dist/test', (file)-> 18 | # We only want to run tests once (a second), 19 | # even if a bunch of test files change 20 | time = new Date().getTime() 21 | if (time-lastTest) > 1000 22 | lastTest = time 23 | invoke 'test' 24 | 25 | task 'test', 'Run the tests', -> 26 | util.log "Running tests..." 27 | exec binDir + "jasmine-node --nocolor dist/test", (err, stdout, stderr) -> 28 | if err 29 | handleError(parseTestResults(stdout), stderr) 30 | else 31 | displayNotification "Tests pass!" 32 | util.log lastLine(stdout) 33 | 34 | task 'build', 'Build source and tests', -> 35 | invoke 'build:src' 36 | invoke 'build:min' 37 | invoke 'build:test' 38 | 39 | task 'build:src', 'Build the src files into lib', -> 40 | util.log "Compiling src..." 41 | exec binDir + "coffee -o lib/ -c src/", (err, stdout, stderr) -> 42 | handleError(err) if err 43 | 44 | task 'build:min', 'Build the minified files into lib', -> 45 | util.log "Minify src..." 46 | exec binDir + "uglifyjs -m --comments all -o lib/stomp.min.js lib/stomp.js", (err, stdout, stderr) -> 47 | handleError(err) if err 48 | 49 | task 'build:doc', 'Build docco documentation', -> 50 | util.log "Building doc..." 51 | exec binDir + "docco -o doc/ src/*.coffee", (err, stdout, stderr) -> 52 | handleError(err) if err 53 | 54 | task 'build:test', 'Build the test files into lib/test', -> 55 | util.log "Compiling test..." 56 | exec binDir + "coffee -o dist/test/ -c test/", (err, stdout, stderr) -> 57 | handleError(err) if err 58 | 59 | watchDir = (dir, callback) -> 60 | fs.readdir dir, (err, files) -> 61 | handleError(err) if err 62 | for file in files then do (file) -> 63 | fs.watchFile "#{dir}/#{file}", (curr, prev) -> 64 | if +curr.mtime isnt +prev.mtime 65 | callback "#{dir}/#{file}" 66 | 67 | parseTestResults = (data) -> 68 | lines = (line for line in data.split('\n') when line.length > 5) 69 | results = lines.pop() 70 | details = lines[1...lines.length-2].join('\n') 71 | results + '\n\n' + details + '\n' 72 | 73 | lastLine = (data) -> 74 | (line for line in data.split('\n') when line.length > 5).pop() 75 | 76 | handleError = (error, stderr) -> 77 | if stderr? and !error 78 | util.log stderr 79 | displayNotification stderr.match(/\n(Error:[^\n]+)/)?[1] 80 | else 81 | util.log error 82 | displayNotification error 83 | 84 | displayNotification = (message = '') -> 85 | options = { title: 'CoffeeScript' } 86 | try require('growl').notify message, options 87 | -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/stomp-websocket/LICENSE.txt: -------------------------------------------------------------------------------- 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 [yyyy] [name of copyright owner] 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. -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/stomp-websocket/README.md: -------------------------------------------------------------------------------- 1 | # STOMP.js 2 | 3 | This library provides a STOMP client for Web browser (using Web Sockets) or node.js applications (either using raw TCP sockets or Web Sockets). 4 | 5 | ## Web Browser support 6 | 7 | The library file is located in `lib/stomp.js` (a minified version is available in `lib/stomp.min.js`). 8 | It does not require any dependency (except WebSocket support from the browser or an alternative to WebSocket!) 9 | 10 | Online [documentation][doc] describes the library API (including the [annotated source code][annotated]). 11 | 12 | ## node.js support 13 | 14 | Install the 'stompjs' module 15 | 16 | $ npm install stompjs 17 | 18 | In the node.js app, require the module with: 19 | 20 | var Stomp = require('stompjs'); 21 | 22 | To connect to a STOMP broker over a TCP socket, use the `Stomp.overTCP(host, port)` method: 23 | 24 | var client = Stomp.overTCP('localhost', 61613); 25 | 26 | To connect to a STOMP broker over a WebSocket, use instead the `Stomp.overWS(url)` method: 27 | 28 | var client = Stomp.overWS('ws://localhost:61614'); 29 | 30 | ## Development Requirements 31 | 32 | For development (testing, building) the project requires node.js. This allows us to run tests without the browser continuously during development (see `cake watch`). 33 | 34 | $ npm install 35 | 36 | ## Building and Testing 37 | 38 | [![Build Status](https://secure.travis-ci.org/jmesnil/stomp-websocket.png)](http://travis-ci.org/jmesnil/stomp-websocket) 39 | 40 | To build JavaScript from the CoffeeScript source code: 41 | 42 | $ cake build 43 | 44 | To run tests: 45 | 46 | $ cake test 47 | 48 | To continuously run tests on file changes: 49 | 50 | $ cake watch 51 | 52 | 53 | ## Browser Tests 54 | 55 | * Make sure you have a running STOMP broker which supports the WebSocket protocol 56 | (see the [documentation][doc]) 57 | * Open in your web browser the project's [test page](browsertests/index.html) 58 | * Check all tests pass 59 | 60 | ## Use 61 | 62 | The project contains examples for using stomp.js 63 | to send and receive STOMP messages from a server directly in the Web Browser or in a WebWorker. 64 | 65 | ## Authors 66 | 67 | * [Jeff Mesnil](http://jmesnil.net/) 68 | * [Jeff Lindsay](http://github.com/progrium) 69 | 70 | [doc]: http://jmesnil.net/stomp-websocket/doc/ 71 | [annotated]: http://jmesnil.net/stomp-websocket/doc/stomp.html 72 | -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/stomp-websocket/RELEASE_NOTES.md: -------------------------------------------------------------------------------- 1 | # Release Notes 2 | 3 | ## 2.0 (2012/11/29) 4 | 5 | ### STOMP 1.1 support 6 | 7 | * heart-beat 8 | * nack 9 | * content-length 10 | 11 | ### API change 12 | 13 | * the `errorCallback` passed to the `connect()` method is no longer called when the 14 | client is properly disconnected by calling `disconnect()`. 15 | 16 | * ack() method takes 3 parameters: 17 | * `messageID` & `subscription` are MANDATORY. 18 | * `headers` is OPTIONAL 19 | 20 | * the `client` object has a `heartbeat` field which can be used to configure heart-beating by changing its `incoming` and `outgoing` integer fields (default value for both is 10000ms): 21 | 22 | client.heartbeat.outgoing = 20000 // client will send heartbeats every 20000ms 23 | client.heartbeat.incoming = 0 // client does not want to receive heartbeats 24 | // from the server 25 | 26 | ### Minified version 27 | 28 | In addition to the regular `stomp.js` file, the library is also available in a minified version `stomp.min.js` 29 | 30 | ### Annotated source 31 | 32 | The source is now [documented](http://jmesnil.net/stomp-websocket/stomp.html) :) 33 | -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/stomp-websocket/browsertests/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Stomp Over Web Socket 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 |

Stomp Over Web Socket

35 |
36 |

Tests requires that a Stomp Server accepting WebSocket protocol is running with the configuration:

37 |
    38 |
  • URL: 39 |
  • Destination: 40 |
  • User: / 41 |
42 |

These values can be configured in unit/config.js 43 |

44 | 45 |

46 |

47 |
    48 | 49 |
    
    50 |   
    51 | 52 | 53 | -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/stomp-websocket/browsertests/integration/integration.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |

    To run the integration tests, you need a Stomp server listening to 11 | with a queue . 12 |

    13 |
    
    14 |   
    15 | 
    16 | 
    17 | 
    
    
    --------------------------------------------------------------------------------
    /spring-doge-web/src/main/resources/public/lib/stomp-websocket/browsertests/integration/integration.js:
    --------------------------------------------------------------------------------
     1 | $(document).ready(function(){
     2 | 
     3 |   var url = "ws://localhost:61623";
     4 |   var login = "admin";
     5 |   var passcode = "password"
     6 |   var destination = "/topic/chat.general";
     7 |   
     8 |   $("#server_url").text(url);
     9 |   $("#queue_name").text(destination);
    10 |   
    11 |   var client = Stomp.client(url);
    12 | 
    13 |   debug = function(str) {
    14 |     $("#debug").append(str + "\n");
    15 |   };
    16 |   client.debug = debug;
    17 |   // the client is notified when it is connected to the server.
    18 |   var onconnect = function(frame) {
    19 |       debug("connected to Stomp");
    20 |       client.subscribe(destination,
    21 |         function(frame) {
    22 |           client.unsubscribe(destination);
    23 |           client.disconnect();
    24 |         },
    25 |         { receipt: 1234 });
    26 |   };
    27 |   client.onerror = function(frame) {
    28 |       debug("connected to Stomp");
    29 |   };
    30 |   client.ondisconnect = function() {
    31 |     debug("disconnected from Stomp");
    32 |   };
    33 |   client.onreceipt = function() {
    34 |     debug("receipt from Stomp");
    35 |     client.send(destination, {foo: 1}, "test")
    36 |   };
    37 | 
    38 |   client.connect(login, passcode, onconnect);
    39 | 
    40 |   return false;
    41 | });
    42 | 
    
    
    --------------------------------------------------------------------------------
    /spring-doge-web/src/main/resources/public/lib/stomp-websocket/browsertests/qunit.css:
    --------------------------------------------------------------------------------
      1 | 
      2 | ol#qunit-tests {
      3 | 	font-family:"Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial;
      4 | 	margin:0;
      5 | 	padding:0;
      6 | 	list-style-position:inside;
      7 | 
      8 | 	font-size: smaller;
      9 | }
     10 | ol#qunit-tests li{
     11 | 	padding:0.4em 0.5em 0.4em 2.5em;
     12 | 	border-bottom:1px solid #fff;
     13 | 	font-size:small;
     14 | 	list-style-position:inside;
     15 | }
     16 | ol#qunit-tests li ol{
     17 | 	box-shadow: inset 0px 2px 13px #999;
     18 | 	-moz-box-shadow: inset 0px 2px 13px #999;
     19 | 	-webkit-box-shadow: inset 0px 2px 13px #999;
     20 | 	margin-top:0.5em;
     21 | 	margin-left:0;
     22 | 	padding:0.5em;
     23 | 	background-color:#fff;
     24 | 	border-radius:15px;
     25 | 	-moz-border-radius: 15px;
     26 | 	-webkit-border-radius: 15px;
     27 | }
     28 | ol#qunit-tests li li{
     29 | 	border-bottom:none;
     30 | 	margin:0.5em;
     31 | 	background-color:#fff;
     32 | 	list-style-position: inside;
     33 | 	padding:0.4em 0.5em 0.4em 0.5em;
     34 | }
     35 | 
     36 | ol#qunit-tests li li.pass{
     37 | 	border-left:26px solid #C6E746;
     38 | 	background-color:#fff;
     39 | 	color:#5E740B;
     40 | 	}
     41 | ol#qunit-tests li li.fail{
     42 | 	border-left:26px solid #EE5757;
     43 | 	background-color:#fff;
     44 | 	color:#710909;
     45 | }
     46 | ol#qunit-tests li.pass{
     47 | 	background-color:#D2E0E6;
     48 | 	color:#528CE0;
     49 | }
     50 | ol#qunit-tests li.fail{
     51 | 	background-color:#EE5757;
     52 | 	color:#000;
     53 | }
     54 | ol#qunit-tests li strong {
     55 | 	cursor:pointer;
     56 | }
     57 | h1#qunit-header{
     58 | 	background-color:#0d3349;
     59 | 	margin:0;
     60 | 	padding:0.5em 0 0.5em 1em;
     61 | 	color:#fff;
     62 | 	font-family:"Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial;
     63 | 	border-top-right-radius:15px;
     64 | 	border-top-left-radius:15px;
     65 | 	-moz-border-radius-topright:15px;
     66 | 	-moz-border-radius-topleft:15px;
     67 | 	-webkit-border-top-right-radius:15px;
     68 | 	-webkit-border-top-left-radius:15px;
     69 | 	text-shadow: rgba(0, 0, 0, 0.5) 4px 4px 1px;
     70 | }
     71 | h2#qunit-banner{
     72 | 	font-family:"Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial;
     73 | 	height:5px;
     74 | 	margin:0;
     75 | 	padding:0;
     76 | }
     77 | h2#qunit-banner.qunit-pass{
     78 | 	background-color:#C6E746;
     79 | }
     80 | h2#qunit-banner.qunit-fail, #qunit-testrunner-toolbar {
     81 | 	background-color:#EE5757;
     82 | }
     83 | #qunit-testrunner-toolbar {
     84 | 	font-family:"Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial;
     85 | 	padding:0;
     86 | 	/*width:80%;*/
     87 | 	padding:0em 0 0.5em 2em;
     88 | 	font-size: small;
     89 | }
     90 | h2#qunit-userAgent {
     91 | 	font-family:"Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial;
     92 | 	background-color:#2b81af;
     93 | 	margin:0;
     94 | 	padding:0;
     95 | 	color:#fff;
     96 | 	font-size: small;
     97 | 	padding:0.5em 0 0.5em 2.5em;
     98 | 	text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
     99 | }
    100 | p#qunit-testresult{
    101 | 	font-family:"Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial;
    102 | 	margin:0;
    103 | 	font-size: small;
    104 | 	color:#2b81af;
    105 | 	border-bottom-right-radius:15px;
    106 | 	border-bottom-left-radius:15px;
    107 | 	-moz-border-radius-bottomright:15px;
    108 | 	-moz-border-radius-bottomleft:15px;
    109 | 	-webkit-border-bottom-right-radius:15px;
    110 | 	-webkit-border-bottom-left-radius:15px;
    111 | 	background-color:#D2E0E6;
    112 | 	padding:0.5em 0.5em 0.5em 2.5em;
    113 | }
    114 | strong b.fail{
    115 | 	color:#710909;
    116 | 	}
    117 | strong b.pass{
    118 | 	color:#5E740B;
    119 | 	}
    120 | 
    
    
    --------------------------------------------------------------------------------
    /spring-doge-web/src/main/resources/public/lib/stomp-websocket/browsertests/test.css:
    --------------------------------------------------------------------------------
    1 | #debug {
    2 |   background-color: #F0F0F0;
    3 |   font-size: 12px;
    4 |   height: 75%;
    5 |   overflow: auto;
    6 |   padding: 10px;
    7 |   z-index: 100;
    8 | }
    
    
    --------------------------------------------------------------------------------
    /spring-doge-web/src/main/resources/public/lib/stomp-websocket/browsertests/unit/ack.js:
    --------------------------------------------------------------------------------
     1 | module("Stomp Acknowledgement");
     2 | 
     3 | test("Subscribe using client ack mode, send a message and ack it", function() {
     4 |   
     5 |   var body = Math.random();
     6 |   
     7 |   var client = Stomp.client(TEST.url);
     8 |   
     9 |   client.debug = TEST.debug;
    10 |   client.connect(TEST.login, TEST.password, function() {
    11 |     var onmessage = function(message) {
    12 |       start();        
    13 |       // we should receive the 2nd message outside the transaction
    14 |       equals(message.body, body);
    15 |       var receipt = Math.random();
    16 |       client.onreceipt = function(frame) {
    17 |         equals(receipt, frame.headers['receipt-id'])
    18 |         client.disconnect();
    19 |       }
    20 |       message.ack({'receipt': receipt});
    21 |     }
    22 |     var sub = client.subscribe(TEST.destination, onmessage, {'ack': 'client'});      
    23 |     client.send(TEST.destination, {}, body);
    24 |   });
    25 |   stop(TEST.timeout);
    26 | });
    27 | 
    28 | test("Subscribe using client ack mode, send a message and nack it", function() {
    29 |   
    30 |   var body = Math.random();
    31 |   
    32 |   var client = Stomp.client(TEST.url);
    33 |   
    34 |   client.debug = TEST.debug;
    35 |   client.connect(TEST.login, TEST.password, function() {
    36 |     var onmessage = function(message) {
    37 |       start();        
    38 |       equals(message.body, body);
    39 |       var receipt = Math.random();
    40 |       client.onreceipt = function(frame) {
    41 |         equals(receipt, frame.headers['receipt-id'])
    42 |         client.disconnect();
    43 |       }
    44 |       message.nack({'receipt': receipt});
    45 |     }
    46 |     var sub = client.subscribe(TEST.destination, onmessage, {'ack': 'client'});      
    47 |     client.send(TEST.destination, {}, body);
    48 |   });
    49 |   stop(TEST.timeout);
    50 | });
    51 | 
    
    
    --------------------------------------------------------------------------------
    /spring-doge-web/src/main/resources/public/lib/stomp-websocket/browsertests/unit/config.js:
    --------------------------------------------------------------------------------
     1 | $(document).ready(function(){
     2 |   
     3 |   TEST = {
     4 |     destination : "/topic/chat.general",
     5 |     login : "admin",
     6 |     password : "password",
     7 |     url : "ws://localhost:61623",
     8 |     badUrl: "ws://localhost:61625",
     9 |     timeout: 2000,
    10 |     debug : function(str) {
    11 |       $("#debug").append(str + "\n");
    12 |     }
    13 |     
    14 |   };
    15 | 
    16 |   // fill server requirements:
    17 |   $("#test_url").text(TEST.url);
    18 |   $("#test_destination").text(TEST.destination);
    19 |   $("#test_login").text(TEST.login);
    20 |   $("#test_password").text(TEST.password);
    21 |   
    22 | });
    23 | 
    
    
    --------------------------------------------------------------------------------
    /spring-doge-web/src/main/resources/public/lib/stomp-websocket/browsertests/unit/connection.js:
    --------------------------------------------------------------------------------
     1 | module("Stomp Connection");
     2 | 
     3 | test("Connect to an invalid Stomp server", function() {
     4 |   
     5 |   var client = Stomp.client(TEST.badUrl);
     6 |   client.connect("foo", "bar", 
     7 |     function() {},
     8 |     function() {
     9 |       start();
    10 |     });
    11 |   stop(TEST.timeout);
    12 | });
    13 | 
    14 | test("Connect to a valid Stomp server", function() {
    15 |   
    16 |   var client = Stomp.client(TEST.url);
    17 |   client.connect(TEST.login, TEST.password, 
    18 |     function() {
    19 |       start();
    20 |     });
    21 |   stop(TEST.timeout);
    22 | });
    23 | 
    24 | test("Disconnect", function() {
    25 |   
    26 |   var client = Stomp.client(TEST.url);
    27 |   client.connect(TEST.login, TEST.password, 
    28 |     function() {
    29 |       // once connected, we disconnect
    30 |       client.disconnect(function() {
    31 |         start();
    32 |       });
    33 |     });
    34 |   stop(TEST.timeout);
    35 | });
    
    
    --------------------------------------------------------------------------------
    /spring-doge-web/src/main/resources/public/lib/stomp-websocket/browsertests/unit/frame.js:
    --------------------------------------------------------------------------------
     1 | module("Stomp Frame");
     2 | 
     3 | test("marshall a CONNECT frame", function() {
     4 |   var out = Stomp.Frame.marshall("CONNECT", {login: 'jmesnil', passcode: 'wombats'});
     5 |   equals(out, "CONNECT\nlogin:jmesnil\npasscode:wombats\n\n\0");
     6 | });
     7 | 
     8 | test("marshall a SEND frame", function() {
     9 |   var out = Stomp.Frame.marshall("SEND", {destination: '/queue/test'}, "hello, world!");
    10 |   equals(out, "SEND\ndestination:/queue/test\ncontent-length:13\n\nhello, world!\0");
    11 | });
    12 | 
    13 | test("unmarshall a CONNECTED frame", function() {
    14 |   var data = "CONNECTED\nsession-id: 1234\n\n\0";
    15 |   var frame = Stomp.Frame.unmarshall(data)[0];
    16 |   equals(frame.command, "CONNECTED");
    17 |   same(frame.headers, {'session-id': "1234"});
    18 |   equals(frame.body, '');
    19 | });
    20 | 
    21 | test("unmarshall a RECEIVE frame", function() {
    22 |   var data = "RECEIVE\nfoo: abc\nbar: 1234\n\nhello, world!\0";
    23 |   var frame = Stomp.Frame.unmarshall(data)[0];
    24 |   equals(frame.command, "RECEIVE");
    25 |   same(frame.headers, {foo: 'abc', bar: "1234"});
    26 |   equals(frame.body, "hello, world!");
    27 | });
    28 | 
    29 | test("unmarshall should not include the null byte in the body", function() {
    30 |   var body1 = 'Just the text please.',
    31 |       body2 = 'And the newline\n',
    32 |       msg = "MESSAGE\ndestination: /queue/test\nmessage-id: 123\n\n";
    33 | 
    34 |   equals(Stomp.Frame.unmarshall(msg + body1 + '\0')[0].body, body1);
    35 |   equals(Stomp.Frame.unmarshall(msg + body2 + '\0')[0].body, body2);
    36 | });
    37 | 
    38 | test("unmarshall should support colons (:) in header values", function() {
    39 |   var dest = 'foo:bar:baz',
    40 |       msg = "MESSAGE\ndestination: " + dest + "\nmessage-id: 456\n\n\0";
    41 | 
    42 |   equals(Stomp.Frame.unmarshall(msg)[0].headers.destination, dest);
    43 | });
    44 | 
    45 | test("only the 1st value of repeated headers is used", function() {
    46 |   var msg = "MESSAGE\ndestination: /queue/test\nfoo:World\nfoo:Hello\n\n\0";
    47 | 
    48 |   equals(Stomp.Frame.unmarshall(msg)[0].headers['foo'], 'World');
    49 | });
    
    
    --------------------------------------------------------------------------------
    /spring-doge-web/src/main/resources/public/lib/stomp-websocket/browsertests/unit/message.js:
    --------------------------------------------------------------------------------
     1 | module("Stomp Message");
     2 | 
     3 | test("Send and receive a message", function() {
     4 |   var body = Math.random();
     5 |   
     6 |   var client = Stomp.client(TEST.url);
     7 |   client.debug = TEST.debug;
     8 |   client.connect(TEST.login, TEST.password,
     9 |     function() {
    10 |       client.subscribe(TEST.destination, function(message)
    11 |       {
    12 |         start();
    13 |         equals(message.body, body);
    14 |         client.disconnect();
    15 |       });
    16 |       
    17 |       client.send(TEST.destination, {}, body);
    18 |     });
    19 |     stop(TEST.timeout);
    20 | });
    21 | 
    22 | test("Send and receive a message with a JSON body", function() {
    23 |   
    24 |   var client = Stomp.client(TEST.url);
    25 |   var payload = {text: "hello", bool: true, value: Math.random()};
    26 |   
    27 |   client.connect(TEST.login, TEST.password,
    28 |     function() {
    29 |       client.subscribe(TEST.destination, function(message)
    30 |       {
    31 |         start();
    32 |         var res = JSON.parse(message.body);
    33 |         equals(res.text, payload.text);
    34 |         equals(res.bool, payload.bool);
    35 |         equals(res.value, payload.value);
    36 |         client.disconnect();
    37 |       });
    38 |       
    39 |       client.send(TEST.destination, {}, JSON.stringify(payload));
    40 |     });
    41 |     stop(TEST.timeout);
    42 | });
    
    
    --------------------------------------------------------------------------------
    /spring-doge-web/src/main/resources/public/lib/stomp-websocket/browsertests/unit/parse_connect.js:
    --------------------------------------------------------------------------------
     1 | (function() {
     2 |   module("Parse connect method arguments", {
     3 | 
     4 |     setup: function() {
     5 |       // prepare something for all following tests
     6 |       myConnectCallback = function() {
     7 |         // called back when the client is connected to STOMP broker
     8 |       };
     9 | 
    10 |       myErrorCallback = function() {
    11 |         // called back if the client can not connect to STOMP broker
    12 |       };
    13 | 
    14 |       client = Stomp.client(TEST.url);
    15 |       
    16 |       checkArgs = function(args, expectedHeaders, expectedConnectCallback, expectedErrorCallback) {
    17 |         var headers = args[0];
    18 |         var connectCallback = args[1];
    19 |         var errorCallback = args[2];
    20 | 
    21 |         deepEqual(headers, expectedHeaders);
    22 |         strictEqual(connectCallback, expectedConnectCallback);
    23 |         strictEqual(errorCallback, expectedErrorCallback);        
    24 |       }
    25 |     }
    26 |   });
    27 | 
    28 |   test("connect(login, passcode, connectCallback)", function() {
    29 |     checkArgs(
    30 |       client._parseConnect("jmesnil", "wombats", myConnectCallback),
    31 |       
    32 |       {login: 'jmesnil', passcode: 'wombats'},
    33 |       myConnectCallback,
    34 |       undefined);
    35 |   });
    36 | 
    37 |   test("connect(login, passcode, connectCallback, errorCallback)", function() {
    38 |     checkArgs(
    39 |       client._parseConnect("jmesnil", "wombats", myConnectCallback, myErrorCallback),
    40 |       
    41 |       {login: 'jmesnil', passcode: 'wombats'},
    42 |       myConnectCallback,
    43 |       myErrorCallback);
    44 |   });
    45 | 
    46 |   test("connect(login, passcode, connectCallback, errorCallback, vhost)", function() {
    47 |     checkArgs(
    48 |       client._parseConnect("jmesnil", "wombats", myConnectCallback, myErrorCallback, "myvhost"),
    49 |       
    50 |       {login: 'jmesnil', passcode: 'wombats', host: 'myvhost'},
    51 |       myConnectCallback,
    52 |       myErrorCallback);
    53 |   });
    54 | 
    55 |   test("connect(headers, connectCallback)", function() {
    56 |     var headers = {login: 'jmesnil', passcode: 'wombats', host: 'myvhost'};
    57 | 
    58 |     checkArgs(
    59 |       client._parseConnect(headers, myConnectCallback),
    60 |       
    61 |       headers,
    62 |       myConnectCallback,
    63 |       undefined);
    64 |   });
    65 | 
    66 |   test("connect(headers, connectCallback, errorCallback)", function() {
    67 |     var headers = {login: 'jmesnil', passcode: 'wombats', host: 'myvhost'};
    68 | 
    69 |     checkArgs(
    70 |       client._parseConnect(headers, myConnectCallback, myErrorCallback),
    71 |       
    72 |       headers,
    73 |       myConnectCallback,
    74 |       myErrorCallback);
    75 |   });
    76 | })();
    77 | 
    
    
    --------------------------------------------------------------------------------
    /spring-doge-web/src/main/resources/public/lib/stomp-websocket/browsertests/unit/subscription.js:
    --------------------------------------------------------------------------------
     1 | var client = null;
     2 | 
     3 | module("Stomp Subscription", {
     4 |   setup: function() {
     5 |     client = Stomp.client(TEST.url);
     6 |     client.debug = TEST.debug;
     7 |   },
     8 | 
     9 |   teardown: function() {
    10 |     client.disconnect();
    11 |   }
    12 | });
    13 | 
    14 | test("Should receive messages sent to destination after subscribing", 1, function() {
    15 |   var msg = 'Is anybody out there?';
    16 | 
    17 |   client.connect(TEST.login, TEST.password, function() {
    18 |     client.subscribe(TEST.destination, function(frame) {
    19 |       start();
    20 |       equals(frame.body, msg);
    21 |     });
    22 | 
    23 |     client.send(TEST.destination, {}, msg);
    24 |   });
    25 | 
    26 |   stop(TEST.timeout);
    27 | });
    28 | 
    29 | test("Should no longer receive messages after unsubscribing to destination", 1, function() {
    30 |   var msg1 = 'Calling all cars!',
    31 |       subscription1 = null,
    32 |       subscription2 = null;
    33 | 
    34 |   client.connect(TEST.login, TEST.password, function() {
    35 |     subscription1 = client.subscribe(TEST.destination, function(frame) {
    36 |       start();
    37 |       ok(false, 'Should not have received message!');
    38 |     });
    39 | 
    40 |     subscription2 = client.subscribe(TEST.destination, function(frame) {
    41 |       start();
    42 |       equals(frame.body, msg1);
    43 |     });
    44 | 
    45 |     subscription1.unsubscribe();
    46 |     client.send(TEST.destination, {}, msg1);
    47 |   });
    48 | 
    49 |   stop(TEST.timeout);
    50 | });
    51 | 
    
    
    --------------------------------------------------------------------------------
    /spring-doge-web/src/main/resources/public/lib/stomp-websocket/browsertests/unit/transaction.js:
    --------------------------------------------------------------------------------
     1 | module("Stomp Transaction");
     2 | 
     3 | test("Send a message in a transaction and abort", function() {
     4 |   
     5 |   var body = Math.random();
     6 |   var body2 = Math.random();
     7 |   
     8 |   var client = Stomp.client(TEST.url);
     9 |   
    10 |   client.debug = TEST.debug;
    11 |   client.connect(TEST.login, TEST.password,
    12 |     function() {
    13 |       client.subscribe(TEST.destination, function(message)
    14 |       {
    15 |         start();
    16 |         // we should receive the 2nd message outside the transaction
    17 |         equals(message.body, body2);
    18 |         client.disconnect();
    19 |       });
    20 |       
    21 |       var tx = client.begin("txid_" + Math.random());
    22 |       client.send(TEST.destination, {transaction: tx.id}, body);
    23 |       tx.abort();
    24 |       client.send(TEST.destination, {}, body2);
    25 |     });
    26 |     stop(TEST.timeout);
    27 | });
    28 | 
    29 | test("Send a message in a transaction and commit", function() {
    30 |   
    31 |   var body = Math.random();
    32 |   
    33 |   var client = Stomp.client(TEST.url);
    34 |   
    35 |   client.debug = TEST.debug;
    36 |   client.connect(TEST.login, TEST.password,
    37 |     function() {
    38 |       client.subscribe(TEST.destination, function(message)
    39 |       {
    40 |         start();
    41 |         equals(message.body, body);
    42 |         client.disconnect();
    43 |       });
    44 |       var tx = client.begin();
    45 |       client.send(TEST.destination, {transaction: tx.id}, body);
    46 |       tx.commit();
    47 |     });
    48 |     stop(TEST.timeout);
    49 | });
    50 | 
    51 | test("Send a message outside a transaction and abort", function() {
    52 | 
    53 |   var body = Math.random();
    54 | 
    55 |   var client = Stomp.client(TEST.url);
    56 | 
    57 |   client.debug = TEST.debug;
    58 |   client.connect(TEST.login, TEST.password,
    59 |     function() {
    60 |       client.subscribe(TEST.destination, function(message)
    61 |       {
    62 |         start();
    63 |         // we should receive the message since it was sent outside the transaction
    64 |         equals(message.body, body);
    65 |         client.disconnect();
    66 |       });
    67 | 
    68 |       var tx = client.begin();
    69 |       client.send(TEST.destination, {}, body);
    70 |       tx.abort();
    71 |     });
    72 |     stop(TEST.timeout);
    73 | });
    
    
    --------------------------------------------------------------------------------
    /spring-doge-web/src/main/resources/public/lib/stomp-websocket/browsertests/unit/websocket.js:
    --------------------------------------------------------------------------------
    1 | module("Web Sockets");
    2 | 
    3 | test("check Web Sockets support", function() {
    4 |   ok(WebSocket, "this browser support Web Sockets");
    5 | });
    6 | 
    
    
    --------------------------------------------------------------------------------
    /spring-doge-web/src/main/resources/public/lib/stomp-websocket/coffeelint.json:
    --------------------------------------------------------------------------------
    1 | {
    2 |   "max_line_length": {
    3 |     "value": 80,
    4 |     "level": "warn"
    5 |   }
    6 | }
    7 | 
    
    
    --------------------------------------------------------------------------------
    /spring-doge-web/src/main/resources/public/lib/stomp-websocket/doc/.gitignore:
    --------------------------------------------------------------------------------
    1 | docco.css
    2 | stomp.html
    3 | stomp-node.html
    4 | 
    
    
    --------------------------------------------------------------------------------
    /spring-doge-web/src/main/resources/public/lib/stomp-websocket/doc/j/doc.js:
    --------------------------------------------------------------------------------
     1 | /*
     2 | Copyright (c) 2009, Mark Pilgrim, All rights reserved.
     3 | 
     4 | Redistribution and use in source and binary forms, with or without modification,
     5 | are permitted provided that the following conditions are met:
     6 | 
     7 | * Redistributions of source code must retain the above copyright notice,
     8 |   this list of conditions and the following disclaimer.
     9 | * Redistributions in binary form must reproduce the above copyright notice,
    10 |   this list of conditions and the following disclaimer in the documentation
    11 |   and/or other materials provided with the distribution.
    12 | 
    13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
    14 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    15 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    16 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
    17 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    18 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    19 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    20 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    21 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    22 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    23 | POSSIBILITY OF SUCH DAMAGE.
    24 | */
    25 | 
    26 | $(document).ready(function() {
    27 | 	hideTOC();
    28 | 	$("#live-web-sockets").html(supports("WebSocket" in window, "WebSockets"));
    29 | }); /* document.ready */
    30 | 
    31 | function hideTOC() {
    32 |     var toc = 'Show Table of Contents';
    33 |     $("#toc").html(toc);
    34 | }
    35 | 
    36 | function showTOC() {
    37 |     var toc = '';
    38 |     var old_level = 1;
    39 |     $('h2,h3').each(function(i, h) {
    40 | 	    level = parseInt(h.tagName.substring(1));
    41 | 	    if (level < old_level) {
    42 | 		toc += '';
    43 | 	    } else if (level > old_level) {
    44 | 		toc += '
      '; 45 | } 46 | toc += '
    1. ' + h.innerHTML + ''; 47 | old_level = level; 48 | }); 49 | while (level > 1) { 50 | toc += '
    '; 51 | level -= 1; 52 | } 53 | toc = 'Hide Table of Contents
      ' + toc.substring(4); 54 | $("#toc").html(toc); 55 | } 56 | 57 | function supports(bool, suffix) { 58 | var s = "Your browser "; 59 | if (bool) { 60 | s += "supports " + suffix + "."; 61 | } else { 62 | s += "does not support " + suffix + ". :("; 63 | } 64 | return s; 65 | } 66 | -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/stomp-websocket/doc/screen.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2010, Jeff Mesnil (http://jmesnil.net) All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, 9 | this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | 26 | Acknowledgements & Inspirations 27 | 28 | The stub of the stylesheet (and the documentation in general) was taken 29 | from Mark Pilgrim's Dive into HTML 5 (http//diveintohtml5.org). 30 | 31 | "The Elements of Typographic Style Applied to the Web" ... http://webtypography.net/toc/ 32 | "Use the Best Available Ampersand" ....................... http://simplebits.com/notebook/2008/08/14/ampersands.html 33 | "Unicode Support in HTML, Fonts, and Web Browsers" ....... http://alanwood.net/unicode/ 34 | "Punctuation" ............................................ http://en.wikipedia.org/wiki/Punctuation 35 | "Essays 1743" ............................................ http://www.thibault.org/fonts/essays/ 36 | "Linux Libertine" ........................................ http://linuxlibertine.sourceforge.net/ 37 | "CSS Styled Restaurant Menu" ............................. http://www.web-graphics.com/mtarchive/ItalianMenu.html 38 | */ 39 | 40 | footer { 41 | clear: both; 42 | text-align: center; 43 | font-size: small; 44 | display: block; 45 | } 46 | 47 | 48 | body { 49 | font: large/1.556 "Linux Libertine", Palatino, "Palatino Linotype", "Book Antiqua", Georgia, "Times New Roman", serif; 50 | word-spacing: 0.1em; 51 | max-width: 800px; 52 | margin: 0 auto; 53 | padding-bottom: 2em; 54 | } 55 | 56 | pre, kbd, samp, code, var { 57 | font: medium Consolas, "Andale Mono", Monaco, "Liberation Mono", "Bitstream Vera Sans Mono", "DejaVu Sans Mono", monospace; 58 | word-spacing: 0; 59 | letter-spacing: 0; 60 | } 61 | 62 | code, var, samp { 63 | line-height:inherit !important; 64 | } 65 | 66 | samp { 67 | display:inline ; 68 | color: #667; 69 | } 70 | mark { 71 | display: inline-block; 72 | background: #ff8; 73 | border: 1px dotted #888; 74 | } 75 | 76 | h1, h2, h3, h4, caption, thead th { 77 | font-family: "Essays 1743", "Linux Libertine", Palatino, "Palatino Linotype", "Book Antiqua", Georgia, "Times New Roman", serif; 78 | } 79 | 80 | h1, h2, h3, h4 { 81 | clear: both; 82 | } 83 | 84 | 85 | img { 86 | float: left; 87 | margin-right: 5px; 88 | margin-bottom: 5px; 89 | } 90 | 91 | .bc, .st { 92 | width:100%; 93 | border-collapse:collapse; 94 | } 95 | 96 | .st { 97 | border: 1px solid; 98 | } 99 | 100 | .st th { 101 | text-align: left; 102 | font-weight: normal; 103 | } 104 | 105 | .st tr > th:first-child { 106 | padding-left: 5px; 107 | } 108 | 109 | .ho th { 110 | border-bottom: 1px solid; 111 | } 112 | 113 | .zebra { 114 | background: #eee; 115 | } 116 | 117 | .ss { 118 | float: right; 119 | margin: 0 0 1.75em 1.75em; 120 | font-size: medium; 121 | } 122 | 123 | aside { 124 | display: block; 125 | padding: 0.75em; 126 | border: 1px solid #000; 127 | -moz-border-radius: 1em; 128 | -webkit-border-radius: 1em; 129 | border-radius: 1em; 130 | font-style: oblique; 131 | margin: 1.75em 0; 132 | } 133 | 134 | .advice { 135 | display: block; 136 | padding: 0.75em; 137 | border: 1px solid #000; 138 | -moz-border-radius: 1em; 139 | -webkit-border-radius: 1em; 140 | border-radius: 1em; 141 | font-style: oblique; 142 | margin: 1.75em 0; 143 | min-height: 148px; 144 | 145 | } 146 | 147 | .ss span { 148 | display: block; 149 | text-align: center; 150 | border-bottom: 3px double; 151 | } -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/stomp-websocket/example/README.md: -------------------------------------------------------------------------------- 1 | # STOMP Over WebSocket Examples 2 | 3 | To run the examples, start a local HTPP server: 4 | 5 | $ node server.js 6 | 7 | The [Chat example](http://localhost:8080/chat/) shows how to use `stomp.js` to send and receive STOMP messages directly from the Web browser. 8 | 9 | The [WebWorker example](http://localhost:8080/chat/) uses a WebWorker to send and receive STOMP messages from the broker. 10 | 11 | -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/stomp-websocket/example/chat/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Chat Example Using STOMP Over WebSockets 6 | 9 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 25 | 26 |
      27 |
      28 |
      29 |
      30 | 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 | 77 |
      78 |
      79 | 82 |
      
       83 |         
      84 |
      85 |
      86 | 87 | 88 | 89 | 90 | 147 | 148 | 149 | 150 | -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/stomp-websocket/example/css/bootstrap.min.responsive.css: -------------------------------------------------------------------------------- 1 | 2 | .hidden{display:none;visibility:hidden;} 3 | @media (max-width:480px){.nav-collapse{-webkit-transform:translate3d(0, 0, 0);} .page-header h1 small{display:block;line-height:18px;} input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;height:28px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box;} .input-prepend input[class*="span"],.input-append input[class*="span"]{width:auto;} input[type="checkbox"],input[type="radio"]{border:1px solid #ccc;} .form-horizontal .control-group>label{float:none;width:auto;padding-top:0;text-align:left;} .form-horizontal .controls{margin-left:0;} .form-horizontal .control-list{padding-top:0;} .form-horizontal .form-actions{padding-left:10px;padding-right:10px;} .modal{position:absolute;top:10px;left:10px;right:10px;width:auto;margin:0;}.modal.fade.in{top:auto;} .modal-header .close{padding:10px;margin:-10px;} .carousel-caption{position:static;}}@media (max-width:768px){.container{width:auto;padding:0 20px;} .row-fluid{width:100%;} .row{margin-left:0;} .row>[class*="span"],.row-fluid>[class*="span"]{float:none;display:block;width:auto;margin:0;}}@media (min-width:768px) and (max-width:980px){.row{margin-left:-20px;*zoom:1;}.row:before,.row:after{display:table;content:"";} .row:after{clear:both;} [class*="span"]{float:left;margin-left:20px;} .span1{width:42px;} .span2{width:104px;} .span3{width:166px;} .span4{width:228px;} .span5{width:290px;} .span6{width:352px;} .span7{width:414px;} .span8{width:476px;} .span9{width:538px;} .span10{width:600px;} .span11{width:662px;} .span12,.container{width:724px;} .offset1{margin-left:82px;} .offset2{margin-left:144px;} .offset3{margin-left:206px;} .offset4{margin-left:268px;} .offset5{margin-left:330px;} .offset6{margin-left:392px;} .offset7{margin-left:454px;} .offset8{margin-left:516px;} .offset9{margin-left:578px;} .offset10{margin-left:640px;} .offset11{margin-left:702px;} .row-fluid{width:100%;*zoom:1;}.row-fluid:before,.row-fluid:after{display:table;content:"";} .row-fluid:after{clear:both;} .row-fluid>[class*="span"]{float:left;margin-left:2.762430939%;} .row-fluid>[class*="span"]:first-child{margin-left:0;} .row-fluid .span1{width:5.801104972%;} .row-fluid .span2{width:14.364640883%;} .row-fluid .span3{width:22.928176794%;} .row-fluid .span4{width:31.491712705%;} .row-fluid .span5{width:40.055248616%;} .row-fluid .span6{width:48.618784527%;} .row-fluid .span7{width:57.182320438000005%;} .row-fluid .span8{width:65.74585634900001%;} .row-fluid .span9{width:74.30939226%;} .row-fluid .span10{width:82.87292817100001%;} .row-fluid .span11{width:91.436464082%;} .row-fluid .span12{width:99.999999993%;} input.span1,textarea.span1,.uneditable-input.span1{width:32px;} input.span2,textarea.span2,.uneditable-input.span2{width:94px;} input.span3,textarea.span3,.uneditable-input.span3{width:156px;} input.span4,textarea.span4,.uneditable-input.span4{width:218px;} input.span5,textarea.span5,.uneditable-input.span5{width:280px;} input.span6,textarea.span6,.uneditable-input.span6{width:342px;} input.span7,textarea.span7,.uneditable-input.span7{width:404px;} input.span8,textarea.span8,.uneditable-input.span8{width:466px;} input.span9,textarea.span9,.uneditable-input.span9{width:528px;} input.span10,textarea.span10,.uneditable-input.span10{width:590px;} input.span11,textarea.span11,.uneditable-input.span11{width:652px;} input.span12,textarea.span12,.uneditable-input.span12{width:714px;}}@media (max-width:980px){body{padding-top:0;} .navbar-fixed-top{position:static;margin-bottom:18px;} .navbar-fixed-top .navbar-inner{padding:5px;} .navbar .container{width:auto;padding:0;} .navbar .brand{padding-left:10px;padding-right:10px;margin:0 0 0 -5px;} .navbar .nav-collapse{clear:left;} .navbar .nav{float:none;margin:0 0 9px;} .navbar .nav>li{float:none;} .navbar .nav>li>a{margin-bottom:2px;} .navbar .nav>.divider-vertical{display:none;} .navbar .nav>li>a,.navbar .dropdown-menu a{padding:6px 15px;font-weight:bold;color:#999999;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} .navbar .dropdown-menu li+li a{margin-bottom:2px;} .navbar .nav>li>a:hover,.navbar .dropdown-menu a:hover{background-color:#222222;} .navbar .dropdown-menu{position:static;top:auto;left:auto;float:none;display:block;max-width:none;margin:0 15px;padding:0;background-color:transparent;border:none;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;} .navbar .dropdown-menu:before,.navbar .dropdown-menu:after{display:none;} .navbar .dropdown-menu .divider{display:none;} .navbar-form,.navbar-search{float:none;padding:9px 15px;margin:9px 0;border-top:1px solid #222222;border-bottom:1px solid #222222;-webkit-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.1),0 1px 0 rgba(255, 255, 255, 0.1);-moz-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.1),0 1px 0 rgba(255, 255, 255, 0.1);box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.1),0 1px 0 rgba(255, 255, 255, 0.1);} .navbar .nav.pull-right{float:none;margin-left:0;} .navbar-static .navbar-inner{padding-left:10px;padding-right:10px;} .btn-navbar{display:block;} .nav-collapse{overflow:hidden;height:0;}}@media (min-width:980px){.nav-collapse.collapse{height:auto !important;}}@media (min-width:1200px){.row{margin-left:-30px;*zoom:1;}.row:before,.row:after{display:table;content:"";} .row:after{clear:both;} [class*="span"]{float:left;margin-left:30px;} .span1{width:70px;} .span2{width:170px;} .span3{width:270px;} .span4{width:370px;} .span5{width:470px;} .span6{width:570px;} .span7{width:670px;} .span8{width:770px;} .span9{width:870px;} .span10{width:970px;} .span11{width:1070px;} .span12,.container{width:1170px;} .offset1{margin-left:130px;} .offset2{margin-left:230px;} .offset3{margin-left:330px;} .offset4{margin-left:430px;} .offset5{margin-left:530px;} .offset6{margin-left:630px;} .offset7{margin-left:730px;} .offset8{margin-left:830px;} .offset9{margin-left:930px;} .offset10{margin-left:1030px;} .offset11{margin-left:1130px;} .row-fluid{width:100%;*zoom:1;}.row-fluid:before,.row-fluid:after{display:table;content:"";} .row-fluid:after{clear:both;} .row-fluid>[class*="span"]{float:left;margin-left:2.564102564%;} .row-fluid>[class*="span"]:first-child{margin-left:0;} .row-fluid .span1{width:5.982905983%;} .row-fluid .span2{width:14.529914530000001%;} .row-fluid .span3{width:23.076923077%;} .row-fluid .span4{width:31.623931624%;} .row-fluid .span5{width:40.170940171000005%;} .row-fluid .span6{width:48.717948718%;} .row-fluid .span7{width:57.264957265%;} .row-fluid .span8{width:65.81196581200001%;} .row-fluid .span9{width:74.358974359%;} .row-fluid .span10{width:82.905982906%;} .row-fluid .span11{width:91.45299145300001%;} .row-fluid .span12{width:100%;} input.span1,textarea.span1,.uneditable-input.span1{width:60px;} input.span2,textarea.span2,.uneditable-input.span2{width:160px;} input.span3,textarea.span3,.uneditable-input.span3{width:260px;} input.span4,textarea.span4,.uneditable-input.span4{width:360px;} input.span5,textarea.span5,.uneditable-input.span5{width:460px;} input.span6,textarea.span6,.uneditable-input.span6{width:560px;} input.span7,textarea.span7,.uneditable-input.span7{width:660px;} input.span8,textarea.span8,.uneditable-input.span8{width:760px;} input.span9,textarea.span9,.uneditable-input.span9{width:860px;} input.span10,textarea.span10,.uneditable-input.span10{width:960px;} input.span11,textarea.span11,.uneditable-input.span11{width:1060px;} input.span12,textarea.span12,.uneditable-input.span12{width:1160px;} .thumbnails{margin-left:-30px;} .thumbnails>li{margin-left:30px;}} 4 | -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/stomp-websocket/example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Examples Using STOMP Over WebSockets 6 | 9 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 25 | 26 |
      27 |
      28 |

      The Chat example shows how to use stomp.js to send and receive STOMP messages directly from the Web browser.

      29 |

      The WebWorker example uses a WebWorker instead to send and receive STOMP messages from the broker.

      30 |
      31 |
      32 | 33 | 34 | -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/stomp-websocket/example/server.js: -------------------------------------------------------------------------------- 1 | var connect = require('connect'); 2 | 3 | connect() 4 | .use(connect.logger('dev')) 5 | .use(connect.static(__dirname)) 6 | .use(connect.static(__dirname + '/../lib/')) 7 | .listen(8080); 8 | console.log('Server running at http://0.0.0.0:8080/'); 9 | -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/stomp-websocket/example/webworker/README.md: -------------------------------------------------------------------------------- 1 | #WebWorker Example Using STOMP Over WebSocket 2 | 3 | This example uses a WebWorker to send and receive STOMP messages from the broker. 4 | 5 | The main page creates a WebWorker and post all the configuration to connect to the STOMP broker and send a text message. 6 | When the WebWorker will receive a message, it will inform the main page using its `postMessage` method. 7 | 8 | ##Running the Example 9 | 10 | run in the `example`parent directory: 11 | 12 | $ node server.js 13 | 14 | and go to [/webworker/](http://localhost:8080/webworker/). 15 | -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/stomp-websocket/example/webworker/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | WebWorker Example Using STOMP Over WebSocket 6 | 9 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 25 | 26 |
      27 |
      28 |
      29 |
      30 | 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 |
      66 | 67 |
      68 |
      69 |
      70 |
      71 |
      72 |

      Messages

      73 |
      74 |
      75 |
      76 |
      77 | 78 | 79 | 80 | 116 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/stomp-websocket/example/webworker/webworker.js: -------------------------------------------------------------------------------- 1 | importScripts ("/stomp.js"); 2 | 3 | // *WebWorker* onmessage implementation 4 | onmessage = function (event) { 5 | var url = event.data.url; 6 | var login = event.data.login; 7 | var passcode = event.data.passcode; 8 | var destination = event.data.destination; 9 | var text = event.data.text; 10 | 11 | // create the Stomp client 12 | var client = Stomp.client(url); 13 | 14 | // connect to the server 15 | client.connect(login, passcode, function(frame) { 16 | // upon connection, subscribe to the destination 17 | var sub = client.subscribe(destination, function(message) { 18 | // when a message is received, post it to the current WebWorker 19 | postMessage("WebWorker: " + message.body); 20 | //... unsubscribe from the destination 21 | sub.unsubscribe(); 22 | //... and disconnect from the server 23 | client.disconnect(); 24 | }); 25 | // send the text to the destination 26 | client.send(destination, {}, text); 27 | }); 28 | }; 29 | -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/stomp-websocket/index.js: -------------------------------------------------------------------------------- 1 | var Stomp = require('./lib/stomp.js'); 2 | var StompNode = require('./lib/stomp-node.js'); 3 | 4 | module.exports = Stomp.Stomp; 5 | module.exports.overTCP = StompNode.overTCP; 6 | module.exports.overWS = StompNode.overWS; -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/stomp-websocket/lib/stomp-node.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.6.3 2 | (function() { 3 | var Stomp, net, overTCP, overWS, wrapTCP, wrapWS; 4 | 5 | Stomp = require('./stomp'); 6 | 7 | net = require('net'); 8 | 9 | wrapTCP = function(port, host) { 10 | var socket, ws; 11 | socket = null; 12 | ws = { 13 | url: 'tcp:// ' + host + ':' + port, 14 | send: function(d) { 15 | return socket.write(d); 16 | }, 17 | close: function() { 18 | return socket.end(); 19 | } 20 | }; 21 | socket = net.connect(port, host, function(e) { 22 | return ws.onopen(); 23 | }); 24 | socket.on('error', function(e) { 25 | return typeof ws.onclose === "function" ? ws.onclose(e) : void 0; 26 | }); 27 | socket.on('close', function(e) { 28 | return typeof ws.onclose === "function" ? ws.onclose(e) : void 0; 29 | }); 30 | socket.on('data', function(data) { 31 | var event; 32 | event = { 33 | 'data': data.toString() 34 | }; 35 | return ws.onmessage(event); 36 | }); 37 | return ws; 38 | }; 39 | 40 | wrapWS = function(url) { 41 | var WebSocketClient, connection, socket, ws; 42 | WebSocketClient = require('websocket').client; 43 | connection = null; 44 | ws = { 45 | url: url, 46 | send: function(d) { 47 | return connection.sendUTF(d); 48 | }, 49 | close: function() { 50 | return connection.close(); 51 | } 52 | }; 53 | socket = new WebSocketClient(); 54 | socket.on('connect', function(conn) { 55 | connection = conn; 56 | ws.onopen(); 57 | connection.on('error', function(error) { 58 | return typeof ws.onclose === "function" ? ws.onclose(error) : void 0; 59 | }); 60 | connection.on('close', function() { 61 | return typeof ws.onclose === "function" ? ws.onclose(error) : void 0; 62 | }); 63 | return connection.on('message', function(message) { 64 | var event; 65 | if (message.type === 'utf8') { 66 | event = { 67 | 'data': message.utf8Data 68 | }; 69 | return ws.onmessage(event); 70 | } 71 | }); 72 | }); 73 | socket.connect(url); 74 | return ws; 75 | }; 76 | 77 | overTCP = function(host, port) { 78 | var socket; 79 | socket = wrapTCP(port, host); 80 | return Stomp.Stomp.over(socket); 81 | }; 82 | 83 | overWS = function(url) { 84 | var socket; 85 | socket = wrapWS(url); 86 | return Stomp.Stomp.over(socket); 87 | }; 88 | 89 | exports.overTCP = overTCP; 90 | 91 | exports.overWS = overWS; 92 | 93 | }).call(this); 94 | -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/stomp-websocket/lib/stomp.min.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.6.3 2 | /* 3 | Stomp Over WebSocket http://www.jmesnil.net/stomp-websocket/doc/ | Apache License V2.0 4 | 5 | Copyright (C) 2010-2013 [Jeff Mesnil](http://jmesnil.net/) 6 | Copyright (C) 2012 [FuseSource, Inc.](http://fusesource.com) 7 | */ 8 | !function(){var t,n,e,i,o={}.hasOwnProperty,r=[].slice;t={LF:"\n",NULL:"\0"};e=function(){var n;function e(t,n,e){this.command=t;this.headers=n!=null?n:{};this.body=e!=null?e:""}e.prototype.toString=function(){var n,e,i,r;n=[this.command];r=this.headers;for(e in r){if(!o.call(r,e))continue;i=r[e];n.push(""+e+":"+i)}if(this.body){n.push("content-length:"+(""+this.body).length)}n.push(t.LF+this.body);return n.join(t.LF)};n=function(n){var i,o,r,s,u,a,c,f,d,h,l,p,g,b,m,y,v;s=n.search(RegExp(""+t.LF+t.LF));u=n.substring(0,s).split(t.LF);r=u.shift();a={};p=function(t){return t.replace(/^\s+|\s+$/g,"")};y=u.reverse();for(g=0,m=y.length;gv;c=l<=v?++b:--b){o=n.charAt(c);if(o===t.NULL){break}i+=o}}return new e(r,a,i)};e.unmarshall=function(e){var i;return function(){var o,r,s,u;s=e.split(RegExp(""+t.NULL+t.LF+"*"));u=[];for(o=0,r=s.length;o0){u.push(n(i))}}return u}()};e.marshall=function(n,i,o){var r;r=new e(n,i,o);return r.toString()+t.NULL};return e}();n=function(){var n;function o(t){this.ws=t;this.ws.binaryType="arraybuffer";this.counter=0;this.connected=false;this.heartbeat={outgoing:1e4,incoming:1e4};this.maxWebSocketFrameSize=16*1024;this.subscriptions={}}o.prototype.debug=function(t){var n;return typeof window!=="undefined"&&window!==null?(n=window.console)!=null?n.log(t):void 0:void 0};n=function(){return Date.now||(new Date).valueOf};o.prototype._transmit=function(t,n,i){var o;o=e.marshall(t,n,i);if(typeof this.debug==="function"){this.debug(">>> "+o)}while(true){if(o.length>this.maxWebSocketFrameSize){this.ws.send(o.substring(0,this.maxWebSocketFrameSize));o=o.substring(this.maxWebSocketFrameSize);if(typeof this.debug==="function"){this.debug("remaining = "+o.length)}}else{return this.ws.send(o)}}};o.prototype._setupHeartbeat=function(e){var o,r,s,u,a,c,f=this;if((a=e.version)!==i.VERSIONS.V1_1&&a!==i.VERSIONS.V1_2){return}c=function(){var t,n,i,o;i=e["heart-beat"].split(",");o=[];for(t=0,n=i.length;t>> PING"):void 0},s):void 0}if(!(this.heartbeat.incoming===0||r===0)){s=Math.max(this.heartbeat.incoming,r);if(typeof this.debug==="function"){this.debug("check PONG every "+s+"ms")}return this.ponger=typeof window!=="undefined"&&window!==null?window.setInterval(function(){var t;t=n()-f.serverActivity;if(t>s*2){if(typeof f.debug==="function"){f.debug("did not receive server activity for the last "+t+"ms")}return f.ws.close()}},s):void 0}};o.prototype._parseConnect=function(){var t,n,e,i;t=1<=arguments.length?r.call(arguments,0):[];i={};switch(t.length){case 2:i=t[0],n=t[1];break;case 3:if(t[1]instanceof Function){i=t[0],n=t[1],e=t[2]}else{i.login=t[0],i.passcode=t[1],n=t[2]}break;case 4:i.login=t[0],i.passcode=t[1],n=t[2],e=t[3];break;default:i.login=t[0],i.passcode=t[1],n=t[2],e=t[3],i.host=t[4]}return[i,n,e]};o.prototype.connect=function(){var o,s,u,a,c=this;o=1<=arguments.length?r.call(arguments,0):[];a=this._parseConnect.apply(this,o);u=a[0],this.connectCallback=a[1],s=a[2];if(typeof this.debug==="function"){this.debug("Opening Web Socket...")}this.ws.onmessage=function(i){var o,r,u,a,f,d,h,l,p,g,b,m;a=typeof ArrayBuffer!=="undefined"&&i.data instanceof ArrayBuffer?(o=new Uint8Array(i.data),typeof c.debug==="function"?c.debug("--- got data length: "+o.length):void 0,function(){var t,n,e;e=[];for(t=0,n=o.length;t", 5 | "description": "STOMP for JavaScript apps (Web browser & node.js)", 6 | "scripts": { 7 | "build": "cake build", 8 | "test": "coffeelint -f coffeelint.json -r src && cake test" 9 | }, 10 | "devDependencies": { 11 | "coffee-script": "latest", 12 | "coffeelint": "latest", 13 | "jasmine-node": "latest", 14 | "uglify-js": "latest", 15 | "docco": "latest", 16 | "connect": "latest" 17 | }, 18 | "optionalDependencies": { 19 | "websocket": "latest" 20 | }, 21 | "directories": { 22 | "doc": "doc", 23 | "example": "example", 24 | "test": "test" 25 | }, 26 | "repository": { 27 | "type": "git", 28 | "url": "https://github.com/jmesnil/stomp-websocket" 29 | }, 30 | "keywords": [ 31 | "STOMP", 32 | "Web sockets", 33 | "messaging", 34 | "queue" 35 | ], 36 | "license": "APL v2", 37 | "bugs": { 38 | "url": "https://github.com/jmesnil/stomp-websocket/issues" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/stomp-websocket/src/stomp-node.coffee: -------------------------------------------------------------------------------- 1 | Stomp = require('./stomp') 2 | net = require('net') 3 | 4 | wrapTCP= (port, host) -> 5 | socket = null 6 | 7 | ws = { 8 | url: 'tcp:// ' + host + ':' + port 9 | send: (d) -> socket.write(d) 10 | close: -> socket.end() 11 | } 12 | 13 | socket = net.connect port, host, (e) -> ws.onopen() 14 | socket.on 'error', (e) -> ws.onclose?(e) 15 | socket.on 'close', (e) -> ws.onclose?(e) 16 | socket.on 'data', (data) -> 17 | event = { 18 | 'data': data.toString() 19 | } 20 | ws.onmessage(event) 21 | 22 | return ws 23 | 24 | wrapWS= (url) -> 25 | WebSocketClient = require('websocket').client 26 | 27 | connection = null 28 | 29 | ws = { 30 | url: url 31 | send: (d) -> connection.sendUTF(d) 32 | close: ->connection.close() 33 | } 34 | 35 | socket = new WebSocketClient() 36 | socket.on 'connect', (conn) -> 37 | connection = conn 38 | ws.onopen() 39 | connection.on 'error', (error) -> ws.onclose?(error) 40 | connection.on 'close', -> ws.onclose?(error) 41 | connection.on 'message', (message) -> 42 | if message.type == 'utf8' 43 | event = { 44 | 'data': message.utf8Data 45 | } 46 | ws.onmessage(event) 47 | 48 | socket.connect url 49 | return ws 50 | 51 | overTCP = (host, port) -> 52 | socket = wrapTCP port, host 53 | Stomp.Stomp.over socket 54 | 55 | overWS = (url) -> 56 | socket = wrapWS url 57 | Stomp.Stomp.over socket 58 | 59 | exports.overTCP = overTCP 60 | exports.overWS = overWS 61 | -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/stomp-websocket/src/stomp-node.orig.js: -------------------------------------------------------------------------------- 1 | var Stomp = require("./stomp"); 2 | var net = require('net'); 3 | 4 | var wrapTCP = function(port, host) { 5 | // node.js net.Socket; 6 | var socket; 7 | 8 | // Web Socket-like object 9 | var ws = { 10 | url: 'tcp:// ' + host + ':' + port, 11 | send: function(d) { 12 | socket.write(d); 13 | }, 14 | close: function() { 15 | socket.end(); 16 | } 17 | }; 18 | 19 | socket = net.connect(port, host, function(e) { 20 | ws.onopen(); 21 | }); 22 | socket.on('error', function(e) { 23 | // handler can be null if the ws is properly closed 24 | if (ws.onclose) { 25 | ws.onclose(e); 26 | } 27 | }); 28 | socket.on('close', function(e) { 29 | // handler can be null if the ws is properly closed 30 | if (ws.onclose) { 31 | ws.onclose(); 32 | } 33 | }); 34 | socket.on('data', function(data) { 35 | // wrap the data in an event object 36 | var event = { 37 | 'data': data.toString() 38 | }; 39 | ws.onmessage(event); 40 | }); 41 | 42 | return ws; 43 | }; 44 | 45 | var wrapWS = function(url) { 46 | var WebSocketClient = require('websocket').client; 47 | 48 | var connection; 49 | 50 | var ws = { 51 | url: url, 52 | send : function(d) { 53 | connection.sendUTF(d); 54 | }, 55 | close : function() { 56 | connection.close(); 57 | } 58 | }; 59 | 60 | var socket = new WebSocketClient(); 61 | socket.on('connect', function(conn) { 62 | connection = conn; 63 | ws.onopen(); 64 | connection.on('error', function(error) { 65 | if (ws.onclose) { 66 | ws.onclose(error); 67 | } 68 | }); 69 | connection.on('close', function() { 70 | if (ws.onclose) { 71 | ws.onclose(); 72 | } 73 | }); 74 | connection.on('message', function(message) { 75 | if (message.type === 'utf8') { 76 | // wrap the data in an event object 77 | var event = { 78 | 'data': message.utf8Data 79 | }; 80 | ws.onmessage(event); 81 | } 82 | }); 83 | }); 84 | 85 | socket.connect(url); 86 | return ws; 87 | } 88 | 89 | var overTCP = function(host, port) { 90 | var socket = wrapTCP(port, host); 91 | return Stomp.Stomp.over(socket); 92 | } 93 | 94 | var overWS= function(url) { 95 | var socket = wrapWS(url); 96 | return Stomp.Stomp.over(socket); 97 | } 98 | 99 | exports.overTCP = overTCP; 100 | exports.overWS = overWS; 101 | -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/stomp-websocket/src/stomp.orig.js: -------------------------------------------------------------------------------- 1 | // (c) 2010 Jeff Mesnil -- http://jmesnil.net/ 2 | // Copyright (C) FuseSource, Inc. -- http://fusesource.com 3 | 4 | (function(window) { 5 | 6 | var Stomp = {}; 7 | 8 | Stomp.frame = function(command, headers, body) { 9 | return { 10 | command: command, 11 | headers: headers, 12 | body: body, 13 | toString: function() { 14 | var out = command + '\n'; 15 | if (headers) { 16 | for (header in headers) { 17 | if(headers.hasOwnProperty(header)) { 18 | out = out + header + ': ' + headers[header] + '\n'; 19 | } 20 | } 21 | } 22 | out = out + '\n'; 23 | if (body) { 24 | out = out + body; 25 | } 26 | return out; 27 | } 28 | } 29 | }; 30 | 31 | trim = function(str) { 32 | return str.replace(/^\s+/g,'').replace(/\s+$/g,''); 33 | }; 34 | 35 | Stomp.unmarshal = function(data) { 36 | var divider = data.search(/\n\n/), 37 | headerLines = data.substring(0, divider).split('\n'), 38 | command = headerLines.shift(), 39 | headers = {}, 40 | body = ''; 41 | 42 | // Parse headers 43 | var line = idx = null; 44 | for (var i = 0; i < headerLines.length; i++) { 45 | line = headerLines[i]; 46 | idx = line.indexOf(':'); 47 | headers[trim(line.substring(0, idx))] = trim(line.substring(idx + 1)); 48 | } 49 | 50 | // Parse body, stopping at the first \0 found. 51 | // TODO: Add support for content-length header. 52 | var chr = null; 53 | for (var i = divider + 2; i < data.length; i++) { 54 | chr = data.charAt(i); 55 | if (chr === '\0') { 56 | break; 57 | } 58 | body += chr; 59 | } 60 | 61 | return Stomp.frame(command, headers, body); 62 | }; 63 | 64 | Stomp.marshal = function(command, headers, body) { 65 | return Stomp.frame(command, headers, body).toString() + '\0'; 66 | }; 67 | 68 | Stomp.client = function (url){ 69 | 70 | var that, ws, login, passcode; 71 | var counter = 0; // used to index subscribers 72 | // subscription callbacks indexed by subscriber's ID 73 | var subscriptions = {}; 74 | 75 | debug = function(str) { 76 | if (that.debug) { 77 | that.debug(str); 78 | } 79 | }; 80 | 81 | onmessage = function(evt) { 82 | var data = evt.data 83 | if (data instanceof ArrayBuffer) { 84 | view = new Uint8Array(data); 85 | data = ""; 86 | var i, len; 87 | for (i = 0, len = view.length; i < len; i++) { 88 | data += String.fromCharCode(view[i]); 89 | } 90 | } 91 | debug('<<< ' + data); 92 | var frame = Stomp.unmarshal(data); 93 | if (frame.command === "CONNECTED" && that.connectCallback) { 94 | that.connectCallback(frame); 95 | } else if (frame.command === "MESSAGE") { 96 | var onreceive = subscriptions[frame.headers.subscription]; 97 | if (onreceive) { 98 | onreceive(frame); 99 | } 100 | } else if (frame.command === "RECEIPT" && that.onreceipt) { 101 | that.onreceipt(frame); 102 | } else if (frame.command === "ERROR" && that.onerror) { 103 | that.onerror(frame); 104 | } 105 | }; 106 | 107 | transmit = function(command, headers, body) { 108 | var out = Stomp.marshal(command, headers, body); 109 | debug(">>> " + out); 110 | ws.send(out); 111 | }; 112 | 113 | that = {}; 114 | 115 | that.connect = function(login_, passcode_, connectCallback, errorCallback) { 116 | debug("Opening Web Socket..."); 117 | var Socket = "MozWebSocket" in window ? MozWebSocket : WebSocket; 118 | ws = new Socket(url); 119 | ws.binaryType = "arraybuffer"; 120 | ws.onmessage = onmessage; 121 | ws.onclose = function() { 122 | var msg = "Whoops! Lost connection to " + url; 123 | debug(msg); 124 | if (errorCallback) { 125 | errorCallback(msg); 126 | } 127 | }; 128 | ws.onopen = function() { 129 | debug('Web Socket Opened...'); 130 | transmit("CONNECT", {login: login, passcode: passcode}); 131 | // connectCallback handler will be called from onmessage when a CONNECTED frame is received 132 | }; 133 | login = login_; 134 | passcode = passcode_; 135 | that.connectCallback = connectCallback; 136 | }; 137 | 138 | that.disconnect = function(disconnectCallback) { 139 | transmit("DISCONNECT"); 140 | ws.close(); 141 | if (disconnectCallback) { 142 | disconnectCallback(); 143 | } 144 | }; 145 | 146 | that.send = function(destination, headers, body) { 147 | var headers = headers || {}; 148 | headers.destination = destination; 149 | transmit("SEND", headers, body); 150 | }; 151 | 152 | that.subscribe = function(destination, callback, headers) { 153 | var headers = headers || {}; 154 | var id = "sub-" + counter++; 155 | headers.destination = destination; 156 | headers.id = id; 157 | subscriptions[id] = callback; 158 | transmit("SUBSCRIBE", headers); 159 | return id; 160 | }; 161 | 162 | that.unsubscribe = function(id, headers) { 163 | var headers = headers || {}; 164 | headers.id = id; 165 | delete subscriptions[id]; 166 | transmit("UNSUBSCRIBE", headers); 167 | }; 168 | 169 | that.begin = function(transaction, headers) { 170 | var headers = headers || {}; 171 | headers.transaction = transaction; 172 | transmit("BEGIN", headers); 173 | }; 174 | 175 | that.commit = function(transaction, headers) { 176 | var headers = headers || {}; 177 | headers.transaction = transaction; 178 | transmit("COMMIT", headers); 179 | }; 180 | 181 | that.abort = function(transaction, headers) { 182 | var headers = headers || {}; 183 | headers.transaction = transaction; 184 | transmit("ABORT", headers); 185 | }; 186 | 187 | that.ack = function(message_id, headers) { 188 | var headers = headers || {}; 189 | headers["message-id"] = message_id; 190 | transmit("ACK", headers); 191 | }; 192 | return that; 193 | }; 194 | 195 | window.Stomp = Stomp; 196 | 197 | })(window); 198 | -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/stomp-websocket/test/server.mock.coffee: -------------------------------------------------------------------------------- 1 | WebSocketMock = require('./websocket.mock.js').WebSocketMock 2 | Stomp = require('../../lib/stomp.js').Stomp 3 | 4 | console = require 'console' 5 | 6 | class StompServerMock extends WebSocketMock 7 | # WebSocketMock handlers 8 | 9 | handle_send: (msg) => 10 | @stomp_dispatch(Stomp.Frame.unmarshall(msg)[0]) 11 | 12 | handle_close: => 13 | @_shutdown() 14 | 15 | handle_open: => 16 | @stomp_init() 17 | @_accept() 18 | 19 | # Stomp server implementation 20 | 21 | stomp_init: -> 22 | @transactions = {} 23 | @subscriptions = {} 24 | @messages = [] 25 | 26 | stomp_send: (command, headers, body=null) -> 27 | @_respond(Stomp.Frame.marshall(command, headers, body)) 28 | 29 | stomp_send_receipt: (frame) -> 30 | if frame.headers.message? 31 | @stomp_send("ERROR", {'receipt-id': frame.headers['receipt-id'], 'message': frame.headers.message}) 32 | else 33 | @stomp_send("RECEIPT", {'receipt-id': frame.headers['receipt-id']}) 34 | 35 | stomp_send_message: (destination, subscription, message_id, body) -> 36 | @stomp_send("MESSAGE", { 37 | 'destination': destination, 38 | 'message-id': message_id, 39 | 'subscription': subscription}, body) 40 | 41 | stomp_dispatch: (frame) -> 42 | handler = "stomp_handle_#{frame.command.toLowerCase()}" 43 | if this[handler]? 44 | this[handler](frame) 45 | if frame.receipt 46 | @stomp_send_receipt(frame) 47 | else 48 | console.log "StompServerMock: Unknown command: #{frame.command}" 49 | 50 | stomp_handle_connect: (frame) -> 51 | @session_id = Math.random() 52 | @stomp_send("CONNECTED", {'session': @session_id}) 53 | 54 | stomp_handle_begin: (frame) -> 55 | @transactions[frame.headers.transaction] = [] 56 | 57 | stomp_handle_commit: (frame) -> 58 | transaction = @transactions[frame.headers.transaction] 59 | for frame in transaction 60 | @messages.push(frame.body) 61 | delete @transactions[frame.headers.transaction] 62 | 63 | stomp_handle_abort: (frame) -> 64 | delete @transactions[frame.headers.transaction] 65 | 66 | stomp_handle_send: (frame) -> 67 | if frame.headers.transaction 68 | @transactions[frame.headers.transaction].push(frame) 69 | else 70 | @messages.push(frame.body) 71 | 72 | stomp_handle_subscribe: (frame) -> 73 | sub_id = frame.headers.id or Math.random() 74 | cb = (id, body) => @stomp_send_message(frame.headers.destination, sub_id, id, body) 75 | @subscriptions[sub_id] = [frame.headers.destination, cb] 76 | 77 | stomp_handle_unsubscribe: (frame) -> 78 | if frame.headers.id in Object.keys(@subscriptions) 79 | delete @subscriptions[frame.headers.id] 80 | else 81 | frame.headers.message = "Subscription does not exist" 82 | 83 | stomp_handle_disconnect: (frame) -> 84 | @_shutdown() 85 | 86 | # Test helpers 87 | 88 | test_send: (sub_id, message) -> 89 | msgid = 'msg-' + Math.random() 90 | @subscriptions[sub_id][1](msgid, message) 91 | 92 | 93 | exports.StompServerMock = StompServerMock -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/stomp-websocket/test/stomp.spec.coffee: -------------------------------------------------------------------------------- 1 | Stomp = require('../../lib/stomp.js').Stomp 2 | StompServerMock = require('./server.mock.js').StompServerMock 3 | 4 | Stomp.WebSocketClass = StompServerMock 5 | 6 | describe "Stomp", -> 7 | it "lets you connect to a server with a websocket and get a callback", -> 8 | ws = new StompServerMock("ws://mocked/stomp/server") 9 | client = Stomp.over(ws) 10 | connected = false 11 | client.connect("guest", "guest", -> 12 | connected = true 13 | ) 14 | waitsFor -> connected 15 | runs -> expect(client.connected).toBe(true) 16 | 17 | it "lets you connect to a server and get a callback", -> 18 | client = Stomp.client("ws://mocked/stomp/server") 19 | connected = false 20 | client.connect("guest", "guest", -> 21 | connected = true 22 | ) 23 | waitsFor -> connected 24 | runs -> expect(client.connected).toBe(true) 25 | 26 | it "lets you subscribe to a destination", -> 27 | client = Stomp.client("ws://mocked/stomp/server") 28 | subscription = null 29 | client.connect("guest", "guest", -> 30 | subscription = client.subscribe("/queue/test") 31 | ) 32 | waitsFor -> subscription 33 | runs -> expect(Object.keys(client.ws.subscriptions)).toContain(subscription.id) 34 | 35 | it "lets you publish a message to a destination", -> 36 | client = Stomp.client("ws://mocked/stomp/server") 37 | message = null 38 | client.connect("guest", "guest", -> 39 | message = "Hello world!" 40 | client.send("/queue/test", {}, message) 41 | ) 42 | waitsFor -> message 43 | runs -> expect(client.ws.messages).toContain(message) 44 | 45 | it "lets you unsubscribe from a destination", -> 46 | client = Stomp.client("ws://mocked/stomp/server") 47 | unsubscribed = false 48 | subscription = null 49 | client.connect("guest", "guest", -> 50 | subscription = client.subscribe("/queue/test") 51 | subscription.unsubscribe() 52 | unsubscribed = true 53 | ) 54 | waitsFor -> unsubscribed 55 | runs -> expect(Object.keys(client.ws.subscriptions)).not.toContain(subscription.id) 56 | 57 | it "lets you receive messages only while subscribed", -> 58 | client = Stomp.client("ws://mocked/stomp/server") 59 | subscription = null 60 | messages = [] 61 | client.connect("guest", "guest", -> 62 | subscription = client.subscribe("/queue/test", (msg) -> 63 | messages.push(msg) 64 | ) 65 | ) 66 | waitsFor -> subscription 67 | runs -> 68 | client.ws.test_send(subscription.id, Math.random()) 69 | client.ws.test_send(subscription.id, Math.random()) 70 | expect(messages.length).toEqual(2) 71 | subscription.unsubscribe() 72 | try 73 | client.ws.test_send(id, Math.random()) 74 | catch err 75 | null 76 | expect(messages.length).toEqual(2) 77 | 78 | it "lets you send messages in a transaction", -> 79 | client = Stomp.client("ws://mocked/stomp/server") 80 | connected = false 81 | client.connect("guest", "guest", -> 82 | connected = true 83 | ) 84 | waitsFor -> connected 85 | runs -> 86 | txid = "123" 87 | client.begin(txid) 88 | client.send("/queue/test", {transaction: txid}, "messages 1") 89 | client.send("/queue/test", {transaction: txid}, "messages 2") 90 | expect(client.ws.messages.length).toEqual(0) 91 | client.send("/queue/test", {transaction: txid}, "messages 3") 92 | client.commit(txid) 93 | expect(client.ws.messages.length).toEqual(3) 94 | 95 | it "lets you abort a transaction", -> 96 | client = Stomp.client("ws://mocked/stomp/server") 97 | connected = false 98 | client.connect("guest", "guest", -> 99 | connected = true 100 | ) 101 | waitsFor -> connected 102 | runs -> 103 | txid = "123" 104 | client.begin(txid) 105 | client.send("/queue/test", {transaction: txid}, "messages 1") 106 | client.send("/queue/test", {transaction: txid}, "messages 2") 107 | expect(client.ws.messages.length).toEqual(0) 108 | client.send("/queue/test", {transaction: txid}, "messages 3") 109 | client.abort(txid) 110 | expect(client.ws.messages.length).toEqual(0) -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/lib/stomp-websocket/test/websocket.mock.coffee: -------------------------------------------------------------------------------- 1 | class WebSocketMock 2 | constructor: (@url) -> 3 | @onclose = -> 4 | @onopen = -> 5 | @onerror = -> 6 | @onmessage = -> 7 | @readyState = 0 8 | @bufferedAmount = 0 9 | @extensions = '' 10 | @protocol = '' 11 | setTimeout(@handle_open, 0) 12 | 13 | # WebSocket API 14 | 15 | close: -> 16 | @handle_close() 17 | @readyState = 2 18 | 19 | send: (msg) -> 20 | if @readyState isnt 1 then return false 21 | @handle_send(msg) 22 | return true 23 | 24 | # Helpers 25 | 26 | _accept: -> 27 | @readyState = 1 28 | @onopen({'type': 'open'}) 29 | 30 | _shutdown: -> 31 | @readyState = 3 32 | @onclose({'type': 'close'}) 33 | 34 | _error: -> 35 | @readyState = 3 36 | @onerror({'type': 'error'}) 37 | 38 | _respond: (data) -> 39 | @onmessage({'type': 'message', 'data': data}) 40 | 41 | # Handlers 42 | 43 | handle_send: (msg) -> 44 | # implement me 45 | 46 | handle_close: -> 47 | # implement me 48 | 49 | handle_open: -> 50 | # implement me 51 | 52 | exports.WebSocketMock = WebSocketMock -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/public/monitorApp.js: -------------------------------------------------------------------------------- 1 | var appName = 'monitor'; 2 | 3 | /******************************************************************************* 4 | * Displays newly uploaded images communicated using websockets 5 | */ 6 | require.config({ 7 | paths: { 8 | doge: 'doge', 9 | stomp: doge.jsUrl('stomp-websocket/lib/stomp'), 10 | sockjs: doge.jsUrl('sockjs/sockjs'), 11 | angular: doge.jsUrl('angular/angular'), 12 | domReady: doge.jsUrl('requirejs-domready/domReady') 13 | }, 14 | shim: { 15 | angular: { 16 | exports: 'angular' 17 | } 18 | } 19 | }); 20 | 21 | define([ 'require', 'angular' ], function (require, angular) { 22 | 'use strict'; 23 | require([ 'sockjs', 'angular', 'stomp', 'domReady!' ], function (sockjs, angular, stomp) { 24 | angular.bootstrap(document, [ appName ]); 25 | }); 26 | 27 | var doge = angular.module(appName, []); 28 | 29 | doge.controller('MonitorController', [ 30 | '$scope', 31 | '$http', 32 | '$log', 33 | function ($scope, $http, $log) { 34 | 35 | $scope.imgSource = ""; 36 | $scope.uploads = []; 37 | $scope.size = 0; 38 | 39 | require([ 'sockjs', 'stomp' ], function (sockjs, stomp) { 40 | var socket = new SockJS('/doge'); 41 | var client = Stomp.over(socket); 42 | client.connect({}, function (frame) { 43 | console.log('Connected ' + frame); 44 | client.subscribe("/topic/alarms", function (message) { 45 | var body = JSON.parse(message.body); 46 | $scope.$apply(function () { 47 | $scope.onDoge(body); 48 | }); 49 | }); 50 | }, function (error) { 51 | console.log("STOMP protocol error " + error); 52 | }); 53 | }); 54 | 55 | $scope.onDoge = function (msg) { 56 | $scope.uploads.unshift(msg); 57 | $scope.size = $scope.uploads.length 58 | }; 59 | 60 | } ]); 61 | }); 62 | -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/templates/client.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Spring Doge: Such Boot! 7 | 8 | 9 | 10 | 11 | 12 | 13 | 19 | 20 |
      21 | 22 |

      Upload an Image

      23 | 24 | 28 | 29 |

      30 | Welcome, . 34 |

      35 | 36 |
      Drop files to "Dogeify" here
      39 | 40 |
      HTML5 Drop File is not supported on this browser
      41 | 42 | 47 | 48 |
      49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /spring-doge-web/src/main/resources/templates/monitor.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Spring Doge: Such Boot! 7 | 8 | 9 | 10 | 11 | 12 | 13 | 19 | 20 |
      21 | 22 |
      23 | 24 | Showing {{size}} upload(s). 25 | 26 |
      27 | 28 |
      by {{ u.userName }} on {{ u.uploadDate }}.
      29 |
      30 | 31 |
      32 |
      33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /spring-doge/.springBeans: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1 4 | 5 | 6 | 7 | 8 | 9 | 10 | java:doge.Application 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /spring-doge/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | io.spring.doge 7 | spring-doge-parent 8 | 0.0.1-SNAPSHOT 9 | 10 | jar 11 | spring-doge 12 | spring-doge 13 | 14 | ${basedir}/.. 15 | 16 | 17 | 18 | 19 | ${project.groupId} 20 | spring-doge-photo 21 | ${project.version} 22 | 23 | 24 | ${project.groupId} 25 | spring-doge-web 26 | ${project.version} 27 | 28 | 29 | io.dropwizard.metrics 30 | metrics-graphite 31 | ${dropwizard-metrics.version} 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-starter-remote-shell 36 | 37 | 38 | org.springframework.boot 39 | spring-boot-starter-actuator 40 | 41 | 42 | org.springframework.boot 43 | spring-boot-starter-web 44 | 45 | 46 | org.springframework.boot 47 | spring-boot-starter-data-mongodb 48 | 49 | 50 | org.springframework.boot 51 | spring-boot-starter-websocket 52 | 53 | 54 | org.apache.httpcomponents 55 | httpcore 56 | 4.3.1 57 | 58 | 59 | org.springframework.boot 60 | spring-boot-starter-test 61 | test 62 | 63 | 64 | 65 | spring-doge 66 | 67 | 68 | org.springframework.boot 69 | spring-boot-maven-plugin 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /spring-doge/src/main/java/doge/Application.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012-2014 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 | * http://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 | 17 | package doge; 18 | 19 | import com.codahale.metrics.MetricRegistry; 20 | import com.codahale.metrics.graphite.Graphite; 21 | import com.codahale.metrics.graphite.GraphiteReporter; 22 | import doge.domain.User; 23 | import doge.domain.UserRepository; 24 | import doge.photo.DogePhotoManipulator; 25 | import org.springframework.beans.factory.InitializingBean; 26 | import org.springframework.beans.factory.annotation.Value; 27 | import org.springframework.boot.SpringApplication; 28 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 29 | import org.springframework.context.annotation.Bean; 30 | import org.springframework.context.annotation.ComponentScan; 31 | import org.springframework.context.annotation.Configuration; 32 | import org.springframework.messaging.simp.config.MessageBrokerRegistry; 33 | import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; 34 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; 35 | import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer; 36 | import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; 37 | import org.springframework.web.socket.config.annotation.StompEndpointRegistry; 38 | 39 | import java.util.concurrent.TimeUnit; 40 | 41 | /** 42 | * Application configuration and main method. 43 | * 44 | * @author Josh Long 45 | * @author Phillip Webb 46 | */ 47 | @Configuration 48 | @ComponentScan 49 | @EnableAutoConfiguration 50 | public class Application { 51 | 52 | @Bean 53 | WebMvcConfigurerAdapter mvcViewConfigurer() { 54 | return new WebMvcConfigurerAdapter() { 55 | @Override 56 | public void addViewControllers(ViewControllerRegistry registry) { 57 | registry.addViewController("/").setViewName("client"); 58 | registry.addViewController("/monitor").setViewName("monitor"); 59 | } 60 | }; 61 | } 62 | 63 | @Bean 64 | DogePhotoManipulator dogePhotoManipulator() { 65 | DogePhotoManipulator dogePhotoManipulator = new DogePhotoManipulator(); 66 | dogePhotoManipulator.addTextOverlay("pivotal", "abstractfactorybean", "java"); 67 | dogePhotoManipulator.addTextOverlay("spring", "annotations", "boot"); 68 | dogePhotoManipulator.addTextOverlay("code", "semicolonfree", "groovy"); 69 | dogePhotoManipulator.addTextOverlay("clean", "juergenized", "spring"); 70 | dogePhotoManipulator.addTextOverlay("js", "nonblocking", "wat"); 71 | return dogePhotoManipulator; 72 | } 73 | 74 | @Bean 75 | InitializingBean populateTestData(UserRepository repository) { 76 | return () -> { 77 | repository.save(new User("philwebb", "Phil Webb")); 78 | repository.save(new User("joshlong", "Josh Long")); 79 | repository.findAll().forEach(System.err::println); 80 | }; 81 | } 82 | 83 | @Configuration 84 | @EnableWebSocketMessageBroker 85 | static class WebSocketConfiguration extends AbstractWebSocketMessageBrokerConfigurer { 86 | 87 | @Override 88 | public void registerStompEndpoints(StompEndpointRegistry registry) { 89 | registry.addEndpoint("/doge").withSockJS(); 90 | } 91 | 92 | @Override 93 | public void configureMessageBroker(MessageBrokerRegistry registry) { 94 | registry.enableSimpleBroker("/topic/"); 95 | } 96 | 97 | } 98 | 99 | @Configuration 100 | static class MetricsConfiguration { 101 | 102 | // see bit.ly/spring-boot-metrics for more on the 103 | // DropWizard & Spring Boot integration 104 | @Bean 105 | public GraphiteReporter graphiteReporter( 106 | MetricRegistry registry, 107 | @Value("${graphite.host}") String host, 108 | @Value("${graphite.port}") int port) { 109 | 110 | GraphiteReporter reporter = 111 | GraphiteReporter.forRegistry(registry) 112 | .prefixedWith("doge.spring.io") 113 | .build(new Graphite(host, port)); 114 | reporter.start(2, TimeUnit.SECONDS); 115 | return reporter; 116 | } 117 | } 118 | 119 | public static void main(String[] args) { 120 | SpringApplication.run(Application.class, args); 121 | } 122 | 123 | } 124 | -------------------------------------------------------------------------------- /spring-doge/src/main/java/doge/ServletInitializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012-2014 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 | * http://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 | 17 | package doge; 18 | 19 | import org.springframework.boot.builder.SpringApplicationBuilder; 20 | import org.springframework.boot.context.web.SpringBootServletInitializer; 21 | 22 | public class ServletInitializer extends SpringBootServletInitializer { 23 | 24 | @Override 25 | protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { 26 | return application.sources(Application.class); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /spring-doge/src/main/java/doge/controller/UsersRestController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012-2014 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 | * http://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 | 17 | package doge.controller; 18 | 19 | import java.io.IOException; 20 | import java.net.URI; 21 | import java.util.HashMap; 22 | import java.util.List; 23 | import java.util.Map; 24 | 25 | import org.springframework.beans.factory.annotation.Autowired; 26 | import org.springframework.core.io.Resource; 27 | import org.springframework.http.HttpHeaders; 28 | import org.springframework.http.HttpStatus; 29 | import org.springframework.http.MediaType; 30 | import org.springframework.http.ResponseEntity; 31 | import org.springframework.messaging.simp.SimpMessagingTemplate; 32 | import org.springframework.web.bind.annotation.PathVariable; 33 | import org.springframework.web.bind.annotation.RequestMapping; 34 | import org.springframework.web.bind.annotation.RequestMethod; 35 | import org.springframework.web.bind.annotation.RequestParam; 36 | import org.springframework.web.bind.annotation.ResponseStatus; 37 | import org.springframework.web.bind.annotation.RestController; 38 | import org.springframework.web.multipart.MultipartFile; 39 | import org.springframework.web.util.UriComponentsBuilder; 40 | 41 | import doge.domain.DogePhoto; 42 | import doge.domain.User; 43 | import doge.domain.UserRepository; 44 | import doge.photo.Photo; 45 | import doge.photo.PhotoResource; 46 | import doge.service.DogeService; 47 | 48 | /** 49 | * MVC Controller for '/users' REST endpoints. 50 | * 51 | * @author Josh Long 52 | * @author Phillip Webb 53 | */ 54 | @RestController 55 | @RequestMapping("/users") 56 | public class UsersRestController { 57 | 58 | private final UserRepository userRepository; 59 | 60 | private final DogeService dogeService; 61 | 62 | private final SimpMessagingTemplate messaging; 63 | 64 | @Autowired 65 | public UsersRestController(UserRepository userRepository, DogeService dogeService, 66 | SimpMessagingTemplate messaging) { 67 | this.userRepository = userRepository; 68 | this.dogeService = dogeService; 69 | this.messaging = messaging; 70 | } 71 | 72 | @RequestMapping(method = RequestMethod.GET) 73 | public List getUsers() { 74 | return this.userRepository.findAll(); 75 | } 76 | 77 | @RequestMapping(method = RequestMethod.POST, value = "{userId}/doge") 78 | public ResponseEntity postDogePhoto(@PathVariable String userId, 79 | @RequestParam MultipartFile file, UriComponentsBuilder uriBuilder) 80 | throws IOException { 81 | Photo photo = file::getInputStream; 82 | User user = this.userRepository.findOne(userId); 83 | DogePhoto doge = this.dogeService.addDogePhoto(user, photo); 84 | URI uri = uriBuilder.path("/users/{userId}/doge/{dogeId}") 85 | .buildAndExpand(userId, doge.getId()).toUri(); 86 | sendMessage(user, uri); 87 | return ResponseEntity.created(uri).build(); 88 | } 89 | 90 | private void sendMessage(User user, URI uri) { 91 | Map msg = new HashMap<>(); 92 | msg.put("dogePhotoUri", uri.toString()); 93 | msg.put("userId", user.getId()); 94 | msg.put("userName", user.getName()); 95 | msg.put("uploadDate", java.time.Clock.systemUTC().instant().toString()); 96 | this.messaging.convertAndSend("/topic/alarms", msg); 97 | } 98 | 99 | @RequestMapping(method = RequestMethod.GET, value = "{userId}/doge/{dogeId}", produces = MediaType.IMAGE_JPEG_VALUE) 100 | @ResponseStatus(HttpStatus.OK) 101 | public Resource getDogePhoto(@PathVariable String userId, @PathVariable String dogeId) 102 | throws IOException { 103 | User user = this.userRepository.findOne(userId); 104 | Photo photo = this.dogeService.getDogePhoto(user, dogeId); 105 | HttpHeaders headers = new HttpHeaders(); 106 | headers.setContentType(MediaType.IMAGE_JPEG); 107 | return new PhotoResource(photo); 108 | } 109 | 110 | } 111 | -------------------------------------------------------------------------------- /spring-doge/src/main/java/doge/domain/DogePhoto.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012-2014 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 | * http://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 | 17 | package doge.domain; 18 | 19 | import org.springframework.data.annotation.Id; 20 | import org.springframework.data.mongodb.core.mapping.DBRef; 21 | import org.springframework.util.Assert; 22 | 23 | /** 24 | * A Doge submitted by a {@link User}. 25 | * 26 | * @author Josh Long 27 | * @author Phillip Webb 28 | */ 29 | public class DogePhoto { 30 | 31 | @Id 32 | private String id; 33 | 34 | @DBRef(lazy = true) 35 | private User user; 36 | 37 | private String fileRef; 38 | 39 | public DogePhoto(User user, String fileRef) { 40 | Assert.notNull(user, "User must not be null"); 41 | Assert.notNull(fileRef, "FileRef must not be null"); 42 | this.user = user; 43 | this.fileRef = fileRef; 44 | } 45 | 46 | public String getId() { 47 | return this.id; 48 | } 49 | 50 | public String getFileRef() { 51 | return this.fileRef; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /spring-doge/src/main/java/doge/domain/DogePhotoRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012-2014 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 | * http://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 | 17 | package doge.domain; 18 | 19 | import org.springframework.data.mongodb.repository.MongoRepository; 20 | 21 | /** 22 | * The {@link DogePhoto} repository. 23 | * 24 | * @author Josh Long 25 | * @author Phillip Webb 26 | */ 27 | public interface DogePhotoRepository extends MongoRepository { 28 | 29 | DogePhoto findOneByIdAndUser(String id, User user); 30 | 31 | } 32 | -------------------------------------------------------------------------------- /spring-doge/src/main/java/doge/domain/User.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012-2014 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 | * http://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 | 17 | package doge.domain; 18 | 19 | import org.springframework.data.annotation.Id; 20 | 21 | /** 22 | * A single user of the system. Each {@link User} may submit one or more 23 | * {@link doge.domain.DogePhoto}s. 24 | * 25 | * @author Josh Long 26 | * @author Phillip Webb 27 | * @see doge.domain.DogePhoto 28 | */ 29 | public class User { 30 | 31 | @Id 32 | private String id; 33 | 34 | private String name; 35 | 36 | public String getId() { 37 | return this.id; 38 | } 39 | 40 | public User(String id, String name) { 41 | this.id = id; 42 | this.name = name; 43 | } 44 | 45 | public String getName() { 46 | return this.name; 47 | } 48 | 49 | @Override 50 | public String toString() { 51 | return "User {" + "id='" + this.id + '\'' + ", name='" + this.name + '\'' + '}'; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /spring-doge/src/main/java/doge/domain/UserRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012-2014 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 | * http://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 | 17 | package doge.domain; 18 | 19 | import org.springframework.data.mongodb.repository.MongoRepository; 20 | 21 | /** 22 | * The {@link User} repository. 23 | * 24 | * @author Josh Long 25 | * @author Phillip Webb 26 | */ 27 | public interface UserRepository extends MongoRepository { 28 | 29 | } 30 | -------------------------------------------------------------------------------- /spring-doge/src/main/java/doge/service/DogeService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012-2014 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 | * http://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 | 17 | package doge.service; 18 | 19 | import java.io.IOException; 20 | import java.io.InputStream; 21 | import java.util.UUID; 22 | 23 | import org.springframework.beans.factory.annotation.Autowired; 24 | import org.springframework.data.mongodb.gridfs.GridFsTemplate; 25 | import org.springframework.stereotype.Service; 26 | 27 | import doge.domain.DogePhoto; 28 | import doge.domain.DogePhotoRepository; 29 | import doge.domain.User; 30 | import doge.photo.Photo; 31 | import doge.photo.PhotoManipulator; 32 | 33 | /** 34 | * @author Josh Long 35 | * @author Phillip Webb 36 | */ 37 | @Service 38 | public class DogeService { 39 | 40 | private final DogePhotoRepository dogePhotoRepository; 41 | private final PhotoManipulator manipulator; 42 | private final GridFsTemplate fs; 43 | 44 | @Autowired 45 | public DogeService(DogePhotoRepository dogePhotoRepository, 46 | PhotoManipulator manipulator, GridFsTemplate fs) { 47 | this.dogePhotoRepository = dogePhotoRepository; 48 | this.manipulator = manipulator; 49 | this.fs = fs; 50 | } 51 | 52 | public Photo getDogePhoto(User user, String dogeId) throws IOException { 53 | DogePhoto dogePhoto = this.dogePhotoRepository.findOneByIdAndUser(dogeId, user); 54 | return () -> this.fs.getResource(dogePhoto.getFileRef()).getInputStream(); 55 | } 56 | 57 | public DogePhoto addDogePhoto(User user, Photo photo) throws IOException { 58 | photo = this.manipulator.manipulate(photo); 59 | String fileRef = UUID.randomUUID() + ".jpg"; 60 | try (InputStream inputStream = photo.getInputStream()) { 61 | this.fs.store(inputStream, fileRef); 62 | } 63 | return this.dogePhotoRepository.save(new DogePhoto(user, fileRef)); 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /spring-doge/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.thymeleaf.cache: false 2 | shell.auth.simple.user.password: spring 3 | -------------------------------------------------------------------------------- /spring-doge/src/test/java/doge/controller/UsersRestControllerTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012-2014 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 | * http://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 | 17 | package doge.controller; 18 | 19 | import org.junit.Before; 20 | import org.junit.Ignore; 21 | import org.junit.Test; 22 | import org.junit.runner.RunWith; 23 | import org.springframework.beans.factory.annotation.Autowired; 24 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 25 | import org.springframework.context.annotation.Bean; 26 | import org.springframework.context.annotation.Configuration; 27 | import org.springframework.context.annotation.Import; 28 | import org.springframework.context.annotation.Profile; 29 | import org.springframework.http.MediaType; 30 | import org.springframework.messaging.simp.SimpMessagingTemplate; 31 | import org.springframework.test.context.ActiveProfiles; 32 | import org.springframework.test.context.ContextConfiguration; 33 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 34 | import org.springframework.test.context.web.WebAppConfiguration; 35 | import org.springframework.test.web.servlet.MockMvc; 36 | import org.springframework.test.web.servlet.ResultActions; 37 | import org.springframework.web.context.WebApplicationContext; 38 | 39 | import doge.domain.User; 40 | import doge.domain.UserRepository; 41 | import doge.service.DogeService; 42 | 43 | import static org.hamcrest.Matchers.containsString; 44 | import static org.mockito.BDDMockito.given; 45 | import static org.mockito.Mockito.mock; 46 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; 47 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; 48 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 49 | import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup; 50 | 51 | /** 52 | * Tests for {@link UsersRestController}. 53 | * 54 | * @author Josh Long 55 | * @author Phillip Webb 56 | */ 57 | @RunWith(SpringJUnit4ClassRunner.class) 58 | @ContextConfiguration(classes = { TestConfiguration.class }) 59 | @WebAppConfiguration 60 | @ActiveProfiles("unittest") 61 | public class UsersRestControllerTest { 62 | 63 | @Autowired 64 | private WebApplicationContext context; 65 | 66 | @Autowired 67 | private UserRepository userRepository; 68 | 69 | @Autowired 70 | private DogeService dogePhotoService; 71 | 72 | private MockMvc mvc; 73 | 74 | @Before 75 | public void setup() { 76 | this.mvc = webAppContextSetup(this.context).build(); 77 | } 78 | 79 | @Test 80 | @Ignore 81 | public void getUser() throws Exception { 82 | given(this.userRepository.findOne("1")).willReturn( 83 | new User("philwebb", "Phil Webb")); 84 | ResultActions result = this.mvc.perform(get("/users/philwebb").accept( 85 | MediaType.APPLICATION_JSON)); 86 | result.andExpect(status().isOk()); 87 | result.andExpect(content().string(containsString("Phil Webb"))); 88 | } 89 | 90 | } 91 | 92 | @Configuration 93 | @EnableAutoConfiguration 94 | @Import(UsersRestController.class) 95 | @Profile("unittest") 96 | class TestConfiguration { 97 | 98 | @Bean 99 | public SimpMessagingTemplate messageTemplate() { 100 | return mock(SimpMessagingTemplate.class); 101 | } 102 | 103 | @Bean 104 | public UserRepository userRepository() { 105 | return mock(UserRepository.class); 106 | } 107 | 108 | @Bean 109 | public DogeService dogePhotoService() { 110 | return mock(DogeService.class); 111 | } 112 | 113 | } 114 | --------------------------------------------------------------------------------