├── .gitignore ├── README.md ├── docImages ├── highlevelarc.png └── tunerLinks.png ├── mobile └── iOS │ ├── Cars Mobile Sample │ ├── Cars Mobile Sample.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ ├── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ │ └── xcuserdata │ │ │ │ └── tom.batchelor.xcuserdatad │ │ │ │ └── UserInterfaceState.xcuserstate │ │ └── xcuserdata │ │ │ └── tom.batchelor.xcuserdatad │ │ │ ├── xcdebugger │ │ │ └── Breakpoints_v2.xcbkptlist │ │ │ └── xcschemes │ │ │ ├── Cars Mobile Sample.xcscheme │ │ │ └── xcschememanagement.plist │ ├── Cars Mobile Sample.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcuserdata │ │ │ └── tom.batchelor.xcuserdatad │ │ │ ├── UserInterfaceState.xcuserstate │ │ │ └── xcdebugger │ │ │ └── Breakpoints_v2.xcbkptlist │ ├── Cars Mobile Sample │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ ├── Contents.json │ │ │ │ ├── Icon-App-29x29@1x.png │ │ │ │ ├── Icon-App-29x29@2x-1.png │ │ │ │ ├── Icon-App-29x29@2x.png │ │ │ │ ├── Icon-App-29x29@3x.png │ │ │ │ ├── Icon-App-40x40@1x.png │ │ │ │ ├── Icon-App-40x40@2x-1.png │ │ │ │ ├── Icon-App-40x40@2x.png │ │ │ │ ├── Icon-App-60x60@2x-1.png │ │ │ │ ├── Icon-App-60x60@2x.png │ │ │ │ ├── Icon-App-60x60@3x.png │ │ │ │ ├── Icon-App-76x76@1x.png │ │ │ │ ├── Icon-App-76x76@2x-1.png │ │ │ │ └── Icon-App-76x76@2x.png │ │ │ ├── Contents.json │ │ │ └── sample.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── PinkTeapot.jpeg │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ ├── Car.swift │ │ ├── CarTableViewCell.swift │ │ ├── CarTableViewController.swift │ │ ├── CarViewController.swift │ │ ├── HomeViewController.swift │ │ ├── Info.plist │ │ ├── LoginViewController.swift │ │ ├── Manufacturer.swift │ │ ├── ManufacturerTableViewCell.swift │ │ ├── ManufacturerTableViewController.swift │ │ ├── RestApiManager.swift │ │ ├── SearchViewController.swift │ │ ├── SellViewController.swift │ │ └── User.swift │ └── Cars Mobile SampleTests │ │ ├── Cars_Mobile_SampleTests.swift │ │ └── Info.plist │ └── README.md ├── nb-configuration.xml ├── pom.xml ├── src └── main │ ├── java │ ├── com │ │ └── supercars │ │ │ ├── Car.java │ │ │ ├── Engine.java │ │ │ ├── Enquiry.java │ │ │ ├── Leak.java │ │ │ ├── Manufacturer.java │ │ │ ├── XMLException.java │ │ │ ├── dataloader │ │ │ ├── CarDataLoader.java │ │ │ ├── Constants.java │ │ │ ├── EnquiryDataLoader.java │ │ │ └── ManufacturerDataLoader.java │ │ │ ├── externaldata │ │ │ └── FuelPrices.java │ │ │ ├── logging │ │ │ ├── LogLevel.java │ │ │ └── Logger.java │ │ │ ├── preferences │ │ │ ├── Preference.java │ │ │ ├── PreferenceException.java │ │ │ └── PreferenceManager.java │ │ │ ├── rest │ │ │ ├── CarService.java │ │ │ ├── EnquiryService.java │ │ │ ├── FuelService.java │ │ │ ├── LeakService.java │ │ │ ├── ManufacturerService.java │ │ │ ├── PreferenceService.java │ │ │ └── UserService.java │ │ │ └── usermanagement │ │ │ ├── User.java │ │ │ └── UserManager.java │ └── conf │ │ └── MANIFEST.MF │ ├── resources │ └── db │ │ └── mysql.sql │ └── webapp │ ├── META-INF │ └── context.xml │ ├── WEB-INF │ ├── c.tld │ ├── jboss-web.xml │ ├── validator-rules.xml │ └── web.xml │ ├── angular │ ├── about.html │ ├── alpina.html │ ├── amg.html │ ├── angular-route.js │ ├── angular.js │ ├── car.html │ ├── cars.html │ ├── enquire.html │ ├── gembella.html │ ├── home.html │ ├── images │ │ ├── about_car.gif │ │ ├── aboutus_but.gif │ │ ├── cars │ │ │ ├── 0.gif │ │ │ ├── 0.jpg │ │ │ ├── 10.jpg │ │ │ ├── 11.jpg │ │ │ ├── 12.jpg │ │ │ ├── 13.jpg │ │ │ ├── 14.jpg │ │ │ ├── 15.jpg │ │ │ ├── 16.jpg │ │ │ ├── 17.jpg │ │ │ ├── 18.jpg │ │ │ ├── 19.jpg │ │ │ ├── 2.jpg │ │ │ ├── 20.jpg │ │ │ ├── 21.jpg │ │ │ ├── 22.jpg │ │ │ ├── 23.jpg │ │ │ ├── 24.jpg │ │ │ ├── 25.jpg │ │ │ ├── 26.jpg │ │ │ ├── 27.jpg │ │ │ ├── 28.jpg │ │ │ ├── 29.jpg │ │ │ ├── 3.jpg │ │ │ ├── 30.jpg │ │ │ ├── 31.jpg │ │ │ ├── 32.jpg │ │ │ ├── 33.jpg │ │ │ ├── 34.jpg │ │ │ ├── 35.jpg │ │ │ ├── 4.jpg │ │ │ ├── 5.jpg │ │ │ ├── 6.jpg │ │ │ ├── 7.jpg │ │ │ ├── 8.jpg │ │ │ └── 9.jpg │ │ ├── enquire_but.gif │ │ ├── enquire_button.gif │ │ ├── homepage_car.gif │ │ ├── insurance_but.gif │ │ ├── insurance_car.gif │ │ ├── line.gif │ │ ├── logo.gif │ │ ├── magnify.gif │ │ ├── manufacturers │ │ │ ├── AstonMartin.gif │ │ │ ├── Bmw.gif │ │ │ ├── Ferrari.gif │ │ │ ├── Ford.gif │ │ │ ├── Jaguar.gif │ │ │ ├── Lamborghini.gif │ │ │ ├── Lotus.gif │ │ │ ├── Mazda.gif │ │ │ ├── Mercedes.gif │ │ │ ├── Porsche.gif │ │ │ ├── Subaru.gif │ │ │ └── Tvr.gif │ │ ├── performance │ │ │ ├── alpina.gif │ │ │ ├── amg.gif │ │ │ ├── b10.gif │ │ │ ├── gcar.gif │ │ │ ├── gembella.gif │ │ │ ├── mazda.gif │ │ │ ├── rgt.gif │ │ │ ├── ruf.gif │ │ │ ├── rx8.gif │ │ │ └── slk.gif │ │ ├── pipe.gif │ │ ├── search_but.gif │ │ ├── search_button.gif │ │ ├── sell_but.gif │ │ ├── small_search_but.gif │ │ ├── submit_button.gif │ │ ├── supercars_but.gif │ │ ├── ukmap.gif │ │ └── view_enquiries_button.gif │ ├── index.html │ ├── index.jsp │ ├── insurance.html │ ├── login.html │ ├── logout.html │ ├── manufacturers.html │ ├── mazdaspeed.html │ ├── preferences.html │ ├── ruf.html │ ├── search.html │ ├── sell.html │ ├── superCars.js │ ├── superCarsController.js │ ├── thankyou.html │ ├── trader.css │ └── tuner.jsp │ └── trader.css └── updateDeployLocalhost.sh /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Cars Sample App Readme 2 | 3 | This is a simple web app which provides for a Super car store which has a couple of performance/code issues. The app can be build with Maven. 4 | 5 | ## Architecture 6 | 7 | The app is based on a Angular 1 front end, calling back to RESTful services, base on [Jersey](https://jersey.java.net), with a [MySQL](https://www.mysql.com) back end. 8 | 9 | ![image](docImages/highlevelarc.png) 10 | 11 | There is also a iOS mobile app which uses the same REST endpoints. This app is described in it's own [README](mobile/iOS/README.md). 12 | 13 | The internals of the web app are fairly simple. The packages in the code are: 14 | 15 | * com.supercars - Contains classes to describe the different business entities, e.g. car, manufacturer etc. 16 | * com.supercars.dataloader - Classes to access the DB and retrieve or persist the different business entities 17 | * com.supercars.externaldata - Classes to retrieve data from 3rd party services of HTTP - This is where the fuel prices come from on the home page 18 | * com.supercars.logging - Classes for custom logging, used to help with exercises for AppDynamics 19 | * com.supercars.rest - Classes which exposes the REST services 20 | * com.supercars.usermanagement - Classes for user management 21 | 22 | ### A JSP Page 23 | 24 | There is one application page which isn't Angular, but is a standalone JSP page this is "/Cars_Sample_App/angular/tuner.jsp". This page is access using the links from the performance accessories section on the home page: 25 | 26 | ![image](docImages/tunerLinks.png) 27 | 28 | ## Database 29 | 30 | The app uses a MySQL DB in the backend, this be default is expected to be the "supercars" schema, and MySQL running locally to the app. The schema build is in src/main/resources/db/mysql.sql. Execute this script against the schema you create in MySQL. 31 | 32 | The datasouce is defined in context.xml in src/webapp/META-INF 33 | 34 | ## Building 35 | 36 | This app uses [Maven](https://maven.apache.org) for the build. To get a build environment working: 37 | 38 | 1. Have [git](https://git-scm.com) installed and working 39 | 1. Get [Maven](https://maven.apache.org) installed 40 | 1. Get the tar.gz or zip package from the Maven site 41 | 1. Unpack somewhere on your file system, e.g. "/opt/maven/apache-maven-3.3.9/" 42 | 1. Add the Maven bin directory to your path, e.g. in "vi .bash_profile" add: 43 |

44 |  		export M2_HOME=/opt/maven/apache-maven-3.3.9
45 |  		export M2=$M2_HOME/bin
46 |  		export PATH=$PATH:$M2
47 |  		
48 | 1. Login and out of your shell to get the new path 49 | 1. Test using the command "mvn". This should run Maven and indicate "Build Failure" 50 | 1. Use git to get the source code 51 |

52 |  	git clone https://github.com/Appdynamics/Cars_Sample_App.git
53 |  	
54 | 1. Change to the Cars_Sample_App directory and then execute the following for the build 55 |

56 | 	mvn install
57 | 	
58 | 1. This should run and leave "Cars_Sample_App.war" in the "target/" directory 59 | 60 | It is also possible to have Maven auto deploy right into Tomcat. 61 | 62 | 1. First step is to configure a user for the Tomcat Manager. In "$TOMCAT_HOME/conf/tomcat-users.xml" add a line line the following: 63 |

64 |  	<user username="user" password="pass" roles="manager-script,manager-gui"/>
65 | 	
66 | 1. Restart Tomcat 67 | 1. Update our Maven config with this information. This is in the file "$M2_HOME/conf/settings.xml". 68 | 1. Locate the "<servers>" tag 69 | 1. Inside here add a server entry like the following: 70 |

71 | 	<server>
72 |       <id>Tomcat</id>
73 |       <username>user</username>
74 |       <password>pass</password>
75 |     </server>
76 |     
77 | 1. Note that the user/pass must match what you set in the Tomcat config 78 | 1. Now go back to the Cars_Sample_App source. Instead of "mvn install", the following will build and deploy: 79 |

80 | 	mvn tomcat7:deploy
81 | 	
82 | 1. If the app is already deployed into the Tomcat the following will build and re-deploy 83 |

84 | 	mvn tomcat7:redeploy
85 | 	
86 | 1. Now the app is available on "/Cars_Sample_App/angular/index.jsp" on your Tomcat 87 | 88 | -------------------------------------------------------------------------------- /docImages/highlevelarc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/docImages/highlevelarc.png -------------------------------------------------------------------------------- /docImages/tunerLinks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/docImages/tunerLinks.png -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile Sample.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile Sample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile Sample.xcodeproj/project.xcworkspace/xcuserdata/tom.batchelor.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/mobile/iOS/Cars Mobile Sample/Cars Mobile Sample.xcodeproj/project.xcworkspace/xcuserdata/tom.batchelor.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile Sample.xcodeproj/xcuserdata/tom.batchelor.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 20 | 21 | 22 | 24 | 36 | 37 | 38 | 40 | 52 | 53 | 54 | 56 | 68 | 69 | 70 | 72 | 84 | 85 | 86 | 88 | 100 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile Sample.xcodeproj/xcuserdata/tom.batchelor.xcuserdatad/xcschemes/Cars Mobile Sample.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 85 | 91 | 92 | 93 | 94 | 96 | 97 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile Sample.xcodeproj/xcuserdata/tom.batchelor.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Cars Mobile Sample.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 148C62281DCFA4E60009440E 16 | 17 | primary 18 | 19 | 20 | 148C623C1DCFA4E60009440E 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile Sample.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile Sample.xcworkspace/xcuserdata/tom.batchelor.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/mobile/iOS/Cars Mobile Sample/Cars Mobile Sample.xcworkspace/xcuserdata/tom.batchelor.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile Sample.xcworkspace/xcuserdata/tom.batchelor.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 20 | 21 | 22 | 24 | 36 | 37 | 38 | 40 | 52 | 53 | 54 | 56 | 68 | 69 | 70 | 72 | 84 | 85 | 86 | 88 | 100 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Cars Mobile Sample 4 | // 5 | // Created by Tom Batchelor on 11/6/16. 6 | // Copyright © 2016 Tom Batchelor. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(_ application: UIApplication) { 28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "size" : "29x29", 15 | "idiom" : "iphone", 16 | "filename" : "Icon-App-29x29@2x.png", 17 | "scale" : "2x" 18 | }, 19 | { 20 | "size" : "29x29", 21 | "idiom" : "iphone", 22 | "filename" : "Icon-App-29x29@3x.png", 23 | "scale" : "3x" 24 | }, 25 | { 26 | "size" : "40x40", 27 | "idiom" : "iphone", 28 | "filename" : "Icon-App-40x40@2x.png", 29 | "scale" : "2x" 30 | }, 31 | { 32 | "size" : "40x40", 33 | "idiom" : "iphone", 34 | "filename" : "Icon-App-60x60@2x.png", 35 | "scale" : "3x" 36 | }, 37 | { 38 | "size" : "60x60", 39 | "idiom" : "iphone", 40 | "filename" : "Icon-App-60x60@2x-1.png", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "size" : "60x60", 45 | "idiom" : "iphone", 46 | "filename" : "Icon-App-60x60@3x.png", 47 | "scale" : "3x" 48 | }, 49 | { 50 | "idiom" : "ipad", 51 | "size" : "20x20", 52 | "scale" : "1x" 53 | }, 54 | { 55 | "idiom" : "ipad", 56 | "size" : "20x20", 57 | "scale" : "2x" 58 | }, 59 | { 60 | "size" : "29x29", 61 | "idiom" : "ipad", 62 | "filename" : "Icon-App-29x29@1x.png", 63 | "scale" : "1x" 64 | }, 65 | { 66 | "size" : "29x29", 67 | "idiom" : "ipad", 68 | "filename" : "Icon-App-29x29@2x-1.png", 69 | "scale" : "2x" 70 | }, 71 | { 72 | "size" : "40x40", 73 | "idiom" : "ipad", 74 | "filename" : "Icon-App-40x40@1x.png", 75 | "scale" : "1x" 76 | }, 77 | { 78 | "size" : "40x40", 79 | "idiom" : "ipad", 80 | "filename" : "Icon-App-40x40@2x-1.png", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "size" : "76x76", 85 | "idiom" : "ipad", 86 | "filename" : "Icon-App-76x76@1x.png", 87 | "scale" : "1x" 88 | }, 89 | { 90 | "size" : "76x76", 91 | "idiom" : "ipad", 92 | "filename" : "Icon-App-76x76@2x.png", 93 | "scale" : "2x" 94 | }, 95 | { 96 | "size" : "83.5x83.5", 97 | "idiom" : "ipad", 98 | "filename" : "Icon-App-76x76@2x-1.png", 99 | "scale" : "2x" 100 | }, 101 | { 102 | "idiom" : "ios-marketing", 103 | "size" : "1024x1024", 104 | "scale" : "1x" 105 | } 106 | ], 107 | "info" : { 108 | "version" : 1, 109 | "author" : "xcode" 110 | } 111 | } -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x-1.png -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x-1.png -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x-1.png -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x-1.png -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/Assets.xcassets/sample.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "PinkTeapot.jpeg", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/Assets.xcassets/sample.imageset/PinkTeapot.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/Assets.xcassets/sample.imageset/PinkTeapot.jpeg -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/Car.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Car.swift 3 | // Cars Mobile Sample 4 | // 5 | // Created by Tom Batchelor on 11/13/16. 6 | // Copyright © 2016 Tom Batchelor. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | class Car { 13 | 14 | var carId: Int 15 | var name: String 16 | var model: String 17 | var manufacturer: Manufacturer? 18 | var colour: String? 19 | var year: Int? 20 | var price: Float64? 21 | var summary: String? 22 | var description: String? 23 | var picture: UIImage? 24 | 25 | init?(carId: Int, name: String, model: String) { 26 | self.carId = carId 27 | self.name = name 28 | self.model = model 29 | 30 | if carId < 0 || name.isEmpty || model.isEmpty { 31 | return nil 32 | } 33 | } 34 | 35 | func getCarAsDict() -> [String: AnyObject] { 36 | var dict = [String: AnyObject]() 37 | dict["name"] = self.name as AnyObject; 38 | dict["model"] = self.model as AnyObject; 39 | dict["manufacturerId"] = self.manufacturer!.manufacturerId as AnyObject; 40 | dict["colour"] = self.colour as AnyObject; 41 | dict["year"] = self.year as AnyObject; 42 | dict["price"] = self.price as AnyObject; 43 | dict["summary"] = self.summary as AnyObject; 44 | dict["description"] = self.description as AnyObject; 45 | dict["wheelSize"] = 0 as AnyObject; 46 | dict["tyreSize"] = 0 as AnyObject; 47 | dict["photo"] = "0" as AnyObject; 48 | dict["manual"] = false as AnyObject; 49 | return dict 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/CarTableViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CarTableViewCell.swift 3 | // Cars Mobile Sample 4 | // 5 | // Created by Tom Batchelor on 11/13/16. 6 | // Copyright © 2016 Tom Batchelor. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class CarTableViewCell: UITableViewCell { 12 | 13 | //MARK - Properties 14 | @IBOutlet weak var carShortDescription: UILabel! 15 | @IBOutlet weak var manufacturerLogo: UIImageView! 16 | @IBOutlet weak var carPicture: UIImageView! 17 | 18 | 19 | override func awakeFromNib() { 20 | super.awakeFromNib() 21 | // Initialization code 22 | } 23 | 24 | override func setSelected(_ selected: Bool, animated: Bool) { 25 | super.setSelected(selected, animated: animated) 26 | 27 | // Configure the view for the selected state 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/CarTableViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CarTableViewController.swift 3 | // Cars Mobile Sample 4 | // 5 | // Created by Tom Batchelor on 11/13/16. 6 | // Copyright © 2016 Tom Batchelor. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class CarTableViewController: UITableViewController { 12 | 13 | var cars = [Car]() 14 | var manufacturer:Manufacturer? 15 | let carDetailSegue = "CarDetailSegue" 16 | 17 | 18 | 19 | override func viewDidLoad() { 20 | super.viewDidLoad() 21 | 22 | RestApiManager.sharedInstance.getCarsByManufacturer(manufacturer!, onCompletion: {cars in 23 | self.cars = cars 24 | DispatchQueue.main.async(execute: { 25 | self.tableView.reloadData() 26 | return 27 | }) 28 | }) 29 | 30 | // Uncomment the following line to preserve selection between presentations 31 | // self.clearsSelectionOnViewWillAppear = false 32 | 33 | // Uncomment the following line to display an Edit button in the navigation bar for this view controller. 34 | // self.navigationItem.rightBarButtonItem = self.editButtonItem() 35 | } 36 | 37 | override func didReceiveMemoryWarning() { 38 | super.didReceiveMemoryWarning() 39 | // Dispose of any resources that can be recreated. 40 | } 41 | 42 | // MARK: - Table view data source 43 | 44 | override func numberOfSections(in tableView: UITableView) -> Int { 45 | return 1 46 | } 47 | 48 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 49 | return cars.count 50 | } 51 | 52 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 53 | let cellIdentifier = "CarTableViewCell" 54 | let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! CarTableViewCell 55 | let car = cars[indexPath.row] 56 | 57 | // Configure the cell 58 | cell.carShortDescription.text = car.name + " - " + car.model 59 | cell.manufacturerLogo.image = car.manufacturer!.logo 60 | cell.carPicture.image = car.picture! 61 | 62 | return cell 63 | } 64 | 65 | // Mark - Actions 66 | 67 | @IBAction func windBackToManufacturers(_ sender: AnyObject) { 68 | dismiss(animated: true, completion: nil) 69 | } 70 | 71 | /* 72 | // Override to support conditional editing of the table view. 73 | override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool { 74 | // Return false if you do not want the specified item to be editable. 75 | return true 76 | } 77 | */ 78 | 79 | /* 80 | // Override to support editing the table view. 81 | override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) { 82 | if editingStyle == .Delete { 83 | // Delete the row from the data source 84 | tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade) 85 | } else if editingStyle == .Insert { 86 | // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view 87 | } 88 | } 89 | */ 90 | 91 | /* 92 | // Override to support rearranging the table view. 93 | override func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) { 94 | 95 | } 96 | */ 97 | 98 | /* 99 | // Override to support conditional rearranging of the table view. 100 | override func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool { 101 | // Return false if you do not want the item to be re-orderable. 102 | return true 103 | } 104 | */ 105 | 106 | // MARK: - Navigation 107 | 108 | // In a storyboard-based application, you will often want to do a little preparation before navigation 109 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 110 | if segue.identifier == carDetailSegue, 111 | let destination = segue.destination as? CarViewController, 112 | let carIndex = tableView.indexPathForSelectedRow?.row { 113 | destination.car = cars[carIndex] 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/CarViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CarViewController.swift 3 | // Cars Mobile Sample 4 | // 5 | // Created by Tom Batchelor on 11/14/16. 6 | // Copyright © 2016 Tom Batchelor. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class CarViewController: UIViewController { 12 | 13 | @IBOutlet weak var carImage: UIImageView! 14 | @IBOutlet weak var carName: UILabel! 15 | @IBOutlet weak var carModel: UILabel! 16 | @IBOutlet weak var carColour: UILabel! 17 | @IBOutlet weak var carYear: UILabel! 18 | @IBOutlet weak var carPrice: UILabel! 19 | @IBOutlet weak var carSummary: UILabel! 20 | @IBOutlet weak var carDescription: UILabel! 21 | 22 | 23 | var car:Car? 24 | 25 | override func viewDidLoad() { 26 | super.viewDidLoad() 27 | 28 | // Do any additional setup after loading the view. 29 | carImage.image = car?.picture 30 | carName.text = car?.name 31 | carModel.text = car?.model 32 | carColour.text = car?.colour 33 | if let year = car?.year { 34 | carYear.text = String(year) 35 | } 36 | if let price = car?.price { 37 | carPrice.text = String(price) 38 | } 39 | carSummary.text = car?.summary 40 | carDescription.text = car?.description 41 | } 42 | 43 | override func didReceiveMemoryWarning() { 44 | super.didReceiveMemoryWarning() 45 | // Dispose of any resources that can be recreated. 46 | } 47 | 48 | 49 | /* 50 | // MARK: - Navigation 51 | 52 | // In a storyboard-based application, you will often want to do a little preparation before navigation 53 | override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 54 | // Get the new view controller using segue.destinationViewController. 55 | // Pass the selected object to the new view controller. 56 | } 57 | */ 58 | 59 | } 60 | -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/HomeViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Cars Mobile Sample 4 | // 5 | // Created by Tom Batchelor on 11/6/16. 6 | // Copyright © 2016 Tom Batchelor. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class HomeViewController: UIViewController { 12 | 13 | @IBOutlet weak var userLabel: UILabel! 14 | 15 | override func viewDidLoad() { 16 | super.viewDidLoad() 17 | // Do any additional setup after loading the view, typically from a nib. 18 | } 19 | 20 | override func viewWillAppear(_ animated: Bool) { 21 | RestApiManager.sharedInstance.getUser({user in 22 | if (user != nil) { 23 | self.userLabel.text = user!.username 24 | } else { 25 | self.userLabel.text = "Anonymous" 26 | } 27 | }) 28 | } 29 | override func didReceiveMemoryWarning() { 30 | super.didReceiveMemoryWarning() 31 | // Dispose of any resources that can be recreated. 32 | } 33 | 34 | // MARK: Actions 35 | 36 | @IBAction func logout(_ sender: AnyObject) { 37 | RestApiManager.sharedInstance.logoutUser() 38 | } 39 | 40 | } 41 | 42 | -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | NSAppTransportSecurity 47 | 48 | NSExceptionDomains 49 | 50 | localhost - 2 51 | 52 | NSIncludesSubdomains 53 | 54 | NSTemporaryExceptionAllowsInsecureHTTPLoads 55 | 56 | NSTemporaryExceptionMinimumTLSVersion 57 | TLSv1.1 58 | 59 | localhost 60 | 61 | NSIncludesSubdomains 62 | 63 | NSTemporaryExceptionAllowsInsecureHTTPLoads 64 | 65 | NSTemporaryExceptionMinimumTLSVersion 66 | TLSv1.1 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/LoginViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LoginViewController.swift 3 | // Cars Mobile Sample 4 | // 5 | // Created by Tom Batchelor on 12/27/16. 6 | // Copyright © 2016 Tom Batchelor. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class LoginViewController: UIViewController { 12 | 13 | 14 | @IBOutlet weak var username: UITextField! 15 | @IBOutlet weak var password: UITextField! 16 | 17 | override func viewDidLoad() { 18 | super.viewDidLoad() 19 | 20 | // Do any additional setup after loading the view. 21 | } 22 | 23 | override func didReceiveMemoryWarning() { 24 | super.didReceiveMemoryWarning() 25 | // Dispose of any resources that can be recreated. 26 | } 27 | 28 | // MARK: Actions 29 | 30 | @IBAction func login(_ sender: AnyObject) { 31 | let user = User(username: username.text!) 32 | user.password = password.text! 33 | 34 | RestApiManager.sharedInstance.loginUser(user, onCompletion: {user in 35 | }) 36 | self.dismiss(animated: false, completion: nil) 37 | } 38 | 39 | /* 40 | // MARK: - Navigation 41 | 42 | // In a storyboard-based application, you will often want to do a little preparation before navigation 43 | override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 44 | // Get the new view controller using segue.destinationViewController. 45 | // Pass the selected object to the new view controller. 46 | } 47 | */ 48 | 49 | } 50 | -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/Manufacturer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Manufacturer.swift 3 | // Cars Mobile Sample 4 | // 5 | // Created by Tom Batchelor on 11/7/16. 6 | // Copyright © 2016 Tom Batchelor. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | class Manufacturer { 13 | 14 | var manufacturerId:Int 15 | var name: String 16 | var country: String? 17 | var web: String? 18 | var email: String? 19 | var logo: UIImage? 20 | var engineId: Int? 21 | 22 | init?(manufacturerId: Int, name: String, web: String, email: String) { 23 | self.manufacturerId = manufacturerId 24 | self.name = name 25 | self.web = web 26 | self.email = email 27 | 28 | if manufacturerId < 0 || name.isEmpty { // || logo.images?.count < 0 { 29 | return nil 30 | } 31 | } 32 | 33 | init?(manufacturerId: Int, name: String, country: String, web: String, email: String, logo: UIImage, engineId: Int?) { 34 | self.manufacturerId = manufacturerId 35 | self.name = name 36 | self.country = country 37 | self.web = web 38 | self.email = email 39 | self.logo = logo 40 | self.engineId = engineId 41 | 42 | if manufacturerId < 0 || name.isEmpty { // || logo.images?.count < 0 { 43 | return nil 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/ManufacturerTableViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ManufacturerTableViewCell.swift 3 | // Cars Mobile Sample 4 | // 5 | // Created by Tom Batchelor on 11/7/16. 6 | // Copyright © 2016 Tom Batchelor. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ManufacturerTableViewCell: UITableViewCell { 12 | 13 | // MARK: Properties 14 | @IBOutlet weak var manuName: UILabel! 15 | @IBOutlet weak var manuLogo: UIImageView! 16 | 17 | 18 | override func awakeFromNib() { 19 | super.awakeFromNib() 20 | // Initialization code 21 | } 22 | 23 | override func setSelected(_ selected: Bool, animated: Bool) { 24 | super.setSelected(selected, animated: animated) 25 | 26 | // Configure the view for the selected state 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/ManufacturerTableViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ManufacturerTableViewController.swift 3 | // Cars Mobile Sample 4 | // 5 | // Created by Tom Batchelor on 11/7/16. 6 | // Copyright © 2016 Tom Batchelor. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ManufacturerTableViewController: UITableViewController { 12 | 13 | // MARK: Properties 14 | 15 | var manufacturers = [Manufacturer]() 16 | let carsByManufacturerSegue = "CarsByManufacturerSegue" 17 | 18 | override func viewDidLoad() { 19 | super.viewDidLoad() 20 | 21 | RestApiManager.sharedInstance.getManufacturers({manufacturers in 22 | self.manufacturers = manufacturers 23 | DispatchQueue.main.async(execute: { 24 | self.tableView.reloadData() 25 | return 26 | }) 27 | }) 28 | 29 | // Uncomment the following line to preserve selection between presentations 30 | // self.clearsSelectionOnViewWillAppear = false 31 | } 32 | 33 | override func didReceiveMemoryWarning() { 34 | super.didReceiveMemoryWarning() 35 | // Dispose of any resources that can be recreated. 36 | } 37 | 38 | // MARK: - Table view data source 39 | 40 | override func numberOfSections(in tableView: UITableView) -> Int { 41 | return 1 42 | } 43 | 44 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 45 | return manufacturers.count 46 | } 47 | 48 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 49 | let cellIdentifier = "ManufacturerTableViewCell" 50 | let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! ManufacturerTableViewCell 51 | let manufacturer = manufacturers[indexPath.row] 52 | 53 | // Configure the cell... 54 | cell.manuName.text = manufacturer.name 55 | cell.manuLogo.image = manufacturer.logo 56 | return cell 57 | } 58 | 59 | // MARK - Actions 60 | 61 | @IBAction func unwindToMainMenu(_ sender: AnyObject) { 62 | dismiss(animated: true, completion: nil) 63 | } 64 | 65 | /* 66 | // Override to support conditional editing of the table view. 67 | override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool { 68 | // Return false if you do not want the specified item to be editable. 69 | return true 70 | } 71 | */ 72 | 73 | /* 74 | // Override to support editing the table view. 75 | override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) { 76 | if editingStyle == .Delete { 77 | // Delete the row from the data source 78 | tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade) 79 | } else if editingStyle == .Insert { 80 | // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view 81 | } 82 | } 83 | */ 84 | 85 | /* 86 | // Override to support rearranging the table view. 87 | override func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) { 88 | 89 | } 90 | */ 91 | 92 | /* 93 | // Override to support conditional rearranging of the table view. 94 | override func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool { 95 | // Return false if you do not want the item to be re-orderable. 96 | return true 97 | } 98 | */ 99 | 100 | 101 | // MARK: - Navigation 102 | 103 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 104 | if segue.identifier == carsByManufacturerSegue, 105 | let destination = segue.destination as? CarTableViewController, 106 | let manufacturerIndex = tableView.indexPathForSelectedRow?.row { 107 | destination.manufacturer = manufacturers[manufacturerIndex] 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/SearchViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SearchViewController.swift 3 | // Cars Mobile Sample 4 | // 5 | // Created by Tom Batchelor on 12/13/16. 6 | // Copyright © 2016 Tom Batchelor. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class SearchViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { 12 | 13 | var cars = [Car](); 14 | @IBOutlet weak var tableView: UITableView! 15 | let carDetailSegue = "CarDetailSegue" 16 | 17 | override func viewDidLoad() { 18 | super.viewDidLoad() 19 | 20 | // Do any additional setup after loading the view. 21 | //self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "CarTableViewCell") 22 | 23 | tableView.delegate = self 24 | tableView.dataSource = self 25 | } 26 | 27 | override func didReceiveMemoryWarning() { 28 | super.didReceiveMemoryWarning() 29 | // Dispose of any resources that can be recreated. 30 | } 31 | 32 | 33 | // MARK: Actions 34 | 35 | @IBAction func searchField(_ sender: UITextField) { 36 | print(sender.text!) 37 | RestApiManager.sharedInstance.getCarsBySearch(sender.text!, onCompletion: {cars in 38 | self.cars = cars 39 | DispatchQueue.main.async(execute: { 40 | self.tableView.reloadData() 41 | return 42 | }) 43 | }) 44 | } 45 | // MARK - TableView Stuff 46 | 47 | func numberOfSections(in tableView: UITableView) -> Int { 48 | return 1 49 | } 50 | 51 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 52 | return cars.count 53 | } 54 | 55 | 56 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 57 | let cellIdentifier = "CarTableViewCell" 58 | let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! CarTableViewCell 59 | print(indexPath.row) 60 | let car = cars[indexPath.row] 61 | 62 | // Configure the cell 63 | cell.carShortDescription.text = car.name + " - " + car.model 64 | cell.manufacturerLogo.image = car.manufacturer!.logo 65 | cell.carPicture.image = car.picture! 66 | 67 | return cell 68 | } 69 | /* 70 | // MARK: - Navigation 71 | 72 | */ 73 | // In a storyboard-based application, you will often want to do a little preparation before navigation 74 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 75 | if segue.identifier == carDetailSegue, 76 | let destination = segue.destination as? CarViewController, 77 | let carIndex = tableView.indexPathForSelectedRow?.row { 78 | destination.car = cars[carIndex] 79 | } 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/SellViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SellViewController.swift 3 | // Cars Mobile Sample 4 | // 5 | // Created by Tom Batchelor on 12/27/16. 6 | // Copyright © 2016 Tom Batchelor. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class SellViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate { 12 | 13 | var manufacturers = [Manufacturer]() 14 | 15 | @IBOutlet weak var manufacturerPicker: UIPickerView! 16 | @IBOutlet weak var carModel: UITextField! 17 | @IBOutlet weak var carName: UITextField! 18 | @IBOutlet weak var carColour: UITextField! 19 | @IBOutlet weak var carYear: UITextField! 20 | @IBOutlet weak var carPrice: UITextField! 21 | @IBOutlet weak var carSummary: UITextField! 22 | @IBOutlet weak var carDescription: UITextField! 23 | 24 | override func viewDidLoad() { 25 | super.viewDidLoad() 26 | 27 | // Do any additional setup after loading the view. 28 | self.manufacturerPicker.dataSource = self 29 | self.manufacturerPicker.delegate = self 30 | 31 | RestApiManager.sharedInstance.getManufacturers({manufacturers in 32 | self.manufacturers = manufacturers 33 | DispatchQueue.main.async(execute: { 34 | self.manufacturerPicker.reloadAllComponents() 35 | return 36 | }) 37 | }) 38 | } 39 | 40 | override func didReceiveMemoryWarning() { 41 | super.didReceiveMemoryWarning() 42 | // Dispose of any resources that can be recreated. 43 | } 44 | 45 | // Mark: Picker 46 | func numberOfComponents(in pickerView: UIPickerView) -> Int { 47 | return 1 48 | } 49 | 50 | func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { 51 | return manufacturers.count 52 | } 53 | 54 | func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { 55 | return manufacturers[row].name 56 | } 57 | 58 | // ACTIONS 59 | 60 | @IBAction func sellCar(_ sender: UIButton) { 61 | let car = Car(carId: 0, name: carName.text!, model: carModel.text!) 62 | car?.manufacturer = manufacturers[manufacturerPicker.selectedRow(inComponent: 0)] 63 | car?.colour = carColour.text! 64 | car?.year = Int(carYear.text!) 65 | car?.price = Float64(carPrice.text!) 66 | car?.summary = carSummary.text! 67 | car?.description = carDescription.text! 68 | RestApiManager.sharedInstance.saveCar(car!, onCompletion: { car in 69 | 70 | }) 71 | } 72 | 73 | /* 74 | // MARK: - Navigation 75 | 76 | // In a storyboard-based application, you will often want to do a little preparation before navigation 77 | override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 78 | // Get the new view controller using segue.destinationViewController. 79 | // Pass the selected object to the new view controller. 80 | } 81 | */ 82 | 83 | } 84 | -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile Sample/User.swift: -------------------------------------------------------------------------------- 1 | // 2 | // User.swift 3 | // Cars Mobile Sample 4 | // 5 | // Created by Tom Batchelor on 12/27/16. 6 | // Copyright © 2016 Tom Batchelor. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | class User { 12 | var username: String 13 | var password: String 14 | 15 | init(username: String) { 16 | self.username = username 17 | password = "" 18 | } 19 | 20 | func getUserAsDict() -> [String: AnyObject] { 21 | var dict = [String: AnyObject]() 22 | dict["username"] = self.username as AnyObject 23 | dict["password"] = self.password as AnyObject 24 | 25 | return dict 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile SampleTests/Cars_Mobile_SampleTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Cars_Mobile_SampleTests.swift 3 | // Cars Mobile SampleTests 4 | // 5 | // Created by Tom Batchelor on 11/6/16. 6 | // Copyright © 2016 Tom Batchelor. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import Cars_Mobile_Sample 11 | 12 | class Cars_Mobile_SampleTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | // Use XCTAssert and related functions to verify your tests produce the correct results. 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measure { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /mobile/iOS/Cars Mobile Sample/Cars Mobile SampleTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /mobile/iOS/README.md: -------------------------------------------------------------------------------- 1 | # Cars Sample App iOS 2 | 3 | This is a simple iOS client which has been built to access the REST services the web app provides. This is built using Swift 4.0, iOS SDK 12.1 and XCode 10.1 4 | 5 | ## Security Settings 6 | 7 | iOS requires that a app explicitly states URLs where it's permitted to make plain text HTTP connections. This is currently configured to allow connections to "localhost" which is fine if you are running in the Simulator to talk back to locally running instance of Cars_Sample_App. 8 | 9 | To add additional hosts to this: 10 | 11 | 1. Open the project in XCode 12 | 1. Locate the Info.plist file in The Project Navigator 13 | 1. Navigate through the tree 14 | 1. App Transport Secuirty Settings 15 | 1. Exception Domains 16 | 1. Here you will see a entry for "localhost" 17 | 1. Copy and Paste this to create a new entry 18 | 1. You should now have "localhost - 2". Update this with the new domain 19 | 1. Rebuild the app 20 | 21 | You can also just update the localhost entry alone if you don't want to have that any more 22 | -------------------------------------------------------------------------------- /nb-configuration.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | 16 | 1.7-web 17 | Tomcat 18 | ide 19 | 20 | 21 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | com.tombatchelor 6 | Cars_Sample_App 7 | 2.0-SNAPSHOT 8 | war 9 | 10 | Cars_Sample_App 11 | 12 | 13 | ${project.build.directory}/endorsed 14 | UTF-8 15 | 16 | 17 | 18 | 19 | mysql 20 | mysql-connector-java 21 | 5.1.38 22 | 23 | 24 | 25 | javax.ws.rs 26 | javax.ws.rs-api 27 | 2.0.1 28 | 29 | 30 | 31 | org.glassfish.jersey.core 32 | jersey-client 33 | 2.23 34 | 35 | 36 | org.glassfish.jersey.core 37 | jersey-server 38 | 2.23 39 | 40 | 41 | org.glassfish.jersey.containers 42 | jersey-container-servlet-core 43 | 2.23 44 | 45 | 46 | org.json 47 | json 48 | 20160212 49 | 50 | 51 | org.glassfish.jersey.media 52 | jersey-media-json-jackson 53 | 2.23.1 54 | 55 | 56 | javax.servlet 57 | javax.servlet-api 58 | 3.0.1 59 | jar 60 | 61 | 62 | 63 | c3p0 64 | c3p0 65 | 0.9.1 66 | 67 | 68 | 69 | 70 | Cars_Sample_App 71 | 72 | 73 | org.apache.maven.plugins 74 | maven-compiler-plugin 75 | 3.1 76 | 77 | 1.7 78 | 1.7 79 | 80 | ${endorsed.dir} 81 | 82 | 83 | 84 | 85 | org.apache.maven.plugins 86 | maven-war-plugin 87 | 2.3 88 | 89 | false 90 | 91 | 92 | 93 | org.apache.maven.plugins 94 | maven-dependency-plugin 95 | 2.6 96 | 97 | 98 | validate 99 | 100 | copy 101 | 102 | 103 | ${endorsed.dir} 104 | true 105 | 106 | 107 | javax 108 | javaee-endorsed-api 109 | 7.0 110 | jar 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | org.apache.tomcat.maven 119 | tomcat7-maven-plugin 120 | 2.2 121 | 122 | http://localhost:8080/manager/text 123 | Tomcat 124 | /Cars_Sample_App 125 | 126 | 127 | 128 | 129 | 130 | 131 | -------------------------------------------------------------------------------- /src/main/java/com/supercars/Car.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Created on 31-May-2005 3 | * 4 | * TODO To change the template for this generated file go to 5 | * Window - Preferences - Java - Code Style - Code Templates 6 | */ 7 | package com.supercars; 8 | 9 | /** 10 | * @author v023094 11 | * 12 | * TODO To change the template for this generated type comment go to Window - 13 | * Preferences - Java - Code Style - Code Templates 14 | */ 15 | public class Car { 16 | 17 | private int carId; 18 | private String name; 19 | private String model; 20 | private int manufacturerId; 21 | private String colour; 22 | private int year; 23 | private int price; 24 | private String summary; 25 | private String description; 26 | private int wheelSize; 27 | private int tyreSize; 28 | private boolean isManual; 29 | private String photo; 30 | private Manufacturer manufacturer; 31 | 32 | public String getPhoto() { 33 | return photo; 34 | } 35 | 36 | public void setPhoto(String photo) { 37 | this.photo = photo; 38 | } 39 | 40 | public String getSummary() { 41 | return summary; 42 | } 43 | 44 | public void setSummary(String summary) { 45 | this.summary = summary; 46 | } 47 | 48 | public String getColour() { 49 | return colour; 50 | } 51 | 52 | public void setColour(String colour) { 53 | this.colour = colour; 54 | } 55 | 56 | public String getDescription() { 57 | return description; 58 | } 59 | 60 | public void setDescription(String description) { 61 | this.description = description; 62 | } 63 | 64 | public boolean isManual() { 65 | return isManual; 66 | } 67 | 68 | public void setManual(boolean isManual) { 69 | this.isManual = isManual; 70 | } 71 | 72 | public int getManufacturerId() { 73 | return manufacturerId; 74 | } 75 | 76 | public void setManufacturerId(int manufacturerId) { 77 | this.manufacturerId = manufacturerId; 78 | } 79 | 80 | public String getModel() { 81 | return model; 82 | } 83 | 84 | public void setModel(String model) { 85 | this.model = model; 86 | } 87 | 88 | public String getName() { 89 | return name; 90 | } 91 | 92 | public void setName(String name) { 93 | this.name = name; 94 | } 95 | 96 | public int getPrice() { 97 | return price; 98 | } 99 | 100 | public void setPrice(int price) { 101 | this.price = price; 102 | } 103 | 104 | public int getTyreSize() { 105 | return tyreSize; 106 | } 107 | 108 | public void setTyreSize(int tyreSize) { 109 | this.tyreSize = tyreSize; 110 | } 111 | 112 | public int getWheelSize() { 113 | return wheelSize; 114 | } 115 | 116 | public void setWheelSize(int wheelSize) { 117 | this.wheelSize = wheelSize; 118 | } 119 | 120 | public int getYear() { 121 | return year; 122 | } 123 | 124 | public void setYear(int year) { 125 | this.year = year; 126 | } 127 | 128 | public int getCarId() { 129 | return carId; 130 | } 131 | 132 | public void setCarId(int carId) { 133 | this.carId = carId; 134 | } 135 | 136 | /** 137 | * @return the manufacturer 138 | */ 139 | public Manufacturer getManufacturer() { 140 | return manufacturer; 141 | } 142 | 143 | /** 144 | * @param manufacturer the manufacturer to set 145 | */ 146 | public void setManufacturer(Manufacturer manufacturer) { 147 | this.manufacturer = manufacturer; 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /src/main/java/com/supercars/Engine.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Created on 13-Jun-2005 3 | * 4 | * TODO To change the template for this generated file go to 5 | * Window - Preferences - Java - Code Style - Code Templates 6 | */ 7 | package com.supercars; 8 | 9 | /** 10 | * @author v023094 11 | * 12 | * TODO To change the template for this generated type comment go to 13 | * Window - Preferences - Java - Code Style - Code Templates 14 | */ 15 | public class Engine { 16 | 17 | private long engineId; 18 | private int capacity; 19 | private int bhp; 20 | private String torque; 21 | private int topSpeed; 22 | private float zeroSixty; 23 | 24 | 25 | public int getBhp() { 26 | return bhp; 27 | } 28 | public void setBhp(int bhp) { 29 | this.bhp = bhp; 30 | } 31 | public int getCapacity() { 32 | return capacity; 33 | } 34 | public void setCapacity(int capacity) { 35 | this.capacity = capacity; 36 | } 37 | public long getEngineId() { 38 | return engineId; 39 | } 40 | public void setEngineId(long engineId) { 41 | this.engineId = engineId; 42 | } 43 | public int getTopSpeed() { 44 | return topSpeed; 45 | } 46 | public void setTopSpeed(int topSpeed) { 47 | this.topSpeed = topSpeed; 48 | } 49 | public String getTorque() { 50 | return torque; 51 | } 52 | public void setTorque(String torque) { 53 | this.torque = torque; 54 | } 55 | public float getZeroSixty() { 56 | return zeroSixty; 57 | } 58 | public void setZeroSixty(float zeroSixty) { 59 | this.zeroSixty = zeroSixty; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/com/supercars/Enquiry.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package com.supercars; 7 | 8 | /** 9 | * 10 | * @author tom.batchelor 11 | */ 12 | public class Enquiry { 13 | 14 | private int enquiryId; 15 | private String name = null; 16 | private String email = null; 17 | private String comment = null; 18 | private int carId = 0; 19 | 20 | /** 21 | * @return the enquiryId 22 | */ 23 | public int getEnquiryId() { 24 | return enquiryId; 25 | } 26 | 27 | /** 28 | * @param enquiryId the enquiryId to set 29 | */ 30 | public void setEnquiryId(int enquiryId) { 31 | this.enquiryId = enquiryId; 32 | } 33 | 34 | /** 35 | * @return the name 36 | */ 37 | public String getName() { 38 | return name; 39 | } 40 | 41 | /** 42 | * @param name the name to set 43 | */ 44 | public void setName(String name) { 45 | this.name = name; 46 | } 47 | 48 | /** 49 | * @return the email 50 | */ 51 | public String getEmail() { 52 | return email; 53 | } 54 | 55 | /** 56 | * @param email the email to set 57 | */ 58 | public void setEmail(String email) { 59 | this.email = email; 60 | } 61 | 62 | /** 63 | * @return the comment 64 | */ 65 | public String getComment() { 66 | return comment; 67 | } 68 | 69 | /** 70 | * @param comment the comment to set 71 | */ 72 | public void setComment(String comment) { 73 | this.comment = comment; 74 | } 75 | 76 | /** 77 | * @return the carId 78 | */ 79 | public int getCarId() { 80 | return carId; 81 | } 82 | 83 | /** 84 | * @param carId the carId to set 85 | */ 86 | public void setCarId(int carId) { 87 | this.carId = carId; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/main/java/com/supercars/Leak.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package com.supercars; 7 | 8 | import java.util.LinkedList; 9 | import java.util.List; 10 | 11 | /** 12 | * 13 | * @author tom.batchelor 14 | */ 15 | public class Leak { 16 | public static List leakyCollection = new LinkedList<>(); 17 | 18 | public static void addToCollection(int number, int size) { 19 | for (int i = 0; i < number; i++) { 20 | leakyCollection.add(new byte[size]); 21 | } 22 | } 23 | 24 | public static long getSize() { 25 | long size = 0L; 26 | for(byte[] bytes : leakyCollection) { 27 | size += bytes.length; 28 | } 29 | 30 | return size; 31 | } 32 | 33 | public static void drainCollection() { 34 | leakyCollection = new LinkedList<>(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/supercars/Manufacturer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Created on 31-May-2005 3 | * 4 | * TODO To change the template for this generated file go to 5 | * Window - Preferences - Java - Code Style - Code Templates 6 | */ 7 | package com.supercars; 8 | 9 | /** 10 | * @author v023094 11 | * 12 | * TODO To change the template for this generated type comment go to 13 | * Window - Preferences - Java - Code Style - Code Templates 14 | */ 15 | public class Manufacturer { 16 | 17 | private int manufacturerId; 18 | private String name; 19 | private String country; 20 | private String web; 21 | private String email; 22 | private String logo; 23 | private int engineId; 24 | 25 | 26 | public int getEngineId() { 27 | return engineId; 28 | } 29 | public void setEngineId(int engineId) { 30 | this.engineId = engineId; 31 | } 32 | public String getEmail() { 33 | return email; 34 | } 35 | public void setEmail(String email) { 36 | this.email = email; 37 | } 38 | public String getLogo() { 39 | return logo; 40 | } 41 | public void setLogo(String logo) { 42 | this.logo = logo; 43 | } 44 | public int getManufacturerId() { 45 | return manufacturerId; 46 | } 47 | public void setManufacturerId(int manufacturerId) { 48 | this.manufacturerId = manufacturerId; 49 | } 50 | public String getWeb() { 51 | return web; 52 | } 53 | public void setWeb(String web) { 54 | this.web = web; 55 | } 56 | public String getCountry() { 57 | return country; 58 | } 59 | public void setCountry(String country) { 60 | this.country = country; 61 | } 62 | public String getName() { 63 | return name; 64 | } 65 | public void setName(String name) { 66 | this.name = name; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/com/supercars/XMLException.java: -------------------------------------------------------------------------------- 1 | package com.supercars; 2 | 3 | public class XMLException extends Exception { 4 | private Throwable cause = null; 5 | 6 | public XMLException() { 7 | super(); 8 | } 9 | 10 | public XMLException(String message) { 11 | super(message); 12 | } 13 | 14 | public XMLException(String message, Throwable 15 | cause) { 16 | super(message); 17 | this.cause = cause; 18 | } 19 | 20 | @Override 21 | public Throwable getCause() { 22 | return cause; 23 | } 24 | 25 | @Override 26 | public void printStackTrace(java.io.PrintStream ps) 27 | { 28 | super.printStackTrace(ps); 29 | if (cause != null) { 30 | ps.println("Caused by:"); 31 | cause.printStackTrace(ps); 32 | } 33 | } 34 | 35 | @Override 36 | public void printStackTrace(java.io.PrintWriter pw) 37 | { 38 | super.printStackTrace(pw); 39 | if (cause != null) { 40 | pw.println("Caused by:"); 41 | cause.printStackTrace(pw); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/supercars/dataloader/CarDataLoader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Created on 31-May-2005 3 | * 4 | * TODO To change the template for this generated file go to 5 | * Window - Preferences - Java - Code Style - Code Templates 6 | */ 7 | package com.supercars.dataloader; 8 | 9 | import java.sql.Connection; 10 | import java.sql.PreparedStatement; 11 | import java.sql.ResultSet; 12 | import java.sql.SQLException; 13 | import java.sql.Statement; 14 | import java.util.ArrayList; 15 | import java.util.List; 16 | 17 | import com.supercars.Car; 18 | import com.supercars.Engine; 19 | import com.supercars.XMLException; 20 | import com.supercars.logging.Logger; 21 | 22 | /** 23 | * @author v023094 24 | * 25 | * TODO To change the template for this generated type comment go to Window - 26 | * Preferences - Java - Code Style - Code Templates 27 | */ 28 | public class CarDataLoader { 29 | 30 | Statement statement = null; 31 | ResultSet resultSet = null; 32 | 33 | public void saveCar(Car car) { 34 | try (Connection connection = Constants.getDBConnection()) { 35 | PreparedStatement pstmt = connection.prepareStatement("INSERT INTO CARS(NAME, MODEL, DESCRIPTION, MANUFACTURER_ID, COLOUR, YEAR, PRICE, SUMMARY, PHOTO) SELECT ?, ?, ?, ?, ?, ?, ?, ?, 0"); 36 | pstmt.setString(1, car.getName()); 37 | pstmt.setString(2, car.getModel()); 38 | pstmt.setString(3, car.getDescription()); 39 | pstmt.setInt(4, car.getManufacturerId()); 40 | pstmt.setString(5, car.getColour()); 41 | pstmt.setInt(6, car.getYear()); 42 | pstmt.setFloat(7, car.getPrice()); 43 | pstmt.setString(8, car.getSummary()); 44 | pstmt.execute(); 45 | pstmt.close(); 46 | connection.close(); 47 | throw new XMLException("XML Example Exception Thrown"); 48 | } catch (SQLException | XMLException e) { 49 | Logger.log(e); 50 | } 51 | } 52 | 53 | public Car getCar(int carId) { 54 | 55 | Car car = new Car(); 56 | Engine engine = new Engine(); 57 | try (Connection connection = Constants.getDBConnection()) { 58 | String sql = "SELECT CARS.CAR_ID, NAME, MODEL, SUMMARY, DESCRIPTION, MANUFACTURER_ID, COLOUR, YEAR, PRICE, PHOTO"; 59 | sql += " FROM CARS WHERE CARS.CAR_ID = " + carId; 60 | 61 | //connection = Constants.getDBConnection(); 62 | statement = connection.createStatement(); 63 | resultSet = statement.executeQuery(sql); 64 | resultSet.next(); 65 | // Create Car Object 66 | car.setCarId(resultSet.getInt("CAR_ID")); 67 | car.setName(resultSet.getString("NAME")); 68 | car.setModel(resultSet.getString("MODEL")); 69 | car.setSummary(resultSet.getString("SUMMARY")); 70 | car.setDescription(resultSet.getString("DESCRIPTION")); 71 | car.setManufacturerId(Integer.parseInt(resultSet.getString("MANUFACTURER_ID"))); 72 | car.setColour(resultSet.getString("COLOUR")); 73 | car.setYear(resultSet.getInt("YEAR")); 74 | car.setPrice(resultSet.getInt("PRICE")); 75 | car.setPhoto(resultSet.getString("PHOTO")); 76 | car.setManufacturer(new ManufacturerDataLoader().getManufacturer(car.getManufacturerId())); 77 | 78 | resultSet.close(); 79 | statement.close(); 80 | } catch (Exception e) { 81 | Logger.log(e); 82 | } 83 | 84 | return car; 85 | } 86 | 87 | public List getCarsByManufacturer(int manufacturerId) { 88 | 89 | List cars = new ArrayList(); 90 | Car car; 91 | try (Connection connection = Constants.getDBConnection()) { 92 | String sql = "SELECT CAR_ID, NAME, MODEL, SUMMARY, DESCRIPTION, PRICE, PHOTO FROM CARS WHERE MANUFACTURER_ID = " + manufacturerId; 93 | 94 | statement = connection.createStatement(); 95 | resultSet = statement.executeQuery(sql); 96 | while (resultSet.next()) { 97 | car = new Car(); 98 | car.setCarId(resultSet.getInt("CAR_ID")); 99 | car.setName(resultSet.getString("NAME")); 100 | car.setModel(resultSet.getString("MODEL")); 101 | car.setSummary(resultSet.getString("SUMMARY")); 102 | car.setDescription(resultSet.getString("DESCRIPTION")); 103 | car.setPrice(resultSet.getInt("PRICE")); 104 | car.setPhoto(resultSet.getString("PHOTO")); 105 | cars.add(car); 106 | } 107 | resultSet.close(); 108 | statement.close(); 109 | connection.close(); 110 | } catch (Exception e) { 111 | Logger.log(e); 112 | } 113 | return cars; 114 | } 115 | 116 | public List getCarsBySearch(String query) { 117 | 118 | List cars = new ArrayList(); 119 | Car car; 120 | try (Connection connection = Constants.getDBConnection()) { 121 | String sql = "SELECT CAR_ID, C.NAME, MODEL, SUMMARY, DESCRIPTION, PRICE, PHOTO, M.MANUFACTURER_ID FROM CARS C, MANUFACTURER M WHERE C.MANUFACTURER_ID = M.MANUFACTURER_ID AND (C.NAME LIKE '%" + query + "%' OR C.MODEL LIKE '%" + query + "%' OR M.NAME LIKE '%" + query + "%')"; 122 | 123 | statement = connection.createStatement(); 124 | resultSet = statement.executeQuery(sql); 125 | while (resultSet.next()) { 126 | car = new Car(); 127 | car.setCarId(resultSet.getInt("CAR_ID")); 128 | car.setName(resultSet.getString("NAME")); 129 | car.setModel(resultSet.getString("MODEL")); 130 | car.setSummary(resultSet.getString("SUMMARY")); 131 | car.setDescription(resultSet.getString("DESCRIPTION")); 132 | car.setPrice(resultSet.getInt("PRICE")); 133 | car.setPhoto(resultSet.getString("PHOTO")); 134 | car.setManufacturerId(Integer.parseInt(resultSet.getString("MANUFACTURER_ID"))); 135 | car.setManufacturer(new ManufacturerDataLoader().getManufacturer(car.getManufacturerId())); 136 | cars.add(car); 137 | } 138 | resultSet.close(); 139 | statement.close(); 140 | connection.close(); 141 | } catch (Exception e) { 142 | Logger.log(e); 143 | } 144 | 145 | return cars; 146 | } 147 | 148 | } 149 | -------------------------------------------------------------------------------- /src/main/java/com/supercars/dataloader/Constants.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Constants.java 3 | * 4 | * Created on 31 July 2007, 09:59 5 | * 6 | * To change this template, choose Tools | Template Manager 7 | * and open the template in the editor. 8 | */ 9 | package com.supercars.dataloader; 10 | 11 | import com.supercars.preferences.Preference; 12 | import com.supercars.preferences.PreferenceException; 13 | import com.supercars.preferences.PreferenceManager; 14 | import java.sql.Connection; 15 | import java.sql.ResultSet; 16 | import java.sql.SQLException; 17 | import java.sql.Statement; 18 | import java.util.logging.Level; 19 | import java.util.logging.Logger; 20 | import javax.naming.Context; 21 | import javax.naming.InitialContext; 22 | import javax.naming.NamingException; 23 | import com.mchange.v2.c3p0.ComboPooledDataSource; 24 | import javax.sql.DataSource; 25 | 26 | /** 27 | * 28 | * @author Thomas_Batchelor 29 | */ 30 | public class Constants { 31 | 32 | private static final String PREFERENCES_TABLE = "CREATE TABLE PREFERENCES (\n" 33 | + " PREFERENCE_ID MEDIUMINT NOT NULL AUTO_INCREMENT,\n" 34 | + " NAME VARCHAR(30)," 35 | + " VALUE VARCHAR(50)," 36 | + " DESCRIPTION VARCHAR(100), " 37 | + " HIDDEN INT(1), " 38 | + " PRIMARY KEY (PREFERENCE_ID) " 39 | + ");"; 40 | 41 | static { 42 | try { 43 | int schemaVersion = getSchemaVersion(); 44 | switch (schemaVersion) { 45 | case 1: 46 | upgradeToSchema_2(); 47 | case 2: 48 | upgradeToSchema_3(); 49 | case 3: 50 | upgradeToSchema_4(); 51 | default: 52 | } 53 | } catch (SQLException | PreferenceException ex) { 54 | Logger.getLogger(Constants.class.getName()).log(Level.SEVERE, null, ex); 55 | } 56 | } 57 | 58 | /** 59 | * Creates a new instance of Constants 60 | */ 61 | public Constants() { 62 | } 63 | 64 | public static Connection getDBConnectionStandardPool() { 65 | try { 66 | Context initContext = new InitialContext(); 67 | Context webContext = (Context) initContext.lookup("java:/comp/env"); 68 | DataSource ds = (DataSource) webContext.lookup("jdbc/standard"); 69 | Connection connection = ds.getConnection(); 70 | return connection; 71 | } catch (NamingException | SQLException ex) { 72 | Logger.getLogger(Constants.class.getName()).log(Level.SEVERE, null, ex); 73 | } 74 | 75 | return null; 76 | } 77 | 78 | public static Connection getDBConnection() { 79 | try { 80 | String jndiName = PreferenceManager.getPreference("CONNECTION_POOL").getValue(); 81 | Context initContext = new InitialContext(); 82 | Context webContext = (Context) initContext.lookup("java:/comp/env"); 83 | DataSource ds = (DataSource) webContext.lookup(jndiName); 84 | Connection dbCon = ds.getConnection(); 85 | return dbCon; 86 | } catch (NamingException | SQLException | PreferenceException ex) { 87 | Logger.getLogger(Constants.class.getName()).log(Level.SEVERE, null, ex); 88 | } 89 | 90 | return null; 91 | } 92 | 93 | private static boolean checkPropertiesTableExist() throws SQLException { 94 | boolean exists = false; 95 | try (Connection connection = getDBConnectionStandardPool(); Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery("SELECT table_name FROM information_schema.tables WHERE table_schema = 'supercars' AND table_name = 'PREFERENCES'")) { 96 | exists = resultSet.next(); 97 | } 98 | return exists; 99 | } 100 | 101 | private static int getSchemaVersion() throws SQLException, PreferenceException { 102 | int version = 1; 103 | if (checkPropertiesTableExist()) { 104 | return Integer.parseInt(PreferenceManager.getPreference("SCHEMA_VERSION").getValue()); 105 | } 106 | return version; 107 | } 108 | 109 | private static void updateSchemaVersion(int version) throws SQLException { 110 | try { 111 | PreferenceManager.updatePreference("SCHEMA_VERSION", String.valueOf(version), "Schema Version", true); 112 | } catch (PreferenceException ex) { 113 | Logger.getLogger(Constants.class.getName()).log(Level.SEVERE, null, ex); 114 | } 115 | } 116 | 117 | private static boolean upgradeToSchema_2() throws SQLException { 118 | try (Connection connection = getDBConnectionStandardPool(); Statement statement = connection.createStatement()) { 119 | statement.execute(PREFERENCES_TABLE); 120 | updateSchemaVersion(2); 121 | } 122 | return true; 123 | } 124 | 125 | private static void upgradeToSchema_3() throws PreferenceException, SQLException { 126 | PreferenceManager.updatePreference(new Preference("REST_CLIENT", "Jersey_Sync", "Client to call fueleconomy.gov, either 'Jersey_Sync' or 'Jersey_Async'", false)); 127 | updateSchemaVersion(3); 128 | } 129 | 130 | private static void upgradeToSchema_4() throws PreferenceException, SQLException { 131 | PreferenceManager.updatePreference(new Preference("CONNECTION_POOL", "jdbc/standard", "Connection pool to use, either 'jdbc/standard' or 'jdbc/c3p0'", false)); 132 | updateSchemaVersion(4); 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /src/main/java/com/supercars/dataloader/EnquiryDataLoader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Created on 31-May-2005 3 | * 4 | * TODO To change the template for this generated file go to 5 | * Window - Preferences - Java - Code Style - Code Templates 6 | */ 7 | package com.supercars.dataloader; 8 | 9 | import java.sql.Connection; 10 | import java.sql.PreparedStatement; 11 | import java.sql.ResultSet; 12 | import java.sql.Statement; 13 | import java.util.ArrayList; 14 | import java.util.List; 15 | import com.supercars.Enquiry; 16 | 17 | import com.supercars.logging.Logger; 18 | 19 | /** 20 | * @author v023094 21 | * 22 | * TODO To change the template for this generated type comment go to Window - 23 | * Preferences - Java - Code Style - Code Templates 24 | */ 25 | public class EnquiryDataLoader { 26 | 27 | Statement statement = null; 28 | ResultSet resultSet = null; 29 | 30 | public Enquiry getEnquiry(int enquiryId) { 31 | 32 | Enquiry enquiry = new Enquiry(); 33 | try (Connection connection = Constants.getDBConnection()) { 34 | String sql = "SELECT ENQUIRY_ID, NAME, EMAIL, COMMENT, CAR_ID FROM ENQUIRIES WHERE ENQUIRY_ID = " + enquiryId; 35 | statement = connection.createStatement(); 36 | resultSet = statement.executeQuery(sql); 37 | resultSet.next(); 38 | enquiry.setEnquiryId(resultSet.getInt("ENQUIRY_ID")); 39 | enquiry.setName(resultSet.getString("NAME")); 40 | enquiry.setEmail(resultSet.getString("EMAIL")); 41 | enquiry.setComment(resultSet.getString("COMMENT")); 42 | enquiry.setCarId(resultSet.getInt("carId")); 43 | resultSet.close(); 44 | statement.close(); 45 | connection.close(); 46 | } catch (Exception e) { 47 | Logger.log(e); 48 | } 49 | return enquiry; 50 | } 51 | 52 | public List getEnquirysForCar(int carId) { 53 | 54 | List enquiries = new ArrayList(); 55 | try (Connection connection = Constants.getDBConnection()) { 56 | String sql = "SELECT NAME, EMAIL, COMMENT FROM ENQUIRIES WHERE CAR_ID = " + carId; 57 | statement = connection.createStatement(); 58 | resultSet = statement.executeQuery(sql); 59 | while (resultSet.next()) { 60 | Enquiry enquiry = new Enquiry(); 61 | enquiry.setName(resultSet.getString("NAME")); 62 | enquiry.setEmail(resultSet.getString("EMAIL")); 63 | enquiry.setComment(resultSet.getString("COMMENT")); 64 | enquiries.add(enquiry); 65 | } 66 | resultSet.close(); 67 | statement.close(); 68 | connection.close(); 69 | } catch (Exception e) { 70 | Logger.log(e); 71 | } 72 | return enquiries; 73 | } 74 | 75 | public void saveEnquiry(Enquiry enquiry) { 76 | try (Connection connection = Constants.getDBConnection()) { 77 | PreparedStatement pstmt = connection.prepareStatement("INSERT INTO ENQUIRIES (NAME, EMAIL, COMMENT, CAR_ID, DUMMY) SELECT ?,?,?,?, SLEEP(1)"); 78 | pstmt.setString(1, enquiry.getName()); 79 | pstmt.setString(2, enquiry.getEmail()); 80 | pstmt.setString(3, enquiry.getComment()); 81 | pstmt.setInt(4, enquiry.getCarId()); 82 | pstmt.execute(); 83 | pstmt.close(); 84 | connection.close(); 85 | } catch (Exception e) { 86 | Logger.log(e); 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/main/java/com/supercars/dataloader/ManufacturerDataLoader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Created on 31-May-2005 3 | * 4 | * TODO To change the template for this generated file go to 5 | * Window - Preferences - Java - Code Style - Code Templates 6 | */ 7 | package com.supercars.dataloader; 8 | 9 | import java.sql.Connection; 10 | import java.sql.ResultSet; 11 | import java.sql.Statement; 12 | import java.util.ArrayList; 13 | import java.util.Collection; 14 | import java.util.List; 15 | 16 | import com.supercars.Manufacturer; 17 | import com.supercars.logging.Logger; 18 | 19 | /** 20 | * @author v023094 21 | * 22 | * TODO To change the template for this generated type comment go to 23 | * Window - Preferences - Java - Code Style - Code Templates 24 | */ 25 | public class ManufacturerDataLoader { 26 | 27 | Statement statement = null; 28 | ResultSet resultSet = null; 29 | 30 | public List getManufacturers() { 31 | 32 | Manufacturer manufacturer = null; 33 | List manufacturers = new ArrayList(); 34 | 35 | try (Connection connection = Constants.getDBConnection()) { 36 | String sql = "SELECT MANUFACTURER_ID, NAME, WEB, EMAIL, LOGO FROM MANUFACTURER ORDER BY NAME"; 37 | 38 | statement = connection.createStatement(); 39 | resultSet = statement.executeQuery(sql); 40 | while(resultSet.next()) { 41 | manufacturer = new Manufacturer(); 42 | manufacturer.setManufacturerId(resultSet.getInt("MANUFACTURER_ID")); 43 | manufacturer.setName(resultSet.getString("NAME")); 44 | manufacturer.setWeb(resultSet.getString("WEB")); 45 | manufacturer.setEmail(resultSet.getString("EMAIL")); 46 | manufacturer.setLogo(resultSet.getString("LOGO")); 47 | manufacturers.add(manufacturer); 48 | } 49 | resultSet.close(); 50 | statement.close(); 51 | connection.close(); 52 | } catch(Exception e){ 53 | Logger.log(e); 54 | } 55 | 56 | return manufacturers; 57 | } 58 | 59 | public Manufacturer getManufacturer(int manufacturerId) { 60 | 61 | Manufacturer manufacturer = null; 62 | 63 | try (Connection connection = Constants.getDBConnection()) { 64 | String sql = "SELECT MANUFACTURER_ID, NAME, WEB, EMAIL, LOGO FROM MANUFACTURER WHERE MANUFACTURER_ID = "+manufacturerId; 65 | 66 | statement = connection.createStatement(); 67 | resultSet = statement.executeQuery(sql); 68 | while(resultSet.next()) { 69 | manufacturer = new Manufacturer(); 70 | manufacturer.setManufacturerId(resultSet.getInt("MANUFACTURER_ID")); 71 | manufacturer.setName(resultSet.getString("NAME")); 72 | manufacturer.setWeb(resultSet.getString("WEB")); 73 | manufacturer.setEmail(resultSet.getString("EMAIL")); 74 | manufacturer.setLogo(resultSet.getString("LOGO")); 75 | } 76 | resultSet.close(); 77 | statement.close(); 78 | connection.close(); 79 | } catch(Exception e){ 80 | Logger.log(e); 81 | } 82 | 83 | return manufacturer; 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/com/supercars/externaldata/FuelPrices.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package com.supercars.externaldata; 7 | 8 | import com.supercars.logging.Logger; 9 | import com.supercars.preferences.Preference; 10 | import com.supercars.preferences.PreferenceException; 11 | import com.supercars.preferences.PreferenceManager; 12 | import java.util.concurrent.ExecutionException; 13 | import java.util.concurrent.Future; 14 | import javax.ws.rs.client.Client; 15 | import javax.ws.rs.client.ClientBuilder; 16 | import javax.ws.rs.client.WebTarget; 17 | import javax.ws.rs.core.MediaType; 18 | import javax.xml.bind.annotation.XmlRootElement; 19 | 20 | /** 21 | * 22 | * @author tom.batchelor 23 | */ 24 | @XmlRootElement 25 | public class FuelPrices { 26 | 27 | private double cng; 28 | private double diesel; 29 | private double e85; 30 | private double electric; 31 | private double lpg; 32 | private double midgrade; 33 | private double premium; 34 | private double regular; 35 | 36 | public static FuelPrices getFuelPrices() { 37 | try { 38 | Preference preference = PreferenceManager.getPreference("REST_CLIENT"); 39 | switch (preference.getValue()) { 40 | case "Jersey_Sync": 41 | return getFuelPricesJerseySync(); 42 | case "Jersey_Async": 43 | return getFuelPriceJerseysAsync().get(); 44 | } 45 | } catch (PreferenceException | InterruptedException | ExecutionException ex) { 46 | Logger.log(ex); 47 | } 48 | 49 | return null; 50 | } 51 | 52 | private static FuelPrices getFuelPricesJerseySync() { 53 | Client client = ClientBuilder.newClient(); 54 | WebTarget target = client.target("http://www.fueleconomy.gov/ws/rest/fuelprices"); 55 | return target.request(MediaType.APPLICATION_XML) 56 | .get(FuelPrices.class); 57 | } 58 | 59 | private static Future getFuelPriceJerseysAsync() { 60 | Client client = ClientBuilder.newClient(); 61 | WebTarget target = client.target("http://www.fueleconomy.gov/ws/rest/fuelprices"); 62 | Future response = target.request(MediaType.APPLICATION_XML).async().get(FuelPrices.class); 63 | return response; 64 | } 65 | 66 | /** 67 | * @return the cng 68 | */ 69 | public double getCng() { 70 | return cng; 71 | } 72 | 73 | /** 74 | * @param cng the cng to set 75 | */ 76 | public void setCng(double cng) { 77 | this.cng = cng; 78 | } 79 | 80 | /** 81 | * @return the diesel 82 | */ 83 | public double getDiesel() { 84 | return diesel; 85 | } 86 | 87 | /** 88 | * @param diesel the diesel to set 89 | */ 90 | public void setDiesel(double diesel) { 91 | this.diesel = diesel; 92 | } 93 | 94 | /** 95 | * @return the e85 96 | */ 97 | public double getE85() { 98 | return e85; 99 | } 100 | 101 | /** 102 | * @param e85 the e85 to set 103 | */ 104 | public void setE85(double e85) { 105 | this.e85 = e85; 106 | } 107 | 108 | /** 109 | * @return the electric 110 | */ 111 | public double getElectric() { 112 | return electric; 113 | } 114 | 115 | /** 116 | * @param electric the electric to set 117 | */ 118 | public void setElectric(double electric) { 119 | this.electric = electric; 120 | } 121 | 122 | /** 123 | * @return the lpg 124 | */ 125 | public double getLpg() { 126 | return lpg; 127 | } 128 | 129 | /** 130 | * @param lpg the lpg to set 131 | */ 132 | public void setLpg(double lpg) { 133 | this.lpg = lpg; 134 | } 135 | 136 | /** 137 | * @return the midgrade 138 | */ 139 | public double getMidgrade() { 140 | return midgrade; 141 | } 142 | 143 | /** 144 | * @param midgrade the midgrade to set 145 | */ 146 | public void setMidgrade(double midgrade) { 147 | this.midgrade = midgrade; 148 | } 149 | 150 | /** 151 | * @return the premium 152 | */ 153 | public double getPremium() { 154 | return premium; 155 | } 156 | 157 | /** 158 | * @param premium the premium to set 159 | */ 160 | public void setPremium(double premium) { 161 | this.premium = premium; 162 | } 163 | 164 | /** 165 | * @return the regular 166 | */ 167 | public double getRegular() { 168 | return regular; 169 | } 170 | 171 | /** 172 | * @param regular the regular to set 173 | */ 174 | public void setRegular(double regular) { 175 | this.regular = regular; 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /src/main/java/com/supercars/logging/LogLevel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package com.supercars.logging; 7 | 8 | /** 9 | * 10 | * @author tom.batchelor 11 | */ 12 | public enum LogLevel { 13 | TRACE, DEBUG, INFO, ERROR, FATAL 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/supercars/logging/Logger.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package com.supercars.logging; 7 | 8 | import java.io.PrintStream; 9 | 10 | /** 11 | * 12 | * @author tom.batchelor 13 | */ 14 | public class Logger { 15 | 16 | private static PrintStream outputLocation = System.err; 17 | 18 | public static void setOutputLocation(PrintStream ps) { 19 | outputLocation = ps; 20 | } 21 | 22 | public static void log(Exception e) { 23 | e.printStackTrace(outputLocation); 24 | } 25 | 26 | public static void log(String s, LogLevel level) { 27 | outputLocation.println(s); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/supercars/preferences/Preference.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package com.supercars.preferences; 7 | 8 | /** 9 | * 10 | * @author tom.batchelor 11 | */ 12 | public class Preference { 13 | 14 | private String name; 15 | private String value; 16 | private String description; 17 | private boolean hidden; 18 | 19 | public Preference() { 20 | 21 | } 22 | 23 | public Preference(String name) { 24 | this.name = name; 25 | } 26 | 27 | public Preference(String name, String value, String description, boolean hidden) { 28 | this.name = name; 29 | this.value = value; 30 | this.description = description; 31 | this.hidden = hidden; 32 | } 33 | /** 34 | * @return the name 35 | */ 36 | public String getName() { 37 | return name; 38 | } 39 | 40 | /** 41 | * @param name the name to set 42 | */ 43 | public void setName(String name) { 44 | this.name = name; 45 | } 46 | 47 | /** 48 | * @return the value 49 | */ 50 | public String getValue() { 51 | return value; 52 | } 53 | 54 | /** 55 | * @param value the value to set 56 | */ 57 | public void setValue(String value) { 58 | this.value = value; 59 | } 60 | 61 | /** 62 | * @return the description 63 | */ 64 | public String getDescription() { 65 | return description; 66 | } 67 | 68 | /** 69 | * @param description the description to set 70 | */ 71 | public void setDescription(String description) { 72 | this.description = description; 73 | } 74 | 75 | /** 76 | * @return the hidden 77 | */ 78 | public boolean isHidden() { 79 | return hidden; 80 | } 81 | 82 | /** 83 | * @param hidden the hidden to set 84 | */ 85 | public void setHidden(boolean hidden) { 86 | this.hidden = hidden; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/com/supercars/preferences/PreferenceException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package com.supercars.preferences; 7 | 8 | /** 9 | * 10 | * @author tom.batchelor 11 | */ 12 | public class PreferenceException extends Exception { 13 | 14 | PreferenceException(String string) { 15 | super(string); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/supercars/preferences/PreferenceManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package com.supercars.preferences; 7 | 8 | import static com.supercars.dataloader.Constants.getDBConnectionStandardPool; 9 | import com.supercars.logging.Logger; 10 | import java.sql.Connection; 11 | import java.sql.PreparedStatement; 12 | import java.sql.ResultSet; 13 | import java.sql.SQLException; 14 | import java.util.LinkedList; 15 | import java.util.List; 16 | 17 | /** 18 | * 19 | * @author tom.batchelor 20 | */ 21 | public class PreferenceManager { 22 | 23 | public static Preference getPreference(String name) throws PreferenceException { 24 | Preference preference = new Preference(name); 25 | try { 26 | try (Connection connection = getDBConnectionStandardPool(); PreparedStatement statement = connection.prepareStatement("SELECT VALUE, DESCRIPTION, HIDDEN FROM PREFERENCES WHERE NAME=?")) { 27 | statement.setString(1, name); 28 | try (ResultSet resultSet = statement.executeQuery()) { 29 | if (resultSet.next()) { 30 | preference.setValue(resultSet.getString(1)); 31 | preference.setDescription(resultSet.getString(2)); 32 | preference.setHidden((resultSet.getInt(3) != 0)); 33 | } else { 34 | throw new PreferenceException("No preference found for: " + name); 35 | } 36 | } 37 | } 38 | 39 | return preference; 40 | } catch (SQLException ex) { 41 | Logger.log(ex); 42 | PreferenceException pe = new PreferenceException("DB error getting preference: " + ex.getMessage()); 43 | pe.addSuppressed(ex); 44 | throw pe; 45 | } 46 | } 47 | 48 | public static boolean doesPreferenceExist(String name) throws PreferenceException { 49 | try { 50 | try (Connection connection = getDBConnectionStandardPool()) { 51 | boolean exists; 52 | try (PreparedStatement statement = connection.prepareStatement("SELECT VALUE FROM PREFERENCES WHERE NAME=?")) { 53 | statement.setString(1, name); 54 | try (ResultSet resultSet = statement.executeQuery()) { 55 | exists = resultSet.next(); 56 | } 57 | } 58 | return exists; 59 | } 60 | } catch (SQLException ex) { 61 | Logger.log(ex); 62 | PreferenceException pe = new PreferenceException("DB error getting preference: " + ex.getMessage()); 63 | pe.addSuppressed(ex); 64 | throw pe; 65 | } 66 | } 67 | 68 | public static void updatePreference(String name, String value) throws PreferenceException { 69 | updatePreference(name, value, null); 70 | } 71 | 72 | public static void updatePreference(String name, String value, String description) throws PreferenceException { 73 | updatePreference(name, value, description, false); 74 | } 75 | 76 | public static void updatePreference(String name, String value, String description, boolean hidden) throws PreferenceException { 77 | updatePreference(new Preference(name, value, description, hidden)); 78 | } 79 | 80 | public static void updatePreference(Preference preference) throws PreferenceException { 81 | int hidden = 0; 82 | if (preference.isHidden()) { 83 | hidden = 1; 84 | } 85 | try { 86 | try (Connection connection = getDBConnectionStandardPool()) { 87 | if (doesPreferenceExist(preference.getName())) { 88 | try (PreparedStatement statement = connection.prepareStatement("UPDATE PREFERENCES SET VALUE = ?, DESCRIPTION = ?, HIDDEN = ? WHERE NAME = ?")) { 89 | statement.setString(1, preference.getValue()); 90 | statement.setString(2, preference.getDescription()); 91 | statement.setInt(3, hidden); 92 | statement.setString(4, preference.getName()); 93 | statement.execute(); 94 | } 95 | } else { 96 | try (PreparedStatement statement = connection.prepareStatement("INSERT INTO PREFERENCES (NAME, VALUE, DESCRIPTION, HIDDEN) SELECT ?, ?, ?, ?")) { 97 | statement.setString(1, preference.getName()); 98 | statement.setString(2, preference.getValue()); 99 | statement.setString(3, preference.getDescription()); 100 | statement.setInt(4, hidden); 101 | statement.execute(); 102 | } 103 | } 104 | } 105 | } catch (SQLException ex) { 106 | Logger.log(ex); 107 | PreferenceException pe = new PreferenceException("DB error getting preference: " + ex.getMessage()); 108 | pe.addSuppressed(ex); 109 | throw pe; 110 | } 111 | } 112 | 113 | public static List getAllPreferences(boolean includeHidden) throws PreferenceException { 114 | List preferences = new LinkedList<>(); 115 | try (Connection connection = getDBConnectionStandardPool(); PreparedStatement statement = connection.prepareStatement("SELECT NAME, VALUE, DESCRIPTION, HIDDEN FROM PREFERENCES")) { 116 | ResultSet resultSet = statement.executeQuery(); 117 | while (resultSet.next()) { 118 | Preference preference = new Preference(); 119 | preference.setName(resultSet.getString(1)); 120 | preference.setValue(resultSet.getString(2)); 121 | preference.setDescription(resultSet.getString(3)); 122 | preference.setHidden((resultSet.getInt(4) > 0)); 123 | if (includeHidden || !preference.isHidden()) { 124 | preferences.add(preference); 125 | } 126 | } 127 | } catch (SQLException ex) { 128 | Logger.log(ex); 129 | PreferenceException pe = new PreferenceException("DB error getting all preferences: " + ex.getMessage()); 130 | pe.addSuppressed(ex); 131 | throw pe; 132 | } 133 | 134 | return preferences; 135 | } 136 | 137 | public static void setPreferences(List preferences) throws PreferenceException { 138 | for (Preference preference : preferences) { 139 | updatePreference(preference); 140 | } 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /src/main/java/com/supercars/rest/CarService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package com.supercars.rest; 7 | 8 | import java.util.List; 9 | import javax.ws.rs.Consumes; 10 | import javax.ws.rs.GET; 11 | import javax.ws.rs.POST; 12 | import javax.ws.rs.PUT; 13 | import javax.ws.rs.Path; 14 | import javax.ws.rs.PathParam; 15 | import javax.ws.rs.Produces; 16 | import javax.ws.rs.core.MediaType; 17 | import com.supercars.Car; 18 | import com.supercars.dataloader.CarDataLoader; 19 | 20 | /** 21 | * 22 | * @author tom.batchelor 23 | */ 24 | @Path("/car") 25 | public class CarService { 26 | 27 | @Path("{id}") 28 | @GET 29 | @Produces(MediaType.APPLICATION_JSON) 30 | public Car getCar(@PathParam("id") int id) { 31 | Car car = new CarDataLoader().getCar(id); 32 | 33 | return car; 34 | } 35 | 36 | @Path("/manufacturer/{id}") 37 | @GET 38 | @Produces(MediaType.APPLICATION_JSON) 39 | public List getCarsForManufacturer(@PathParam("id") int id) { 40 | List cars = new CarDataLoader().getCarsByManufacturer(id); 41 | 42 | return cars; 43 | } 44 | 45 | @Path("{query}") 46 | @POST 47 | @Produces(MediaType.APPLICATION_JSON) 48 | public List searchCars(@PathParam("query") String query) { 49 | 50 | List cars = new CarDataLoader().getCarsBySearch(query); 51 | return cars; 52 | } 53 | 54 | @PUT 55 | @Consumes(MediaType.APPLICATION_JSON) 56 | public void addCar(Car car) { 57 | new CarDataLoader().saveCar(car); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/com/supercars/rest/EnquiryService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package com.supercars.rest; 7 | 8 | import java.util.List; 9 | import javax.ws.rs.Consumes; 10 | import javax.ws.rs.GET; 11 | import javax.ws.rs.POST; 12 | import javax.ws.rs.PUT; 13 | import javax.ws.rs.Path; 14 | import javax.ws.rs.PathParam; 15 | import javax.ws.rs.Produces; 16 | import javax.ws.rs.core.MediaType; 17 | import com.supercars.Enquiry; 18 | import com.supercars.dataloader.EnquiryDataLoader; 19 | 20 | /** 21 | * 22 | * @author tom.batchelor 23 | */ 24 | @Path("/enquiry") 25 | public class EnquiryService { 26 | 27 | @Path("{id}") 28 | @GET 29 | @Produces(MediaType.APPLICATION_JSON) 30 | public Enquiry getEnqury(@PathParam("id") int id) { 31 | Enquiry enquiry = new EnquiryDataLoader().getEnquiry(id); 32 | 33 | return enquiry; 34 | } 35 | 36 | @Path("{carId}") 37 | @POST 38 | @Produces(MediaType.APPLICATION_JSON) 39 | public List getEnquiryForCar(@PathParam("carId") int carId) { 40 | List enquiries = new EnquiryDataLoader().getEnquirysForCar(carId); 41 | 42 | return enquiries; 43 | } 44 | 45 | @PUT 46 | @Consumes(MediaType.APPLICATION_JSON) 47 | public void saveEnquiry(Enquiry enquiry) { 48 | new EnquiryDataLoader().saveEnquiry(enquiry); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/supercars/rest/FuelService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package com.supercars.rest; 7 | 8 | import javax.ws.rs.GET; 9 | import javax.ws.rs.Path; 10 | import javax.ws.rs.Produces; 11 | import javax.ws.rs.core.MediaType; 12 | import com.supercars.externaldata.FuelPrices; 13 | import java.util.concurrent.ExecutionException; 14 | import java.util.concurrent.Future; 15 | 16 | /** 17 | * 18 | * @author tom.batchelor 19 | */ 20 | @Path("/fuel") 21 | public class FuelService { 22 | 23 | @GET 24 | @Produces(MediaType.APPLICATION_JSON) 25 | public FuelPrices getFuelPrices() throws InterruptedException, ExecutionException { 26 | return FuelPrices.getFuelPrices(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/supercars/rest/LeakService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package com.supercars.rest; 7 | 8 | import javax.ws.rs.DELETE; 9 | import javax.ws.rs.GET; 10 | import javax.ws.rs.Path; 11 | import javax.ws.rs.PathParam; 12 | import javax.ws.rs.Produces; 13 | import javax.ws.rs.core.MediaType; 14 | import com.supercars.Leak; 15 | 16 | /** 17 | * 18 | * @author tom.batchelor 19 | */ 20 | 21 | @Path("/leak") 22 | public class LeakService { 23 | 24 | @Path("{number}/{size}") 25 | @GET 26 | public void leak(@PathParam("number") int number, @PathParam("size") int size) { 27 | System.out.println(number); 28 | System.out.println(size); 29 | Leak.addToCollection(number, size); 30 | } 31 | 32 | @GET 33 | @Produces(MediaType.TEXT_PLAIN) 34 | public String getSize() { 35 | return Long.toString(Leak.getSize()); 36 | } 37 | 38 | @DELETE 39 | public void drainLeak() { 40 | Leak.drainCollection(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/supercars/rest/ManufacturerService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package com.supercars.rest; 7 | 8 | import java.util.List; 9 | import javax.ws.rs.GET; 10 | import javax.ws.rs.Path; 11 | import javax.ws.rs.PathParam; 12 | import javax.ws.rs.Produces; 13 | import javax.ws.rs.core.MediaType; 14 | import com.supercars.Manufacturer; 15 | import com.supercars.dataloader.ManufacturerDataLoader; 16 | 17 | /** 18 | * 19 | * @author tom.batchelor 20 | */ 21 | @Path("/manufacturer") 22 | public class ManufacturerService { 23 | 24 | @GET 25 | @Produces(MediaType.APPLICATION_JSON) 26 | public List getManufacturers() { 27 | List manufacturers = new ManufacturerDataLoader().getManufacturers(); 28 | 29 | return manufacturers; 30 | } 31 | 32 | @Path("{id}") 33 | @GET 34 | @Produces(MediaType.APPLICATION_JSON) 35 | public Manufacturer getManufacturer(@PathParam("id") int id) { 36 | Manufacturer manufacturer = new ManufacturerDataLoader().getManufacturer(id); 37 | 38 | return manufacturer; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/supercars/rest/PreferenceService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package com.supercars.rest; 7 | 8 | import com.supercars.preferences.Preference; 9 | import com.supercars.preferences.PreferenceException; 10 | import com.supercars.preferences.PreferenceManager; 11 | import com.supercars.logging.Logger; 12 | import java.util.List; 13 | import java.util.logging.Level; 14 | import javax.ws.rs.Consumes; 15 | import javax.ws.rs.GET; 16 | import javax.ws.rs.POST; 17 | import javax.ws.rs.Path; 18 | import javax.ws.rs.Produces; 19 | import javax.ws.rs.core.MediaType; 20 | 21 | /** 22 | * 23 | * @author tom.batchelor 24 | */ 25 | @Path("/preferences") 26 | public class PreferenceService { 27 | 28 | @Path("/all") 29 | @GET 30 | @Produces(MediaType.APPLICATION_JSON) 31 | public List getAllPreferences() { 32 | List preferences = null; 33 | try { 34 | preferences = PreferenceManager.getAllPreferences(false); 35 | } catch (PreferenceException ex) { 36 | Logger.log(ex); 37 | } 38 | 39 | return preferences; 40 | } 41 | 42 | @Path("/all") 43 | @POST 44 | @Consumes(MediaType.APPLICATION_JSON) 45 | public void saveAllPreferences(List preferences) { 46 | try { 47 | PreferenceManager.setPreferences(preferences); 48 | } catch (PreferenceException ex) { 49 | Logger.log(ex); 50 | } 51 | } 52 | 53 | @Path("") 54 | @POST 55 | @Consumes(MediaType.APPLICATION_JSON) 56 | public void savePreference(Preference preference) { 57 | try { 58 | PreferenceManager.updatePreference(preference); 59 | } catch (PreferenceException ex) { 60 | Logger.log(ex); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/com/supercars/rest/UserService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package com.supercars.rest; 7 | 8 | import com.supercars.usermanagement.User; 9 | import com.supercars.usermanagement.UserManager; 10 | import javax.servlet.http.HttpServletRequest; 11 | import javax.servlet.http.HttpSession; 12 | import javax.ws.rs.Consumes; 13 | import javax.ws.rs.GET; 14 | import javax.ws.rs.POST; 15 | import javax.ws.rs.Path; 16 | import javax.ws.rs.Produces; 17 | import javax.ws.rs.core.Context; 18 | import javax.ws.rs.core.MediaType; 19 | 20 | /** 21 | * 22 | * @author tom.batchelor 23 | */ 24 | @Path("/user") 25 | public class UserService { 26 | 27 | @Path("/login") 28 | @POST 29 | @Consumes(MediaType.APPLICATION_JSON) 30 | public boolean login(User user, @Context HttpServletRequest request) { 31 | HttpSession session = request.getSession(); 32 | return UserManager.login(user, session); 33 | } 34 | 35 | @Path("/logout") 36 | @GET 37 | public boolean logout(@Context HttpServletRequest request){ 38 | HttpSession session = request.getSession(); 39 | return UserManager.logout(session); 40 | } 41 | 42 | @GET 43 | @Produces(MediaType.APPLICATION_JSON) 44 | public User getLoggedInUser(@Context HttpServletRequest request) { 45 | HttpSession session = request.getSession(); 46 | return UserManager.getUserForSession(session); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/supercars/usermanagement/User.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package com.supercars.usermanagement; 7 | 8 | /** 9 | * 10 | * @author tom.batchelor 11 | */ 12 | public class User { 13 | 14 | private String username; 15 | private String password; 16 | 17 | public User() { 18 | username = null; 19 | password = null; 20 | } 21 | 22 | protected User (String username, String password) { 23 | this.username = username; 24 | this.password = password; 25 | } 26 | 27 | /** 28 | * @return the username 29 | */ 30 | public String getUsername() { 31 | return username; 32 | } 33 | 34 | /** 35 | * @param username the username to set 36 | */ 37 | public void setUsername(String username) { 38 | this.username = username; 39 | } 40 | 41 | /** 42 | * @return the password 43 | */ 44 | public String getPassword() { 45 | return password; 46 | } 47 | 48 | /** 49 | * @param password the password to set 50 | */ 51 | public void setPassword(String password) { 52 | this.password = password; 53 | } 54 | 55 | public User clone() { 56 | return new User(this.username, this.password); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/com/supercars/usermanagement/UserManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package com.supercars.usermanagement; 7 | 8 | import javax.servlet.http.HttpSession; 9 | 10 | /** 11 | * 12 | * @author tom.batchelor 13 | */ 14 | public class UserManager { 15 | 16 | private static User bob = new User("bob@test.com", "password"); 17 | private static User geoff = new User("geoff@cars.com", "password"); 18 | private static User bill = new User("bill@yahoo.co.uk", "password"); 19 | private static User dave = new User("dave@internet.org", "password"); 20 | 21 | private static User[] users = {bob, geoff, bill, dave}; 22 | 23 | private static final String USER_ATTRIBUTE = "user"; 24 | 25 | public static boolean login(User user, HttpSession session) { 26 | if (user == null || user.getUsername() == null || user.getPassword() == null) { 27 | return false; 28 | } 29 | 30 | String username = user.getUsername(); 31 | String password = user.getPassword(); 32 | for (User u : users) { 33 | if (u.getUsername().equals(username)) { 34 | if (u.getPassword().equals(password)) { 35 | session.setAttribute(USER_ATTRIBUTE, u.clone()); 36 | return true; 37 | } 38 | } 39 | } 40 | 41 | return false; 42 | } 43 | 44 | public static boolean logout(HttpSession session) { 45 | session.setAttribute(USER_ATTRIBUTE, null); 46 | return true; 47 | } 48 | 49 | public static User getUserForSession(HttpSession session) { 50 | User user = (User) session.getAttribute(USER_ATTRIBUTE); 51 | if (user == null) { 52 | user = new User(); 53 | } else { 54 | user = user.clone(); 55 | user.setPassword(null); 56 | } 57 | 58 | return user; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/conf/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | 3 | -------------------------------------------------------------------------------- /src/main/resources/db/mysql.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE supercars; 2 | 3 | connect supercars; 4 | 5 | CREATE TABLE MANUFACTURER ( 6 | MANUFACTURER_ID MEDIUMINT NOT NULL, 7 | NAME VARCHAR(30), 8 | WEB VARCHAR(50), 9 | EMAIL VARCHAR(50), 10 | LOGO VARCHAR(30), 11 | PRIMARY KEY (MANUFACTURER_ID) 12 | ); 13 | 14 | CREATE TABLE CARS ( 15 | CAR_ID MEDIUMINT NOT NULL AUTO_INCREMENT, 16 | NAME VARCHAR(30), 17 | MODEL VARCHAR(30), 18 | DESCRIPTION VARCHAR(200), 19 | MANUFACTURER_ID MEDIUMINT NOT NULL, 20 | COLOUR VARCHAR(20), 21 | YEAR MEDIUMINT, 22 | PRICE FLOAT, 23 | SUMMARY VARCHAR(200), 24 | PHOTO VARCHAR(30), 25 | PRIMARY KEY (CAR_ID) 26 | ); 27 | 28 | CREATE TABLE ENQUIRIES ( 29 | ENQUIRY_ID MEDIUMINT NOT NULL AUTO_INCREMENT, 30 | NAME VARCHAR(50), 31 | EMAIL VARCHAR(50), 32 | COMMENT VARCHAR(200), 33 | CAR_ID MEDIUMINT, 34 | DUMMY MEDIUMINT, 35 | PRIMARY KEY (ENQUIRY_ID) 36 | ); 37 | 38 | INSERT INTO MANUFACTURER (MANUFACTURER_ID, NAME, WEB, EMAIL, LOGO) VALUES 39 | (1, 'Porsche', 'http://www.porsche.com', 'web@porsche.com', 'Porsche.gif'), 40 | (2, 'Ferrari', 'http://www.ferrari.com/en_us/', 'web@ferrari.com','Ferrari.gif'), 41 | (3, 'Aston Martin','http://www.astonmartin.com','web@astonmartin.com','AstonMartin.gif'), 42 | (4, 'BMW', 'http://www.bmw.com/com/en/', 'web@bmw.com', 'Bmw.gif'), 43 | (5, 'Ford', 'http://www.ford.com', 'web@ford.com', 'Ford.gif'), 44 | (6, 'Jaguar', 'http://www.jaguarusa.com/index.html', 'web@jaguarusa.com', 'Jaguar.gif'), 45 | (7, 'Lamborghini', 'http://www.lamborghini.com/en/home/', 'web@lamborghini.com', 'Lamborghini.gif'), 46 | (8, 'Lotus', 'http://www.lotuscars.com', 'web@lotuscars.com', 'Lotus.gif'); 47 | -------------------------------------------------------------------------------- /src/main/webapp/META-INF/context.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 24 | 25 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/jboss-web.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | Super Car Store Application 7 | 8 | 9 | Jersey Web Application 10 | org.glassfish.jersey.servlet.ServletContainer 11 | 12 | jersey.config.server.provider.packages 13 | com.supercars.rest 14 | 15 | 1 16 | 17 | 18 | Jersey Web Application 19 | /public/* 20 | 21 | 22 | 23 | /angular/index.html 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/main/webapp/angular/about.html: -------------------------------------------------------------------------------- 1 | 6 |

7 | About Us
8 | 9 |

10 |

11 | 12 |

13 |

14 | Supercar Trader is published in 13 regional editions. To find details of your local edition, simply click on the links below or use the map to locate your local Supercar Trader magazine. 15 |

16 |

17 | Launched in 2004, Supercar Trader is the biggest selling motoring magazine in Britain and is published across thirteen regional editions. More people buy and read Supercar Trader than any other motoring title and the magazine continues to be the market leader with a circulation of 351,654 (ABC Jan-June 2004) and a readership of 1,800,000 (NRS Jan-Dec 2003). 18 |

19 |

20 | Supercar Trader has positioned itself as the synonymous choice for buying and selling a motor vehicle with the success of the magazine built on the combination of photo-ads, choice and a unique structure of regional publishing, offering the combined advantages of local targeting and comprehensive national coverage. 21 |

22 |

23 | Leak Generation 24 |

25 |

26 | Memory leaks! Under the covers this is a LinkedList of Byte arrays. the form below sets how many arrays and their size to add. 27 |

28 |

29 | Current list size is: {{leakSize}} 30 |

31 |
32 |
33 | Number:
34 | Size:
35 | 36 | 37 |
38 |
39 | -------------------------------------------------------------------------------- /src/main/webapp/angular/alpina.html: -------------------------------------------------------------------------------- 1 |

2 | Alpina
3 | 4 |

5 |

6 | 7 |

8 |

9 | 10 |

11 |

12 | Throughout ALPINA's 40-year history, its automobiles have been known for their notion of exclusivity. 13 | Over this period, BMW ALPINA's have evolved, taking advantage of, and improving upon, the technology 14 | offered at the time - and not just in the pursuit of more power, for improving performance is only one 15 | part of ALPINA's philosophy. The ALPINA customer is an enthusiast who appreciates high technology and 16 | seeks great driving pleasure from his car, yet prefers a car more refined and more practical than today's 17 | sports cars. The BMW ALPINA B10 V8 S is high performance in a most subtle guise. 18 |

19 | -------------------------------------------------------------------------------- /src/main/webapp/angular/amg.html: -------------------------------------------------------------------------------- 1 |

2 | AMG
3 | 4 |

5 |

6 | 7 |

8 |

9 | 10 |

11 |

12 | Inspired by the core values of Mercedes-Benz - like quality, safety, comfort and environmental 13 | protection - Mercedes-AMG GmbH develops and builds high-performance sports cars, options and accessories. 14 | 15 | Development work at Mercedes-AMG is driven by the pursuit of performance, sporting prowess and 16 | individuality. The dynamism and sporty character of these fascinating and unique vehicles catapult 17 | them into "pole position" in their respective Mercedes-Benz model ranges. 18 |

-------------------------------------------------------------------------------- /src/main/webapp/angular/car.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 28 | 29 | 30 | 33 | 34 | 35 | 36 | 43 | 44 | 45 | 47 | 48 |
9 |

10 | 11 | 12 |  {{car.manufacturer.name}} - {{car.model}} 13 | 14 |

15 |

16 | Performance Summary: 17 |
18 |

19 |

Name: {{car.name}}
20 | Model: {{car.model}}
21 | Summary: {{car.summary}}
22 | Description: {{car.description}}
23 | Price: £{{car.price}}
24 | Colour: {{car.colour}}
25 | Year: {{car.year}} 26 |

27 |
31 | 32 |
37 |

38 | From:{{enquiry.name}}, {{enquiry.email}}
39 | {{enquiry.comment}}
40 | 41 |

42 |
46 |
49 | -------------------------------------------------------------------------------- /src/main/webapp/angular/cars.html: -------------------------------------------------------------------------------- 1 | 6 |

{{cars.length}} cars found:

7 | 8 | 9 | 12 | 15 | 16 |
10 |

11 |
13 | 14 |
17 | -------------------------------------------------------------------------------- /src/main/webapp/angular/enquire.html: -------------------------------------------------------------------------------- 1 | 6 |

Enquire
7 | 8 |

9 |
10 | 11 | 12 | 15 | 16 | 17 | 20 | 21 | 22 | 25 | 26 | 31 | 32 | 33 | 36 | 37 |
Name:
13 |   14 |
Email:
18 |   19 |
Car:
23 |  {{car.model}} {{car.version}} 24 |
Description:
27 |
28 |
29 |   30 |
34 | 35 |
38 |
39 | 40 | -------------------------------------------------------------------------------- /src/main/webapp/angular/gembella.html: -------------------------------------------------------------------------------- 1 |

2 | Gembella
3 | 4 |

5 |

6 | 7 |

8 |

9 | 10 |

11 |

12 | Porsche customizer Gemballa from Leonberg thrills the hearts of the drivers of the 13 | noble Porsche-SUV by its new high-performance cure, the Gemballa V6 Turbo conversion 14 | kit for the Porsche Cayenne V6, for the Cayenne V6 reaches new dimensions of 15 | performance with the help of the new Gemballa conversion kit. 16 |

17 | -------------------------------------------------------------------------------- /src/main/webapp/angular/home.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
Welcome: {{currentUser.username}}
6 | 7 | 8 | 40 | 58 | 102 | 103 |
9 | 10 | 11 | 18 | 19 | 20 | 26 | 27 | 28 | 37 | 38 |

New to the site?
12 | Registration Benefits
13 | Register here
14 |
Already a customer?
15 | Log in
16 | Log out 17 |

21 |
22 | Quick Search
 
23 |
24 |
25 |
Trade Advertisers
29 | List your stock
30 | Place a Trade Advert
31 | Testimonials
32 | Trader Link
33 | Dealer Directory
34 | Research Centre
35 | Media Centre
36 |
39 |
41 | 42 | 43 | 55 | 56 |


Search the biggest selection of new cars, used cars
44 | Find a local car dealer
45 | Find a local car dealer
46 | UK car dealer directory
47 | Car dealers in your area

48 |
49 |  Research your next car

50 | Find a local car dealerNew Car Roadtests
51 | Used Car Roadtests
52 | Car buying advice 53 | 54 |
57 |
59 | 60 | 61 | 99 | 100 |
62 | 63 | 64 | 69 | 70 | 71 | 72 | 73 | 82 | 83 | 84 | 85 | 86 | 87 | 96 | 97 |
65 | TEST APP PREFERENCES 66 |
Change test app behavior, e.g. DB pool type etc.
67 |
Preferences 68 |
 
74 | Performance Accessories 75 |
Manufacturer OEM parts from:
76 |
AMG 77 |
Alpina 78 |
MazdaSpeed 79 |
Ruf 80 |
Gemballa 81 |
 
 
88 | Latest Fuel Prices
89 |
Regular: {{fuelPrices.regular}} 90 |
Mid Grade: {{fuelPrices.midgrade}} 91 |
Premium: {{fuelPrices.premium}} 92 |
E85: {{fuelPrices.e85}} 93 |
Diesel: {{fuelPrices.diesel}} 94 |
  95 |
98 |
101 |
-------------------------------------------------------------------------------- /src/main/webapp/angular/images/about_car.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/about_car.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/images/aboutus_but.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/aboutus_but.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/images/cars/0.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/cars/0.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/images/cars/0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/cars/0.jpg -------------------------------------------------------------------------------- /src/main/webapp/angular/images/cars/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/cars/10.jpg -------------------------------------------------------------------------------- /src/main/webapp/angular/images/cars/11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/cars/11.jpg -------------------------------------------------------------------------------- /src/main/webapp/angular/images/cars/12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/cars/12.jpg -------------------------------------------------------------------------------- /src/main/webapp/angular/images/cars/13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/cars/13.jpg -------------------------------------------------------------------------------- /src/main/webapp/angular/images/cars/14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/cars/14.jpg -------------------------------------------------------------------------------- /src/main/webapp/angular/images/cars/15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/cars/15.jpg -------------------------------------------------------------------------------- /src/main/webapp/angular/images/cars/16.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/cars/16.jpg -------------------------------------------------------------------------------- /src/main/webapp/angular/images/cars/17.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/cars/17.jpg -------------------------------------------------------------------------------- /src/main/webapp/angular/images/cars/18.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/cars/18.jpg -------------------------------------------------------------------------------- /src/main/webapp/angular/images/cars/19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/cars/19.jpg -------------------------------------------------------------------------------- /src/main/webapp/angular/images/cars/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/cars/2.jpg -------------------------------------------------------------------------------- /src/main/webapp/angular/images/cars/20.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/cars/20.jpg -------------------------------------------------------------------------------- /src/main/webapp/angular/images/cars/21.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/cars/21.jpg -------------------------------------------------------------------------------- /src/main/webapp/angular/images/cars/22.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/cars/22.jpg -------------------------------------------------------------------------------- /src/main/webapp/angular/images/cars/23.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/cars/23.jpg -------------------------------------------------------------------------------- /src/main/webapp/angular/images/cars/24.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/cars/24.jpg -------------------------------------------------------------------------------- /src/main/webapp/angular/images/cars/25.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/cars/25.jpg -------------------------------------------------------------------------------- /src/main/webapp/angular/images/cars/26.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/cars/26.jpg -------------------------------------------------------------------------------- /src/main/webapp/angular/images/cars/27.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/cars/27.jpg -------------------------------------------------------------------------------- /src/main/webapp/angular/images/cars/28.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/cars/28.jpg -------------------------------------------------------------------------------- /src/main/webapp/angular/images/cars/29.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/cars/29.jpg -------------------------------------------------------------------------------- /src/main/webapp/angular/images/cars/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/cars/3.jpg -------------------------------------------------------------------------------- /src/main/webapp/angular/images/cars/30.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/cars/30.jpg -------------------------------------------------------------------------------- /src/main/webapp/angular/images/cars/31.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/cars/31.jpg -------------------------------------------------------------------------------- /src/main/webapp/angular/images/cars/32.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/cars/32.jpg -------------------------------------------------------------------------------- /src/main/webapp/angular/images/cars/33.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/cars/33.jpg -------------------------------------------------------------------------------- /src/main/webapp/angular/images/cars/34.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/cars/34.jpg -------------------------------------------------------------------------------- /src/main/webapp/angular/images/cars/35.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/cars/35.jpg -------------------------------------------------------------------------------- /src/main/webapp/angular/images/cars/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/cars/4.jpg -------------------------------------------------------------------------------- /src/main/webapp/angular/images/cars/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/cars/5.jpg -------------------------------------------------------------------------------- /src/main/webapp/angular/images/cars/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/cars/6.jpg -------------------------------------------------------------------------------- /src/main/webapp/angular/images/cars/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/cars/7.jpg -------------------------------------------------------------------------------- /src/main/webapp/angular/images/cars/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/cars/8.jpg -------------------------------------------------------------------------------- /src/main/webapp/angular/images/cars/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/cars/9.jpg -------------------------------------------------------------------------------- /src/main/webapp/angular/images/enquire_but.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/enquire_but.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/images/enquire_button.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/enquire_button.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/images/homepage_car.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/homepage_car.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/images/insurance_but.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/insurance_but.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/images/insurance_car.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/insurance_car.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/images/line.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/line.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/images/logo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/logo.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/images/magnify.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/magnify.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/images/manufacturers/AstonMartin.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/manufacturers/AstonMartin.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/images/manufacturers/Bmw.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/manufacturers/Bmw.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/images/manufacturers/Ferrari.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/manufacturers/Ferrari.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/images/manufacturers/Ford.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/manufacturers/Ford.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/images/manufacturers/Jaguar.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/manufacturers/Jaguar.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/images/manufacturers/Lamborghini.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/manufacturers/Lamborghini.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/images/manufacturers/Lotus.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/manufacturers/Lotus.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/images/manufacturers/Mazda.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/manufacturers/Mazda.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/images/manufacturers/Mercedes.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/manufacturers/Mercedes.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/images/manufacturers/Porsche.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/manufacturers/Porsche.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/images/manufacturers/Subaru.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/manufacturers/Subaru.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/images/manufacturers/Tvr.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/manufacturers/Tvr.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/images/performance/alpina.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/performance/alpina.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/images/performance/amg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/performance/amg.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/images/performance/b10.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/performance/b10.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/images/performance/gcar.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/performance/gcar.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/images/performance/gembella.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/performance/gembella.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/images/performance/mazda.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/performance/mazda.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/images/performance/rgt.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/performance/rgt.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/images/performance/ruf.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/performance/ruf.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/images/performance/rx8.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/performance/rx8.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/images/performance/slk.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/performance/slk.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/images/pipe.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/pipe.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/images/search_but.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/search_but.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/images/search_button.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/search_button.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/images/sell_but.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/sell_but.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/images/small_search_but.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/small_search_but.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/images/submit_button.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/submit_button.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/images/supercars_but.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/supercars_but.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/images/ukmap.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/ukmap.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/images/view_enquiries_button.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appdynamics/Cars_Sample_App/56ccb134e09fccfa7a7a5ea90e4ebfe0ec43598e/src/main/webapp/angular/images/view_enquiries_button.gif -------------------------------------------------------------------------------- /src/main/webapp/angular/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Supercar Trader 7 | 8 | 9 |
10 | 11 | 12 | 13 | 18 | 19 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 51 |
14 | 15 | 16 | 17 |
21 | 22 | 23 | 24 | 26 | 27 | 28 | 29 | 31 | 32 | 33 | 34 | 36 | 37 | 38 | 39 | 41 | 42 | 43 | 44 | 46 | 47 | 48 | 49 |
52 |
53 |
54 |
55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /src/main/webapp/angular/index.jsp: -------------------------------------------------------------------------------- 1 | <%-- 2 | Document : index.jsp 3 | Created on : Aug 30, 2016, 2:40:33 PM 4 | Author : tom.batchelor 5 | --%> 6 | 7 | <%@page contentType="text/html" pageEncoding="UTF-8"%> 8 | 9 | 10 | 11 | 12 | 13 | Supercar Trader 14 | 15 | 16 |
17 | 18 | 19 | 20 | 25 | 26 | 27 | 32 | 37 | 42 | 47 | 52 | 57 | 58 |
21 | 22 | 23 | 24 |
28 | 29 | 30 | 31 | 33 | 34 | 35 | 36 | 38 | 39 | 40 | 41 | 43 | 44 | 45 | 46 | 48 | 49 | 50 | 51 | 53 | 54 | 55 | 56 |
59 |
60 |
61 |
62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /src/main/webapp/angular/insurance.html: -------------------------------------------------------------------------------- 1 | 6 |

7 | Insurance
8 | 9 |

10 |

11 | 12 |

13 |

14 | Welcome to Supercar Insurance If you're looking for a cheap car insurance quote, you're in the right place. 15 | 16 | Because we're direct on the net our overheads are lower, so we can offer car insurance for less. So if you're looking for cheap car insurance, why not get a quote from us now? 17 | 18 | Our secure quote pages will provide you with a car insurance quote in minutes. This means that paying for your motor insurance online is completely safe. 19 | 20 | And if you want to talk to someone for help or advice about your car insurance quote, there's a national rate number to call. You can even pay for your car insurance over the phone! 21 |

-------------------------------------------------------------------------------- /src/main/webapp/angular/login.html: -------------------------------------------------------------------------------- 1 | 2 | 7 |

Login

8 |

Please enter your credentials:

9 |
10 | 11 | 12 | 16 | 17 | 18 | 22 | 23 | 24 | 27 | 28 |
13 | Username:
  14 | 15 |
19 | Password:
  20 | 21 |
25 | 26 |
29 |
30 | -------------------------------------------------------------------------------- /src/main/webapp/angular/logout.html: -------------------------------------------------------------------------------- 1 | 2 | 7 |

You have been logged out {{currentUser.username}}!

8 | -------------------------------------------------------------------------------- /src/main/webapp/angular/manufacturers.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 13 | 14 |
9 | 12 |
15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/main/webapp/angular/mazdaspeed.html: -------------------------------------------------------------------------------- 1 |

2 | MazdaSpeed
3 | 4 |

5 |

6 | 7 |

8 |

9 | 10 |

11 |

12 | Mazda Motor Corporation announces the release of a limited edition RX-8 Mazdaspeed 13 | Version, which is based on the RX-8 and fitted with Mazdaspeed* brand tune-up parts 14 | for enhanced sports driving performance. The RX-8 Mazdaspeed Version goes on sale 15 | from the middle of February at Mazda Anfini and Mazda dealerships throughout Japan. 16 |

17 |

18 | The new RX-8 Mazdaspeed Version is based on the RX-8 Type S. Mazda has tuned 19 | up the engine using it`s exclusively designed PCM (Powertrain Control Module) 20 | to match the modified intake and exhaust systems of the Mazdaspeed Version, 21 | as well as going through balance adjustments around the eccentric shaft in 22 | response to the lightweight flywheel. Mazda has also tuned up the suspension 23 | and fitted aero parts to further enhance sports driving performance. Those 24 | modifications, carried out under Mazda`s strict quality control system, 25 | provide the RX-8 Mazdaspeed Version with well-balanced performance. 26 |

-------------------------------------------------------------------------------- /src/main/webapp/angular/preferences.html: -------------------------------------------------------------------------------- 1 | 2 | 7 |

Preferences

8 |

Available preferences:

9 | 10 | 11 | 14 | 17 | 20 | 21 | 22 | 25 | 28 | 31 | 32 |
12 | Name 13 | 15 | Value 16 | 18 | Description 19 |
23 | {{preference.name}} 24 | 26 | 27 | 29 | {{preference.description}} 30 |
33 | -------------------------------------------------------------------------------- /src/main/webapp/angular/ruf.html: -------------------------------------------------------------------------------- 1 |

2 | Ruf
3 | 4 |

5 |

6 | 7 |

8 |

9 | 10 |

11 |

12 | The latest year 2003 release from RUF Automobiles. A RUF manufactured sports 13 | version of the 996 Carrera constructed on the basis of a natural aspirated 14 | engine, that has a dry oil sump with a separate oil tank. Built at the RUF 15 | headquarters in Pfaffenhausen. 16 |

17 |

18 | The RUF RGT with an elevated power output of 395 bhp. This normally 19 | aspirated power-plant performance is achieved through equipping motorsports 20 | based engine with four new camshafts, a performance exhaust system, air 21 | filter and a re-mapped engine management system. 22 | -------------------------------------------------------------------------------- /src/main/webapp/angular/search.html: -------------------------------------------------------------------------------- 1 | 6 |

7 | Search
8 | 9 |

10 |

11 | Please enter your search criteria, for example 'Lamborghini', or '911'
12 |
13 |   14 | 15 |
16 |

17 | 18 | 19 | 22 | 28 | 29 |
20 |

21 |
23 | 27 |
30 | -------------------------------------------------------------------------------- /src/main/webapp/angular/sell.html: -------------------------------------------------------------------------------- 1 | 6 |

Sell

7 |

Please enter details of your supercar:

8 |
9 | 10 | 11 | 18 | 19 | 20 | 24 | 25 | 26 | 30 | 31 | 32 | 36 | 37 | 38 | 42 | 43 | 44 | 48 | 49 | 50 | 57 | 58 | 59 | 65 | 66 | 67 | 70 | 71 |
Manufacturer:
12 |   17 |
21 | Model:
  22 | 23 |
27 | Version:
  28 | 29 |
33 | Colour:
  34 | 35 |
39 | Year:
  40 | 41 |
45 | Price:
  46 | 47 |
51 | Summary:
52 | 53 |
54 |
55 | 56 |
Detailed Description:
60 | 61 |
62 |
63 |   64 |
68 | 69 |
72 |
-------------------------------------------------------------------------------- /src/main/webapp/angular/superCars.js: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | 7 | var app = angular.module('superCars', ["ngRoute"]); 8 | app.config(function ($routeProvider) { 9 | $routeProvider.when("/", { 10 | templateUrl: "home.html", 11 | controller: "homeController" 12 | }) 13 | .when("/home", { 14 | templateUrl: "home.html", 15 | controller: "homeController" 16 | }) 17 | .when("/manufacturers", { 18 | templateUrl: "manufacturers.html", 19 | controller: "manufacturerController" 20 | }) 21 | .when("/cars", { 22 | templateUrl: "cars.html", 23 | controller: "carsController" 24 | }) 25 | .when("/car", { 26 | templateUrl: "car.html", 27 | controller: "carController" 28 | }) 29 | .when("/search", { 30 | templateUrl: "search.html", 31 | controller: "searchController" 32 | }) 33 | .when("/sell", { 34 | templateUrl: "sell.html", 35 | controller: "sellController" 36 | }) 37 | .when("/enquire", { 38 | templateUrl: "enquire.html", 39 | controller: "enquireController" 40 | }) 41 | .when("/insurance", { 42 | templateUrl: "insurance.html" 43 | }) 44 | .when("/about", { 45 | templateUrl: "about.html", 46 | controller: "leakController" 47 | }) 48 | .when("/thankyou", { 49 | templateUrl: "thankyou.html" 50 | }) 51 | .when('/alpina', { 52 | templateUrl: "alpina.html" 53 | }) 54 | .when("/amg", { 55 | templateUrl: "amg.html" 56 | }) 57 | .when("/gembella", { 58 | templateUrl: "gembella.html" 59 | }) 60 | .when("/mazdaspeed", { 61 | templateUrl: "mazdaspeed.html" 62 | }) 63 | .when("/ruf", { 64 | templateUrl: "ruf.html" 65 | }) 66 | .when("/login", { 67 | templateUrl: "login.html", 68 | controller: "loginController" 69 | }) 70 | .when("/logout", { 71 | templateUrl: "logout.html", 72 | controller: "logoutController" 73 | }) 74 | .when("/preferences", { 75 | templateUrl: "preferences.html", 76 | controller: "preferencesController" 77 | }); 78 | }); 79 | 80 | app.factory('carsUtils', function () { 81 | var manufacturerId; 82 | var carId; 83 | var searchTerm; 84 | var carsUtilsService = {}; 85 | 86 | carsUtilsService.setCarId = function (id) { 87 | carId = id; 88 | }; 89 | 90 | carsUtilsService.getCarId = function () { 91 | return carId; 92 | }; 93 | 94 | carsUtilsService.setManufacturerId = function (id) { 95 | manufacturerId = id; 96 | }; 97 | 98 | carsUtilsService.getManufacturerId = function () { 99 | return manufacturerId; 100 | }; 101 | 102 | carsUtilsService.setSearchTerm = function (term) { 103 | searchTerm = term; 104 | }; 105 | 106 | carsUtilsService.getSearchTerm = function () { 107 | return searchTerm; 108 | }; 109 | 110 | return carsUtilsService; 111 | }); 112 | -------------------------------------------------------------------------------- /src/main/webapp/angular/superCarsController.js: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | 7 | app.controller('mainController', function ($scope) { 8 | 9 | }); 10 | 11 | app.controller('homeController', function ($scope, $http, $location, carsUtils) { 12 | $http.get("../public/fuel") 13 | .then(function (response) { 14 | $scope.fuelPrices = response.data; 15 | }); 16 | $http.get("../public/user") 17 | .then(function (response) { 18 | $scope.currentUser = response.data; 19 | }); 20 | $scope.search = function () { 21 | carsUtils.setSearchTerm($scope.searchTerm) 22 | $location.path("/search"); 23 | }; 24 | }); 25 | 26 | app.controller('manufacturerController', function ($scope, $http, $location, carsUtils) { 27 | $http.get("../public/manufacturer") 28 | .then(function (response) { 29 | $scope.manufacturers = response.data; 30 | }); 31 | $scope.manufacturerLink = function (manufacturerId) { 32 | carsUtils.setManufacturerId(manufacturerId); 33 | $location.path("/cars"); 34 | }; 35 | }); 36 | 37 | app.controller('carsController', function ($scope, $http, $location, carsUtils) { 38 | $scope.manufacturerId = carsUtils.getManufacturerId(); 39 | $http.get("../public/car/manufacturer/" + $scope.manufacturerId) 40 | .then(function (response) { 41 | $scope.cars = response.data; 42 | }); 43 | $http.get("../public/manufacturer/" + $scope.manufacturerId) 44 | .then(function (response) { 45 | $scope.manufacturer = response.data; 46 | }); 47 | $scope.carLink = function (carId) { 48 | carsUtils.setCarId(carId); 49 | $location.path("/car"); 50 | }; 51 | }); 52 | 53 | app.controller('carController', function ($scope, $http, $location, carsUtils) { 54 | $scope.carId = carsUtils.getCarId(); 55 | $http.get("../public/car/" + $scope.carId) 56 | .then(function (response) { 57 | $scope.car = response.data; 58 | }); 59 | $http.post("../public/enquiry/" + $scope.carId) 60 | .then(function (response) { 61 | $scope.enquiries = response.data; 62 | }); 63 | $scope.enquireLink = function (carId) { 64 | carsUtils.setCarId(carId); 65 | $location.path("/enquire"); 66 | }; 67 | $scope.doError = function () { 68 | adddlert("This will error!"); 69 | }; 70 | }); 71 | 72 | app.controller('searchController', function ($scope, $http, $location, carsUtils) { 73 | if (carsUtils.getSearchTerm() !== null) { 74 | $scope.searchTerm = carsUtils.getSearchTerm(); 75 | } 76 | if ($scope.searchTerm !== null) { 77 | $http.post("../public/car/" + $scope.searchTerm) 78 | .then(function (response) { 79 | $scope.cars = response.data; 80 | }); 81 | } 82 | $scope.search = function () { 83 | $http.post("../public/car/" + $scope.searchTerm) 84 | .then(function (response) { 85 | $scope.cars = response.data; 86 | }); 87 | }; 88 | $scope.carLink = function (carId) { 89 | carsUtils.setCarId(carId); 90 | $location.path("/car"); 91 | }; 92 | }); 93 | 94 | app.controller('sellController', function ($scope, $http, $location) { 95 | $http.get("../public/manufacturer") 96 | .then(function (response) { 97 | $scope.manufacturers = response.data; 98 | }); 99 | $scope.saveCar = function () { 100 | var carJSON = {}; 101 | carJSON["name"] = $scope.name; 102 | carJSON["model"] = $scope.model; 103 | carJSON["manufacturerId"] = parseInt($scope.manufacturer); 104 | carJSON["colour"] = $scope.colour; 105 | carJSON["year"] = $scope.year; 106 | carJSON["price"] = $scope.price; 107 | carJSON["summary"] = $scope.summary; 108 | carJSON["description"] = $scope.description; 109 | carJSON["wheelSize"] = 0; 110 | carJSON["tyreSize"] = 0; 111 | carJSON["photo"] = "0"; 112 | carJSON["manual"] = false; 113 | $http.put("../public/car", carJSON); 114 | $location.path("/thankyou"); 115 | }; 116 | }); 117 | 118 | app.controller('enquireController', function ($scope, $http, $location, carsUtils) { 119 | $scope.carId = carsUtils.getCarId(); 120 | $http.get("../public/car/" + $scope.carId) 121 | .then(function (response) { 122 | $scope.car = response.data; 123 | }); 124 | $scope.saveEnquiry = function () { 125 | enquiryJSON = {}; 126 | enquiryJSON["name"] = $scope.name; 127 | enquiryJSON["email"] = $scope.email; 128 | enquiryJSON["comment"] = $scope.comment; 129 | enquiryJSON["carId"] = $scope.car.carId; 130 | $http.put("../public/enquiry", enquiryJSON); 131 | $location.path("/thankyou"); 132 | }; 133 | }); 134 | 135 | app.controller('leakController', function ($scope, $http) { 136 | $http.get("../public/leak") 137 | .then(function (response) { 138 | $scope.leakSize = response.data; 139 | }); 140 | $scope.addToLeak = function () { 141 | $http.get("../public/leak/" + $scope.number + "/" + $scope.size); 142 | $http.get('../public/leak') 143 | .then(function (response) { 144 | $scope.leakSize = response.data; 145 | }); 146 | }; 147 | $scope.resetLeak = function () { 148 | $http.delete("../public/leak"); 149 | $http.get('../public/leak') 150 | .then(function (response) { 151 | $scope.leakSize = response.data; 152 | }); 153 | }; 154 | }); 155 | 156 | app.controller('loginController', function ($scope, $http, $location) { 157 | $scope.login = function () { 158 | var loginJSON = {}; 159 | loginJSON["username"] = $scope.username; 160 | loginJSON["password"] = $scope.password; 161 | $http.post("../public/user/login", loginJSON); 162 | $location.path("/home"); 163 | }; 164 | }); 165 | 166 | app.controller('logoutController', function ($scope, $http) { 167 | $http.get("../public/user") 168 | .then(function (response) { 169 | $scope.currentUser = response.data; 170 | }); 171 | $http.get("../public/user/logout"); 172 | }); 173 | 174 | app.controller('preferencesController', function ($scope, $http) { 175 | $http.get("../public/preferences/all") 176 | .then(function (response) { 177 | $scope.preferences = response.data; 178 | }); 179 | $scope.savePreferences = function() { 180 | $http.post("../public/preferences/all", $scope.preferences); 181 | $location.path("/preferences"); 182 | } 183 | }); -------------------------------------------------------------------------------- /src/main/webapp/angular/thankyou.html: -------------------------------------------------------------------------------- 1 | 6 | 7 |
8 |

9 | Thank you for your submission! 10 |

11 |
12 | 13 | -------------------------------------------------------------------------------- /src/main/webapp/angular/trader.css: -------------------------------------------------------------------------------- 1 | table 2 | { text-align: center; 3 | font-family: Verdana; 4 | font-weight: normal; 5 | font-size: 11px; 6 | color: #404040; 7 | border: 0px #d79900 solid; 8 | border-collapse: collapse; 9 | border-spacing: 0px; 10 | } 11 | 12 | td.home 13 | { text-align: center; 14 | font-family: Verdana; 15 | font-weight: normal; 16 | font-size: 11px; 17 | color: #404040; 18 | width: 203px; 19 | border: 0px #d79900 solid; 20 | border-collapse: collapse; 21 | border-spacing: 0px; 22 | } 23 | 24 | td.ad 25 | { text-align: center; 26 | font-family: Verdana; 27 | font-weight: normal; 28 | font-size: 11px; 29 | background-color: #E6F1F5; 30 | border: 0px #d79900 solid; 31 | border-collapse: collapse; 32 | border-spacing: 10px; 33 | } 34 | 35 | 36 | img 37 | { text-align: left; 38 | background-color: #fafafa; 39 | border: 0px #d79900 solid; 40 | border-collapse: collapse; 41 | border-spacing: 0px; 42 | } 43 | 44 | tr.grey 45 | {; 46 | background-color: #F9F7F7; 47 | font-family: Verdana; 48 | font-weight: normal; 49 | font-size: 11px; 50 | border: 0px #d79900 solid; 51 | border-collapse: collapse; 52 | border-spacing: 0px; 53 | } 54 | 55 | td 56 | { 57 | text-align: left; 58 | font-family: Verdana; 59 | font-weight: normal; 60 | font-size: 11px; 61 | border: 0px #d79900 solid; 62 | border-collapse: collapse; 63 | border-spacing: 0px; 64 | } 65 | 66 | table.car 67 | { 68 | background-color: #F9F7F7; 69 | font-family: Verdana; 70 | font-weight: normal; 71 | font-size: 11px; 72 | width: 550px; 73 | border: 0px #d79900 solid; 74 | border-collapse: collapse; 75 | border-spacing: 0px; 76 | } 77 | 78 | p.car 79 | { 80 | background-color: #F9F7F7; 81 | font-family: Verdana; 82 | font-weight: normal; 83 | font-size: 11px; 84 | width: 550px; 85 | border: 0px #d79900 solid; 86 | border-collapse: collapse; 87 | border-spacing: 0px; 88 | } 89 | 90 | p 91 | { 92 | background-color: #FFFFFF; 93 | font-family: Verdana; 94 | font-weight: normal; 95 | font-size: 11px; 96 | border: 0px #d79900 solid; 97 | border-collapse: collapse; 98 | border-spacing: 0px; 99 | } 100 | 101 | p.normal 102 | { 103 | background-color: #FFFFFF; 104 | font-family: Verdana; 105 | font-weight: normal; 106 | font-size: 11px; 107 | width:550; 108 | border: 0px #d79900 solid; 109 | border-collapse: collapse; 110 | border-spacing: 0px; 111 | } 112 | 113 | p.summary 114 | { 115 | text-align: left; 116 | background-color: #F9F7F7; 117 | font-family: Verdana; 118 | font-weight: normal; 119 | font-size: 11px; 120 | width: 430px; 121 | border: 0px #d79900 solid; 122 | border-collapse: collapse; 123 | border-spacing: 0px; 124 | } 125 | 126 | p.link 127 | { 128 | text-align: left; 129 | background-color: #F9F7F7; 130 | font-family: Verdana; 131 | font-weight: normal; 132 | font-size: 11px; 133 | width: 430px; 134 | border: 0px #d79900 solid; 135 | border-collapse: collapse; 136 | border-spacing: 0px; 137 | cursor: pointer; 138 | color: blue; 139 | text-decoration: underline; 140 | } 141 | 142 | p.manulink 143 | { 144 | cursor: pointer; 145 | color: blue; 146 | text-decoration: underline; 147 | } -------------------------------------------------------------------------------- /src/main/webapp/angular/tuner.jsp: -------------------------------------------------------------------------------- 1 | <%-- 2 | Document : tuner.jsp 3 | Created on : Oct 13, 2016, 10:21:06 AM 4 | Author : tom.batchelor 5 | --%> 6 | 7 | <%@page contentType="text/html" pageEncoding="UTF-8"%> 8 | <% 9 | String tunerName = request.getParameter("tunerName"); 10 | %> 11 | 12 | 13 | 14 | 15 | <%=tunerName%> 16 | 17 | 18 | 19 | 23 | 24 | 25 | 26 | 31 | 32 |
27 | 28 | 29 | 30 |
33 |
34 | 35 | <% if (tunerName.equals("AMG")) { %> 36 |

37 |


38 | 39 |

40 |

41 | 42 |

43 |

44 | 45 |

46 |

47 | Inspired by the core values of Mercedes-Benz - like quality, safety, comfort and environmental 48 | protection - Mercedes-AMG GmbH develops and builds high-performance sports cars, options and accessories. 49 | 50 | Development work at Mercedes-AMG is driven by the pursuit of performance, sporting prowess and 51 | individuality. The dynamism and sporty character of these fascinating and unique vehicles catapult 52 | them into "pole position" in their respective Mercedes-Benz model ranges. 53 |

54 | <% } %> 55 | 56 | <% if (tunerName.equals("Alpina")) { %> 57 |

58 |


59 | 60 |

61 |

62 | 63 |

64 |

65 | 66 |

67 |

68 | Throughout ALPINA's 40-year history, its automobiles have been known for their notion of exclusivity. 69 | Over this period, BMW ALPINA's have evolved, taking advantage of, and improving upon, the technology 70 | offered at the time - and not just in the pursuit of more power, for improving performance is only one 71 | part of ALPINA's philosophy. The ALPINA customer is an enthusiast who appreciates high technology and 72 | seeks great driving pleasure from his car, yet prefers a car more refined and more practical than today's 73 | sports cars. The BMW ALPINA B10 V8 S is high performance in a most subtle guise. 74 |

75 | <% } %> 76 | 77 | <% if (tunerName.equals("Gembella")) { %> 78 |

79 |


80 | 81 |

82 |

83 | 84 |

85 |

86 | 87 |

88 |

89 | Porsche customizer Gemballa from Leonberg thrills the hearts of the drivers of the 90 | noble Porsche-SUV by its new high-performance cure, the Gemballa V6 Turbo conversion 91 | kit for the Porsche Cayenne V6, for the Cayenne V6 reaches new dimensions of 92 | performance with the help of the new Gemballa conversion kit. 93 |

94 | <% } %> 95 | 96 | <% if (tunerName.equals("Mazdaspeed")) { %> 97 |

98 |


99 | 100 |

101 |

102 | 103 |

104 |

105 | 106 |

107 |

108 | Mazda Motor Corporation announces the release of a limited edition RX-8 Mazdaspeed 109 | Version, which is based on the RX-8 and fitted with Mazdaspeed* brand tune-up parts 110 | for enhanced sports driving performance. The RX-8 Mazdaspeed Version goes on sale 111 | from the middle of February at Mazda Anfini and Mazda dealerships throughout Japan. 112 |

113 |

114 | The new RX-8 Mazdaspeed Version is based on the RX-8 Type S. Mazda has tuned 115 | up the engine using it`s exclusively designed PCM (Powertrain Control Module) 116 | to match the modified intake and exhaust systems of the Mazdaspeed Version, 117 | as well as going through balance adjustments around the eccentric shaft in 118 | response to the lightweight flywheel. Mazda has also tuned up the suspension 119 | and fitted aero parts to further enhance sports driving performance. Those 120 | modifications, carried out under Mazda`s strict quality control system, 121 | provide the RX-8 Mazdaspeed Version with well-balanced performance. 122 |

123 | <% } %> 124 | 125 | <% if (tunerName.equals("RUF")) { %> 126 |

127 |


128 | 129 |

130 |

131 | 132 |

133 |

134 | 135 |

136 |

137 | The latest year 2003 release from RUF Automobiles. A RUF manufactured sports 138 | version of the 996 Carrera constructed on the basis of a natural aspirated 139 | engine, that has a dry oil sump with a separate oil tank. Built at the RUF 140 | headquarters in Pfaffenhausen. 141 |

142 |

143 | The RUF RGT with an elevated power output of 395 bhp. This normally 144 | aspirated power-plant performance is achieved through equipping motorsports 145 | based engine with four new camshafts, a performance exhaust system, air 146 | filter and a re-mapped engine management system. 147 | 148 | <% }%> 149 | 150 | 151 | 152 | 153 | -------------------------------------------------------------------------------- /src/main/webapp/trader.css: -------------------------------------------------------------------------------- 1 | table 2 | { text-align: center; 3 | font-family: Verdana; 4 | font-weight: normal; 5 | font-size: 11px; 6 | color: #404040; 7 | border: 0px #d79900 solid; 8 | border-collapse: collapse; 9 | border-spacing: 0px;} 10 | 11 | td.home 12 | { text-align: center; 13 | font-family: Verdana; 14 | font-weight: normal; 15 | font-size: 11px; 16 | color: #404040; 17 | width: 203px; 18 | border: 0px #d79900 solid; 19 | border-collapse: collapse; 20 | border-spacing: 0px;} 21 | 22 | td.ad 23 | { text-align: center; 24 | font-family: Verdana; 25 | font-weight: normal; 26 | font-size: 11px; 27 | background-color: #E6F1F5; 28 | border: 0px #d79900 solid; 29 | border-collapse: collapse; 30 | border-spacing: 10px;} 31 | 32 | 33 | img 34 | { text-align: left; 35 | background-color: #fafafa; 36 | border: 0px #d79900 solid; 37 | border-collapse: collapse; 38 | border-spacing: 0px;} 39 | 40 | tr.grey 41 | {; 42 | background-color: #F9F7F7; 43 | font-family: Verdana; 44 | font-weight: normal; 45 | font-size: 11px; 46 | border: 0px #d79900 solid; 47 | border-collapse: collapse; 48 | border-spacing: 0px;} 49 | 50 | td 51 | { 52 | text-align: left; 53 | font-family: Verdana; 54 | font-weight: normal; 55 | font-size: 11px; 56 | border: 0px #d79900 solid; 57 | border-collapse: collapse; 58 | border-spacing: 0px;} 59 | 60 | table.car 61 | { 62 | background-color: #F9F7F7; 63 | font-family: Verdana; 64 | font-weight: normal; 65 | font-size: 11px; 66 | width: 550px; 67 | border: 0px #d79900 solid; 68 | border-collapse: collapse; 69 | border-spacing: 0px;} 70 | 71 | p.car 72 | { 73 | background-color: #F9F7F7; 74 | font-family: Verdana; 75 | font-weight: normal; 76 | font-size: 11px; 77 | width: 550px; 78 | border: 0px #d79900 solid; 79 | border-collapse: collapse; 80 | border-spacing: 0px;} 81 | 82 | p 83 | { 84 | background-color: #FFFFFF; 85 | font-family: Verdana; 86 | font-weight: normal; 87 | font-size: 11px; 88 | border: 0px #d79900 solid; 89 | border-collapse: collapse; 90 | border-spacing: 0px;} 91 | 92 | p.normal 93 | { 94 | background-color: #FFFFFF; 95 | font-family: Verdana; 96 | font-weight: normal; 97 | font-size: 11px; 98 | width:550; 99 | border: 0px #d79900 solid; 100 | border-collapse: collapse; 101 | border-spacing: 0px;} 102 | 103 | p.summary 104 | { 105 | text-align: left; 106 | background-color: #F9F7F7; 107 | font-family: Verdana; 108 | font-weight: normal; 109 | font-size: 11px; 110 | width: 430px; 111 | border: 0px #d79900 solid; 112 | border-collapse: collapse; 113 | border-spacing: 0px;} 114 | -------------------------------------------------------------------------------- /updateDeployLocalhost.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | git pull 4 | mvn tomcat7:redeploy 5 | --------------------------------------------------------------------------------