- Petclinic uses XML configuration by default. In case you'd like to use Java Config instead, there is a Java Config branch available here. Thanks to Antoine Rey for his contribution.
-
-
-
-## Interaction with other open source projects
-
-One of the best parts about working on the Spring Petclinic application is that we have the opportunity to work in direct contact with many Open Source projects. We found some bugs/suggested improvements on various topics such as Spring, Spring Data, Bean Validation and even Eclipse! In many cases, they've been fixed/implemented in just a few days.
-Here is a list of them:
-
-
-
-
Name
-
Issue
-
-
-
-
Spring JDBC: simplify usage of NamedParameterJdbcTemplate
-
-
-
diff --git a/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java b/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java
new file mode 100644
index 000000000..21d6e053b
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java
@@ -0,0 +1,19 @@
+package org.springframework.samples.petclinic;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.context.request.WebRequest;
+import org.springframework.web.context.request.WebRequestInterceptor;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+
+@SpringBootApplication
+public class PetClinicApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(PetClinicApplication.class, args);
+ }
+}
+
diff --git a/src/main/java/org/springframework/samples/petclinic/model/Pet.java b/src/main/java/org/springframework/samples/petclinic/model/Pet.java
index d618f08bb..a121e7b81 100644
--- a/src/main/java/org/springframework/samples/petclinic/model/Pet.java
+++ b/src/main/java/org/springframework/samples/petclinic/model/Pet.java
@@ -15,11 +15,9 @@
*/
package org.springframework.samples.petclinic.model;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.springframework.beans.support.MutableSortDefinition;
+import org.springframework.beans.support.PropertyComparator;
import javax.persistence.CascadeType;
import javax.persistence.Column;
@@ -29,13 +27,14 @@ import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
-
-import org.hibernate.annotations.Type;
-import org.joda.time.DateTime;
-import org.springframework.beans.support.MutableSortDefinition;
-import org.springframework.beans.support.PropertyComparator;
-
-import com.fasterxml.jackson.annotation.JsonIgnore;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
/**
* Simple business object representing a pet.
@@ -49,8 +48,8 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
public class Pet extends NamedEntity {
@Column(name = "birth_date")
- @Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime")
- private DateTime birthDate;
+ @Temporal(TemporalType.DATE)
+ private Date birthDate;
@ManyToOne
@JoinColumn(name = "type_id")
@@ -65,11 +64,11 @@ public class Pet extends NamedEntity {
private Set visits;
- public void setBirthDate(DateTime birthDate) {
+ public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
- public DateTime getBirthDate() {
+ public Date getBirthDate() {
return this.birthDate;
}
diff --git a/src/main/java/org/springframework/samples/petclinic/model/Visit.java b/src/main/java/org/springframework/samples/petclinic/model/Visit.java
index 181830abc..4440c6f5c 100644
--- a/src/main/java/org/springframework/samples/petclinic/model/Visit.java
+++ b/src/main/java/org/springframework/samples/petclinic/model/Visit.java
@@ -15,18 +15,18 @@
*/
package org.springframework.samples.petclinic.model;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
-
-import org.hibernate.annotations.Type;
-import org.hibernate.validator.constraints.NotEmpty;
-import org.joda.time.DateTime;
-import org.springframework.format.annotation.DateTimeFormat;
-
-import com.fasterxml.jackson.annotation.JsonIgnore;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+import javax.validation.constraints.Size;
+import java.util.Date;
/**
* Simple JavaBean domain object representing a visit.
@@ -41,14 +41,14 @@ public class Visit extends BaseEntity {
* Holds value of property date.
*/
@Column(name = "visit_date")
- @Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime")
- @DateTimeFormat(pattern = "yyyy/MM/dd")
- private DateTime date;
+ @Temporal(TemporalType.TIMESTAMP)
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ private Date date;
/**
* Holds value of property description.
*/
- @NotEmpty
+ @Size(max = 8192)
@Column(name = "description")
private String description;
@@ -65,7 +65,7 @@ public class Visit extends BaseEntity {
* Creates a new instance of Visit for the current date
*/
public Visit() {
- this.date = new DateTime();
+ this.date = new Date();
}
@@ -74,7 +74,7 @@ public class Visit extends BaseEntity {
*
* @return Value of property date.
*/
- public DateTime getDate() {
+ public Date getDate() {
return this.date;
}
@@ -83,7 +83,7 @@ public class Visit extends BaseEntity {
*
* @param date New value of property date.
*/
- public void setDate(DateTime date) {
+ public void setDate(Date date) {
this.date = date;
}
diff --git a/src/main/java/org/springframework/samples/petclinic/repository/OwnerRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/OwnerRepository.java
index 131833706..4e0c7c4af 100644
--- a/src/main/java/org/springframework/samples/petclinic/repository/OwnerRepository.java
+++ b/src/main/java/org/springframework/samples/petclinic/repository/OwnerRepository.java
@@ -1,18 +1,3 @@
-/*
- * Copyright 2002-2013 the original author or authors.
- *
- * Licensed 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.
- */
/*
* Copyright 2002-2013 the original author or authors.
*
@@ -33,6 +18,10 @@ package org.springframework.samples.petclinic.repository;
import java.util.Collection;
import org.springframework.dao.DataAccessException;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.Repository;
+import org.springframework.data.repository.query.Param;
import org.springframework.samples.petclinic.model.BaseEntity;
import org.springframework.samples.petclinic.model.Owner;
@@ -45,36 +34,4 @@ import org.springframework.samples.petclinic.model.Owner;
* @author Sam Brannen
* @author Michael Isvy
*/
-public interface OwnerRepository {
-
- /**
- * Retrieve Owners from the data store by last name, returning all owners whose last name starts
- * with the given name.
- *
- * @param lastName Value to search for
- * @return a Collection of matching Owners (or an empty Collection if none
- * found)
- */
- Collection findByLastName(String lastName) throws DataAccessException;
-
- /**
- * Retrieve an Owner from the data store by id.
- *
- * @param id the id to search for
- * @return the Owner if found
- * @throws org.springframework.dao.DataRetrievalFailureException
- * if not found
- */
- Owner findById(int id) throws DataAccessException;
-
-
- /**
- * Save an Owner to the data store, either inserting or updating it.
- *
- * @param owner the Owner to save
- * @see BaseEntity#isNew
- */
- void save(Owner owner) throws DataAccessException;
-
-
-}
+public interface OwnerRepository extends JpaRepository { }
diff --git a/src/main/java/org/springframework/samples/petclinic/repository/PetRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/PetRepository.java
index 693b2e5e9..58e73d7f6 100644
--- a/src/main/java/org/springframework/samples/petclinic/repository/PetRepository.java
+++ b/src/main/java/org/springframework/samples/petclinic/repository/PetRepository.java
@@ -18,6 +18,8 @@ package org.springframework.samples.petclinic.repository;
import java.util.List;
import org.springframework.dao.DataAccessException;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.Repository;
import org.springframework.samples.petclinic.model.BaseEntity;
import org.springframework.samples.petclinic.model.Pet;
import org.springframework.samples.petclinic.model.PetType;
@@ -31,31 +33,27 @@ import org.springframework.samples.petclinic.model.PetType;
* @author Sam Brannen
* @author Michael Isvy
*/
-public interface PetRepository {
+public interface PetRepository extends Repository {
/**
- * Retrieve all PetTypes from the data store.
- *
- * @return a Collection of PetTypes
+ * Retrieve all {@link PetType}s from the data store.
+ * @return a Collection of {@link PetType}s.
*/
- List findPetTypes() throws DataAccessException;
+ @Query("SELECT ptype FROM PetType ptype ORDER BY ptype.name")
+ List findPetTypes();
/**
- * Retrieve a Pet from the data store by id.
- *
+ * Retrieve a {@link Pet} from the data store by id.
* @param id the id to search for
- * @return the Pet if found
- * @throws org.springframework.dao.DataRetrievalFailureException
- * if not found
+ * @return the {@link Pet} if found
*/
- Pet findById(int id) throws DataAccessException;
+ Pet findById(int id);
/**
- * Save a Pet to the data store, either inserting or updating it.
- *
- * @param pet the Pet to save
- * @see BaseEntity#isNew
+ * Save a {@link Pet} to the data store, either inserting or updating it.
+ * @param pet the {@link Pet} to save
*/
- void save(Pet pet) throws DataAccessException;
+ void save(Pet pet);
}
+
diff --git a/src/main/java/org/springframework/samples/petclinic/repository/VetRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/VetRepository.java
index 923c3c23d..aabdfd65d 100644
--- a/src/main/java/org/springframework/samples/petclinic/repository/VetRepository.java
+++ b/src/main/java/org/springframework/samples/petclinic/repository/VetRepository.java
@@ -18,6 +18,7 @@ package org.springframework.samples.petclinic.repository;
import java.util.Collection;
import org.springframework.dao.DataAccessException;
+import org.springframework.data.repository.Repository;
import org.springframework.samples.petclinic.model.Vet;
/**
@@ -29,7 +30,7 @@ import org.springframework.samples.petclinic.model.Vet;
* @author Sam Brannen
* @author Michael Isvy
*/
-public interface VetRepository {
+public interface VetRepository extends Repository {
/**
* Retrieve all Vets from the data store.
diff --git a/src/main/java/org/springframework/samples/petclinic/repository/VisitRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/VisitRepository.java
index 96b7a208c..e734f3275 100644
--- a/src/main/java/org/springframework/samples/petclinic/repository/VisitRepository.java
+++ b/src/main/java/org/springframework/samples/petclinic/repository/VisitRepository.java
@@ -18,6 +18,7 @@ package org.springframework.samples.petclinic.repository;
import java.util.List;
import org.springframework.dao.DataAccessException;
+import org.springframework.data.repository.Repository;
import org.springframework.samples.petclinic.model.BaseEntity;
import org.springframework.samples.petclinic.model.Visit;
@@ -30,7 +31,7 @@ import org.springframework.samples.petclinic.model.Visit;
* @author Sam Brannen
* @author Michael Isvy
*/
-public interface VisitRepository {
+public interface VisitRepository extends Repository {
/**
* Save a Visit to the data store, either inserting or updating it.
diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcOwnerRepositoryImpl.java b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcOwnerRepositoryImpl.java
deleted file mode 100644
index 579de5284..000000000
--- a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcOwnerRepositoryImpl.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright 2002-2013 the original author or authors.
- *
- * Licensed 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.springframework.samples.petclinic.repository.jdbc;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.sql.DataSource;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.dao.DataAccessException;
-import org.springframework.dao.EmptyResultDataAccessException;
-import org.springframework.jdbc.core.BeanPropertyRowMapper;
-import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
-import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
-import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
-import org.springframework.orm.ObjectRetrievalFailureException;
-import org.springframework.samples.petclinic.model.Owner;
-import org.springframework.samples.petclinic.model.Pet;
-import org.springframework.samples.petclinic.model.PetType;
-import org.springframework.samples.petclinic.model.Visit;
-import org.springframework.samples.petclinic.repository.OwnerRepository;
-import org.springframework.samples.petclinic.repository.VisitRepository;
-import org.springframework.samples.petclinic.util.EntityUtils;
-import org.springframework.stereotype.Repository;
-
-/**
- * A simple JDBC-based implementation of the {@link OwnerRepository} interface.
- *
- * @author Ken Krebs
- * @author Juergen Hoeller
- * @author Rob Harrop
- * @author Sam Brannen
- * @author Thomas Risberg
- * @author Mark Fisher
- */
-@Repository
-public class JdbcOwnerRepositoryImpl implements OwnerRepository {
-
- private VisitRepository visitRepository;
-
- private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
-
- private SimpleJdbcInsert insertOwner;
-
- @Autowired
- public JdbcOwnerRepositoryImpl(DataSource dataSource, NamedParameterJdbcTemplate namedParameterJdbcTemplate,
- VisitRepository visitRepository) {
-
- this.insertOwner = new SimpleJdbcInsert(dataSource)
- .withTableName("owners")
- .usingGeneratedKeyColumns("id");
-
- this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
-
- this.visitRepository = visitRepository;
- }
-
-
- /**
- * Loads {@link Owner Owners} from the data store by last name, returning all owners whose last name starts with
- * the given name; also loads the {@link Pet Pets} and {@link Visit Visits} for the corresponding owners, if not
- * already loaded.
- */
- @Override
- public Collection findByLastName(String lastName) throws DataAccessException {
- Map params = new HashMap();
- params.put("lastName", lastName + "%");
- List owners = this.namedParameterJdbcTemplate.query(
- "SELECT id, first_name, last_name, address, city, telephone FROM owners WHERE last_name like :lastName",
- params,
- BeanPropertyRowMapper.newInstance(Owner.class)
- );
- loadOwnersPetsAndVisits(owners);
- return owners;
- }
-
- /**
- * Loads the {@link Owner} with the supplied id; also loads the {@link Pet Pets} and {@link Visit Visits}
- * for the corresponding owner, if not already loaded.
- */
- @Override
- public Owner findById(int id) throws DataAccessException {
- Owner owner;
- try {
- Map params = new HashMap();
- params.put("id", id);
- owner = this.namedParameterJdbcTemplate.queryForObject(
- "SELECT id, first_name, last_name, address, city, telephone FROM owners WHERE id= :id",
- params,
- BeanPropertyRowMapper.newInstance(Owner.class)
- );
- } catch (EmptyResultDataAccessException ex) {
- throw new ObjectRetrievalFailureException(Owner.class, id);
- }
- loadPetsAndVisits(owner);
- return owner;
- }
-
- public void loadPetsAndVisits(final Owner owner) {
- Map params = new HashMap();
- params.put("id", owner.getId().intValue());
- final List pets = this.namedParameterJdbcTemplate.query(
- "SELECT id, name, birth_date, type_id, owner_id FROM pets WHERE owner_id=:id",
- params,
- new JdbcPetRowMapper()
- );
- for (JdbcPet pet : pets) {
- owner.addPet(pet);
- // Pet types have not been loaded at this stage. They are loaded separately
- pet.setType(EntityUtils.getById(getPetTypes(), PetType.class, pet.getTypeId()));
- List visits = this.visitRepository.findByPetId(pet.getId());
- for (Visit visit : visits) {
- pet.addVisit(visit);
- }
- }
- }
-
- @Override
- public void save(Owner owner) throws DataAccessException {
- BeanPropertySqlParameterSource parameterSource = new BeanPropertySqlParameterSource(owner);
- if (owner.isNew()) {
- Number newKey = this.insertOwner.executeAndReturnKey(parameterSource);
- owner.setId(newKey.intValue());
- } else {
- this.namedParameterJdbcTemplate.update(
- "UPDATE owners SET first_name=:firstName, last_name=:lastName, address=:address, " +
- "city=:city, telephone=:telephone WHERE id=:id",
- parameterSource);
- }
- }
-
- public Collection getPetTypes() throws DataAccessException {
- return this.namedParameterJdbcTemplate.query(
- "SELECT id, name FROM types ORDER BY name", new HashMap(),
- BeanPropertyRowMapper.newInstance(PetType.class));
- }
-
- /**
- * Loads the {@link Pet} and {@link Visit} data for the supplied {@link List} of {@link Owner Owners}.
- *
- * @param owners the list of owners for whom the pet and visit data should be loaded
- * @see #loadPetsAndVisits(Owner)
- */
- private void loadOwnersPetsAndVisits(List owners) {
- for (Owner owner : owners) {
- loadPetsAndVisits(owner);
- }
- }
-
-
-}
diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcPet.java b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcPet.java
deleted file mode 100644
index 39ba53b83..000000000
--- a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcPet.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright 2002-2013 the original author or authors.
- *
- * Licensed 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.springframework.samples.petclinic.repository.jdbc;
-
-import org.springframework.samples.petclinic.model.Pet;
-
-/**
- * Subclass of Pet that carries temporary id properties which are only relevant for a JDBC implementation of the
- * PetRepository.
- *
- * @author Juergen Hoeller
- */
-class JdbcPet extends Pet {
-
- private int typeId;
-
- private int ownerId;
-
-
- public void setTypeId(int typeId) {
- this.typeId = typeId;
- }
-
- public int getTypeId() {
- return this.typeId;
- }
-
- public void setOwnerId(int ownerId) {
- this.ownerId = ownerId;
- }
-
- public int getOwnerId() {
- return this.ownerId;
- }
-
-}
diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcPetRepositoryImpl.java b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcPetRepositoryImpl.java
deleted file mode 100644
index 546451dcc..000000000
--- a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcPetRepositoryImpl.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright 2002-2013 the original author or authors.
- *
- * Licensed 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.springframework.samples.petclinic.repository.jdbc;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.sql.DataSource;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.dao.DataAccessException;
-import org.springframework.dao.EmptyResultDataAccessException;
-import org.springframework.jdbc.core.BeanPropertyRowMapper;
-import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
-import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
-import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
-import org.springframework.orm.ObjectRetrievalFailureException;
-import org.springframework.samples.petclinic.model.Owner;
-import org.springframework.samples.petclinic.model.Pet;
-import org.springframework.samples.petclinic.model.PetType;
-import org.springframework.samples.petclinic.model.Visit;
-import org.springframework.samples.petclinic.repository.OwnerRepository;
-import org.springframework.samples.petclinic.repository.PetRepository;
-import org.springframework.samples.petclinic.repository.VisitRepository;
-import org.springframework.samples.petclinic.util.EntityUtils;
-import org.springframework.stereotype.Repository;
-
-/**
- * @author Ken Krebs
- * @author Juergen Hoeller
- * @author Rob Harrop
- * @author Sam Brannen
- * @author Thomas Risberg
- * @author Mark Fisher
- */
-@Repository
-public class JdbcPetRepositoryImpl implements PetRepository {
-
- private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
-
- private SimpleJdbcInsert insertPet;
-
- private OwnerRepository ownerRepository;
-
- private VisitRepository visitRepository;
-
-
- @Autowired
- public JdbcPetRepositoryImpl(DataSource dataSource, OwnerRepository ownerRepository, VisitRepository visitRepository) {
- this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
-
- this.insertPet = new SimpleJdbcInsert(dataSource)
- .withTableName("pets")
- .usingGeneratedKeyColumns("id");
-
- this.ownerRepository = ownerRepository;
- this.visitRepository = visitRepository;
- }
-
- @Override
- public List findPetTypes() throws DataAccessException {
- Map params = new HashMap();
- return this.namedParameterJdbcTemplate.query(
- "SELECT id, name FROM types ORDER BY name",
- params,
- BeanPropertyRowMapper.newInstance(PetType.class));
- }
-
- @Override
- public Pet findById(int id) throws DataAccessException {
- JdbcPet pet;
- try {
- Map params = new HashMap();
- params.put("id", id);
- pet = this.namedParameterJdbcTemplate.queryForObject(
- "SELECT id, name, birth_date, type_id, owner_id FROM pets WHERE id=:id",
- params,
- new JdbcPetRowMapper());
- } catch (EmptyResultDataAccessException ex) {
- throw new ObjectRetrievalFailureException(Pet.class, new Integer(id));
- }
- Owner owner = this.ownerRepository.findById(pet.getOwnerId());
- owner.addPet(pet);
- pet.setType(EntityUtils.getById(findPetTypes(), PetType.class, pet.getTypeId()));
-
- List visits = this.visitRepository.findByPetId(pet.getId());
- for (Visit visit : visits) {
- pet.addVisit(visit);
- }
- return pet;
- }
-
- @Override
- public void save(Pet pet) throws DataAccessException {
- if (pet.isNew()) {
- Number newKey = this.insertPet.executeAndReturnKey(
- createPetParameterSource(pet));
- pet.setId(newKey.intValue());
- } else {
- this.namedParameterJdbcTemplate.update(
- "UPDATE pets SET name=:name, birth_date=:birth_date, type_id=:type_id, " +
- "owner_id=:owner_id WHERE id=:id",
- createPetParameterSource(pet));
- }
- }
-
- /**
- * Creates a {@link MapSqlParameterSource} based on data values from the supplied {@link Pet} instance.
- */
- private MapSqlParameterSource createPetParameterSource(Pet pet) {
- return new MapSqlParameterSource()
- .addValue("id", pet.getId())
- .addValue("name", pet.getName())
- .addValue("birth_date", pet.getBirthDate().toDate())
- .addValue("type_id", pet.getType().getId())
- .addValue("owner_id", pet.getOwner().getId());
- }
-
-}
diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcPetRowMapper.java b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcPetRowMapper.java
deleted file mode 100644
index 4164f746f..000000000
--- a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcPetRowMapper.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2002-2013 the original author or authors.
- *
- * Licensed 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.springframework.samples.petclinic.repository.jdbc;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Date;
-
-import org.joda.time.DateTime;
-import org.springframework.jdbc.core.BeanPropertyRowMapper;
-
-/**
- * {@link BeanPropertyRowMapper} implementation mapping data from a {@link ResultSet} to the corresponding properties
- * of the {@link JdbcPet} class.
- */
-class JdbcPetRowMapper extends BeanPropertyRowMapper {
-
- @Override
- public JdbcPet mapRow(ResultSet rs, int rownum) throws SQLException {
- JdbcPet pet = new JdbcPet();
- pet.setId(rs.getInt("id"));
- pet.setName(rs.getString("name"));
- Date birthDate = rs.getDate("birth_date");
- pet.setBirthDate(new DateTime(birthDate));
- pet.setTypeId(rs.getInt("type_id"));
- pet.setOwnerId(rs.getInt("owner_id"));
- return pet;
- }
-}
diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcVetRepositoryImpl.java b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcVetRepositoryImpl.java
deleted file mode 100644
index 9a85bde11..000000000
--- a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcVetRepositoryImpl.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright 2002-2013 the original author or authors.
- *
- * Licensed 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.springframework.samples.petclinic.repository.jdbc;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.dao.DataAccessException;
-import org.springframework.jdbc.core.BeanPropertyRowMapper;
-import org.springframework.jdbc.core.JdbcTemplate;
-import org.springframework.samples.petclinic.model.Specialty;
-import org.springframework.samples.petclinic.model.Vet;
-import org.springframework.samples.petclinic.repository.VetRepository;
-import org.springframework.samples.petclinic.util.EntityUtils;
-import org.springframework.stereotype.Repository;
-
-/**
- * A simple JDBC-based implementation of the {@link VetRepository} interface. Uses @Cacheable to cache the result of the
- * {@link findAll} method
- *
- * @author Ken Krebs
- * @author Juergen Hoeller
- * @author Rob Harrop
- * @author Sam Brannen
- * @author Thomas Risberg
- * @author Mark Fisher
- * @author Michael Isvy
- */
-@Repository
-public class JdbcVetRepositoryImpl implements VetRepository {
-
- private JdbcTemplate jdbcTemplate;
-
- @Autowired
- public JdbcVetRepositoryImpl(JdbcTemplate jdbcTemplate) {
- this.jdbcTemplate = jdbcTemplate;
- }
-
- /**
- * Refresh the cache of Vets that the ClinicService is holding.
- *
- * @see org.springframework.samples.petclinic.model.service.ClinicService#shouldFindVets()
- */
- @Override
- public Collection findAll() throws DataAccessException {
- List vets = new ArrayList();
- // Retrieve the list of all vets.
- vets.addAll(this.jdbcTemplate.query(
- "SELECT id, first_name, last_name FROM vets ORDER BY last_name,first_name",
- BeanPropertyRowMapper.newInstance(Vet.class)));
-
- // Retrieve the list of all possible specialties.
- final List specialties = this.jdbcTemplate.query(
- "SELECT id, name FROM specialties",
- BeanPropertyRowMapper.newInstance(Specialty.class));
-
- // Build each vet's list of specialties.
- for (Vet vet : vets) {
- final List vetSpecialtiesIds = this.jdbcTemplate.query(
- "SELECT specialty_id FROM vet_specialties WHERE vet_id=?",
- new BeanPropertyRowMapper() {
- @Override
- public Integer mapRow(ResultSet rs, int row) throws SQLException {
- return Integer.valueOf(rs.getInt(1));
- }
- },
- vet.getId().intValue());
- for (int specialtyId : vetSpecialtiesIds) {
- Specialty specialty = EntityUtils.getById(specialties, Specialty.class, specialtyId);
- vet.addSpecialty(specialty);
- }
- }
- return vets;
- }
-}
diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcVisitRepositoryImpl.java b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcVisitRepositoryImpl.java
deleted file mode 100644
index b6a004561..000000000
--- a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcVisitRepositoryImpl.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright 2002-2013 the original author or authors.
- *
- * Licensed 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.springframework.samples.petclinic.repository.jdbc;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Date;
-import java.util.List;
-
-import javax.sql.DataSource;
-
-import org.joda.time.DateTime;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.dao.DataAccessException;
-import org.springframework.jdbc.core.BeanPropertyRowMapper;
-import org.springframework.jdbc.core.JdbcTemplate;
-import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
-import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
-import org.springframework.samples.petclinic.model.Visit;
-import org.springframework.samples.petclinic.repository.VisitRepository;
-import org.springframework.stereotype.Repository;
-
-/**
- * A simple JDBC-based implementation of the {@link VisitRepository} interface.
- *
- * @author Ken Krebs
- * @author Juergen Hoeller
- * @author Rob Harrop
- * @author Sam Brannen
- * @author Thomas Risberg
- * @author Mark Fisher
- * @author Michael Isvy
- */
-@Repository
-public class JdbcVisitRepositoryImpl implements VisitRepository {
-
- private JdbcTemplate jdbcTemplate;
-
- private SimpleJdbcInsert insertVisit;
-
- @Autowired
- public JdbcVisitRepositoryImpl(DataSource dataSource) {
- this.jdbcTemplate = new JdbcTemplate(dataSource);
-
- this.insertVisit = new SimpleJdbcInsert(dataSource)
- .withTableName("visits")
- .usingGeneratedKeyColumns("id");
- }
-
-
- @Override
- public void save(Visit visit) throws DataAccessException {
- if (visit.isNew()) {
- Number newKey = this.insertVisit.executeAndReturnKey(
- createVisitParameterSource(visit));
- visit.setId(newKey.intValue());
- } else {
- throw new UnsupportedOperationException("Visit update not supported");
- }
- }
-
- public void deletePet(int id) throws DataAccessException {
- this.jdbcTemplate.update("DELETE FROM pets WHERE id=?", id);
- }
-
-
- /**
- * Creates a {@link MapSqlParameterSource} based on data values from the supplied {@link Visit} instance.
- */
- private MapSqlParameterSource createVisitParameterSource(Visit visit) {
- return new MapSqlParameterSource()
- .addValue("id", visit.getId())
- .addValue("visit_date", visit.getDate().toDate())
- .addValue("description", visit.getDescription())
- .addValue("pet_id", visit.getPet().getId());
- }
-
- @Override
- public List findByPetId(Integer petId) {
- final List visits = this.jdbcTemplate.query(
- "SELECT id, visit_date, description FROM visits WHERE pet_id=?",
- new BeanPropertyRowMapper() {
- @Override
- public Visit mapRow(ResultSet rs, int row) throws SQLException {
- Visit visit = new Visit();
- visit.setId(rs.getInt("id"));
- Date visitDate = rs.getDate("visit_date");
- visit.setDate(new DateTime(visitDate));
- visit.setDescription(rs.getString("description"));
- return visit;
- }
- },
- petId);
- return visits;
- }
-
-}
diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/package-info.java b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/package-info.java
deleted file mode 100644
index edd0bf855..000000000
--- a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/package-info.java
+++ /dev/null
@@ -1,9 +0,0 @@
-
-/**
- *
- * The classes in this package represent the JDBC implementation
- * of PetClinic's persistence layer.
- *
- */
-package org.springframework.samples.petclinic.repository.jdbc;
-
diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaOwnerRepositoryImpl.java b/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaOwnerRepositoryImpl.java
deleted file mode 100644
index c7398df5b..000000000
--- a/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaOwnerRepositoryImpl.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright 2002-2013 the original author or authors.
- *
- * Licensed 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.springframework.samples.petclinic.repository.jpa;
-
-import java.util.Collection;
-
-import javax.persistence.EntityManager;
-import javax.persistence.PersistenceContext;
-import javax.persistence.Query;
-
-import org.springframework.orm.hibernate3.support.OpenSessionInViewFilter;
-import org.springframework.samples.petclinic.model.Owner;
-import org.springframework.samples.petclinic.repository.OwnerRepository;
-import org.springframework.stereotype.Repository;
-
-/**
- * JPA implementation of the {@link OwnerRepository} interface.
- *
- * @author Mike Keith
- * @author Rod Johnson
- * @author Sam Brannen
- * @author Michael Isvy
- * @since 22.4.2006
- */
-@Repository
-public class JpaOwnerRepositoryImpl implements OwnerRepository {
-
- @PersistenceContext
- private EntityManager em;
-
-
- /**
- * Important: in the current version of this method, we load Owners with all their Pets and Visits while
- * we do not need Visits at all and we only need one property from the Pet objects (the 'name' property).
- * There are some ways to improve it such as:
- * - creating a Ligtweight class (example here: https://community.jboss.org/wiki/LightweightClass)
- * - Turning on lazy-loading and using {@link OpenSessionInViewFilter}
- */
- @SuppressWarnings("unchecked")
- public Collection findByLastName(String lastName) {
- // using 'join fetch' because a single query should load both owners and pets
- // using 'left join fetch' because it might happen that an owner does not have pets yet
- Query query = this.em.createQuery("SELECT DISTINCT owner FROM Owner owner left join fetch owner.pets WHERE owner.lastName LIKE :lastName");
- query.setParameter("lastName", lastName + "%");
- return query.getResultList();
- }
-
- @Override
- public Owner findById(int id) {
- // using 'join fetch' because a single query should load both owners and pets
- // using 'left join fetch' because it might happen that an owner does not have pets yet
- Query query = this.em.createQuery("SELECT owner FROM Owner owner left join fetch owner.pets WHERE owner.id =:id");
- query.setParameter("id", id);
- return (Owner) query.getSingleResult();
- }
-
-
- @Override
- public void save(Owner owner) {
- if (owner.getId() == null) {
- this.em.persist(owner);
- }
- else {
- this.em.merge(owner);
- }
-
- }
-
-}
diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaPetRepositoryImpl.java b/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaPetRepositoryImpl.java
deleted file mode 100644
index 84d564da4..000000000
--- a/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaPetRepositoryImpl.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright 2002-2013 the original author or authors.
- *
- * Licensed 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.springframework.samples.petclinic.repository.jpa;
-
-import java.util.List;
-
-import javax.persistence.EntityManager;
-import javax.persistence.PersistenceContext;
-
-import org.springframework.samples.petclinic.model.Pet;
-import org.springframework.samples.petclinic.model.PetType;
-import org.springframework.samples.petclinic.repository.PetRepository;
-import org.springframework.stereotype.Repository;
-
-/**
- * JPA implementation of the {@link PetRepository} interface.
- *
- * @author Mike Keith
- * @author Rod Johnson
- * @author Sam Brannen
- * @author Michael Isvy
- * @since 22.4.2006
- */
-@Repository
-public class JpaPetRepositoryImpl implements PetRepository {
-
- @PersistenceContext
- private EntityManager em;
-
- @Override
- @SuppressWarnings("unchecked")
- public List findPetTypes() {
- return this.em.createQuery("SELECT ptype FROM PetType ptype ORDER BY ptype.name").getResultList();
- }
-
- @Override
- public Pet findById(int id) {
- return this.em.find(Pet.class, id);
- }
-
- @Override
- public void save(Pet pet) {
- if (pet.getId() == null) {
- this.em.persist(pet);
- }
- else {
- this.em.merge(pet);
- }
- }
-
-}
diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaVetRepositoryImpl.java b/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaVetRepositoryImpl.java
deleted file mode 100644
index e4c222b65..000000000
--- a/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaVetRepositoryImpl.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright 2002-2013 the original author or authors.
- *
- * Licensed 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.springframework.samples.petclinic.repository.jpa;
-
-import java.util.Collection;
-
-import javax.persistence.EntityManager;
-import javax.persistence.PersistenceContext;
-
-import org.springframework.cache.annotation.Cacheable;
-import org.springframework.samples.petclinic.model.Vet;
-import org.springframework.samples.petclinic.repository.VetRepository;
-import org.springframework.stereotype.Repository;
-
-/**
- * JPA implementation of the {@link VetRepository} interface.
- *
- * @author Mike Keith
- * @author Rod Johnson
- * @author Sam Brannen
- * @author Michael Isvy
- * @since 22.4.2006
- */
-@Repository
-public class JpaVetRepositoryImpl implements VetRepository {
-
- @PersistenceContext
- private EntityManager em;
-
-
- @Override
- @Cacheable(value = "vets")
- @SuppressWarnings("unchecked")
- public Collection findAll() {
- return this.em.createQuery("SELECT distinct vet FROM Vet vet left join fetch vet.specialties ORDER BY vet.lastName, vet.firstName").getResultList();
- }
-
-}
diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaVisitRepositoryImpl.java b/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaVisitRepositoryImpl.java
deleted file mode 100644
index 3415def96..000000000
--- a/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaVisitRepositoryImpl.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright 2002-2013 the original author or authors.
- *
- * Licensed 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.springframework.samples.petclinic.repository.jpa;
-
-import java.util.List;
-
-import javax.persistence.EntityManager;
-import javax.persistence.PersistenceContext;
-import javax.persistence.Query;
-
-import org.springframework.samples.petclinic.model.Visit;
-import org.springframework.samples.petclinic.repository.VisitRepository;
-import org.springframework.stereotype.Repository;
-
-/**
- * JPA implementation of the ClinicService interface using EntityManager.
- *
- *
The mappings are defined in "orm.xml" located in the META-INF directory.
- *
- * @author Mike Keith
- * @author Rod Johnson
- * @author Sam Brannen
- * @author Michael Isvy
- * @since 22.4.2006
- */
-@Repository
-public class JpaVisitRepositoryImpl implements VisitRepository {
-
- @PersistenceContext
- private EntityManager em;
-
-
- @Override
- public void save(Visit visit) {
- if (visit.getId() == null) {
- this.em.persist(visit);
- }
- else {
- this.em.merge(visit);
- }
- }
-
-
- @Override
- @SuppressWarnings("unchecked")
- public List findByPetId(Integer petId) {
- Query query = this.em.createQuery("SELECT visit FROM Visit v where v.pets.id= :id");
- query.setParameter("id", petId);
- return query.getResultList();
- }
-
-}
diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jpa/package-info.java b/src/main/java/org/springframework/samples/petclinic/repository/jpa/package-info.java
deleted file mode 100644
index 13c8552ed..000000000
--- a/src/main/java/org/springframework/samples/petclinic/repository/jpa/package-info.java
+++ /dev/null
@@ -1,9 +0,0 @@
-
-/**
- *
- * The classes in this package represent the JPA implementation
- * of PetClinic's persistence layer.
- *
- */
-package org.springframework.samples.petclinic.repository.jpa;
-
diff --git a/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataOwnerRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataOwnerRepository.java
deleted file mode 100644
index ca1f709f6..000000000
--- a/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataOwnerRepository.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2002-2013 the original author or authors.
- *
- * Licensed 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.springframework.samples.petclinic.repository.springdatajpa;
-
-import java.util.Collection;
-
-import org.springframework.data.jpa.repository.Query;
-import org.springframework.data.repository.Repository;
-import org.springframework.data.repository.query.Param;
-import org.springframework.samples.petclinic.model.Owner;
-import org.springframework.samples.petclinic.repository.OwnerRepository;
-
-/**
- * Spring Data JPA specialization of the {@link OwnerRepository} interface
- *
- * @author Michael Isvy
- * @since 15.1.2013
- */
-public interface SpringDataOwnerRepository extends OwnerRepository, Repository {
-
- @Override
- @Query("SELECT DISTINCT owner FROM Owner owner left join fetch owner.pets WHERE owner.lastName LIKE :lastName%")
- public Collection findByLastName(@Param("lastName") String lastName);
-
- @Override
- @Query("SELECT owner FROM Owner owner left join fetch owner.pets WHERE owner.id =:id")
- public Owner findById(@Param("id") int id);
-}
diff --git a/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataPetRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataPetRepository.java
deleted file mode 100644
index 56a413147..000000000
--- a/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataPetRepository.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2002-2013 the original author or authors.
- *
- * Licensed 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.springframework.samples.petclinic.repository.springdatajpa;
-
-import java.util.List;
-
-import org.springframework.dao.DataAccessException;
-import org.springframework.data.jpa.repository.Query;
-import org.springframework.data.repository.Repository;
-import org.springframework.samples.petclinic.model.Pet;
-import org.springframework.samples.petclinic.model.PetType;
-import org.springframework.samples.petclinic.repository.PetRepository;
-
-/**
- * Spring Data JPA specialization of the {@link PetRepository} interface
- *
- * @author Michael Isvy
- * @since 15.1.2013
- */
-public interface SpringDataPetRepository extends PetRepository, Repository {
-
- @Override
- @Query("SELECT ptype FROM PetType ptype ORDER BY ptype.name")
- List findPetTypes() throws DataAccessException;
-}
diff --git a/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataVetRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataVetRepository.java
deleted file mode 100644
index b8211b707..000000000
--- a/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataVetRepository.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright 2002-2013 the original author or authors.
- *
- * Licensed 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.springframework.samples.petclinic.repository.springdatajpa;
-
-import org.springframework.data.repository.Repository;
-import org.springframework.samples.petclinic.model.Vet;
-import org.springframework.samples.petclinic.repository.VetRepository;
-
-/**
- * Spring Data JPA specialization of the {@link VetRepository} interface
- *
- * @author Michael Isvy
- * @since 15.1.2013
- */
-public interface SpringDataVetRepository extends VetRepository, Repository {
-}
diff --git a/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataVisitRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataVisitRepository.java
deleted file mode 100644
index 84740224b..000000000
--- a/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataVisitRepository.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright 2002-2013 the original author or authors.
- *
- * Licensed 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.springframework.samples.petclinic.repository.springdatajpa;
-
-import org.springframework.data.repository.Repository;
-import org.springframework.samples.petclinic.model.Visit;
-import org.springframework.samples.petclinic.repository.VisitRepository;
-
-/**
- * Spring Data JPA specialization of the {@link VisitRepository} interface
- *
- * @author Michael Isvy
- * @since 15.1.2013
- */
-public interface SpringDataVisitRepository extends VisitRepository, Repository {
-}
diff --git a/src/main/java/org/springframework/samples/petclinic/service/ClinicService.java b/src/main/java/org/springframework/samples/petclinic/service/ClinicService.java
index 936582129..d35e26bdf 100644
--- a/src/main/java/org/springframework/samples/petclinic/service/ClinicService.java
+++ b/src/main/java/org/springframework/samples/petclinic/service/ClinicService.java
@@ -17,7 +17,6 @@ package org.springframework.samples.petclinic.service;
import java.util.Collection;
-import org.springframework.dao.DataAccessException;
import org.springframework.samples.petclinic.model.Owner;
import org.springframework.samples.petclinic.model.Pet;
import org.springframework.samples.petclinic.model.PetType;
@@ -32,20 +31,20 @@ import org.springframework.samples.petclinic.model.Visit;
*/
public interface ClinicService {
- Collection findPetTypes() throws DataAccessException;
+ Collection findPetTypes();
- Owner findOwnerById(int id) throws DataAccessException;
+ Owner findOwnerById(int id);
- Pet findPetById(int id) throws DataAccessException;
+ Pet findPetById(int id);
- void savePet(Pet pet) throws DataAccessException;
+ void savePet(Pet pet);
- void saveVisit(Visit visit) throws DataAccessException;
+ void saveVisit(Visit visit);
- Collection findVets() throws DataAccessException;
+ Collection findVets();
- void saveOwner(Owner owner) throws DataAccessException;
+ void saveOwner(Owner owner);
- Collection findOwnerByLastName(String lastName) throws DataAccessException;
+ Collection findAll();
}
diff --git a/src/main/java/org/springframework/samples/petclinic/service/ClinicServiceImpl.java b/src/main/java/org/springframework/samples/petclinic/service/ClinicServiceImpl.java
index 0d7ff4d0c..59b764092 100644
--- a/src/main/java/org/springframework/samples/petclinic/service/ClinicServiceImpl.java
+++ b/src/main/java/org/springframework/samples/petclinic/service/ClinicServiceImpl.java
@@ -63,13 +63,12 @@ public class ClinicServiceImpl implements ClinicService {
@Override
@Transactional(readOnly = true)
public Owner findOwnerById(int id) throws DataAccessException {
- return ownerRepository.findById(id);
+ return ownerRepository.findOne(id);
}
- @Override
@Transactional(readOnly = true)
- public Collection findOwnerByLastName(String lastName) throws DataAccessException {
- return ownerRepository.findByLastName(lastName);
+ public Collection findAll() throws DataAccessException {
+ return ownerRepository.findAll();
}
@Override
diff --git a/src/main/java/org/springframework/samples/petclinic/util/CallMonitoringAspect.java b/src/main/java/org/springframework/samples/petclinic/util/CallMonitoringAspect.java
index 3c699842f..2ddcf5f6c 100644
--- a/src/main/java/org/springframework/samples/petclinic/util/CallMonitoringAspect.java
+++ b/src/main/java/org/springframework/samples/petclinic/util/CallMonitoringAspect.java
@@ -66,10 +66,11 @@ public class CallMonitoringAspect {
@ManagedAttribute
public long getCallTime() {
- if (this.callCount > 0)
- return this.accumulatedCallTime / this.callCount;
- else
- return 0;
+ if (this.callCount > 0) {
+ return this.accumulatedCallTime / this.callCount;
+ } else {
+ return 0;
+ }
}
diff --git a/src/main/java/org/springframework/samples/petclinic/web/CrashController.java b/src/main/java/org/springframework/samples/petclinic/web/CrashController.java
deleted file mode 100644
index e413f3f3b..000000000
--- a/src/main/java/org/springframework/samples/petclinic/web/CrashController.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2002-2013 the original author or authors.
- *
- * Licensed 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.springframework.samples.petclinic.web;
-
-import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-
-/**
- * Controller used to showcase what happens when an exception is thrown
- *
- * @author Michael Isvy
- *
- * Also see how the bean of type 'SimpleMappingExceptionResolver' has been declared inside
- * /WEB-INF/mvc-core-config.xml
- */
-@Controller
-public class CrashController {
-
- @RequestMapping(value = "/oups", method = RequestMethod.GET)
- public String triggerException() {
- throw new RuntimeException("Expected: controller used to showcase what " +
- "happens when an exception is thrown");
- }
-
-
-}
diff --git a/src/main/java/org/springframework/samples/petclinic/web/OwnerResource.java b/src/main/java/org/springframework/samples/petclinic/web/OwnerResource.java
index 851a3ff75..2c3a1d8d0 100644
--- a/src/main/java/org/springframework/samples/petclinic/web/OwnerResource.java
+++ b/src/main/java/org/springframework/samples/petclinic/web/OwnerResource.java
@@ -22,15 +22,17 @@ import org.springframework.http.HttpStatus;
import org.springframework.samples.petclinic.model.Owner;
import org.springframework.samples.petclinic.service.ClinicService;
import org.springframework.web.bind.WebDataBinder;
+import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
+import javax.validation.Valid;
+
/**
* @author Juergen Hoeller
* @author Ken Krebs
@@ -62,9 +64,8 @@ public class OwnerResource {
*/
@RequestMapping(value = "/owner", method = RequestMethod.POST)
@ResponseStatus(HttpStatus.CREATED)
- public void createOwner(@RequestBody Owner owner) {
+ public void createOwner(@Valid @RequestBody Owner owner) {
this.clinicService.saveOwner(owner);
- // TODO: need to handle failure
}
/**
@@ -78,27 +79,16 @@ public class OwnerResource {
/**
* Read List of Owners
*/
- @RequestMapping(value = "/owner/list", method = RequestMethod.GET)
- public Collection findOwnerCollection(@RequestParam("lastName") String ownerLastName) {
-
- if (ownerLastName == null) {
- ownerLastName = "";
- }
-
- Collection results = this.clinicService.findOwnerByLastName(ownerLastName);
- if (results.isEmpty()) {
- return null;
- }
- else {
- return results;
- }
+ @GetMapping("/owner/list")
+ public Collection findAll() {
+ return clinicService.findAll();
}
/**
* Update Owner
*/
@RequestMapping(value = "/owner/{ownerId}", method = RequestMethod.PUT)
- public Owner updateOwner(@PathVariable("ownerId") int ownerId, @RequestBody Owner ownerRequest) {
+ public Owner updateOwner(@PathVariable("ownerId") int ownerId, @Valid @RequestBody Owner ownerRequest) {
Owner ownerModel = retrieveOwner(ownerId);
// This is done by hand for simplicity purpose. In a real life use-case we should consider using MapStruct.
ownerModel.setFirstName(ownerRequest.getFirstName());
@@ -108,7 +98,6 @@ public class OwnerResource {
ownerModel.setTelephone(ownerRequest.getTelephone());
this.clinicService.saveOwner(ownerModel);
return ownerModel;
- // TODO: need to handle failure
}
diff --git a/src/main/java/org/springframework/samples/petclinic/web/PetResource.java b/src/main/java/org/springframework/samples/petclinic/web/PetResource.java
index 3651968bb..8a93d3384 100644
--- a/src/main/java/org/springframework/samples/petclinic/web/PetResource.java
+++ b/src/main/java/org/springframework/samples/petclinic/web/PetResource.java
@@ -15,23 +15,27 @@
*/
package org.springframework.samples.petclinic.web;
-import java.util.Collection;
-import java.util.Map;
-
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import lombok.Getter;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.http.HttpStatus;
import org.springframework.samples.petclinic.model.Owner;
import org.springframework.samples.petclinic.model.Pet;
import org.springframework.samples.petclinic.model.PetType;
import org.springframework.samples.petclinic.service.ClinicService;
-import org.springframework.validation.BindingResult;
-import org.springframework.web.bind.WebDataBinder;
-import org.springframework.web.bind.annotation.InitBinder;
-import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
-import org.springframework.web.bind.support.SessionStatus;
+
+import javax.validation.constraints.Size;
+import java.util.Date;
+import java.util.Map;
/**
* @author Juergen Hoeller
@@ -43,23 +47,17 @@ public class PetResource {
private final ClinicService clinicService;
-
@Autowired
public PetResource(ClinicService clinicService) {
this.clinicService = clinicService;
}
- @ModelAttribute("types")
- public Collection populatePetTypes() {
- return this.clinicService.findPetTypes();
+ @GetMapping("/petTypes")
+ Object getPetTypes() {
+ return clinicService.findPetTypes();
}
- @InitBinder
- public void setAllowedFields(WebDataBinder dataBinder) {
- dataBinder.setDisallowedFields("id");
- }
-
- @RequestMapping(value = "/owners/{ownerId}/pets/new", method = RequestMethod.GET)
+ @GetMapping("/owners/{ownerId}/pets/new")
public String initCreationForm(@PathVariable("ownerId") int ownerId, Map model) {
Owner owner = this.clinicService.findOwnerById(ownerId);
Pet pet = new Pet();
@@ -68,35 +66,73 @@ public class PetResource {
return "pets/createOrUpdatePetForm";
}
- @RequestMapping(value = "/owners/{ownerId}/pets/new", method = RequestMethod.POST)
- public String processCreationForm(@ModelAttribute("pet") Pet pet, BindingResult result, SessionStatus status) {
- new PetValidator().validate(pet, result);
- if (result.hasErrors()) {
- return "pets/createOrUpdatePetForm";
- } else {
- this.clinicService.savePet(pet);
- status.setComplete();
- return "redirect:/owner/{ownerId}";
- }
+ @PostMapping("/owners/{ownerId}/pets")
+ @ResponseStatus(HttpStatus.NO_CONTENT)
+ public void processCreationForm(
+ @RequestBody PetRequest petRequest,
+ @PathVariable("ownerId") int ownerId) {
+
+ Pet pet = new Pet();
+ Owner owner = this.clinicService.findOwnerById(ownerId);
+ owner.addPet(pet);
+
+ save(pet, petRequest);
}
- @RequestMapping(value = "/owner/*/pet/{petId}", method = RequestMethod.GET)
- public Pet findPet(@PathVariable("petId") int petId) {
+ @PutMapping("/owners/{ownerId}/pets/{petId}")
+ @ResponseStatus(HttpStatus.NO_CONTENT)
+ public void processUpdateForm(@RequestBody PetRequest petRequest) {
+ save(clinicService.findPetById(petRequest.getId()), petRequest);
+ }
+
+ private void save(Pet pet, PetRequest petRequest) {
+
+ pet.setName(petRequest.getName());
+ pet.setBirthDate(petRequest.getBirthDate());
+
+ for (PetType petType : clinicService.findPetTypes()) {
+ if (petType.getId() == petRequest.getTypeId()) {
+ pet.setType(petType);
+ }
+ }
+
+ clinicService.savePet(pet);
+ }
+
+ @GetMapping("/owner/*/pet/{petId}")
+ public PetDetails findPet(@PathVariable("petId") int petId) {
Pet pet = this.clinicService.findPetById(petId);
- return pet;
+ return new PetDetails(pet);
}
- @RequestMapping(value = "/owners/{ownerId}/pets/{petId}/edit", method = {RequestMethod.PUT, RequestMethod.POST})
- public String processUpdateForm(@ModelAttribute("pet") Pet pet, BindingResult result, SessionStatus status) {
- // we're not using @Valid annotation here because it is easier to define such validation rule in Java
- new PetValidator().validate(pet, result);
- if (result.hasErrors()) {
- return "pets/createOrUpdatePetForm";
- } else {
- this.clinicService.savePet(pet);
- status.setComplete();
- return "redirect:/owners/{ownerId}";
+ @Data
+ static class PetRequest {
+ int id;
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ Date birthDate;
+ @Size(min = 1)
+ String name;
+ int typeId;
+ }
+
+ @Getter
+ static class PetDetails {
+
+ long id;
+ String name;
+ String owner;
+ @DateTimeFormat(pattern = "yyyy-MM-dd")
+ Date birthDate;
+ PetType type;
+
+ PetDetails(Pet pet) {
+ this.id = pet.getId();
+ this.name = pet.getName();
+ this.owner = pet.getOwner().getFirstName() + " " + pet.getOwner().getLastName();
+ this.birthDate = pet.getBirthDate();
+ this.type = pet.getType();
}
+
}
}
diff --git a/src/main/java/org/springframework/samples/petclinic/web/PetTypeFormatter.java b/src/main/java/org/springframework/samples/petclinic/web/PetTypeFormatter.java
deleted file mode 100644
index 3d47d2201..000000000
--- a/src/main/java/org/springframework/samples/petclinic/web/PetTypeFormatter.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright 2002-2013 the original author or authors.
- *
- * Licensed 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.springframework.samples.petclinic.web;
-
-
-import java.text.ParseException;
-import java.util.Collection;
-import java.util.Locale;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.format.Formatter;
-import org.springframework.samples.petclinic.model.PetType;
-import org.springframework.samples.petclinic.service.ClinicService;
-
-/**
- * Instructs Spring MVC on how to parse and print elements of type 'PetType'. Starting from Spring 3.0, Formatters have
- * come as an improvement in comparison to legacy PropertyEditors. See the following links for more details: - The
- * Spring ref doc: http://static.springsource.org/spring/docs/current/spring-framework-reference/html/validation.html#format-Formatter-SPI
- * - A nice blog entry from Gordon Dickens: http://gordondickens.com/wordpress/2010/09/30/using-spring-3-0-custom-type-converter/
- *
- * Also see how the bean 'conversionService' has been declared inside /WEB-INF/mvc-core-config.xml
- *
- * @author Mark Fisher
- * @author Juergen Hoeller
- * @author Michael Isvy
- */
-public class PetTypeFormatter implements Formatter {
-
- private final ClinicService clinicService;
-
-
- @Autowired
- public PetTypeFormatter(ClinicService clinicService) {
- this.clinicService = clinicService;
- }
-
- @Override
- public String print(PetType petType, Locale locale) {
- return petType.getName();
- }
-
- @Override
- public PetType parse(String text, Locale locale) throws ParseException {
- Collection findPetTypes = this.clinicService.findPetTypes();
- for (PetType type : findPetTypes) {
- if (type.getName().equals(text)) {
- return type;
- }
- }
- throw new ParseException("type not found: " + text, 0);
- }
-
-}
diff --git a/src/main/java/org/springframework/samples/petclinic/web/PetValidator.java b/src/main/java/org/springframework/samples/petclinic/web/PetValidator.java
index 03a1bca7c..fbb7dd5be 100644
--- a/src/main/java/org/springframework/samples/petclinic/web/PetValidator.java
+++ b/src/main/java/org/springframework/samples/petclinic/web/PetValidator.java
@@ -35,14 +35,14 @@ public class PetValidator {
} else if (pet.isNew() && pet.getOwner().getPet(name, true) != null) {
errors.rejectValue("name", "duplicate", "already exists");
}
-
+
// type validation
if (pet.isNew() && pet.getType() == null) {
errors.rejectValue("type", "required", "required");
}
-
+
// birth date validation
- if (pet.getBirthDate()==null) {
+ if (pet.getBirthDate() == null) {
errors.rejectValue("birthDate", "required", "required");
}
}
diff --git a/src/main/java/org/springframework/samples/petclinic/web/VetResource.java b/src/main/java/org/springframework/samples/petclinic/web/VetResource.java
index 968c4d259..7661e97f4 100644
--- a/src/main/java/org/springframework/samples/petclinic/web/VetResource.java
+++ b/src/main/java/org/springframework/samples/petclinic/web/VetResource.java
@@ -21,6 +21,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.samples.petclinic.model.Vet;
import org.springframework.samples.petclinic.service.ClinicService;
+import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@@ -36,17 +37,13 @@ public class VetResource {
private final ClinicService clinicService;
-
@Autowired
public VetResource(ClinicService clinicService) {
this.clinicService = clinicService;
}
- @RequestMapping(value="/vets", method = RequestMethod.GET,
- produces = MediaType.APPLICATION_JSON_VALUE)
+ @GetMapping("/vets")
public Collection showResourcesVetList() {
return this.clinicService.findVets();
}
-
-
}
diff --git a/src/main/java/org/springframework/samples/petclinic/web/VisitController.java b/src/main/java/org/springframework/samples/petclinic/web/VisitController.java
deleted file mode 100644
index f3f6f3ffb..000000000
--- a/src/main/java/org/springframework/samples/petclinic/web/VisitController.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright 2002-2013 the original author or authors.
- *
- * Licensed 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.springframework.samples.petclinic.web;
-
-import java.util.Map;
-
-import javax.validation.Valid;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.samples.petclinic.model.Pet;
-import org.springframework.samples.petclinic.model.Visit;
-import org.springframework.samples.petclinic.service.ClinicService;
-import org.springframework.stereotype.Controller;
-import org.springframework.validation.BindingResult;
-import org.springframework.web.bind.WebDataBinder;
-import org.springframework.web.bind.annotation.InitBinder;
-import org.springframework.web.bind.annotation.ModelAttribute;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-
-/**
- * @author Juergen Hoeller
- * @author Ken Krebs
- * @author Arjen Poutsma
- * @author Michael Isvy
- */
-@Controller
-public class VisitController {
-
- private final ClinicService clinicService;
-
-
- @Autowired
- public VisitController(ClinicService clinicService) {
- this.clinicService = clinicService;
- }
-
- @InitBinder
- public void setAllowedFields(WebDataBinder dataBinder) {
- dataBinder.setDisallowedFields("id");
- }
-
- /**
- * Called before each and every @RequestMapping annotated method.
- * 2 goals:
- * - Make sure we always have fresh data
- * - Since we do not use the session scope, make sure that Pet object always has an id
- * (Even though id is not part of the form fields)
- * @param petId
- * @return Pet
- */
- @ModelAttribute("visit")
- public Visit loadPetWithVisit(@PathVariable("petId") int petId) {
- Pet pet = this.clinicService.findPetById(petId);
- Visit visit = new Visit();
- pet.addVisit(visit);
- return visit;
- }
-
- // Spring MVC calls method loadPetWithVisit(...) before initNewVisitForm is called
- @RequestMapping(value = "/owners/*/pets/{petId}/visits/new", method = RequestMethod.GET)
- public String initNewVisitForm(@PathVariable("petId") int petId, Map model) {
- return "pets/createOrUpdateVisitForm";
- }
-
- // Spring MVC calls method loadPetWithVisit(...) before processNewVisitForm is called
- @RequestMapping(value = "/owners/{ownerId}/pets/{petId}/visits/new", method = RequestMethod.POST)
- public String processNewVisitForm(@Valid Visit visit, BindingResult result) {
- if (result.hasErrors()) {
- return "pets/createOrUpdateVisitForm";
- } else {
- this.clinicService.saveVisit(visit);
- return "redirect:/owners/{ownerId}";
- }
- }
-
- @RequestMapping(value = "/owners/*/pets/{petId}/visits", method = RequestMethod.GET)
- public String showVisits(@PathVariable int petId, Map model) {
- model.put("visits", this.clinicService.findPetById(petId).getVisits());
- return "visitList";
- }
-
-}
diff --git a/src/main/java/org/springframework/samples/petclinic/web/VisitResource.java b/src/main/java/org/springframework/samples/petclinic/web/VisitResource.java
new file mode 100644
index 000000000..68798f79b
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/web/VisitResource.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2002-2013 the original author or authors.
+ *
+ * Licensed 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.springframework.samples.petclinic.web;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.samples.petclinic.model.Visit;
+import org.springframework.samples.petclinic.service.ClinicService;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+
+/**
+ * @author Juergen Hoeller
+ * @author Ken Krebs
+ * @author Arjen Poutsma
+ * @author Michael Isvy
+ */
+@RestController
+public class VisitResource {
+
+ private final ClinicService clinicService;
+
+ @Autowired
+ public VisitResource(ClinicService clinicService) {
+ this.clinicService = clinicService;
+ }
+
+ @PostMapping("/owners/{ownerId}/pets/{petId}/visits")
+ @ResponseStatus(HttpStatus.NO_CONTENT)
+ public void create(
+ @Valid @RequestBody Visit visit,
+ @PathVariable("petId") int petId) {
+
+ clinicService.findPetById(petId).addVisit(visit);
+ clinicService.saveVisit(visit);
+ }
+
+ @GetMapping("/owners/{ownerId}/pets/{petId}/visits")
+ public Object visits(@PathVariable("petId") int petId) {
+ return clinicService.findPetById(petId).getVisits();
+ }
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/web/package-info.java b/src/main/java/org/springframework/samples/petclinic/web/package-info.java
deleted file mode 100644
index c909ccf7f..000000000
--- a/src/main/java/org/springframework/samples/petclinic/web/package-info.java
+++ /dev/null
@@ -1,8 +0,0 @@
-
-/**
- *
- * The classes in this package represent PetClinic's web presentation layer.
- *
- */
-package org.springframework.samples.petclinic.web;
-
diff --git a/src/main/java/overview.html b/src/main/java/overview.html
deleted file mode 100644
index df4f4d6b7..000000000
--- a/src/main/java/overview.html
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
- The Spring Data Binding framework, an internal library used by Spring Web Flow.
-
-
-
\ No newline at end of file
diff --git a/src/main/java/test.html b/src/main/java/test.html
deleted file mode 100644
index 9a7a99675..000000000
--- a/src/main/java/test.html
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
-
-
Organisation
-
-
Speakers
-
-
-
-
-
-
Sergiu Bodiu
-
Java Consultant at Bank of America
- Seasoned consultant experienced in large-scale e-commerce projects, passionate about providing innovative technology solutions to solve complex business problems, have extensive knowledge and experience delivering enterprise wide applications. He is skilled in software design, data modeling, stakeholder management, IT strategic planning, technical know-how and security. Able to design, implement, test and maintain software product components with strong focus on design elegance and software reuse.
-
-
-
-
-
-
Sergiu Bodiu
-
Java Consultant at Bank of America
- Seasoned consultant experienced in large-scale e-commerce projects, passionate about providing innovative technology solutions to solve complex business problems, have extensive knowledge and experience delivering enterprise wide applications. He is skilled in software design, data modeling, stakeholder management, IT strategic planning, technical know-how and security. Able to design, implement, test and maintain software product components with strong focus on design elegance and software reuse.
-
-
-
-
diff --git a/src/main/webapp/WEB-INF/no-spring-config-files-there.txt b/src/main/webapp/WEB-INF/no-spring-config-files-there.txt
deleted file mode 100644
index 45fb7bf0a..000000000
--- a/src/main/webapp/WEB-INF/no-spring-config-files-there.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-All Spring config files (including Spring MVC ones) are inside src/main/resource.
-There are mostly 2 reasons to that:
-- All Spring config files are grouped into one single place
-- It is simpler to reference them from inside JUnit tests
\ No newline at end of file
diff --git a/src/main/webapp/WEB-INF/tags/inputField.tag b/src/main/webapp/WEB-INF/tags/inputField.tag
deleted file mode 100644
index 796dc91c0..000000000
--- a/src/main/webapp/WEB-INF/tags/inputField.tag
+++ /dev/null
@@ -1,19 +0,0 @@
-<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
-<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
-<%@ attribute name="name" required="true" rtexprvalue="true"
- description="Name of corresponding property in bean object" %>
-<%@ attribute name="label" required="true" rtexprvalue="true"
- description="Label appears in red color if input is considered as invalid after submission" %>
-
-
-
-
-
-
-
-
- ${status.errorMessage}
-
-
-
\ No newline at end of file
diff --git a/src/main/webapp/WEB-INF/tags/selectField.tag b/src/main/webapp/WEB-INF/tags/selectField.tag
deleted file mode 100644
index f93256ac8..000000000
--- a/src/main/webapp/WEB-INF/tags/selectField.tag
+++ /dev/null
@@ -1,23 +0,0 @@
-<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
-<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
-<%@ attribute name="name" required="true" rtexprvalue="true"
- description="Name of corresponding property in bean object" %>
-<%@ attribute name="label" required="true" rtexprvalue="true"
- description="Label appears in red color if input is considered as invalid after submission" %>
-<%@ attribute name="names" required="true" rtexprvalue="true" type="java.util.List"
- description="Names in the list" %>
-<%@ attribute name="size" required="true" rtexprvalue="true"
- description="Size of Select" %>
-
-
-
-
-
-
-
-
- ${status.errorMessage}
-
-
-
\ No newline at end of file
diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml
deleted file mode 100644
index fb397e89d..000000000
--- a/src/main/webapp/WEB-INF/web.xml
+++ /dev/null
@@ -1,95 +0,0 @@
-
-
-
- Spring PetClinic
- Spring PetClinic sample application
-
-
- spring.profiles.active
- jpa
-
-
-
-
-
-
-
-
-
-
- contextConfigLocation
- classpath:spring/business-config.xml, classpath:spring/tools-config.xml
-
-
-
- org.springframework.web.context.ContextLoaderListener
-
-
-
-
- petclinic
- org.springframework.web.servlet.DispatcherServlet
-
- contextConfigLocation
- classpath:spring/mvc-core-config.xml
-
- 1
-
-
-
- petclinic
- /
-
-
-
-
-
-
- httpMethodFilter
- org.springframework.web.filter.HiddenHttpMethodFilter
-
-
-
- httpMethodFilter
- petclinic
-
-
-
-
- encodingFilter
- org.springframework.web.filter.CharacterEncodingFilter
-
- encoding
- UTF-8
-
-
- forceEncoding
- true
-
-
-
-
- encodingFilter
- /*
-
-
-
\ No newline at end of file
diff --git a/src/main/webapp/bower_components/angular-mocks/.bower.json b/src/main/webapp/bower_components/angular-mocks/.bower.json
deleted file mode 100644
index c2d3a35ac..000000000
--- a/src/main/webapp/bower_components/angular-mocks/.bower.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "name": "angular-mocks",
- "version": "1.3.11",
- "main": "./angular-mocks.js",
- "ignore": [],
- "dependencies": {
- "angular": "1.3.11"
- },
- "homepage": "https://github.com/angular/bower-angular-mocks",
- "_release": "1.3.11",
- "_resolution": {
- "type": "version",
- "tag": "v1.3.11",
- "commit": "2457be05bbe0d16947e2a1a0add1798cbadd11d2"
- },
- "_source": "git://github.com/angular/bower-angular-mocks.git",
- "_target": "1.3.11",
- "_originalSource": "angular-mocks"
-}
\ No newline at end of file
diff --git a/src/main/webapp/bower_components/angular-mocks/README.md b/src/main/webapp/bower_components/angular-mocks/README.md
deleted file mode 100644
index 1604ef880..000000000
--- a/src/main/webapp/bower_components/angular-mocks/README.md
+++ /dev/null
@@ -1,57 +0,0 @@
-# packaged angular-mocks
-
-This repo is for distribution on `npm` and `bower`. The source for this module is in the
-[main AngularJS repo](https://github.com/angular/angular.js/tree/master/src/ngMock).
-Please file issues and pull requests against that repo.
-
-## Install
-
-You can install this package either with `npm` or with `bower`.
-
-### npm
-
-```shell
-npm install angular-mocks
-```
-
-The mocks are then available at `node_modules/angular-mocks/angular-mocks.js`.
-
-Note that this package is not in CommonJS format, so doing `require('angular-mocks')` will
-return `undefined`.
-
-### bower
-
-```shell
-bower install angular-mocks
-```
-
-The mocks are then available at `bower_components/angular-mocks/angular-mocks.js`.
-
-## Documentation
-
-Documentation is available on the
-[AngularJS docs site](https://docs.angularjs.org/guide/unit-testing).
-
-## License
-
-The MIT License
-
-Copyright (c) 2010-2012 Google, Inc. http://angularjs.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/src/main/webapp/bower_components/angular-mocks/angular-mocks.js b/src/main/webapp/bower_components/angular-mocks/angular-mocks.js
deleted file mode 100644
index 2a411cc38..000000000
--- a/src/main/webapp/bower_components/angular-mocks/angular-mocks.js
+++ /dev/null
@@ -1,2382 +0,0 @@
-/**
- * @license AngularJS v1.3.11
- * (c) 2010-2014 Google, Inc. http://angularjs.org
- * License: MIT
- */
-(function(window, angular, undefined) {
-
-'use strict';
-
-/**
- * @ngdoc object
- * @name angular.mock
- * @description
- *
- * Namespace from 'angular-mocks.js' which contains testing related code.
- */
-angular.mock = {};
-
-/**
- * ! This is a private undocumented service !
- *
- * @name $browser
- *
- * @description
- * This service is a mock implementation of {@link ng.$browser}. It provides fake
- * implementation for commonly used browser apis that are hard to test, e.g. setTimeout, xhr,
- * cookies, etc...
- *
- * The api of this service is the same as that of the real {@link ng.$browser $browser}, except
- * that there are several helper methods available which can be used in tests.
- */
-angular.mock.$BrowserProvider = function() {
- this.$get = function() {
- return new angular.mock.$Browser();
- };
-};
-
-angular.mock.$Browser = function() {
- var self = this;
-
- this.isMock = true;
- self.$$url = "http://server/";
- self.$$lastUrl = self.$$url; // used by url polling fn
- self.pollFns = [];
-
- // TODO(vojta): remove this temporary api
- self.$$completeOutstandingRequest = angular.noop;
- self.$$incOutstandingRequestCount = angular.noop;
-
-
- // register url polling fn
-
- self.onUrlChange = function(listener) {
- self.pollFns.push(
- function() {
- if (self.$$lastUrl !== self.$$url || self.$$state !== self.$$lastState) {
- self.$$lastUrl = self.$$url;
- self.$$lastState = self.$$state;
- listener(self.$$url, self.$$state);
- }
- }
- );
-
- return listener;
- };
-
- self.$$checkUrlChange = angular.noop;
-
- self.cookieHash = {};
- self.lastCookieHash = {};
- self.deferredFns = [];
- self.deferredNextId = 0;
-
- self.defer = function(fn, delay) {
- delay = delay || 0;
- self.deferredFns.push({time:(self.defer.now + delay), fn:fn, id: self.deferredNextId});
- self.deferredFns.sort(function(a, b) { return a.time - b.time;});
- return self.deferredNextId++;
- };
-
-
- /**
- * @name $browser#defer.now
- *
- * @description
- * Current milliseconds mock time.
- */
- self.defer.now = 0;
-
-
- self.defer.cancel = function(deferId) {
- var fnIndex;
-
- angular.forEach(self.deferredFns, function(fn, index) {
- if (fn.id === deferId) fnIndex = index;
- });
-
- if (fnIndex !== undefined) {
- self.deferredFns.splice(fnIndex, 1);
- return true;
- }
-
- return false;
- };
-
-
- /**
- * @name $browser#defer.flush
- *
- * @description
- * Flushes all pending requests and executes the defer callbacks.
- *
- * @param {number=} number of milliseconds to flush. See {@link #defer.now}
- */
- self.defer.flush = function(delay) {
- if (angular.isDefined(delay)) {
- self.defer.now += delay;
- } else {
- if (self.deferredFns.length) {
- self.defer.now = self.deferredFns[self.deferredFns.length - 1].time;
- } else {
- throw new Error('No deferred tasks to be flushed');
- }
- }
-
- while (self.deferredFns.length && self.deferredFns[0].time <= self.defer.now) {
- self.deferredFns.shift().fn();
- }
- };
-
- self.$$baseHref = '/';
- self.baseHref = function() {
- return this.$$baseHref;
- };
-};
-angular.mock.$Browser.prototype = {
-
-/**
- * @name $browser#poll
- *
- * @description
- * run all fns in pollFns
- */
- poll: function poll() {
- angular.forEach(this.pollFns, function(pollFn) {
- pollFn();
- });
- },
-
- addPollFn: function(pollFn) {
- this.pollFns.push(pollFn);
- return pollFn;
- },
-
- url: function(url, replace, state) {
- if (angular.isUndefined(state)) {
- state = null;
- }
- if (url) {
- this.$$url = url;
- // Native pushState serializes & copies the object; simulate it.
- this.$$state = angular.copy(state);
- return this;
- }
-
- return this.$$url;
- },
-
- state: function() {
- return this.$$state;
- },
-
- cookies: function(name, value) {
- if (name) {
- if (angular.isUndefined(value)) {
- delete this.cookieHash[name];
- } else {
- if (angular.isString(value) && //strings only
- value.length <= 4096) { //strict cookie storage limits
- this.cookieHash[name] = value;
- }
- }
- } else {
- if (!angular.equals(this.cookieHash, this.lastCookieHash)) {
- this.lastCookieHash = angular.copy(this.cookieHash);
- this.cookieHash = angular.copy(this.cookieHash);
- }
- return this.cookieHash;
- }
- },
-
- notifyWhenNoOutstandingRequests: function(fn) {
- fn();
- }
-};
-
-
-/**
- * @ngdoc provider
- * @name $exceptionHandlerProvider
- *
- * @description
- * Configures the mock implementation of {@link ng.$exceptionHandler} to rethrow or to log errors
- * passed to the `$exceptionHandler`.
- */
-
-/**
- * @ngdoc service
- * @name $exceptionHandler
- *
- * @description
- * Mock implementation of {@link ng.$exceptionHandler} that rethrows or logs errors passed
- * to it. See {@link ngMock.$exceptionHandlerProvider $exceptionHandlerProvider} for configuration
- * information.
- *
- *
- * ```js
- * describe('$exceptionHandlerProvider', function() {
- *
- * it('should capture log messages and exceptions', function() {
- *
- * module(function($exceptionHandlerProvider) {
- * $exceptionHandlerProvider.mode('log');
- * });
- *
- * inject(function($log, $exceptionHandler, $timeout) {
- * $timeout(function() { $log.log(1); });
- * $timeout(function() { $log.log(2); throw 'banana peel'; });
- * $timeout(function() { $log.log(3); });
- * expect($exceptionHandler.errors).toEqual([]);
- * expect($log.assertEmpty());
- * $timeout.flush();
- * expect($exceptionHandler.errors).toEqual(['banana peel']);
- * expect($log.log.logs).toEqual([[1], [2], [3]]);
- * });
- * });
- * });
- * ```
- */
-
-angular.mock.$ExceptionHandlerProvider = function() {
- var handler;
-
- /**
- * @ngdoc method
- * @name $exceptionHandlerProvider#mode
- *
- * @description
- * Sets the logging mode.
- *
- * @param {string} mode Mode of operation, defaults to `rethrow`.
- *
- * - `log`: Sometimes it is desirable to test that an error is thrown, for this case the `log`
- * mode stores an array of errors in `$exceptionHandler.errors`, to allow later
- * assertion of them. See {@link ngMock.$log#assertEmpty assertEmpty()} and
- * {@link ngMock.$log#reset reset()}
- * - `rethrow`: If any errors are passed to the handler in tests, it typically means that there
- * is a bug in the application or test, so this mock will make these tests fail.
- * For any implementations that expect exceptions to be thrown, the `rethrow` mode
- * will also maintain a log of thrown errors.
- */
- this.mode = function(mode) {
-
- switch (mode) {
- case 'log':
- case 'rethrow':
- var errors = [];
- handler = function(e) {
- if (arguments.length == 1) {
- errors.push(e);
- } else {
- errors.push([].slice.call(arguments, 0));
- }
- if (mode === "rethrow") {
- throw e;
- }
- };
- handler.errors = errors;
- break;
- default:
- throw new Error("Unknown mode '" + mode + "', only 'log'/'rethrow' modes are allowed!");
- }
- };
-
- this.$get = function() {
- return handler;
- };
-
- this.mode('rethrow');
-};
-
-
-/**
- * @ngdoc service
- * @name $log
- *
- * @description
- * Mock implementation of {@link ng.$log} that gathers all logged messages in arrays
- * (one array per logging level). These arrays are exposed as `logs` property of each of the
- * level-specific log function, e.g. for level `error` the array is exposed as `$log.error.logs`.
- *
- */
-angular.mock.$LogProvider = function() {
- var debug = true;
-
- function concat(array1, array2, index) {
- return array1.concat(Array.prototype.slice.call(array2, index));
- }
-
- this.debugEnabled = function(flag) {
- if (angular.isDefined(flag)) {
- debug = flag;
- return this;
- } else {
- return debug;
- }
- };
-
- this.$get = function() {
- var $log = {
- log: function() { $log.log.logs.push(concat([], arguments, 0)); },
- warn: function() { $log.warn.logs.push(concat([], arguments, 0)); },
- info: function() { $log.info.logs.push(concat([], arguments, 0)); },
- error: function() { $log.error.logs.push(concat([], arguments, 0)); },
- debug: function() {
- if (debug) {
- $log.debug.logs.push(concat([], arguments, 0));
- }
- }
- };
-
- /**
- * @ngdoc method
- * @name $log#reset
- *
- * @description
- * Reset all of the logging arrays to empty.
- */
- $log.reset = function() {
- /**
- * @ngdoc property
- * @name $log#log.logs
- *
- * @description
- * Array of messages logged using {@link ng.$log#log `log()`}.
- *
- * @example
- * ```js
- * $log.log('Some Log');
- * var first = $log.log.logs.unshift();
- * ```
- */
- $log.log.logs = [];
- /**
- * @ngdoc property
- * @name $log#info.logs
- *
- * @description
- * Array of messages logged using {@link ng.$log#info `info()`}.
- *
- * @example
- * ```js
- * $log.info('Some Info');
- * var first = $log.info.logs.unshift();
- * ```
- */
- $log.info.logs = [];
- /**
- * @ngdoc property
- * @name $log#warn.logs
- *
- * @description
- * Array of messages logged using {@link ng.$log#warn `warn()`}.
- *
- * @example
- * ```js
- * $log.warn('Some Warning');
- * var first = $log.warn.logs.unshift();
- * ```
- */
- $log.warn.logs = [];
- /**
- * @ngdoc property
- * @name $log#error.logs
- *
- * @description
- * Array of messages logged using {@link ng.$log#error `error()`}.
- *
- * @example
- * ```js
- * $log.error('Some Error');
- * var first = $log.error.logs.unshift();
- * ```
- */
- $log.error.logs = [];
- /**
- * @ngdoc property
- * @name $log#debug.logs
- *
- * @description
- * Array of messages logged using {@link ng.$log#debug `debug()`}.
- *
- * @example
- * ```js
- * $log.debug('Some Error');
- * var first = $log.debug.logs.unshift();
- * ```
- */
- $log.debug.logs = [];
- };
-
- /**
- * @ngdoc method
- * @name $log#assertEmpty
- *
- * @description
- * Assert that all of the logging methods have no logged messages. If any messages are present,
- * an exception is thrown.
- */
- $log.assertEmpty = function() {
- var errors = [];
- angular.forEach(['error', 'warn', 'info', 'log', 'debug'], function(logLevel) {
- angular.forEach($log[logLevel].logs, function(log) {
- angular.forEach(log, function(logItem) {
- errors.push('MOCK $log (' + logLevel + '): ' + String(logItem) + '\n' +
- (logItem.stack || ''));
- });
- });
- });
- if (errors.length) {
- errors.unshift("Expected $log to be empty! Either a message was logged unexpectedly, or " +
- "an expected log message was not checked and removed:");
- errors.push('');
- throw new Error(errors.join('\n---------\n'));
- }
- };
-
- $log.reset();
- return $log;
- };
-};
-
-
-/**
- * @ngdoc service
- * @name $interval
- *
- * @description
- * Mock implementation of the $interval service.
- *
- * Use {@link ngMock.$interval#flush `$interval.flush(millis)`} to
- * move forward by `millis` milliseconds and trigger any functions scheduled to run in that
- * time.
- *
- * @param {function()} fn A function that should be called repeatedly.
- * @param {number} delay Number of milliseconds between each function call.
- * @param {number=} [count=0] Number of times to repeat. If not set, or 0, will repeat
- * indefinitely.
- * @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise
- * will invoke `fn` within the {@link ng.$rootScope.Scope#$apply $apply} block.
- * @returns {promise} A promise which will be notified on each iteration.
- */
-angular.mock.$IntervalProvider = function() {
- this.$get = ['$browser', '$rootScope', '$q', '$$q',
- function($browser, $rootScope, $q, $$q) {
- var repeatFns = [],
- nextRepeatId = 0,
- now = 0;
-
- var $interval = function(fn, delay, count, invokeApply) {
- var iteration = 0,
- skipApply = (angular.isDefined(invokeApply) && !invokeApply),
- deferred = (skipApply ? $$q : $q).defer(),
- promise = deferred.promise;
-
- count = (angular.isDefined(count)) ? count : 0;
- promise.then(null, null, fn);
-
- promise.$$intervalId = nextRepeatId;
-
- function tick() {
- deferred.notify(iteration++);
-
- if (count > 0 && iteration >= count) {
- var fnIndex;
- deferred.resolve(iteration);
-
- angular.forEach(repeatFns, function(fn, index) {
- if (fn.id === promise.$$intervalId) fnIndex = index;
- });
-
- if (fnIndex !== undefined) {
- repeatFns.splice(fnIndex, 1);
- }
- }
-
- if (skipApply) {
- $browser.defer.flush();
- } else {
- $rootScope.$apply();
- }
- }
-
- repeatFns.push({
- nextTime:(now + delay),
- delay: delay,
- fn: tick,
- id: nextRepeatId,
- deferred: deferred
- });
- repeatFns.sort(function(a, b) { return a.nextTime - b.nextTime;});
-
- nextRepeatId++;
- return promise;
- };
- /**
- * @ngdoc method
- * @name $interval#cancel
- *
- * @description
- * Cancels a task associated with the `promise`.
- *
- * @param {promise} promise A promise from calling the `$interval` function.
- * @returns {boolean} Returns `true` if the task was successfully cancelled.
- */
- $interval.cancel = function(promise) {
- if (!promise) return false;
- var fnIndex;
-
- angular.forEach(repeatFns, function(fn, index) {
- if (fn.id === promise.$$intervalId) fnIndex = index;
- });
-
- if (fnIndex !== undefined) {
- repeatFns[fnIndex].deferred.reject('canceled');
- repeatFns.splice(fnIndex, 1);
- return true;
- }
-
- return false;
- };
-
- /**
- * @ngdoc method
- * @name $interval#flush
- * @description
- *
- * Runs interval tasks scheduled to be run in the next `millis` milliseconds.
- *
- * @param {number=} millis maximum timeout amount to flush up until.
- *
- * @return {number} The amount of time moved forward.
- */
- $interval.flush = function(millis) {
- now += millis;
- while (repeatFns.length && repeatFns[0].nextTime <= now) {
- var task = repeatFns[0];
- task.fn();
- task.nextTime += task.delay;
- repeatFns.sort(function(a, b) { return a.nextTime - b.nextTime;});
- }
- return millis;
- };
-
- return $interval;
- }];
-};
-
-
-/* jshint -W101 */
-/* The R_ISO8061_STR regex is never going to fit into the 100 char limit!
- * This directive should go inside the anonymous function but a bug in JSHint means that it would
- * not be enacted early enough to prevent the warning.
- */
-var R_ISO8061_STR = /^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?:\:?(\d\d)(?:\:?(\d\d)(?:\.(\d{3}))?)?)?(Z|([+-])(\d\d):?(\d\d)))?$/;
-
-function jsonStringToDate(string) {
- var match;
- if (match = string.match(R_ISO8061_STR)) {
- var date = new Date(0),
- tzHour = 0,
- tzMin = 0;
- if (match[9]) {
- tzHour = int(match[9] + match[10]);
- tzMin = int(match[9] + match[11]);
- }
- date.setUTCFullYear(int(match[1]), int(match[2]) - 1, int(match[3]));
- date.setUTCHours(int(match[4] || 0) - tzHour,
- int(match[5] || 0) - tzMin,
- int(match[6] || 0),
- int(match[7] || 0));
- return date;
- }
- return string;
-}
-
-function int(str) {
- return parseInt(str, 10);
-}
-
-function padNumber(num, digits, trim) {
- var neg = '';
- if (num < 0) {
- neg = '-';
- num = -num;
- }
- num = '' + num;
- while (num.length < digits) num = '0' + num;
- if (trim)
- num = num.substr(num.length - digits);
- return neg + num;
-}
-
-
-/**
- * @ngdoc type
- * @name angular.mock.TzDate
- * @description
- *
- * *NOTE*: this is not an injectable instance, just a globally available mock class of `Date`.
- *
- * Mock of the Date type which has its timezone specified via constructor arg.
- *
- * The main purpose is to create Date-like instances with timezone fixed to the specified timezone
- * offset, so that we can test code that depends on local timezone settings without dependency on
- * the time zone settings of the machine where the code is running.
- *
- * @param {number} offset Offset of the *desired* timezone in hours (fractions will be honored)
- * @param {(number|string)} timestamp Timestamp representing the desired time in *UTC*
- *
- * @example
- * !!!! WARNING !!!!!
- * This is not a complete Date object so only methods that were implemented can be called safely.
- * To make matters worse, TzDate instances inherit stuff from Date via a prototype.
- *
- * We do our best to intercept calls to "unimplemented" methods, but since the list of methods is
- * incomplete we might be missing some non-standard methods. This can result in errors like:
- * "Date.prototype.foo called on incompatible Object".
- *
- * ```js
- * var newYearInBratislava = new TzDate(-1, '2009-12-31T23:00:00Z');
- * newYearInBratislava.getTimezoneOffset() => -60;
- * newYearInBratislava.getFullYear() => 2010;
- * newYearInBratislava.getMonth() => 0;
- * newYearInBratislava.getDate() => 1;
- * newYearInBratislava.getHours() => 0;
- * newYearInBratislava.getMinutes() => 0;
- * newYearInBratislava.getSeconds() => 0;
- * ```
- *
- */
-angular.mock.TzDate = function(offset, timestamp) {
- var self = new Date(0);
- if (angular.isString(timestamp)) {
- var tsStr = timestamp;
-
- self.origDate = jsonStringToDate(timestamp);
-
- timestamp = self.origDate.getTime();
- if (isNaN(timestamp))
- throw {
- name: "Illegal Argument",
- message: "Arg '" + tsStr + "' passed into TzDate constructor is not a valid date string"
- };
- } else {
- self.origDate = new Date(timestamp);
- }
-
- var localOffset = new Date(timestamp).getTimezoneOffset();
- self.offsetDiff = localOffset * 60 * 1000 - offset * 1000 * 60 * 60;
- self.date = new Date(timestamp + self.offsetDiff);
-
- self.getTime = function() {
- return self.date.getTime() - self.offsetDiff;
- };
-
- self.toLocaleDateString = function() {
- return self.date.toLocaleDateString();
- };
-
- self.getFullYear = function() {
- return self.date.getFullYear();
- };
-
- self.getMonth = function() {
- return self.date.getMonth();
- };
-
- self.getDate = function() {
- return self.date.getDate();
- };
-
- self.getHours = function() {
- return self.date.getHours();
- };
-
- self.getMinutes = function() {
- return self.date.getMinutes();
- };
-
- self.getSeconds = function() {
- return self.date.getSeconds();
- };
-
- self.getMilliseconds = function() {
- return self.date.getMilliseconds();
- };
-
- self.getTimezoneOffset = function() {
- return offset * 60;
- };
-
- self.getUTCFullYear = function() {
- return self.origDate.getUTCFullYear();
- };
-
- self.getUTCMonth = function() {
- return self.origDate.getUTCMonth();
- };
-
- self.getUTCDate = function() {
- return self.origDate.getUTCDate();
- };
-
- self.getUTCHours = function() {
- return self.origDate.getUTCHours();
- };
-
- self.getUTCMinutes = function() {
- return self.origDate.getUTCMinutes();
- };
-
- self.getUTCSeconds = function() {
- return self.origDate.getUTCSeconds();
- };
-
- self.getUTCMilliseconds = function() {
- return self.origDate.getUTCMilliseconds();
- };
-
- self.getDay = function() {
- return self.date.getDay();
- };
-
- // provide this method only on browsers that already have it
- if (self.toISOString) {
- self.toISOString = function() {
- return padNumber(self.origDate.getUTCFullYear(), 4) + '-' +
- padNumber(self.origDate.getUTCMonth() + 1, 2) + '-' +
- padNumber(self.origDate.getUTCDate(), 2) + 'T' +
- padNumber(self.origDate.getUTCHours(), 2) + ':' +
- padNumber(self.origDate.getUTCMinutes(), 2) + ':' +
- padNumber(self.origDate.getUTCSeconds(), 2) + '.' +
- padNumber(self.origDate.getUTCMilliseconds(), 3) + 'Z';
- };
- }
-
- //hide all methods not implemented in this mock that the Date prototype exposes
- var unimplementedMethods = ['getUTCDay',
- 'getYear', 'setDate', 'setFullYear', 'setHours', 'setMilliseconds',
- 'setMinutes', 'setMonth', 'setSeconds', 'setTime', 'setUTCDate', 'setUTCFullYear',
- 'setUTCHours', 'setUTCMilliseconds', 'setUTCMinutes', 'setUTCMonth', 'setUTCSeconds',
- 'setYear', 'toDateString', 'toGMTString', 'toJSON', 'toLocaleFormat', 'toLocaleString',
- 'toLocaleTimeString', 'toSource', 'toString', 'toTimeString', 'toUTCString', 'valueOf'];
-
- angular.forEach(unimplementedMethods, function(methodName) {
- self[methodName] = function() {
- throw new Error("Method '" + methodName + "' is not implemented in the TzDate mock");
- };
- });
-
- return self;
-};
-
-//make "tzDateInstance instanceof Date" return true
-angular.mock.TzDate.prototype = Date.prototype;
-/* jshint +W101 */
-
-angular.mock.animate = angular.module('ngAnimateMock', ['ng'])
-
- .config(['$provide', function($provide) {
-
- var reflowQueue = [];
- $provide.value('$$animateReflow', function(fn) {
- var index = reflowQueue.length;
- reflowQueue.push(fn);
- return function cancel() {
- reflowQueue.splice(index, 1);
- };
- });
-
- $provide.decorator('$animate', ['$delegate', '$$asyncCallback', '$timeout', '$browser',
- function($delegate, $$asyncCallback, $timeout, $browser) {
- var animate = {
- queue: [],
- cancel: $delegate.cancel,
- enabled: $delegate.enabled,
- triggerCallbackEvents: function() {
- $$asyncCallback.flush();
- },
- triggerCallbackPromise: function() {
- $timeout.flush(0);
- },
- triggerCallbacks: function() {
- this.triggerCallbackEvents();
- this.triggerCallbackPromise();
- },
- triggerReflow: function() {
- angular.forEach(reflowQueue, function(fn) {
- fn();
- });
- reflowQueue = [];
- }
- };
-
- angular.forEach(
- ['animate','enter','leave','move','addClass','removeClass','setClass'], function(method) {
- animate[method] = function() {
- animate.queue.push({
- event: method,
- element: arguments[0],
- options: arguments[arguments.length - 1],
- args: arguments
- });
- return $delegate[method].apply($delegate, arguments);
- };
- });
-
- return animate;
- }]);
-
- }]);
-
-
-/**
- * @ngdoc function
- * @name angular.mock.dump
- * @description
- *
- * *NOTE*: this is not an injectable instance, just a globally available function.
- *
- * Method for serializing common angular objects (scope, elements, etc..) into strings, useful for
- * debugging.
- *
- * This method is also available on window, where it can be used to display objects on debug
- * console.
- *
- * @param {*} object - any object to turn into string.
- * @return {string} a serialized string of the argument
- */
-angular.mock.dump = function(object) {
- return serialize(object);
-
- function serialize(object) {
- var out;
-
- if (angular.isElement(object)) {
- object = angular.element(object);
- out = angular.element('');
- angular.forEach(object, function(element) {
- out.append(angular.element(element).clone());
- });
- out = out.html();
- } else if (angular.isArray(object)) {
- out = [];
- angular.forEach(object, function(o) {
- out.push(serialize(o));
- });
- out = '[ ' + out.join(', ') + ' ]';
- } else if (angular.isObject(object)) {
- if (angular.isFunction(object.$eval) && angular.isFunction(object.$apply)) {
- out = serializeScope(object);
- } else if (object instanceof Error) {
- out = object.stack || ('' + object.name + ': ' + object.message);
- } else {
- // TODO(i): this prevents methods being logged,
- // we should have a better way to serialize objects
- out = angular.toJson(object, true);
- }
- } else {
- out = String(object);
- }
-
- return out;
- }
-
- function serializeScope(scope, offset) {
- offset = offset || ' ';
- var log = [offset + 'Scope(' + scope.$id + '): {'];
- for (var key in scope) {
- if (Object.prototype.hasOwnProperty.call(scope, key) && !key.match(/^(\$|this)/)) {
- log.push(' ' + key + ': ' + angular.toJson(scope[key]));
- }
- }
- var child = scope.$$childHead;
- while (child) {
- log.push(serializeScope(child, offset + ' '));
- child = child.$$nextSibling;
- }
- log.push('}');
- return log.join('\n' + offset);
- }
-};
-
-/**
- * @ngdoc service
- * @name $httpBackend
- * @description
- * Fake HTTP backend implementation suitable for unit testing applications that use the
- * {@link ng.$http $http service}.
- *
- * *Note*: For fake HTTP backend implementation suitable for end-to-end testing or backend-less
- * development please see {@link ngMockE2E.$httpBackend e2e $httpBackend mock}.
- *
- * During unit testing, we want our unit tests to run quickly and have no external dependencies so
- * we don’t want to send [XHR](https://developer.mozilla.org/en/xmlhttprequest) or
- * [JSONP](http://en.wikipedia.org/wiki/JSONP) requests to a real server. All we really need is
- * to verify whether a certain request has been sent or not, or alternatively just let the
- * application make requests, respond with pre-trained responses and assert that the end result is
- * what we expect it to be.
- *
- * This mock implementation can be used to respond with static or dynamic responses via the
- * `expect` and `when` apis and their shortcuts (`expectGET`, `whenPOST`, etc).
- *
- * When an Angular application needs some data from a server, it calls the $http service, which
- * sends the request to a real server using $httpBackend service. With dependency injection, it is
- * easy to inject $httpBackend mock (which has the same API as $httpBackend) and use it to verify
- * the requests and respond with some testing data without sending a request to a real server.
- *
- * There are two ways to specify what test data should be returned as http responses by the mock
- * backend when the code under test makes http requests:
- *
- * - `$httpBackend.expect` - specifies a request expectation
- * - `$httpBackend.when` - specifies a backend definition
- *
- *
- * # Request Expectations vs Backend Definitions
- *
- * Request expectations provide a way to make assertions about requests made by the application and
- * to define responses for those requests. The test will fail if the expected requests are not made
- * or they are made in the wrong order.
- *
- * Backend definitions allow you to define a fake backend for your application which doesn't assert
- * if a particular request was made or not, it just returns a trained response if a request is made.
- * The test will pass whether or not the request gets made during testing.
- *
- *
- *
- *
Request expectations
Backend definitions
- *
- *
Syntax
- *
.expect(...).respond(...)
- *
.when(...).respond(...)
- *
- *
- *
Typical usage
- *
strict unit tests
- *
loose (black-box) unit testing
- *
- *
- *
Fulfills multiple requests
- *
NO
- *
YES
- *
- *
- *
Order of requests matters
- *
YES
- *
NO
- *
- *
- *
Request required
- *
YES
- *
NO
- *
- *
- *
Response required
- *
optional (see below)
- *
YES
- *
- *
- *
- * In cases where both backend definitions and request expectations are specified during unit
- * testing, the request expectations are evaluated first.
- *
- * If a request expectation has no response specified, the algorithm will search your backend
- * definitions for an appropriate response.
- *
- * If a request didn't match any expectation or if the expectation doesn't have the response
- * defined, the backend definitions are evaluated in sequential order to see if any of them match
- * the request. The response from the first matched definition is returned.
- *
- *
- * # Flushing HTTP requests
- *
- * The $httpBackend used in production always responds to requests asynchronously. If we preserved
- * this behavior in unit testing, we'd have to create async unit tests, which are hard to write,
- * to follow and to maintain. But neither can the testing mock respond synchronously; that would
- * change the execution of the code under test. For this reason, the mock $httpBackend has a
- * `flush()` method, which allows the test to explicitly flush pending requests. This preserves
- * the async api of the backend, while allowing the test to execute synchronously.
- *
- *
- * # Unit testing with mock $httpBackend
- * The following code shows how to setup and use the mock backend when unit testing a controller.
- * First we create the controller under test:
- *
- ```js
- // The module code
- angular
- .module('MyApp', [])
- .controller('MyController', MyController);
-
- // The controller code
- function MyController($scope, $http) {
- var authToken;
-
- $http.get('/auth.py').success(function(data, status, headers) {
- authToken = headers('A-Token');
- $scope.user = data;
- });
-
- $scope.saveMessage = function(message) {
- var headers = { 'Authorization': authToken };
- $scope.status = 'Saving...';
-
- $http.post('/add-msg.py', message, { headers: headers } ).success(function(response) {
- $scope.status = '';
- }).error(function() {
- $scope.status = 'ERROR!';
- });
- };
- }
- ```
- *
- * Now we setup the mock backend and create the test specs:
- *
- ```js
- // testing controller
- describe('MyController', function() {
- var $httpBackend, $rootScope, createController, authRequestHandler;
-
- // Set up the module
- beforeEach(module('MyApp'));
-
- beforeEach(inject(function($injector) {
- // Set up the mock http service responses
- $httpBackend = $injector.get('$httpBackend');
- // backend definition common for all tests
- authRequestHandler = $httpBackend.when('GET', '/auth.py')
- .respond({userId: 'userX'}, {'A-Token': 'xxx'});
-
- // Get hold of a scope (i.e. the root scope)
- $rootScope = $injector.get('$rootScope');
- // The $controller service is used to create instances of controllers
- var $controller = $injector.get('$controller');
-
- createController = function() {
- return $controller('MyController', {'$scope' : $rootScope });
- };
- }));
-
-
- afterEach(function() {
- $httpBackend.verifyNoOutstandingExpectation();
- $httpBackend.verifyNoOutstandingRequest();
- });
-
-
- it('should fetch authentication token', function() {
- $httpBackend.expectGET('/auth.py');
- var controller = createController();
- $httpBackend.flush();
- });
-
-
- it('should fail authentication', function() {
-
- // Notice how you can change the response even after it was set
- authRequestHandler.respond(401, '');
-
- $httpBackend.expectGET('/auth.py');
- var controller = createController();
- $httpBackend.flush();
- expect($rootScope.status).toBe('Failed...');
- });
-
-
- it('should send msg to server', function() {
- var controller = createController();
- $httpBackend.flush();
-
- // now you don’t care about the authentication, but
- // the controller will still send the request and
- // $httpBackend will respond without you having to
- // specify the expectation and response for this request
-
- $httpBackend.expectPOST('/add-msg.py', 'message content').respond(201, '');
- $rootScope.saveMessage('message content');
- expect($rootScope.status).toBe('Saving...');
- $httpBackend.flush();
- expect($rootScope.status).toBe('');
- });
-
-
- it('should send auth header', function() {
- var controller = createController();
- $httpBackend.flush();
-
- $httpBackend.expectPOST('/add-msg.py', undefined, function(headers) {
- // check if the header was send, if it wasn't the expectation won't
- // match the request and the test will fail
- return headers['Authorization'] == 'xxx';
- }).respond(201, '');
-
- $rootScope.saveMessage('whatever');
- $httpBackend.flush();
- });
- });
- ```
- */
-angular.mock.$HttpBackendProvider = function() {
- this.$get = ['$rootScope', '$timeout', createHttpBackendMock];
-};
-
-/**
- * General factory function for $httpBackend mock.
- * Returns instance for unit testing (when no arguments specified):
- * - passing through is disabled
- * - auto flushing is disabled
- *
- * Returns instance for e2e testing (when `$delegate` and `$browser` specified):
- * - passing through (delegating request to real backend) is enabled
- * - auto flushing is enabled
- *
- * @param {Object=} $delegate Real $httpBackend instance (allow passing through if specified)
- * @param {Object=} $browser Auto-flushing enabled if specified
- * @return {Object} Instance of $httpBackend mock
- */
-function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
- var definitions = [],
- expectations = [],
- responses = [],
- responsesPush = angular.bind(responses, responses.push),
- copy = angular.copy;
-
- function createResponse(status, data, headers, statusText) {
- if (angular.isFunction(status)) return status;
-
- return function() {
- return angular.isNumber(status)
- ? [status, data, headers, statusText]
- : [200, status, data, headers];
- };
- }
-
- // TODO(vojta): change params to: method, url, data, headers, callback
- function $httpBackend(method, url, data, callback, headers, timeout, withCredentials) {
- var xhr = new MockXhr(),
- expectation = expectations[0],
- wasExpected = false;
-
- function prettyPrint(data) {
- return (angular.isString(data) || angular.isFunction(data) || data instanceof RegExp)
- ? data
- : angular.toJson(data);
- }
-
- function wrapResponse(wrapped) {
- if (!$browser && timeout) {
- timeout.then ? timeout.then(handleTimeout) : $timeout(handleTimeout, timeout);
- }
-
- return handleResponse;
-
- function handleResponse() {
- var response = wrapped.response(method, url, data, headers);
- xhr.$$respHeaders = response[2];
- callback(copy(response[0]), copy(response[1]), xhr.getAllResponseHeaders(),
- copy(response[3] || ''));
- }
-
- function handleTimeout() {
- for (var i = 0, ii = responses.length; i < ii; i++) {
- if (responses[i] === handleResponse) {
- responses.splice(i, 1);
- callback(-1, undefined, '');
- break;
- }
- }
- }
- }
-
- if (expectation && expectation.match(method, url)) {
- if (!expectation.matchData(data))
- throw new Error('Expected ' + expectation + ' with different data\n' +
- 'EXPECTED: ' + prettyPrint(expectation.data) + '\nGOT: ' + data);
-
- if (!expectation.matchHeaders(headers))
- throw new Error('Expected ' + expectation + ' with different headers\n' +
- 'EXPECTED: ' + prettyPrint(expectation.headers) + '\nGOT: ' +
- prettyPrint(headers));
-
- expectations.shift();
-
- if (expectation.response) {
- responses.push(wrapResponse(expectation));
- return;
- }
- wasExpected = true;
- }
-
- var i = -1, definition;
- while ((definition = definitions[++i])) {
- if (definition.match(method, url, data, headers || {})) {
- if (definition.response) {
- // if $browser specified, we do auto flush all requests
- ($browser ? $browser.defer : responsesPush)(wrapResponse(definition));
- } else if (definition.passThrough) {
- $delegate(method, url, data, callback, headers, timeout, withCredentials);
- } else throw new Error('No response defined !');
- return;
- }
- }
- throw wasExpected ?
- new Error('No response defined !') :
- new Error('Unexpected request: ' + method + ' ' + url + '\n' +
- (expectation ? 'Expected ' + expectation : 'No more request expected'));
- }
-
- /**
- * @ngdoc method
- * @name $httpBackend#when
- * @description
- * Creates a new backend definition.
- *
- * @param {string} method HTTP method.
- * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
- * and returns true if the url match the current definition.
- * @param {(string|RegExp|function(string))=} data HTTP request body or function that receives
- * data string and returns true if the data is as expected.
- * @param {(Object|function(Object))=} headers HTTP headers or function that receives http header
- * object and returns true if the headers match the current definition.
- * @returns {requestHandler} Returns an object with `respond` method that controls how a matched
- * request is handled. You can save this object for later use and invoke `respond` again in
- * order to change how a matched request is handled.
- *
- * - respond –
- * `{function([status,] data[, headers, statusText])
- * | function(function(method, url, data, headers)}`
- * – The respond method takes a set of static data to be returned or a function that can
- * return an array containing response status (number), response data (string), response
- * headers (Object), and the text for the status (string). The respond method returns the
- * `requestHandler` object for possible overrides.
- */
- $httpBackend.when = function(method, url, data, headers) {
- var definition = new MockHttpExpectation(method, url, data, headers),
- chain = {
- respond: function(status, data, headers, statusText) {
- definition.passThrough = undefined;
- definition.response = createResponse(status, data, headers, statusText);
- return chain;
- }
- };
-
- if ($browser) {
- chain.passThrough = function() {
- definition.response = undefined;
- definition.passThrough = true;
- return chain;
- };
- }
-
- definitions.push(definition);
- return chain;
- };
-
- /**
- * @ngdoc method
- * @name $httpBackend#whenGET
- * @description
- * Creates a new backend definition for GET requests. For more info see `when()`.
- *
- * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
- * and returns true if the url match the current definition.
- * @param {(Object|function(Object))=} headers HTTP headers.
- * @returns {requestHandler} Returns an object with `respond` method that controls how a matched
- * request is handled. You can save this object for later use and invoke `respond` again in
- * order to change how a matched request is handled.
- */
-
- /**
- * @ngdoc method
- * @name $httpBackend#whenHEAD
- * @description
- * Creates a new backend definition for HEAD requests. For more info see `when()`.
- *
- * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
- * and returns true if the url match the current definition.
- * @param {(Object|function(Object))=} headers HTTP headers.
- * @returns {requestHandler} Returns an object with `respond` method that controls how a matched
- * request is handled. You can save this object for later use and invoke `respond` again in
- * order to change how a matched request is handled.
- */
-
- /**
- * @ngdoc method
- * @name $httpBackend#whenDELETE
- * @description
- * Creates a new backend definition for DELETE requests. For more info see `when()`.
- *
- * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
- * and returns true if the url match the current definition.
- * @param {(Object|function(Object))=} headers HTTP headers.
- * @returns {requestHandler} Returns an object with `respond` method that controls how a matched
- * request is handled. You can save this object for later use and invoke `respond` again in
- * order to change how a matched request is handled.
- */
-
- /**
- * @ngdoc method
- * @name $httpBackend#whenPOST
- * @description
- * Creates a new backend definition for POST requests. For more info see `when()`.
- *
- * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
- * and returns true if the url match the current definition.
- * @param {(string|RegExp|function(string))=} data HTTP request body or function that receives
- * data string and returns true if the data is as expected.
- * @param {(Object|function(Object))=} headers HTTP headers.
- * @returns {requestHandler} Returns an object with `respond` method that controls how a matched
- * request is handled. You can save this object for later use and invoke `respond` again in
- * order to change how a matched request is handled.
- */
-
- /**
- * @ngdoc method
- * @name $httpBackend#whenPUT
- * @description
- * Creates a new backend definition for PUT requests. For more info see `when()`.
- *
- * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
- * and returns true if the url match the current definition.
- * @param {(string|RegExp|function(string))=} data HTTP request body or function that receives
- * data string and returns true if the data is as expected.
- * @param {(Object|function(Object))=} headers HTTP headers.
- * @returns {requestHandler} Returns an object with `respond` method that controls how a matched
- * request is handled. You can save this object for later use and invoke `respond` again in
- * order to change how a matched request is handled.
- */
-
- /**
- * @ngdoc method
- * @name $httpBackend#whenJSONP
- * @description
- * Creates a new backend definition for JSONP requests. For more info see `when()`.
- *
- * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
- * and returns true if the url match the current definition.
- * @returns {requestHandler} Returns an object with `respond` method that controls how a matched
- * request is handled. You can save this object for later use and invoke `respond` again in
- * order to change how a matched request is handled.
- */
- createShortMethods('when');
-
-
- /**
- * @ngdoc method
- * @name $httpBackend#expect
- * @description
- * Creates a new request expectation.
- *
- * @param {string} method HTTP method.
- * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
- * and returns true if the url match the current definition.
- * @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that
- * receives data string and returns true if the data is as expected, or Object if request body
- * is in JSON format.
- * @param {(Object|function(Object))=} headers HTTP headers or function that receives http header
- * object and returns true if the headers match the current expectation.
- * @returns {requestHandler} Returns an object with `respond` method that controls how a matched
- * request is handled. You can save this object for later use and invoke `respond` again in
- * order to change how a matched request is handled.
- *
- * - respond –
- * `{function([status,] data[, headers, statusText])
- * | function(function(method, url, data, headers)}`
- * – The respond method takes a set of static data to be returned or a function that can
- * return an array containing response status (number), response data (string), response
- * headers (Object), and the text for the status (string). The respond method returns the
- * `requestHandler` object for possible overrides.
- */
- $httpBackend.expect = function(method, url, data, headers) {
- var expectation = new MockHttpExpectation(method, url, data, headers),
- chain = {
- respond: function(status, data, headers, statusText) {
- expectation.response = createResponse(status, data, headers, statusText);
- return chain;
- }
- };
-
- expectations.push(expectation);
- return chain;
- };
-
-
- /**
- * @ngdoc method
- * @name $httpBackend#expectGET
- * @description
- * Creates a new request expectation for GET requests. For more info see `expect()`.
- *
- * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
- * and returns true if the url match the current definition.
- * @param {Object=} headers HTTP headers.
- * @returns {requestHandler} Returns an object with `respond` method that controls how a matched
- * request is handled. You can save this object for later use and invoke `respond` again in
- * order to change how a matched request is handled. See #expect for more info.
- */
-
- /**
- * @ngdoc method
- * @name $httpBackend#expectHEAD
- * @description
- * Creates a new request expectation for HEAD requests. For more info see `expect()`.
- *
- * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
- * and returns true if the url match the current definition.
- * @param {Object=} headers HTTP headers.
- * @returns {requestHandler} Returns an object with `respond` method that controls how a matched
- * request is handled. You can save this object for later use and invoke `respond` again in
- * order to change how a matched request is handled.
- */
-
- /**
- * @ngdoc method
- * @name $httpBackend#expectDELETE
- * @description
- * Creates a new request expectation for DELETE requests. For more info see `expect()`.
- *
- * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
- * and returns true if the url match the current definition.
- * @param {Object=} headers HTTP headers.
- * @returns {requestHandler} Returns an object with `respond` method that controls how a matched
- * request is handled. You can save this object for later use and invoke `respond` again in
- * order to change how a matched request is handled.
- */
-
- /**
- * @ngdoc method
- * @name $httpBackend#expectPOST
- * @description
- * Creates a new request expectation for POST requests. For more info see `expect()`.
- *
- * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
- * and returns true if the url match the current definition.
- * @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that
- * receives data string and returns true if the data is as expected, or Object if request body
- * is in JSON format.
- * @param {Object=} headers HTTP headers.
- * @returns {requestHandler} Returns an object with `respond` method that controls how a matched
- * request is handled. You can save this object for later use and invoke `respond` again in
- * order to change how a matched request is handled.
- */
-
- /**
- * @ngdoc method
- * @name $httpBackend#expectPUT
- * @description
- * Creates a new request expectation for PUT requests. For more info see `expect()`.
- *
- * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
- * and returns true if the url match the current definition.
- * @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that
- * receives data string and returns true if the data is as expected, or Object if request body
- * is in JSON format.
- * @param {Object=} headers HTTP headers.
- * @returns {requestHandler} Returns an object with `respond` method that controls how a matched
- * request is handled. You can save this object for later use and invoke `respond` again in
- * order to change how a matched request is handled.
- */
-
- /**
- * @ngdoc method
- * @name $httpBackend#expectPATCH
- * @description
- * Creates a new request expectation for PATCH requests. For more info see `expect()`.
- *
- * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
- * and returns true if the url match the current definition.
- * @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that
- * receives data string and returns true if the data is as expected, or Object if request body
- * is in JSON format.
- * @param {Object=} headers HTTP headers.
- * @returns {requestHandler} Returns an object with `respond` method that controls how a matched
- * request is handled. You can save this object for later use and invoke `respond` again in
- * order to change how a matched request is handled.
- */
-
- /**
- * @ngdoc method
- * @name $httpBackend#expectJSONP
- * @description
- * Creates a new request expectation for JSONP requests. For more info see `expect()`.
- *
- * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
- * and returns true if the url match the current definition.
- * @returns {requestHandler} Returns an object with `respond` method that controls how a matched
- * request is handled. You can save this object for later use and invoke `respond` again in
- * order to change how a matched request is handled.
- */
- createShortMethods('expect');
-
-
- /**
- * @ngdoc method
- * @name $httpBackend#flush
- * @description
- * Flushes all pending requests using the trained responses.
- *
- * @param {number=} count Number of responses to flush (in the order they arrived). If undefined,
- * all pending requests will be flushed. If there are no pending requests when the flush method
- * is called an exception is thrown (as this typically a sign of programming error).
- */
- $httpBackend.flush = function(count, digest) {
- if (digest !== false) $rootScope.$digest();
- if (!responses.length) throw new Error('No pending request to flush !');
-
- if (angular.isDefined(count) && count !== null) {
- while (count--) {
- if (!responses.length) throw new Error('No more pending request to flush !');
- responses.shift()();
- }
- } else {
- while (responses.length) {
- responses.shift()();
- }
- }
- $httpBackend.verifyNoOutstandingExpectation(digest);
- };
-
-
- /**
- * @ngdoc method
- * @name $httpBackend#verifyNoOutstandingExpectation
- * @description
- * Verifies that all of the requests defined via the `expect` api were made. If any of the
- * requests were not made, verifyNoOutstandingExpectation throws an exception.
- *
- * Typically, you would call this method following each test case that asserts requests using an
- * "afterEach" clause.
- *
- * ```js
- * afterEach($httpBackend.verifyNoOutstandingExpectation);
- * ```
- */
- $httpBackend.verifyNoOutstandingExpectation = function(digest) {
- if (digest !== false) $rootScope.$digest();
- if (expectations.length) {
- throw new Error('Unsatisfied requests: ' + expectations.join(', '));
- }
- };
-
-
- /**
- * @ngdoc method
- * @name $httpBackend#verifyNoOutstandingRequest
- * @description
- * Verifies that there are no outstanding requests that need to be flushed.
- *
- * Typically, you would call this method following each test case that asserts requests using an
- * "afterEach" clause.
- *
- * ```js
- * afterEach($httpBackend.verifyNoOutstandingRequest);
- * ```
- */
- $httpBackend.verifyNoOutstandingRequest = function() {
- if (responses.length) {
- throw new Error('Unflushed requests: ' + responses.length);
- }
- };
-
-
- /**
- * @ngdoc method
- * @name $httpBackend#resetExpectations
- * @description
- * Resets all request expectations, but preserves all backend definitions. Typically, you would
- * call resetExpectations during a multiple-phase test when you want to reuse the same instance of
- * $httpBackend mock.
- */
- $httpBackend.resetExpectations = function() {
- expectations.length = 0;
- responses.length = 0;
- };
-
- return $httpBackend;
-
-
- function createShortMethods(prefix) {
- angular.forEach(['GET', 'DELETE', 'JSONP', 'HEAD'], function(method) {
- $httpBackend[prefix + method] = function(url, headers) {
- return $httpBackend[prefix](method, url, undefined, headers);
- };
- });
-
- angular.forEach(['PUT', 'POST', 'PATCH'], function(method) {
- $httpBackend[prefix + method] = function(url, data, headers) {
- return $httpBackend[prefix](method, url, data, headers);
- };
- });
- }
-}
-
-function MockHttpExpectation(method, url, data, headers) {
-
- this.data = data;
- this.headers = headers;
-
- this.match = function(m, u, d, h) {
- if (method != m) return false;
- if (!this.matchUrl(u)) return false;
- if (angular.isDefined(d) && !this.matchData(d)) return false;
- if (angular.isDefined(h) && !this.matchHeaders(h)) return false;
- return true;
- };
-
- this.matchUrl = function(u) {
- if (!url) return true;
- if (angular.isFunction(url.test)) return url.test(u);
- if (angular.isFunction(url)) return url(u);
- return url == u;
- };
-
- this.matchHeaders = function(h) {
- if (angular.isUndefined(headers)) return true;
- if (angular.isFunction(headers)) return headers(h);
- return angular.equals(headers, h);
- };
-
- this.matchData = function(d) {
- if (angular.isUndefined(data)) return true;
- if (data && angular.isFunction(data.test)) return data.test(d);
- if (data && angular.isFunction(data)) return data(d);
- if (data && !angular.isString(data)) {
- return angular.equals(angular.fromJson(angular.toJson(data)), angular.fromJson(d));
- }
- return data == d;
- };
-
- this.toString = function() {
- return method + ' ' + url;
- };
-}
-
-function createMockXhr() {
- return new MockXhr();
-}
-
-function MockXhr() {
-
- // hack for testing $http, $httpBackend
- MockXhr.$$lastInstance = this;
-
- this.open = function(method, url, async) {
- this.$$method = method;
- this.$$url = url;
- this.$$async = async;
- this.$$reqHeaders = {};
- this.$$respHeaders = {};
- };
-
- this.send = function(data) {
- this.$$data = data;
- };
-
- this.setRequestHeader = function(key, value) {
- this.$$reqHeaders[key] = value;
- };
-
- this.getResponseHeader = function(name) {
- // the lookup must be case insensitive,
- // that's why we try two quick lookups first and full scan last
- var header = this.$$respHeaders[name];
- if (header) return header;
-
- name = angular.lowercase(name);
- header = this.$$respHeaders[name];
- if (header) return header;
-
- header = undefined;
- angular.forEach(this.$$respHeaders, function(headerVal, headerName) {
- if (!header && angular.lowercase(headerName) == name) header = headerVal;
- });
- return header;
- };
-
- this.getAllResponseHeaders = function() {
- var lines = [];
-
- angular.forEach(this.$$respHeaders, function(value, key) {
- lines.push(key + ': ' + value);
- });
- return lines.join('\n');
- };
-
- this.abort = angular.noop;
-}
-
-
-/**
- * @ngdoc service
- * @name $timeout
- * @description
- *
- * This service is just a simple decorator for {@link ng.$timeout $timeout} service
- * that adds a "flush" and "verifyNoPendingTasks" methods.
- */
-
-angular.mock.$TimeoutDecorator = ['$delegate', '$browser', function($delegate, $browser) {
-
- /**
- * @ngdoc method
- * @name $timeout#flush
- * @description
- *
- * Flushes the queue of pending tasks.
- *
- * @param {number=} delay maximum timeout amount to flush up until
- */
- $delegate.flush = function(delay) {
- $browser.defer.flush(delay);
- };
-
- /**
- * @ngdoc method
- * @name $timeout#verifyNoPendingTasks
- * @description
- *
- * Verifies that there are no pending tasks that need to be flushed.
- */
- $delegate.verifyNoPendingTasks = function() {
- if ($browser.deferredFns.length) {
- throw new Error('Deferred tasks to flush (' + $browser.deferredFns.length + '): ' +
- formatPendingTasksAsString($browser.deferredFns));
- }
- };
-
- function formatPendingTasksAsString(tasks) {
- var result = [];
- angular.forEach(tasks, function(task) {
- result.push('{id: ' + task.id + ', ' + 'time: ' + task.time + '}');
- });
-
- return result.join(', ');
- }
-
- return $delegate;
-}];
-
-angular.mock.$RAFDecorator = ['$delegate', function($delegate) {
- var queue = [];
- var rafFn = function(fn) {
- var index = queue.length;
- queue.push(fn);
- return function() {
- queue.splice(index, 1);
- };
- };
-
- rafFn.supported = $delegate.supported;
-
- rafFn.flush = function() {
- if (queue.length === 0) {
- throw new Error('No rAF callbacks present');
- }
-
- var length = queue.length;
- for (var i = 0; i < length; i++) {
- queue[i]();
- }
-
- queue = [];
- };
-
- return rafFn;
-}];
-
-angular.mock.$AsyncCallbackDecorator = ['$delegate', function($delegate) {
- var callbacks = [];
- var addFn = function(fn) {
- callbacks.push(fn);
- };
- addFn.flush = function() {
- angular.forEach(callbacks, function(fn) {
- fn();
- });
- callbacks = [];
- };
- return addFn;
-}];
-
-/**
- *
- */
-angular.mock.$RootElementProvider = function() {
- this.$get = function() {
- return angular.element('');
- };
-};
-
-/**
- * @ngdoc module
- * @name ngMock
- * @packageName angular-mocks
- * @description
- *
- * # ngMock
- *
- * The `ngMock` module provides support to inject and mock Angular services into unit tests.
- * In addition, ngMock also extends various core ng services such that they can be
- * inspected and controlled in a synchronous manner within test code.
- *
- *
- *
- *
- */
-angular.module('ngMock', ['ng']).provider({
- $browser: angular.mock.$BrowserProvider,
- $exceptionHandler: angular.mock.$ExceptionHandlerProvider,
- $log: angular.mock.$LogProvider,
- $interval: angular.mock.$IntervalProvider,
- $httpBackend: angular.mock.$HttpBackendProvider,
- $rootElement: angular.mock.$RootElementProvider
-}).config(['$provide', function($provide) {
- $provide.decorator('$timeout', angular.mock.$TimeoutDecorator);
- $provide.decorator('$$rAF', angular.mock.$RAFDecorator);
- $provide.decorator('$$asyncCallback', angular.mock.$AsyncCallbackDecorator);
- $provide.decorator('$rootScope', angular.mock.$RootScopeDecorator);
-}]);
-
-/**
- * @ngdoc module
- * @name ngMockE2E
- * @module ngMockE2E
- * @packageName angular-mocks
- * @description
- *
- * The `ngMockE2E` is an angular module which contains mocks suitable for end-to-end testing.
- * Currently there is only one mock present in this module -
- * the {@link ngMockE2E.$httpBackend e2e $httpBackend} mock.
- */
-angular.module('ngMockE2E', ['ng']).config(['$provide', function($provide) {
- $provide.decorator('$httpBackend', angular.mock.e2e.$httpBackendDecorator);
-}]);
-
-/**
- * @ngdoc service
- * @name $httpBackend
- * @module ngMockE2E
- * @description
- * Fake HTTP backend implementation suitable for end-to-end testing or backend-less development of
- * applications that use the {@link ng.$http $http service}.
- *
- * *Note*: For fake http backend implementation suitable for unit testing please see
- * {@link ngMock.$httpBackend unit-testing $httpBackend mock}.
- *
- * This implementation can be used to respond with static or dynamic responses via the `when` api
- * and its shortcuts (`whenGET`, `whenPOST`, etc) and optionally pass through requests to the
- * real $httpBackend for specific requests (e.g. to interact with certain remote apis or to fetch
- * templates from a webserver).
- *
- * As opposed to unit-testing, in an end-to-end testing scenario or in scenario when an application
- * is being developed with the real backend api replaced with a mock, it is often desirable for
- * certain category of requests to bypass the mock and issue a real http request (e.g. to fetch
- * templates or static files from the webserver). To configure the backend with this behavior
- * use the `passThrough` request handler of `when` instead of `respond`.
- *
- * Additionally, we don't want to manually have to flush mocked out requests like we do during unit
- * testing. For this reason the e2e $httpBackend flushes mocked out requests
- * automatically, closely simulating the behavior of the XMLHttpRequest object.
- *
- * To setup the application to run with this http backend, you have to create a module that depends
- * on the `ngMockE2E` and your application modules and defines the fake backend:
- *
- * ```js
- * myAppDev = angular.module('myAppDev', ['myApp', 'ngMockE2E']);
- * myAppDev.run(function($httpBackend) {
- * phones = [{name: 'phone1'}, {name: 'phone2'}];
- *
- * // returns the current list of phones
- * $httpBackend.whenGET('/phones').respond(phones);
- *
- * // adds a new phone to the phones array
- * $httpBackend.whenPOST('/phones').respond(function(method, url, data) {
- * var phone = angular.fromJson(data);
- * phones.push(phone);
- * return [200, phone, {}];
- * });
- * $httpBackend.whenGET(/^\/templates\//).passThrough();
- * //...
- * });
- * ```
- *
- * Afterwards, bootstrap your app with this new module.
- */
-
-/**
- * @ngdoc method
- * @name $httpBackend#when
- * @module ngMockE2E
- * @description
- * Creates a new backend definition.
- *
- * @param {string} method HTTP method.
- * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
- * and returns true if the url match the current definition.
- * @param {(string|RegExp)=} data HTTP request body.
- * @param {(Object|function(Object))=} headers HTTP headers or function that receives http header
- * object and returns true if the headers match the current definition.
- * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that
- * control how a matched request is handled. You can save this object for later use and invoke
- * `respond` or `passThrough` again in order to change how a matched request is handled.
- *
- * - respond –
- * `{function([status,] data[, headers, statusText])
- * | function(function(method, url, data, headers)}`
- * – The respond method takes a set of static data to be returned or a function that can return
- * an array containing response status (number), response data (string), response headers
- * (Object), and the text for the status (string).
- * - passThrough – `{function()}` – Any request matching a backend definition with
- * `passThrough` handler will be passed through to the real backend (an XHR request will be made
- * to the server.)
- * - Both methods return the `requestHandler` object for possible overrides.
- */
-
-/**
- * @ngdoc method
- * @name $httpBackend#whenGET
- * @module ngMockE2E
- * @description
- * Creates a new backend definition for GET requests. For more info see `when()`.
- *
- * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
- * and returns true if the url match the current definition.
- * @param {(Object|function(Object))=} headers HTTP headers.
- * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that
- * control how a matched request is handled. You can save this object for later use and invoke
- * `respond` or `passThrough` again in order to change how a matched request is handled.
- */
-
-/**
- * @ngdoc method
- * @name $httpBackend#whenHEAD
- * @module ngMockE2E
- * @description
- * Creates a new backend definition for HEAD requests. For more info see `when()`.
- *
- * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
- * and returns true if the url match the current definition.
- * @param {(Object|function(Object))=} headers HTTP headers.
- * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that
- * control how a matched request is handled. You can save this object for later use and invoke
- * `respond` or `passThrough` again in order to change how a matched request is handled.
- */
-
-/**
- * @ngdoc method
- * @name $httpBackend#whenDELETE
- * @module ngMockE2E
- * @description
- * Creates a new backend definition for DELETE requests. For more info see `when()`.
- *
- * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
- * and returns true if the url match the current definition.
- * @param {(Object|function(Object))=} headers HTTP headers.
- * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that
- * control how a matched request is handled. You can save this object for later use and invoke
- * `respond` or `passThrough` again in order to change how a matched request is handled.
- */
-
-/**
- * @ngdoc method
- * @name $httpBackend#whenPOST
- * @module ngMockE2E
- * @description
- * Creates a new backend definition for POST requests. For more info see `when()`.
- *
- * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
- * and returns true if the url match the current definition.
- * @param {(string|RegExp)=} data HTTP request body.
- * @param {(Object|function(Object))=} headers HTTP headers.
- * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that
- * control how a matched request is handled. You can save this object for later use and invoke
- * `respond` or `passThrough` again in order to change how a matched request is handled.
- */
-
-/**
- * @ngdoc method
- * @name $httpBackend#whenPUT
- * @module ngMockE2E
- * @description
- * Creates a new backend definition for PUT requests. For more info see `when()`.
- *
- * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
- * and returns true if the url match the current definition.
- * @param {(string|RegExp)=} data HTTP request body.
- * @param {(Object|function(Object))=} headers HTTP headers.
- * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that
- * control how a matched request is handled. You can save this object for later use and invoke
- * `respond` or `passThrough` again in order to change how a matched request is handled.
- */
-
-/**
- * @ngdoc method
- * @name $httpBackend#whenPATCH
- * @module ngMockE2E
- * @description
- * Creates a new backend definition for PATCH requests. For more info see `when()`.
- *
- * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
- * and returns true if the url match the current definition.
- * @param {(string|RegExp)=} data HTTP request body.
- * @param {(Object|function(Object))=} headers HTTP headers.
- * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that
- * control how a matched request is handled. You can save this object for later use and invoke
- * `respond` or `passThrough` again in order to change how a matched request is handled.
- */
-
-/**
- * @ngdoc method
- * @name $httpBackend#whenJSONP
- * @module ngMockE2E
- * @description
- * Creates a new backend definition for JSONP requests. For more info see `when()`.
- *
- * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
- * and returns true if the url match the current definition.
- * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that
- * control how a matched request is handled. You can save this object for later use and invoke
- * `respond` or `passThrough` again in order to change how a matched request is handled.
- */
-angular.mock.e2e = {};
-angular.mock.e2e.$httpBackendDecorator =
- ['$rootScope', '$timeout', '$delegate', '$browser', createHttpBackendMock];
-
-
-/**
- * @ngdoc type
- * @name $rootScope.Scope
- * @module ngMock
- * @description
- * {@link ng.$rootScope.Scope Scope} type decorated with helper methods useful for testing. These
- * methods are automatically available on any {@link ng.$rootScope.Scope Scope} instance when
- * `ngMock` module is loaded.
- *
- * In addition to all the regular `Scope` methods, the following helper methods are available:
- */
-angular.mock.$RootScopeDecorator = ['$delegate', function($delegate) {
-
- var $rootScopePrototype = Object.getPrototypeOf($delegate);
-
- $rootScopePrototype.$countChildScopes = countChildScopes;
- $rootScopePrototype.$countWatchers = countWatchers;
-
- return $delegate;
-
- // ------------------------------------------------------------------------------------------ //
-
- /**
- * @ngdoc method
- * @name $rootScope.Scope#$countChildScopes
- * @module ngMock
- * @description
- * Counts all the direct and indirect child scopes of the current scope.
- *
- * The current scope is excluded from the count. The count includes all isolate child scopes.
- *
- * @returns {number} Total number of child scopes.
- */
- function countChildScopes() {
- // jshint validthis: true
- var count = 0; // exclude the current scope
- var pendingChildHeads = [this.$$childHead];
- var currentScope;
-
- while (pendingChildHeads.length) {
- currentScope = pendingChildHeads.shift();
-
- while (currentScope) {
- count += 1;
- pendingChildHeads.push(currentScope.$$childHead);
- currentScope = currentScope.$$nextSibling;
- }
- }
-
- return count;
- }
-
-
- /**
- * @ngdoc method
- * @name $rootScope.Scope#$countWatchers
- * @module ngMock
- * @description
- * Counts all the watchers of direct and indirect child scopes of the current scope.
- *
- * The watchers of the current scope are included in the count and so are all the watchers of
- * isolate child scopes.
- *
- * @returns {number} Total number of watchers.
- */
- function countWatchers() {
- // jshint validthis: true
- var count = this.$$watchers ? this.$$watchers.length : 0; // include the current scope
- var pendingChildHeads = [this.$$childHead];
- var currentScope;
-
- while (pendingChildHeads.length) {
- currentScope = pendingChildHeads.shift();
-
- while (currentScope) {
- count += currentScope.$$watchers ? currentScope.$$watchers.length : 0;
- pendingChildHeads.push(currentScope.$$childHead);
- currentScope = currentScope.$$nextSibling;
- }
- }
-
- return count;
- }
-}];
-
-
-if (window.jasmine || window.mocha) {
-
- var currentSpec = null,
- isSpecRunning = function() {
- return !!currentSpec;
- };
-
-
- (window.beforeEach || window.setup)(function() {
- currentSpec = this;
- });
-
- (window.afterEach || window.teardown)(function() {
- var injector = currentSpec.$injector;
-
- angular.forEach(currentSpec.$modules, function(module) {
- if (module && module.$$hashKey) {
- module.$$hashKey = undefined;
- }
- });
-
- currentSpec.$injector = null;
- currentSpec.$modules = null;
- currentSpec = null;
-
- if (injector) {
- injector.get('$rootElement').off();
- injector.get('$browser').pollFns.length = 0;
- }
-
- // clean up jquery's fragment cache
- angular.forEach(angular.element.fragments, function(val, key) {
- delete angular.element.fragments[key];
- });
-
- MockXhr.$$lastInstance = null;
-
- angular.forEach(angular.callbacks, function(val, key) {
- delete angular.callbacks[key];
- });
- angular.callbacks.counter = 0;
- });
-
- /**
- * @ngdoc function
- * @name angular.mock.module
- * @description
- *
- * *NOTE*: This function is also published on window for easy access.
- * *NOTE*: This function is declared ONLY WHEN running tests with jasmine or mocha
- *
- * This function registers a module configuration code. It collects the configuration information
- * which will be used when the injector is created by {@link angular.mock.inject inject}.
- *
- * See {@link angular.mock.inject inject} for usage example
- *
- * @param {...(string|Function|Object)} fns any number of modules which are represented as string
- * aliases or as anonymous module initialization functions. The modules are used to
- * configure the injector. The 'ng' and 'ngMock' modules are automatically loaded. If an
- * object literal is passed they will be registered as values in the module, the key being
- * the module name and the value being what is returned.
- */
- window.module = angular.mock.module = function() {
- var moduleFns = Array.prototype.slice.call(arguments, 0);
- return isSpecRunning() ? workFn() : workFn;
- /////////////////////
- function workFn() {
- if (currentSpec.$injector) {
- throw new Error('Injector already created, can not register a module!');
- } else {
- var modules = currentSpec.$modules || (currentSpec.$modules = []);
- angular.forEach(moduleFns, function(module) {
- if (angular.isObject(module) && !angular.isArray(module)) {
- modules.push(function($provide) {
- angular.forEach(module, function(value, key) {
- $provide.value(key, value);
- });
- });
- } else {
- modules.push(module);
- }
- });
- }
- }
- };
-
- /**
- * @ngdoc function
- * @name angular.mock.inject
- * @description
- *
- * *NOTE*: This function is also published on window for easy access.
- * *NOTE*: This function is declared ONLY WHEN running tests with jasmine or mocha
- *
- * The inject function wraps a function into an injectable function. The inject() creates new
- * instance of {@link auto.$injector $injector} per test, which is then used for
- * resolving references.
- *
- *
- * ## Resolving References (Underscore Wrapping)
- * Often, we would like to inject a reference once, in a `beforeEach()` block and reuse this
- * in multiple `it()` clauses. To be able to do this we must assign the reference to a variable
- * that is declared in the scope of the `describe()` block. Since we would, most likely, want
- * the variable to have the same name of the reference we have a problem, since the parameter
- * to the `inject()` function would hide the outer variable.
- *
- * To help with this, the injected parameters can, optionally, be enclosed with underscores.
- * These are ignored by the injector when the reference name is resolved.
- *
- * For example, the parameter `_myService_` would be resolved as the reference `myService`.
- * Since it is available in the function body as _myService_, we can then assign it to a variable
- * defined in an outer scope.
- *
- * ```
- * // Defined out reference variable outside
- * var myService;
- *
- * // Wrap the parameter in underscores
- * beforeEach( inject( function(_myService_){
- * myService = _myService_;
- * }));
- *
- * // Use myService in a series of tests.
- * it('makes use of myService', function() {
- * myService.doStuff();
- * });
- *
- * ```
- *
- * See also {@link angular.mock.module angular.mock.module}
- *
- * ## Example
- * Example of what a typical jasmine tests looks like with the inject method.
- * ```js
- *
- * angular.module('myApplicationModule', [])
- * .value('mode', 'app')
- * .value('version', 'v1.0.1');
- *
- *
- * describe('MyApp', function() {
- *
- * // You need to load modules that you want to test,
- * // it loads only the "ng" module by default.
- * beforeEach(module('myApplicationModule'));
- *
- *
- * // inject() is used to inject arguments of all given functions
- * it('should provide a version', inject(function(mode, version) {
- * expect(version).toEqual('v1.0.1');
- * expect(mode).toEqual('app');
- * }));
- *
- *
- * // The inject and module method can also be used inside of the it or beforeEach
- * it('should override a version and test the new version is injected', function() {
- * // module() takes functions or strings (module aliases)
- * module(function($provide) {
- * $provide.value('version', 'overridden'); // override version here
- * });
- *
- * inject(function(version) {
- * expect(version).toEqual('overridden');
- * });
- * });
- * });
- *
- * ```
- *
- * @param {...Function} fns any number of functions which will be injected using the injector.
- */
-
-
-
- var ErrorAddingDeclarationLocationStack = function(e, errorForStack) {
- this.message = e.message;
- this.name = e.name;
- if (e.line) this.line = e.line;
- if (e.sourceId) this.sourceId = e.sourceId;
- if (e.stack && errorForStack)
- this.stack = e.stack + '\n' + errorForStack.stack;
- if (e.stackArray) this.stackArray = e.stackArray;
- };
- ErrorAddingDeclarationLocationStack.prototype.toString = Error.prototype.toString;
-
- window.inject = angular.mock.inject = function() {
- var blockFns = Array.prototype.slice.call(arguments, 0);
- var errorForStack = new Error('Declaration Location');
- return isSpecRunning() ? workFn.call(currentSpec) : workFn;
- /////////////////////
- function workFn() {
- var modules = currentSpec.$modules || [];
- var strictDi = !!currentSpec.$injectorStrict;
- modules.unshift('ngMock');
- modules.unshift('ng');
- var injector = currentSpec.$injector;
- if (!injector) {
- if (strictDi) {
- // If strictDi is enabled, annotate the providerInjector blocks
- angular.forEach(modules, function(moduleFn) {
- if (typeof moduleFn === "function") {
- angular.injector.$$annotate(moduleFn);
- }
- });
- }
- injector = currentSpec.$injector = angular.injector(modules, strictDi);
- currentSpec.$injectorStrict = strictDi;
- }
- for (var i = 0, ii = blockFns.length; i < ii; i++) {
- if (currentSpec.$injectorStrict) {
- // If the injector is strict / strictDi, and the spec wants to inject using automatic
- // annotation, then annotate the function here.
- injector.annotate(blockFns[i]);
- }
- try {
- /* jshint -W040 *//* Jasmine explicitly provides a `this` object when calling functions */
- injector.invoke(blockFns[i] || angular.noop, this);
- /* jshint +W040 */
- } catch (e) {
- if (e.stack && errorForStack) {
- throw new ErrorAddingDeclarationLocationStack(e, errorForStack);
- }
- throw e;
- } finally {
- errorForStack = null;
- }
- }
- }
- };
-
-
- angular.mock.inject.strictDi = function(value) {
- value = arguments.length ? !!value : true;
- return isSpecRunning() ? workFn() : workFn;
-
- function workFn() {
- if (value !== currentSpec.$injectorStrict) {
- if (currentSpec.$injector) {
- throw new Error('Injector already created, can not modify strict annotations');
- } else {
- currentSpec.$injectorStrict = value;
- }
- }
- }
- };
-}
-
-
-})(window, window.angular);
diff --git a/src/main/webapp/bower_components/angular-mocks/bower.json b/src/main/webapp/bower_components/angular-mocks/bower.json
deleted file mode 100644
index cd52be40d..000000000
--- a/src/main/webapp/bower_components/angular-mocks/bower.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "name": "angular-mocks",
- "version": "1.3.11",
- "main": "./angular-mocks.js",
- "ignore": [],
- "dependencies": {
- "angular": "1.3.11"
- }
-}
diff --git a/src/main/webapp/bower_components/angular-mocks/package.json b/src/main/webapp/bower_components/angular-mocks/package.json
deleted file mode 100644
index c32d09fbd..000000000
--- a/src/main/webapp/bower_components/angular-mocks/package.json
+++ /dev/null
@@ -1,27 +0,0 @@
-{
- "name": "angular-mocks",
- "version": "1.3.11",
- "description": "AngularJS mocks for testing",
- "main": "angular-mocks.js",
- "scripts": {
- "test": "echo \"Error: no test specified\" && exit 1"
- },
- "repository": {
- "type": "git",
- "url": "https://github.com/angular/angular.js.git"
- },
- "keywords": [
- "angular",
- "framework",
- "browser",
- "mocks",
- "testing",
- "client-side"
- ],
- "author": "Angular Core Team ",
- "license": "MIT",
- "bugs": {
- "url": "https://github.com/angular/angular.js/issues"
- },
- "homepage": "http://angularjs.org"
-}
diff --git a/src/main/webapp/bower_components/angular-resource/.bower.json b/src/main/webapp/bower_components/angular-resource/.bower.json
deleted file mode 100644
index 2ab3e3c66..000000000
--- a/src/main/webapp/bower_components/angular-resource/.bower.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "name": "angular-resource",
- "version": "1.3.11",
- "main": "./angular-resource.js",
- "ignore": [],
- "dependencies": {
- "angular": "1.3.11"
- },
- "homepage": "https://github.com/angular/bower-angular-resource",
- "_release": "1.3.11",
- "_resolution": {
- "type": "version",
- "tag": "v1.3.11",
- "commit": "b2ace539da53a66ca54ff88c145a12e9e1606355"
- },
- "_source": "git://github.com/angular/bower-angular-resource.git",
- "_target": "1.3.11",
- "_originalSource": "angular-resource"
-}
\ No newline at end of file
diff --git a/src/main/webapp/bower_components/angular-resource/README.md b/src/main/webapp/bower_components/angular-resource/README.md
deleted file mode 100644
index b09e0a7b6..000000000
--- a/src/main/webapp/bower_components/angular-resource/README.md
+++ /dev/null
@@ -1,77 +0,0 @@
-# packaged angular-resource
-
-This repo is for distribution on `npm` and `bower`. The source for this module is in the
-[main AngularJS repo](https://github.com/angular/angular.js/tree/master/src/ngResource).
-Please file issues and pull requests against that repo.
-
-## Install
-
-You can install this package either with `npm` or with `bower`.
-
-### npm
-
-```shell
-npm install angular-resource
-```
-
-Add a `
-```
-
-Then add `ngResource` as a dependency for your app:
-
-```javascript
-angular.module('myApp', ['ngResource']);
-```
-
-Note that this package is not in CommonJS format, so doing `require('angular-resource')` will
-return `undefined`.
-
-### bower
-
-```shell
-bower install angular-resource
-```
-
-Add a `
-```
-
-Then add `ngResource` as a dependency for your app:
-
-```javascript
-angular.module('myApp', ['ngResource']);
-```
-
-## Documentation
-
-Documentation is available on the
-[AngularJS docs site](http://docs.angularjs.org/api/ngResource).
-
-## License
-
-The MIT License
-
-Copyright (c) 2010-2012 Google, Inc. http://angularjs.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/src/main/webapp/bower_components/angular-resource/angular-resource.js b/src/main/webapp/bower_components/angular-resource/angular-resource.js
deleted file mode 100644
index 6040d7979..000000000
--- a/src/main/webapp/bower_components/angular-resource/angular-resource.js
+++ /dev/null
@@ -1,667 +0,0 @@
-/**
- * @license AngularJS v1.3.11
- * (c) 2010-2014 Google, Inc. http://angularjs.org
- * License: MIT
- */
-(function(window, angular, undefined) {'use strict';
-
-var $resourceMinErr = angular.$$minErr('$resource');
-
-// Helper functions and regex to lookup a dotted path on an object
-// stopping at undefined/null. The path must be composed of ASCII
-// identifiers (just like $parse)
-var MEMBER_NAME_REGEX = /^(\.[a-zA-Z_$][0-9a-zA-Z_$]*)+$/;
-
-function isValidDottedPath(path) {
- return (path != null && path !== '' && path !== 'hasOwnProperty' &&
- MEMBER_NAME_REGEX.test('.' + path));
-}
-
-function lookupDottedPath(obj, path) {
- if (!isValidDottedPath(path)) {
- throw $resourceMinErr('badmember', 'Dotted member path "@{0}" is invalid.', path);
- }
- var keys = path.split('.');
- for (var i = 0, ii = keys.length; i < ii && obj !== undefined; i++) {
- var key = keys[i];
- obj = (obj !== null) ? obj[key] : undefined;
- }
- return obj;
-}
-
-/**
- * Create a shallow copy of an object and clear other fields from the destination
- */
-function shallowClearAndCopy(src, dst) {
- dst = dst || {};
-
- angular.forEach(dst, function(value, key) {
- delete dst[key];
- });
-
- for (var key in src) {
- if (src.hasOwnProperty(key) && !(key.charAt(0) === '$' && key.charAt(1) === '$')) {
- dst[key] = src[key];
- }
- }
-
- return dst;
-}
-
-/**
- * @ngdoc module
- * @name ngResource
- * @description
- *
- * # ngResource
- *
- * The `ngResource` module provides interaction support with RESTful services
- * via the $resource service.
- *
- *
- *
- *
- * See {@link ngResource.$resource `$resource`} for usage.
- */
-
-/**
- * @ngdoc service
- * @name $resource
- * @requires $http
- *
- * @description
- * A factory which creates a resource object that lets you interact with
- * [RESTful](http://en.wikipedia.org/wiki/Representational_State_Transfer) server-side data sources.
- *
- * The returned resource object has action methods which provide high-level behaviors without
- * the need to interact with the low level {@link ng.$http $http} service.
- *
- * Requires the {@link ngResource `ngResource`} module to be installed.
- *
- * By default, trailing slashes will be stripped from the calculated URLs,
- * which can pose problems with server backends that do not expect that
- * behavior. This can be disabled by configuring the `$resourceProvider` like
- * this:
- *
- * ```js
- app.config(['$resourceProvider', function($resourceProvider) {
- // Don't strip trailing slashes from calculated URLs
- $resourceProvider.defaults.stripTrailingSlashes = false;
- }]);
- * ```
- *
- * @param {string} url A parametrized URL template with parameters prefixed by `:` as in
- * `/user/:username`. If you are using a URL with a port number (e.g.
- * `http://example.com:8080/api`), it will be respected.
- *
- * If you are using a url with a suffix, just add the suffix, like this:
- * `$resource('http://example.com/resource.json')` or `$resource('http://example.com/:id.json')`
- * or even `$resource('http://example.com/resource/:resource_id.:format')`
- * If the parameter before the suffix is empty, :resource_id in this case, then the `/.` will be
- * collapsed down to a single `.`. If you need this sequence to appear and not collapse then you
- * can escape it with `/\.`.
- *
- * @param {Object=} paramDefaults Default values for `url` parameters. These can be overridden in
- * `actions` methods. If any of the parameter value is a function, it will be executed every time
- * when a param value needs to be obtained for a request (unless the param was overridden).
- *
- * Each key value in the parameter object is first bound to url template if present and then any
- * excess keys are appended to the url search query after the `?`.
- *
- * Given a template `/path/:verb` and parameter `{verb:'greet', salutation:'Hello'}` results in
- * URL `/path/greet?salutation=Hello`.
- *
- * If the parameter value is prefixed with `@` then the value for that parameter will be extracted
- * from the corresponding property on the `data` object (provided when calling an action method). For
- * example, if the `defaultParam` object is `{someParam: '@someProp'}` then the value of `someParam`
- * will be `data.someProp`.
- *
- * @param {Object.