Commit 63605149 by dblevins

very basic angularjs starter project

parent ad33bc6e
# Apache TomEE JAX-RS Starter Project
Know JAX-RS, but haven't yet dug into Apache TomEE? Way too busy or impatient to read documentation? This repo is for you.
# Apache TomEE JAX-RS AngularJS Starter Project
The only thing better than a Maven archetype is a repo you can fork with everything already setup. Skip the documentation and just fork-and-code. This starter project contains:
- 1 JAX-RS class, 1 JAXB class and 1 JUnit/Arquillian test
- Maven pom for building a war file
- Arquillian setup for testing against TomEE JAX-RS Embedded
- TomEE Maven Plugin for deploying and running our war file
- Java
-- Phone.java
-- PhoneService.java
-- PhoneServiceTest.java
- JavaScript
-- angular.js
-- controllers.js
- CSS
-- bootstrap.css
-- app.css
Everything ready-to-run with a simple `maven clean install tomee:run`
Delete the sample code, replace with your own and you're good to go.
Have time for some reading and curious on how everything works? [Read here](http://www.tomitribe.com/blog/2014/06/apache-tomee-jax-rs-and-arquillian-starter-project/).
......@@ -20,8 +20,8 @@
<modelVersion>4.0.0</modelVersion>
<!-- Change: groupId, artifactId, version -->
<groupId>org.superbiz</groupId>
<artifactId>tomee-rest-arquillian</artifactId>
<groupId>org.supertribe</groupId>
<artifactId>tomee-rest-angular</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
......@@ -54,6 +54,7 @@
</dependencies>
<build>
<finalName>ROOT</finalName>
<plugins>
<plugin>
<groupId>org.apache.openejb.maven</groupId>
......
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.superbiz;
import javax.ejb.Singleton;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
@Path("/color")
@Singleton
public class ColorService {
private String color;
public ColorService() {
this.color = "white";
}
@GET
public String getColor() {
return color;
}
@Path("{color}")
@POST
public void setColor(@PathParam("color") String color) {
this.color = color;
}
@Path("object")
@GET
@Produces({ APPLICATION_JSON })
public Color getColorObject() {
return new Color("orange", 0xE7, 0x71, 0x00);
}
}
......@@ -14,57 +14,79 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.superbiz;
package org.supertribe;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Color {
public class Phone {
private int age;
private String carrier;
private String id;
private String name;
private int r;
private int g;
private int b;
private String snippet;
public Color() {
public Phone() {
}
public Color(String name, int r, int g, int b) {
public Phone(int age, String carrier, String id, String name, String snippet) {
this.age = age;
this.carrier = carrier;
this.id = id;
this.name = name;
this.r = r;
this.g = g;
this.b = b;
this.snippet = snippet;
}
public String getName() {
return name;
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
public void setAge(int age) {
this.age = age;
}
public String getCarrier() {
return carrier;
}
public int getR() {
return r;
public void setCarrier(String carrier) {
this.carrier = carrier;
}
public void setR(int r) {
this.r = r;
public String getId() {
return id;
}
public int getG() {
return g;
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setG(int g) {
this.g = g;
public String getSnippet() {
return snippet;
}
public int getB() {
return b;
public void setSnippet(String snippet) {
this.snippet = snippet;
}
public void setB(int b) {
this.b = b;
@Override
public String toString() {
return "Phone{" +
"age=" + age +
", carrier='" + carrier + '\'' +
", id='" + id + '\'' +
", name='" + name + '\'' +
", snippet='" + snippet + '\'' +
'}';
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.supertribe;
import javax.ejb.Lock;
import javax.ejb.Singleton;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.util.Arrays;
import java.util.List;
import static javax.ejb.LockType.READ;
@Path("/phone")
@Singleton
@Lock(READ)
public class PhoneService {
@GET
@Path("list")
@Produces(MediaType.APPLICATION_JSON)
public List<Phone> getPhones() {
return Arrays.asList(
new Phone(0, "", "motorola-xoom-with-wi-fi", "Motorola XOOM\u2122 with Wi-Fi", "The Next, Next Generation\r\n\r\nExperience the future with Motorola XOOM with Wi-Fi, the world's first tablet powered by Android 3.0 (Honeycomb)."),
new Phone(1, "", "motorola-xoom", "MOTOROLA XOOM\u2122", "The Next, Next Generation\n\nExperience the future with MOTOROLA XOOM, the world's first tablet powered by Android 3.0 (Honeycomb)."),
new Phone(8, "", "samsung-galaxy-tab", "Samsung Galaxy Tab\u2122", "Feel Free to Tab\u2122. The Samsung Galaxy Tab\u2122 brings you an ultra-mobile entertainment experience through its 7\u201d display, high-power processor and Adobe\u00ae Flash\u00ae Player compatibility."),
new Phone(11, "Verizon", "droid-pro-by-motorola", "DROID\u2122 Pro by Motorola", "The next generation of DOES."),
new Phone(18, "", "t-mobile-g2", "T-Mobile G2", "The T-Mobile G2 with Google is the first smartphone built for 4G speeds on T-Mobile's new network. Get the information you need, faster than you ever thought possible.")
);
}
}
/* app css stylesheet */
body {
padding-top: 20px;
}
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
'use strict';
/* Controllers */
var phonecatApp = angular.module('phonecatApp', []);
phonecatApp.controller('PhoneListCtrl', function($scope, $http) {
$http.get('phone/list').success(function(data) {
$scope.phones = data.phone;
});
$scope.orderProp = 'age';
});
<!doctype html>
<html lang="en" ng-app="phonecatApp">
<head>
<meta charset="utf-8">
<title>Google Phone Gallery</title>
<link rel="stylesheet" href="assets/css/bootstrap.css">
<link rel="stylesheet" href="assets/css/app.css">
<script src="assets/js/angular.js"></script>
<script src="assets/js/controllers.js"></script>
</head>
<body ng-controller="PhoneListCtrl">
<div class="container-fluid">
<div class="row">
<div class="col-md-2">
<!--Sidebar content-->
Search: <input ng-model="query">
Sort by:
<select ng-model="orderProp">
<option value="name">Alphabetical</option>
<option value="age">Newest</option>
</select>
</div>
<div class="col-md-10">
<!--Body content-->
<ul class="phones">
<li ng-repeat="phone in phones | filter:query | orderBy:orderProp">
<span>{{phone.name}}</span>
<p>{{phone.snippet}}</p>
</li>
</ul>
</div>
</div>
</div>
</body>
</html>
......@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.superbiz;
package org.supertribe;
import org.apache.cxf.jaxrs.client.WebClient;
import org.jboss.arquillian.container.test.api.Deployment;
......@@ -27,11 +27,9 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Collection;
import java.util.Iterator;
/**
* Arquillian will start the container, deploy all @Deployment bundles, then run all the @Test methods.
......@@ -45,7 +43,7 @@ import java.net.URL;
*
*/
@RunWith(Arquillian.class)
public class ColorServiceTest extends Assert {
public class PhoneServiceTest extends Assert {
/**
* ShrinkWrap is used to create a war file on the fly.
......@@ -58,7 +56,7 @@ public class ColorServiceTest extends Assert {
*/
@Deployment
public static WebArchive createDeployment() {
return ShrinkWrap.create(WebArchive.class).addClasses(ColorService.class, Color.class);
return ShrinkWrap.create(WebArchive.class).addClasses(Phone.class, PhoneService.class);
}
/**
......@@ -73,60 +71,23 @@ public class ColorServiceTest extends Assert {
@ArquillianResource
private URL webappUrl;
@Test
public void postAndGet() throws Exception {
// POST
{
final WebClient webClient = WebClient.create(webappUrl.toURI());
final Response response = webClient.path("color/green").post(null);
assertEquals(204, response.getStatus());
}
// GET
{
final WebClient webClient = WebClient.create(webappUrl.toURI());
final Response response = webClient.path("color").get();
assertEquals(200, response.getStatus());
final String content = slurp((InputStream) response.getEntity());
assertEquals("green", content);
}
}
@Test
public void getColorObject() throws Exception {
public void getPhoneList() throws Exception {
final WebClient webClient = WebClient.create(webappUrl.toURI());
webClient.accept(MediaType.APPLICATION_JSON);
final Color color = webClient.path("color/object").get(Color.class);
final Collection<? extends Phone> phones = webClient.path("phone/list").getCollection(Phone.class);
assertNotNull(color);
assertEquals("orange", color.getName());
assertEquals(0xE7, color.getR());
assertEquals(0x71, color.getG());
assertEquals(0x00, color.getB());
}
assertEquals(5, phones.size());
final Iterator<? extends Phone> it = phones.iterator();
assertEquals("motorola-xoom-with-wi-fi", it.next().getId());
assertEquals("motorola-xoom", it.next().getId());
assertEquals("samsung-galaxy-tab", it.next().getId());
assertEquals("droid-pro-by-motorola", it.next().getId());
assertEquals("t-mobile-g2", it.next().getId());
/**
* Reusable utility method
* Move to a shared class or replace with equivalent
*/
public static String slurp(final InputStream in) throws IOException {
final ByteArrayOutputStream out = new ByteArrayOutputStream();
final byte[] buffer = new byte[1024];
int length;
while ((length = in.read(buffer)) != -1) {
out.write(buffer, 0, length);
}
out.flush();
return new String(out.toByteArray());
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment