diff --git a/spring-data-neo4j-examples/cineasts/.gitignore b/spring-data-neo4j-examples/cineasts/.gitignore new file mode 100644 index 000000000..490bd87be --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/.gitignore @@ -0,0 +1,12 @@ +.DS_Store +*.ipr +*.iws +*.iml +*.zip +data +target +*.log +tmp +.classpath +.project +.settings diff --git a/spring-data-neo4j-examples/cineasts/Readme.md b/spring-data-neo4j-examples/cineasts/Readme.md new file mode 100644 index 000000000..4913adb66 --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/Readme.md @@ -0,0 +1,16 @@ +![Cineasts.net Logo](https://github.com/jexp/cineasts/raw/master/cineasts.png) +Cineasts.net +============ + +This project is the demo/tutorial application for the [Spring Data Graph](http://github.com/springsource/spring-data-graph) library which provides convenient access to the [Neo4j](http://neo4j.org) graph database. + +This tutorial creates a complete web application built on top of Spring Data Graph. + +It uses a domain that should be familiar to most - movies. So for cineasts.net we decided to add a social +touch to the whole movie rating business, allowing friends to share their ratings and get recommendations +for new friends and movies. + +The tutorial is presented as a colloquial description of the steps necessary to create the application. +It provides the configuration and code examples that are needed to understand what's happening. + +The complete tutorial is contained in this projects [github wiki](https://github.com/jexp/cineasts/wiki). \ No newline at end of file diff --git a/spring-data-neo4j-examples/cineasts/cineasts.png b/spring-data-neo4j-examples/cineasts/cineasts.png new file mode 100644 index 000000000..e7778456b Binary files /dev/null and b/spring-data-neo4j-examples/cineasts/cineasts.png differ diff --git a/spring-data-neo4j-examples/cineasts/pom.xml b/spring-data-neo4j-examples/cineasts/pom.xml new file mode 100644 index 000000000..ba51727e3 --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/pom.xml @@ -0,0 +1,325 @@ + + 4.0.0 + + org.neo4j + movies + 1.0-SNAPSHOT + war + + Movies + + + UTF-8 + 3.0.5.RELEASE + 1.6.1 + UTF-8 + 1.3 + 1.0.0.RELEASE + 1.6.11.RELEASE + 1.6.1 + + + + + spring-maven-release + Spring Maven Release Repository + http://maven.springframework.org/release + + + spring-maven-snapshot + Spring Maven Snapshot Repository + + true + + http://maven.springframework.org/snapshot + + + spring-maven-milestone + Spring Maven Milestone Repository + http://maven.springframework.org/milestone + + + neo4j-public-repository + http://m2.neo4j.org/ + Publicly available Maven 2 repository for Neo4j + + + jboss-public-repo + http://repository.jboss.org/maven2/ + JBoss public available repo + + + + + + spring-maven-release + Spring Maven Release Repository + http://maven.springframework.org/release + + + spring-maven-milestone + Spring Maven Milestone Repository + http://maven.springframework.org/milestone + + + + + + + org.springframework + spring-core + ${spring.version} + + + commons-logging + commons-logging + + + + + org.springframework + spring-test + ${spring.version} + test + + + commons-logging + commons-logging + + + + + + org.springframework + spring-context + ${spring.version} + + + org.springframework + spring-aop + ${spring.version} + + + org.springframework + spring-aspects + ${spring.version} + + + org.springframework + spring-tx + ${spring.version} + + + + org.springframework + spring-webmvc + ${spring.version} + + + commons-logging + commons-logging + + + + + + org.springframework.security + spring-security-web + ${spring.version} + + + org.springframework.security + spring-security-config + ${spring.version} + + + + org.slf4j + slf4j-api + ${org.slf4j-version} + + + org.slf4j + jcl-over-slf4j + ${org.slf4j-version} + + + org.slf4j + slf4j-log4j12 + ${org.slf4j-version} + runtime + + + log4j + log4j + 1.2.16 + runtime + + + + org.springframework.data + spring-data-neo4j + ${spring-data-graph.version} + + + org.hibernate.javax.persistence + hibernate-jpa-2.0-api + + + + + + opensymphony + sitemesh + 2.4.2 + + + + org.hibernate + hibernate-validator + 4.0.2.GA + + + + javax.servlet + servlet-api + 2.5 + provided + + + javax.servlet.jsp + jsp-api + 2.1 + provided + + + javax.servlet + jstl + 1.2 + + + + org.codehaus.jackson + jackson-mapper-asl + 1.7.2 + + + + org.aspectj + aspectjrt + ${aspectj.version} + + + + cglib + cglib-nodep + 2.2 + + + + org.hibernate.javax.persistence + hibernate-jpa-2.0-api + 1.0.0.Final + + + + + + org.neo4j + neo4j-kernel + ${neo4j.version} + tests + test + + + + junit + junit + 4.8.1 + test + + + + + + org.mortbay.jetty + jetty-maven-plugin + 7.1.2.v20100523 + + + / + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.1 + + 1.6 + 1.6 + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + **/*Tests.java + **/*Test.java + + + **/Abstract*.java + + junit:junit + + + + org.codehaus.mojo + aspectj-maven-plugin + 1.2 + + + org.aspectj + aspectjrt + ${aspectj.version} + + + org.aspectj + aspectjtools + ${aspectj.version} + + + + + + compile + test-compile + + + + + true + + + org.springframework + spring-aspects + + + org.springframework.data + spring-data-neo4j + + + 1.6 + 1.6 + + + + + + diff --git a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/controller/AuthController.java b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/controller/AuthController.java new file mode 100644 index 000000000..48d7d7c4d --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/controller/AuthController.java @@ -0,0 +1,63 @@ +package org.neo4j.cineasts.controller; + + +import org.neo4j.cineasts.service.CineastsUserDetailsService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; + +/** + * Handles and retrieves the login or denied page depending on the URI template + */ +@Controller +@RequestMapping("/auth") +public class AuthController { + + private final static Logger logger = LoggerFactory.getLogger(AuthController.class); + + @Autowired + CineastsUserDetailsService userDetailsService; + @RequestMapping(value = "/login", method = RequestMethod.GET) + public String login(@RequestParam(value = "login_error", required = false) boolean error, Model model) { + logger.debug("Received request to show login page, error "+error); + if (error) { + model.addAttribute("error", "You have entered an invalid username or password!"); + } + return "/auth/loginpage"; + } + + @RequestMapping(value = "/register", method = RequestMethod.POST) + public String register( + @RequestParam(value = "j_username") String login, + @RequestParam(value = "j_displayname") String name, + @RequestParam(value = "j_password") String password, + Model model) { + + try { + userDetailsService.register(login,name,password); + return "forward:/user/"+login; + } catch(Exception e) { + model.addAttribute("j_username",login); + model.addAttribute("j_displayname",name); + model.addAttribute("error",e.getMessage()); + return "/auth/registerpage"; + } + } + + @RequestMapping(value = "/denied", method = RequestMethod.GET) + public String denied() { + logger.debug("Received request to show denied page"); + return "/auth/deniedpage"; + } + + @RequestMapping(value = "/registerpage", method = RequestMethod.GET) + public String registerPage() { + logger.debug("Received request to show register page"); + return "/auth/registerpage"; + } +} \ No newline at end of file diff --git a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/controller/ImportController.java b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/controller/ImportController.java new file mode 100644 index 000000000..61aa74861 --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/controller/ImportController.java @@ -0,0 +1,64 @@ +package org.neo4j.cineasts.controller; + +import org.neo4j.cineasts.movieimport.MovieDbImportService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * @author mh + * @since 04.03.11 + */ +@Controller +public class ImportController { + + private MovieDbImportService importService; + private static final Logger log = LoggerFactory.getLogger(ImportController.class); + + @Autowired + public ImportController(MovieDbImportService importService) { + this.importService = importService; + } + + @RequestMapping(value = "/import/{ids}", method = RequestMethod.GET) + public String importMovie(@PathVariable String ids, Model model) { + long start=System.currentTimeMillis(); + final Map movies = importService.importMovies(extractRanges(ids)); + long duration = (System.currentTimeMillis() - start) / 1000; + model.addAttribute("duration", duration); + model.addAttribute("ids", ids); + model.addAttribute("movies", movies.entrySet()); + return "import/result"; + } + + + private Map extractRanges(String ids) { + Map ranges = new LinkedHashMap(); + StringBuilder errors = new StringBuilder(); + for (String token : ids.split(",")) { + try { + if (token.contains("-")) { + String[] range = token.split("-"); + ranges.put(Integer.parseInt(range[0]), Integer.parseInt(range[1])); + } else { + int id = Integer.parseInt(token); + ranges.put(id, id); + } + } catch (Exception e) { + errors.append(token).append(": ").append(e.getMessage()).append("\n"); + } + } + if (errors.length() > 0) { + throw new RuntimeException("Error parsing ids\n" + errors); + } + return ranges; + } +} diff --git a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/controller/MovieController.java b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/controller/MovieController.java new file mode 100644 index 000000000..11d4dd956 --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/controller/MovieController.java @@ -0,0 +1,122 @@ +package org.neo4j.cineasts.controller; + +import org.neo4j.cineasts.domain.Movie; +import org.neo4j.cineasts.domain.Person; +import org.neo4j.cineasts.domain.Rating; +import org.neo4j.cineasts.domain.User; +import org.neo4j.cineasts.service.CineastsUserDetailsService; +import org.neo4j.cineasts.service.DatabasePopulator; +import org.neo4j.cineasts.service.CineastsRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.*; + +import java.util.Collection; +import java.util.List; + +/** + * @author mh + * @since 04.03.11 + */ +@Controller +public class MovieController { + + private CineastsRepository moviesRepository; + private CineastsUserDetailsService userDetailsService; + private DatabasePopulator populator; + private static final Logger log = LoggerFactory.getLogger(MovieController.class); + + @Autowired + public MovieController(CineastsRepository moviesRepository, DatabasePopulator populator, CineastsUserDetailsService userDetailsService) { + this.moviesRepository = moviesRepository; + this.populator = populator; + this.userDetailsService = userDetailsService; + } + + // for web service (JSON) clients + + /** + * Only matches 'GET /moviies/{id}}' requests for JSON content; a 404 is sent otherwise. + * TODO send a 406 if an unsupported representation, such as XML, is requested. See SPR-7353. + */ + @RequestMapping(value = "/movies/{id}", method = RequestMethod.GET, headers = "Accept=application/json") + public + @ResponseBody + Movie getMovie(@PathVariable String id) { + return moviesRepository.getMovie(id); + } + + + @RequestMapping(value = "/movies/{movieId}", method = RequestMethod.GET, headers = "Accept=text/html") + public String singleMovieView(final Model model, @PathVariable String movieId) { + User user = addUser(model); + Movie movie = moviesRepository.getMovie(movieId); + model.addAttribute("id", movieId); + if (movie != null) { + model.addAttribute("movie", movie); + final int stars = movie.getStars(); + model.addAttribute("stars", stars); + Rating rating = null; + if (user!=null) rating = movie.getRelationshipTo(user, Rating.class, "RATED"); + if (rating == null) rating = new Rating().rate(stars,null); + model.addAttribute("userRating",rating); + } + return "/movies/show"; + } + + @RequestMapping(value = "/movies/{movieId}", method = RequestMethod.POST, headers = "Accept=text/html") + public String updateMovie(Model model, @PathVariable String movieId, @RequestParam(value = "rated",required = false) Integer stars, @RequestParam(value = "comment",required = false) String comment) { + Movie movie = moviesRepository.getMovie(movieId); + User user = userDetailsService.getUserFromSession(); + moviesRepository.rateMovie(movie,user, stars==null ? -1 : stars,comment!=null ? comment.trim() : null); + return singleMovieView(model,movieId); + } + + private User addUser(Model model) { + User user = userDetailsService.getUserFromSession(); + model.addAttribute("user", user); + return user; + } + + @RequestMapping(value = "/movies", method = RequestMethod.GET, headers = "Accept=text/html") + public String findMovies(Model model, @RequestParam("q") String query) { + List movies = moviesRepository.findMovies(query, 20); + model.addAttribute("movies", movies); + model.addAttribute("query", query); + addUser(model); + return "/movies/list"; + } + + @RequestMapping(value = "/actors/{id}", method = RequestMethod.GET, headers = "Accept=text/html") + public String singleActorView(Model model, @PathVariable String id) { + Person person = moviesRepository.getPerson(id); + model.addAttribute("actor", person); + model.addAttribute("id", id); + addUser(model); + return "/actors/show"; + } + + //@RequestMapping(value = "/admin/populate", method = RequestMethod.GET) + @RequestMapping(value = "/populate", method = RequestMethod.GET) + public String populateDatabase(Model model) { + Collection movies=populator.populateDatabase(); + model.addAttribute("movies",movies); + addUser(model); + return "/movies/list"; + } + + @RequestMapping(value = "/admin/clean", method = RequestMethod.GET) + public String clean(Model model) { + populator.cleanDb(); + return "movies/list"; + } + + @RequestMapping(value = "/", method = RequestMethod.GET) + public String index(Model model) { + addUser(model); + return "index"; + } +} diff --git a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/controller/UserController.java b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/controller/UserController.java new file mode 100644 index 000000000..3ce26359b --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/controller/UserController.java @@ -0,0 +1,61 @@ +package org.neo4j.cineasts.controller; + + +import org.neo4j.cineasts.domain.User; +import org.neo4j.cineasts.service.CineastsRepository; +import org.neo4j.cineasts.service.CineastsUserDetailsService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +/** + * Handles and retrieves the login or denied page depending on the URI template + */ +@Controller +public class UserController { + + @Autowired CineastsUserDetailsService userDetailsService; + @Autowired CineastsRepository repository; + + private final static Logger logger = LoggerFactory.getLogger(UserController.class); + + @RequestMapping(value = "/user", method = RequestMethod.GET) + public String profile(Model model) { + final User user = userDetailsService.getUserFromSession(); + model.addAttribute("user", user); + model.addAttribute("recommendations", repository.recommendMovies(user, 3)); + return "/user/index"; + } + + @RequestMapping(value = "/user/{login}/friends", method = RequestMethod.POST) + public String addFriend(Model model, @PathVariable("login") String login) { + userDetailsService.addFriend(login); + return "forward:/user/"+login; + } + + @RequestMapping(value = "/user/{login}") + public String publicProfile(Model model, @PathVariable("login") String login) { + User profiled = userDetailsService.findUser(login); + User user = userDetailsService.getUserFromSession(); + + return publicProfile(model, profiled, user); + } + + private String publicProfile(Model model, User profiled, User user) { + if (profiled.equals(user)) return profile(model); + + model.addAttribute("profiled", profiled); + model.addAttribute("user", user); + model.addAttribute("isFriend", areFriends(profiled, user)); + return "/user/public"; + } + + private boolean areFriends(User user, User loggedIn) { + return user!=null && user.isFriend(loggedIn); + } +} \ No newline at end of file diff --git a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/domain/Movie.java b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/domain/Movie.java new file mode 100644 index 000000000..b8cf7278f --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/domain/Movie.java @@ -0,0 +1,225 @@ +package org.neo4j.cineasts.domain; + +import org.neo4j.helpers.collection.IteratorUtil; +import org.springframework.data.graph.annotation.NodeEntity; +import org.springframework.data.graph.annotation.RelatedTo; +import org.springframework.data.graph.annotation.RelatedToVia; +import org.springframework.data.graph.neo4j.annotation.Indexed; + +import java.util.*; + +import static org.springframework.data.graph.core.Direction.INCOMING; + +/** + * @author mh + * @since 04.03.11 + */ +@NodeEntity +public class Movie { + + @Indexed + String id; + + @Indexed(fulltext = true, indexName = "search") + String title; + + String description; + + @RelatedTo(type="DIRECTED", direction = INCOMING) + Person director; + + @RelatedTo(elementClass = Person.class, type = "ACTS_IN", direction = INCOMING) + Set actors; + + @RelatedToVia(elementClass = Role.class, type = "ACTS_IN", direction = INCOMING) + Iterable roles; + + @RelatedToVia(elementClass = Rating.class, type = "RATED", direction = INCOMING) + Iterable ratings; + private String language; + private String imdbId; + private String tagline; + private Date releaseDate; + private Integer runtime; + private String homepage; + private String trailer; + private String genre; + private String studio; + private Integer version; + private Date lastModified; + private String imageUrl; + + public Movie() { + } + + public Movie(String id, String title) { + this.id = id; + this.title = title; + } + + public Collection getActors() { + return actors; + } + + public Collection getRoles() { + return IteratorUtil.asCollection(roles); + } + + public int getYear() { + if (releaseDate==null) return 0; + Calendar cal = Calendar.getInstance(); + cal.setTime(releaseDate); + return cal.get(Calendar.YEAR); + } + + public String getId() { + return id; + } + + public String getTitle() { + return title; + } + + @Override + public String toString() { + return String.format("%s (%s) [%s]", title, releaseDate, id); + } + + public String getDescription() { + return description; + } + + public int getStars() { + Iterable allRatings = ratings; + + if (allRatings == null) return 0; + int stars=0, count=0; + for (Rating rating : allRatings) { + stars += rating.getStars(); + count++; + } + return count==0 ? 0 : stars / count; + } + + public Collection getRatings() { + Iterable allRatings = ratings; + return allRatings == null ? Collections.emptyList() : IteratorUtil.asCollection(allRatings); + } + + public Person getDirector() { + return director; + } + + public void setTitle(String title) { + this.title=title; + } + + public void setLanguage(String language) { + this.language = language; + } + + public void setImdbId(String imdbId) { + this.imdbId = imdbId; + } + + public void setTagline(String tagline) { + this.tagline = tagline; + } + + public void setDescription(String description) { + this.description = description; + } + + public void setReleaseDate(Date releaseDate) { + this.releaseDate = releaseDate; + } + + public void setRuntime(Integer runtime) { + this.runtime = runtime; + } + + public void setHomepage(String homepage) { + this.homepage = homepage; + } + + public void setTrailer(String trailer) { + this.trailer = trailer; + } + + public void setGenre(String genre) { + this.genre = genre; + } + + public void setStudio(String studio) { + this.studio = studio; + } + + public void setVersion(Integer version) { + this.version = version; + } + + public void setLastModified(Date lastModified) { + this.lastModified = lastModified; + } + + public void setImageUrl(String imageUrl) { + this.imageUrl = imageUrl; + } + + public String getLanguage() { + return language; + } + + public String getImdbId() { + return imdbId; + } + + public String getTagline() { + return tagline; + } + + public Date getReleaseDate() { + return releaseDate; + } + + public Integer getRuntime() { + return runtime; + } + + public String getHomepage() { + return homepage; + } + + public String getTrailer() { + return trailer; + } + + public String getGenre() { + return genre; + } + + public String getStudio() { + return studio; + } + + public Integer getVersion() { + return version; + } + + public Date getLastModified() { + return lastModified; + } + + public String getImageUrl() { + return imageUrl; + } + + public String getYoutubeId() { + String trailerUrl = trailer; + if (trailerUrl==null || !trailerUrl.contains("youtu")) return null; + String[] parts = trailerUrl.split("[=/]"); + int numberOfParts = parts.length; + return numberOfParts > 0 ? parts[numberOfParts-1] : null; + } +} + diff --git a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/domain/Person.java b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/domain/Person.java new file mode 100644 index 000000000..81f445a92 --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/domain/Person.java @@ -0,0 +1,124 @@ +package org.neo4j.cineasts.domain; + +import org.springframework.data.graph.annotation.NodeEntity; +import org.springframework.data.graph.annotation.RelatedTo; +import org.springframework.data.graph.annotation.RelatedToVia; +import org.springframework.data.graph.neo4j.annotation.Indexed; + +import java.util.Date; +import java.util.Set; + +/** + * @author mh + * @since 12.03.11 + */ +@NodeEntity +public class Person { + @Indexed + String id; + String name; + private Date birthday; + private String birthplace; + private String biography; + private Integer version; + private Date lastModified; + private String profileImageUrl; + + public Person(String id, String name) { + this.id = id; + this.name = name; + } + + public Person() { + } + + public String getId() { + return id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public String toString() { + return String.format("%s [%s]", name, id); + } + + public void setBirthday(Date birthday) { + this.birthday = birthday; + } + + public void setBirthplace(String birthplace) { + this.birthplace = birthplace; + } + + public void setBiography(String biography) { + this.biography = biography; + } + + public void setVersion(Integer version) { + this.version = version; + } + + public void setLastModified(Date lastModified) { + this.lastModified = lastModified; + } + + public Date getBirthday() { + return birthday; + } + + public String getBirthplace() { + return birthplace; + } + + public String getBiography() { + return biography; + } + + public Integer getVersion() { + return version; + } + + public Date getLastModified() { + return lastModified; + } + + public void setProfileImageUrl(String profileImageUrl) { + this.profileImageUrl = profileImageUrl; + } + + public String getProfileImageUrl() { + return profileImageUrl; + } + + @RelatedTo(elementClass = Movie.class, type = "DIRECTED") + private Set directedMovies; + + public Set getDirectedMovies() { + return directedMovies; + } + + public void directed(Movie movie) { + this.directedMovies.add(movie); + } + + @RelatedToVia(elementClass = Role.class, type = "ACTS_IN") + Iterable roles; + + public Iterable getRoles() { + return roles; + } + + public Role playedIn(Movie movie, String roleName) { + Role role = relateTo(movie, Role.class, "ACTS_IN"); + role.setName(roleName); + return role; + } + +} diff --git a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/domain/Rating.java b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/domain/Rating.java new file mode 100644 index 000000000..d93858386 --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/domain/Rating.java @@ -0,0 +1,52 @@ +package org.neo4j.cineasts.domain; + +import org.springframework.data.graph.annotation.EndNode; +import org.springframework.data.graph.annotation.RelationshipEntity; +import org.springframework.data.graph.annotation.StartNode; + +/** + * @author mh + * @since 04.03.11 + */ +@RelationshipEntity +public class Rating { + private static final int MAX_STARS = 5; + private static final int MIN_STARS = 0; + + @StartNode + User user; + @EndNode Movie movie; + + int stars; + String comment; + + public User getUser() { + return user; + } + + public Movie getMovie() { + return movie; + } + + public int getStars() { + return stars; + } + + public void setStars(int stars) { + this.stars = stars; + } + + public String getComment() { + return comment; + } + + public void setComment(String comment) { + this.comment = comment; + } + + public Rating rate(int stars, String comment) { + if (stars>= MIN_STARS && stars <= MAX_STARS) this.stars=stars; + if (comment!=null && !comment.isEmpty()) this.comment = comment; + return this; + } +} diff --git a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/domain/Role.java b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/domain/Role.java new file mode 100644 index 000000000..51ca954b1 --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/domain/Role.java @@ -0,0 +1,38 @@ +package org.neo4j.cineasts.domain; + +import org.springframework.data.graph.annotation.EndNode; +import org.springframework.data.graph.annotation.RelationshipEntity; +import org.springframework.data.graph.annotation.StartNode; + +/** + * @author mh + * @since 04.03.11 + */ +@RelationshipEntity +public class Role { + @EndNode Movie movie; + @StartNode Person actor; + + String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Movie getMovie() { + return movie; + } + + public Person getActor() { + return actor; + } + + @Override + public String toString() { + return String.format("%s acts as %s in %s", actor, name, movie); + } +} diff --git a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/domain/Roles.java b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/domain/Roles.java new file mode 100644 index 000000000..3319ab32f --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/domain/Roles.java @@ -0,0 +1,9 @@ +package org.neo4j.cineasts.domain; + +/** +* @author mh +* @since 12.03.11 +*/ +public enum Roles { + ACTS_IN, DIRECTED +} diff --git a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/domain/User.java b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/domain/User.java new file mode 100644 index 000000000..120d32ebb --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/domain/User.java @@ -0,0 +1,117 @@ +package org.neo4j.cineasts.domain; + +import org.neo4j.helpers.collection.IteratorUtil; +import org.springframework.data.graph.annotation.NodeEntity; +import org.springframework.data.graph.annotation.RelatedTo; +import org.springframework.data.graph.annotation.RelatedToVia; +import org.springframework.data.graph.core.Direction; +import org.springframework.data.graph.neo4j.annotation.Indexed; +import org.springframework.security.authentication.encoding.Md5PasswordEncoder; +import org.springframework.security.core.GrantedAuthority; + +import java.util.Collection; +import java.util.Set; + +@NodeEntity +public class User { + private static final String SALT = "cewuiqwzie"; + public static final String FRIEND = "FRIEND"; + public static final String RATED = "RATED"; + @Indexed + String login; + String name; + String password; + String info; + private Roles[] roles; + + public User() { + } + + public User(String login, String name, String password, Roles... roles) { + this.login = login; + this.name = name; + this.password = encode(password); + this.roles = roles; + } + + private String encode(String password) { + return new Md5PasswordEncoder().encodePassword(password, SALT); + } + + @RelatedToVia(elementClass = Rating.class, type = RATED) + Iterable ratings; + + @RelatedTo(elementClass = Movie.class, type = RATED) + Set favorites; + + + @RelatedTo(elementClass = User.class, type = FRIEND, direction = Direction.BOTH) + Set friends; + + public void addFriend(User friend) { + this.friends.add(friend); + } + + public Rating rate(Movie movie, int stars, String comment) { + return relateTo(movie, Rating.class, RATED).rate(stars, comment); + } + + public Collection getRatings() { + return IteratorUtil.asCollection(ratings); + } + + @Override + public String toString() { + return String.format("%s (%s)", name, login); + } + + public String getName() { + return name; + } + + public Set getFriends() { + return friends; + } + + public Roles[] getRole() { + return roles; + } + + + public String getLogin() { + return login; + } + + public String getPassword() { + return password; + } + + public String getInfo() { + return info; + } + public void setInfo(String info) { + this.info = info; + } + public void updatePassword(String old, String newPass1, String newPass2) { + if (!password.equals(encode(old))) throw new IllegalArgumentException("Existing Password invalid"); + if (!newPass1.equals(newPass2)) throw new IllegalArgumentException("New Passwords don't match"); + this.password = encode(newPass1); + } + + public void setName(String name) { + this.name = name; + } + + public boolean isFriend(User other) { + return other!=null && getFriends().contains(other); + } + + public enum Roles implements GrantedAuthority { + ROLE_USER, ROLE_ADMIN; + + @Override + public String getAuthority() { + return name(); + } + } +} diff --git a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/movieimport/MovieDbApiClient.java b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/movieimport/MovieDbApiClient.java new file mode 100644 index 000000000..f07fc9753 --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/movieimport/MovieDbApiClient.java @@ -0,0 +1,46 @@ +package org.neo4j.cineasts.movieimport; + +import org.codehaus.jackson.map.ObjectMapper; + +import java.net.URL; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +public class MovieDbApiClient { + + private final String baseUrl = "http://api.themoviedb.org/"; + private final String apiKey; + protected final ObjectMapper mapper; + + public MovieDbApiClient(String apiKey) { + this.apiKey = apiKey; + mapper = new ObjectMapper(); + } + + public Map getMovie(String id) { + return loadJsonData(id, buildMovieUrl(id)); + } + + private Map loadJsonData(String id, String url) { + try { + List value = mapper.readValue(new URL(url), List.class); + if (value.isEmpty() || value.get(0).equals("Nothing found.")) return Collections.singletonMap("not_found",System.currentTimeMillis()); + return (Map) value.get(0); + } catch (Exception e) { + throw new RuntimeException("Failed to get data from " + url, e); + } + } + + private String buildMovieUrl(String movieId) { + return String.format("%s2.1/Movie.getInfo/en/json/%s/%s", baseUrl, apiKey, movieId); + } + + public Map getPerson(String id) { + return loadJsonData(id, buildPersonUrl(id)); + } + + private String buildPersonUrl(String personId) { + return String.format("%s2.1/Person.getInfo/en/json/%s/%s", baseUrl, apiKey, personId); + } +} diff --git a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/movieimport/MovieDbException.java b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/movieimport/MovieDbException.java new file mode 100644 index 000000000..a1da5992b --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/movieimport/MovieDbException.java @@ -0,0 +1,14 @@ +package org.neo4j.cineasts.movieimport; + +public class MovieDbException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + public MovieDbException(String message) { + super(message); + } + + public MovieDbException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/movieimport/MovieDbImportService.java b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/movieimport/MovieDbImportService.java new file mode 100644 index 000000000..bb9ed3de6 --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/movieimport/MovieDbImportService.java @@ -0,0 +1,128 @@ +package org.neo4j.cineasts.movieimport; + +import org.neo4j.cineasts.domain.*; +import org.neo4j.cineasts.service.CineastsRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.Map; + +@Service +public class MovieDbImportService { + + private static final Logger logger = LoggerFactory.getLogger(MovieDbImportService.class); + MovieDbJsonMapper movieDbJsonMapper = new MovieDbJsonMapper(); + + @Autowired + CineastsRepository moviesRepository; + + @Autowired + MovieDbApiClient client; + + @Autowired + MovieDbLocalStorage localStorage; + + @Transactional + public Map importMovies(Map ranges) { + final Map movies=new LinkedHashMap(); + for (Map.Entry entry : ranges.entrySet()) { + for (int id = entry.getKey(); id <= entry.getValue(); id++) { + String result = importMovieFailsafe(id); + movies.put(id, result); + } + } + return movies; + } + + private String importMovieFailsafe(Integer id) { + try { + Movie movie = doImportMovie(String.valueOf(id)); + return movie.getTitle(); + } catch (Exception e) { + return e.getMessage(); + } + } + + @Transactional + public Movie importMovie(String movieId) { + return doImportMovie(movieId); + } + + private Movie doImportMovie(String movieId) { + logger.debug("Importing movie " + movieId); + + Movie movie = moviesRepository.getMovie(movieId); + if (movie == null) { // Not found: Create fresh + movie = new Movie(movieId,null); + } + + Map data = loadMovieData(movieId); + if (data.containsKey("not_found")) throw new RuntimeException("Data for Movie "+movieId+" not found."); + movieDbJsonMapper.mapToMovie(data, movie); + movie.persist(); + relatePersonsToMovie(movie, data); + return movie; + } + + private Map loadMovieData(String movieId) { + if (localStorage.hasMovie(movieId)) { + return localStorage.loadMovie(movieId); + } + + Map data = client.getMovie(movieId); + localStorage.storeMovie(movieId, data); + return data; + } + + private void relatePersonsToMovie(Movie movie, Map data) { + Collection cast = (Collection) data.get("cast"); + for (Map entry : cast) { + String id = "" + entry.get("id"); + String jobName = (String) entry.get("job"); + Roles job = movieDbJsonMapper.mapToRole(jobName); + if (job==null) { + if (logger.isInfoEnabled()) logger.info("Could not add person with job "+jobName+" "+entry); + continue; + } + Person person = doImportPerson(id); + switch (job) { + case DIRECTED: + person.directed(movie); + break; + case ACTS_IN: + person.playedIn(movie, (String) entry.get("character")); + break; + } + } + } + + @Transactional + public Person importPerson(String personId) { + return doImportPerson(personId); + } + + private Person doImportPerson(String personId) { + logger.debug("Importing person " + personId); + Person person = moviesRepository.getPerson(personId); + if (person!=null) return person; + Map data = loadPersonData(personId); + if (data.containsKey("not_found")) throw new RuntimeException("Data for Person "+personId+" not found."); + Person newPerson=new Person(personId,null); + movieDbJsonMapper.mapToPerson(data, newPerson); + return newPerson.persist(); + } + + private Map loadPersonData(String personId) { + if (localStorage.hasPerson(personId)) { + return localStorage.loadPerson(personId); + } + Map data = client.getPerson(personId); + localStorage.storePerson(personId, data); + return localStorage.loadPerson(personId); + } +} diff --git a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/movieimport/MovieDbJsonMapper.java b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/movieimport/MovieDbJsonMapper.java new file mode 100644 index 000000000..c1675830c --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/movieimport/MovieDbJsonMapper.java @@ -0,0 +1,704 @@ +package org.neo4j.cineasts.movieimport; + +import org.neo4j.cineasts.domain.Movie; +import org.neo4j.cineasts.domain.Person; +import org.neo4j.cineasts.domain.Roles; +import org.springframework.stereotype.Component; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; +import java.util.Map; + +@Component +public class MovieDbJsonMapper { + + public void mapToMovie(Map data, Movie movie) { + try { + movie.setTitle((String) data.get("name")); + movie.setLanguage((String) data.get("language")); + movie.setImdbId((String) data.get("imdb_id")); + movie.setTagline((String) data.get("tagline")); + movie.setDescription(limit((String) data.get("overview"), 500)); + movie.setReleaseDate(toDate(data, "released", "yyyy-MM-dd")); + movie.setRuntime((Integer) data.get("runtime")); + movie.setHomepage((String) data.get("homepage")); + movie.setTrailer((String) data.get("trailer")); + movie.setGenre(extractFirst(data, "genres", "name")); + movie.setStudio(extractFirst(data,"studios", "name")); + movie.setVersion((Integer)data.get("version")); + movie.setLastModified(toDate(data,"last_modified_at","yyyy-MM-dd HH:mm:ss")); + movie.setImageUrl(selectImageUrl((List) data.get("posters"), "poster", "mid")); + } catch (Exception e) { + throw new MovieDbException("Failed to map json for movie", e); + } + } + + private String selectImageUrl(List data, final String type, final String size) { + if (data==null) return null; + for (Map entry : data) { + Map image = (Map) entry.get("image"); + if (image.get("type").equals(type) && image.get("size").equals(size)) return (String) image.get("url"); + } + return null; + } + + + private String extractFirst(Map data, String field, String property) { + List inner = (List) data.get(field); + if (inner == null || inner.isEmpty()) return null; + return (String) inner.get(0).get(property); + } + + private Date toDate(Map data, String field, final String pattern) throws ParseException { + String dateString = (String) data.get(field); + if (dateString == null || dateString.isEmpty()) return null; + return new SimpleDateFormat(pattern).parse(dateString); + } + + /* + [{"popularity":3, +"translated":true, +"adult":false, +"language":"en", +"original_name":"[Rec]", +"name":"[Rec]", +"alternative_name":"[REC]", +"movie_type":"movie", +"id":8329, +"imdb_id":"tt1038988", +"url":"http://www.themoviedb.org/movie/8329", +"votes":11, +"rating":7.2, +"status":"Released", +"tagline":"One Witness. One Camera", +"certification":"R", +"overview":"\"REC\" turns on a young TV reporter and her cameraman who cover the night shift at the local fire station. Receiving a call from an old lady trapped in her house, +they reach her building to hear horrifying screams -- which begin a long nightmare and a uniquely dramatic TV report.", +"keywords":["terror", +"lebende leichen", +"obsession", +"camcorder", +"firemen", +"reality tv ", +"bite", +"cinematographer", +"attempt to escape", +"virus", +"lodger", +"live-reportage", +"schwerverletzt"], +"released":"2007-08-29", +"runtime":78, +"budget":0, +"revenue":0, +"homepage":"http://www.3l-filmverleih.de/rec", +"trailer":"http://www.youtube.com/watch?v=YQUkX_XowqI", +"genres":[{"type":"genre", +"url":"http://themoviedb.org/genre/horror", +"name":"Horror", +"id":27}], +"studios":[{"url":"http://www.themoviedb.org/company/2270", +"name":"Filmax Group", +"id":2270}], +"languages_spoken":[{"code":"es", +"name":"Spanish", +"native_name":"Espa\u00f1ol"}], +"countries":[{"code":"ES", +"name":"Spain", +"url":"http://www.themoviedb.org/country/es"}], +"posters":[{"image":{"type":"poster", +"size":"original", +"height":1000, +"width":706, +"url":"http://cf1.imgobject.com/posters/3a0/4cc8df415e73d650240003a0/rec-original.jpg", +"id":"4cc8df415e73d650240003a0"}}, +{"image":{"type":"poster", +"size":"mid", +"height":708, +"width":500, +"url":"http://cf1.imgobject.com/posters/3a0/4cc8df415e73d650240003a0/rec-mid.jpg", +"id":"4cc8df415e73d650240003a0"}}, +{"image":{"type":"poster", +"size":"cover", +"height":262, +"width":185, +"url":"http://cf1.imgobject.com/posters/3a0/4cc8df415e73d650240003a0/rec-cover.jpg", +"id":"4cc8df415e73d650240003a0"}}, +{"image":{"type":"poster", +"size":"thumb", +"height":130, +"width":92, +"url":"http://cf1.imgobject.com/posters/3a0/4cc8df415e73d650240003a0/rec-thumb.jpg", +"id":"4cc8df415e73d650240003a0"}}, +{"image":{"type":"poster", +"size":"original", +"height":1000, +"width":711, +"url":"http://cf1.imgobject.com/posters/1e7/4bc92117017a3c57fe00d1e7/rec-original.jpg", +"id":"4bc92117017a3c57fe00d1e7"}}, +{"image":{"type":"poster", +"size":"mid", +"height":703, +"width":500, +"url":"http://cf1.imgobject.com/posters/1e7/4bc92117017a3c57fe00d1e7/rec-mid.jpg", +"id":"4bc92117017a3c57fe00d1e7"}}, +{"image":{"type":"poster", +"size":"cover", +"height":260, +"width":185, +"url":"http://cf1.imgobject.com/posters/1e7/4bc92117017a3c57fe00d1e7/rec-cover.jpg", +"id":"4bc92117017a3c57fe00d1e7"}}, +{"image":{"type":"poster", +"size":"thumb", +"height":129, +"width":92, +"url":"http://cf1.imgobject.com/posters/1e7/4bc92117017a3c57fe00d1e7/rec-thumb.jpg", +"id":"4bc92117017a3c57fe00d1e7"}}, +{"image":{"type":"poster", +"size":"original", +"height":1500, +"width":1000, +"url":"http://cf1.imgobject.com/posters/1ec/4bc92118017a3c57fe00d1ec/rec-original.jpg", +"id":"4bc92118017a3c57fe00d1ec"}}, +{"image":{"type":"poster", +"size":"mid", +"height":750, +"width":500, +"url":"http://cf1.imgobject.com/posters/1ec/4bc92118017a3c57fe00d1ec/rec-mid.jpg", +"id":"4bc92118017a3c57fe00d1ec"}}, +{"image":{"type":"poster", +"size":"cover", +"height":278, +"width":185, +"url":"http://cf1.imgobject.com/posters/1ec/4bc92118017a3c57fe00d1ec/rec-cover.jpg", +"id":"4bc92118017a3c57fe00d1ec"}}, +{"image":{"type":"poster", +"size":"thumb", +"height":138, +"width":92, +"url":"http://cf1.imgobject.com/posters/1ec/4bc92118017a3c57fe00d1ec/rec-thumb.jpg", +"id":"4bc92118017a3c57fe00d1ec"}}, +{"image":{"type":"poster", +"size":"original", +"height":1429, +"width":1000, +"url":"http://cf1.imgobject.com/posters/1f1/4bc92118017a3c57fe00d1f1/rec-original.jpg", +"id":"4bc92118017a3c57fe00d1f1"}}, +{"image":{"type":"poster", +"size":"mid", +"height":715, +"width":500, +"url":"http://cf1.imgobject.com/posters/1f1/4bc92118017a3c57fe00d1f1/rec-mid.jpg", +"id":"4bc92118017a3c57fe00d1f1"}}, +{"image":{"type":"poster", +"size":"cover", +"height":265, +"width":185, +"url":"http://cf1.imgobject.com/posters/1f1/4bc92118017a3c57fe00d1f1/rec-cover.jpg", +"id":"4bc92118017a3c57fe00d1f1"}}, +{"image":{"type":"poster", +"size":"thumb", +"height":132, +"width":92, +"url":"http://cf1.imgobject.com/posters/1f1/4bc92118017a3c57fe00d1f1/rec-thumb.jpg", +"id":"4bc92118017a3c57fe00d1f1"}}, +{"image":{"type":"poster", +"size":"original", +"height":1125, +"width":800, +"url":"http://cf1.imgobject.com/posters/1f6/4bc92118017a3c57fe00d1f6/rec-original.jpg", +"id":"4bc92118017a3c57fe00d1f6"}}, +{"image":{"type":"poster", +"size":"mid", +"height":703, +"width":500, +"url":"http://cf1.imgobject.com/posters/1f6/4bc92118017a3c57fe00d1f6/rec-mid.jpg", +"id":"4bc92118017a3c57fe00d1f6"}}, +{"image":{"type":"poster", +"size":"cover", +"height":260, +"width":185, +"url":"http://cf1.imgobject.com/posters/1f6/4bc92118017a3c57fe00d1f6/rec-cover.jpg", +"id":"4bc92118017a3c57fe00d1f6"}}, +{"image":{"type":"poster", +"size":"thumb", +"height":129, +"width":92, +"url":"http://cf1.imgobject.com/posters/1f6/4bc92118017a3c57fe00d1f6/rec-thumb.jpg", +"id":"4bc92118017a3c57fe00d1f6"}}], +"backdrops":[{"image":{"type":"backdrop", +"size":"original", +"height":1080, +"width":1920, +"url":"http://cf1.imgobject.com/backdrops/1df/4bc92117017a3c57fe00d1df/rec-original.jpg", +"id":"4bc92117017a3c57fe00d1df"}}, +{"image":{"type":"backdrop", +"size":"poster", +"height":439, +"width":780, +"url":"http://cf1.imgobject.com/backdrops/1df/4bc92117017a3c57fe00d1df/rec-poster.jpg", +"id":"4bc92117017a3c57fe00d1df"}}, +{"image":{"type":"backdrop", +"size":"thumb", +"height":169, +"width":300, +"url":"http://cf1.imgobject.com/backdrops/1df/4bc92117017a3c57fe00d1df/rec-thumb.jpg", +"id":"4bc92117017a3c57fe00d1df"}}, +{"image":{"type":"backdrop", +"size":"original", +"height":1080, +"width":1920, +"url":"http://cf1.imgobject.com/backdrops/1d7/4bc92113017a3c57fe00d1d7/rec-original.jpg", +"id":"4bc92113017a3c57fe00d1d7"}}, +{"image":{"type":"backdrop", +"size":"poster", +"height":439, +"width":780, +"url":"http://cf1.imgobject.com/backdrops/1d7/4bc92113017a3c57fe00d1d7/rec-poster.jpg", +"id":"4bc92113017a3c57fe00d1d7"}}, +{"image":{"type":"backdrop", +"size":"thumb", +"height":169, +"width":300, +"url":"http://cf1.imgobject.com/backdrops/1d7/4bc92113017a3c57fe00d1d7/rec-thumb.jpg", +"id":"4bc92113017a3c57fe00d1d7"}}, +{"image":{"type":"backdrop", +"size":"original", +"height":1080, +"width":1920, +"url":"http://cf1.imgobject.com/backdrops/1e3/4bc92117017a3c57fe00d1e3/rec-original.jpg", +"id":"4bc92117017a3c57fe00d1e3"}}, +{"image":{"type":"backdrop", +"size":"poster", +"height":439, +"width":780, +"url":"http://cf1.imgobject.com/backdrops/1e3/4bc92117017a3c57fe00d1e3/rec-poster.jpg", +"id":"4bc92117017a3c57fe00d1e3"}}, +{"image":{"type":"backdrop", +"size":"thumb", +"height":169, +"width":300, +"url":"http://cf1.imgobject.com/backdrops/1e3/4bc92117017a3c57fe00d1e3/rec-thumb.jpg", +"id":"4bc92117017a3c57fe00d1e3"}}, +{"image":{"type":"backdrop", +"size":"original", +"height":1080, +"width":1920, +"url":"http://cf1.imgobject.com/backdrops/1d3/4bc92113017a3c57fe00d1d3/rec-original.jpg", +"id":"4bc92113017a3c57fe00d1d3"}}, +{"image":{"type":"backdrop", +"size":"poster", +"height":439, +"width":780, +"url":"http://cf1.imgobject.com/backdrops/1d3/4bc92113017a3c57fe00d1d3/rec-poster.jpg", +"id":"4bc92113017a3c57fe00d1d3"}}, +{"image":{"type":"backdrop", +"size":"thumb", +"height":169, +"width":300, +"url":"http://cf1.imgobject.com/backdrops/1d3/4bc92113017a3c57fe00d1d3/rec-thumb.jpg", +"id":"4bc92113017a3c57fe00d1d3"}}, +{"image":{"type":"backdrop", +"size":"original", +"height":1080, +"width":1920, +"url":"http://cf1.imgobject.com/backdrops/1db/4bc92114017a3c57fe00d1db/rec-original.jpg", +"id":"4bc92114017a3c57fe00d1db"}}, +{"image":{"type":"backdrop", +"size":"poster", +"height":439, +"width":780, +"url":"http://cf1.imgobject.com/backdrops/1db/4bc92114017a3c57fe00d1db/rec-poster.jpg", +"id":"4bc92114017a3c57fe00d1db"}}, +{"image":{"type":"backdrop", +"size":"thumb", +"height":169, +"width":300, +"url":"http://cf1.imgobject.com/backdrops/1db/4bc92114017a3c57fe00d1db/rec-thumb.jpg", +"id":"4bc92114017a3c57fe00d1db"}}, +{"image":{"type":"backdrop", +"size":"original", +"height":1080, +"width":1920, +"url":"http://cf1.imgobject.com/backdrops/6f4/4d0e39c25e73d637100016f4/rec-original.jpg", +"id":"4d0e39c25e73d637100016f4"}}, +{"image":{"type":"backdrop", +"size":"poster", +"height":439, +"width":780, +"url":"http://cf1.imgobject.com/backdrops/6f4/4d0e39c25e73d637100016f4/rec-poster.jpg", +"id":"4d0e39c25e73d637100016f4"}}, +{"image":{"type":"backdrop", +"size":"thumb", +"height":169, +"width":300, +"url":"http://cf1.imgobject.com/backdrops/6f4/4d0e39c25e73d637100016f4/rec-thumb.jpg", +"id":"4d0e39c25e73d637100016f4"}}, +{"image":{"type":"backdrop", +"size":"original", +"height":1080, +"width":1920, +"url":"http://cf1.imgobject.com/backdrops/567/4d0e39dd5e73d6370a001567/rec-original.jpg", +"id":"4d0e39dd5e73d6370a001567"}}, +{"image":{"type":"backdrop", +"size":"poster", +"height":439, +"width":780, +"url":"http://cf1.imgobject.com/backdrops/567/4d0e39dd5e73d6370a001567/rec-poster.jpg", +"id":"4d0e39dd5e73d6370a001567"}}, +{"image":{"type":"backdrop", +"size":"thumb", +"height":169, +"width":300, +"url":"http://cf1.imgobject.com/backdrops/567/4d0e39dd5e73d6370a001567/rec-thumb.jpg", +"id":"4d0e39dd5e73d6370a001567"}}, +{"image":{"type":"backdrop", +"size":"original", +"height":1080, +"width":1920, +"url":"http://cf1.imgobject.com/backdrops/58a/4d0e39fb5e73d6371c00158a/rec-original.jpg", +"id":"4d0e39fb5e73d6371c00158a"}}, +{"image":{"type":"backdrop", +"size":"poster", +"height":439, +"width":780, +"url":"http://cf1.imgobject.com/backdrops/58a/4d0e39fb5e73d6371c00158a/rec-poster.jpg", +"id":"4d0e39fb5e73d6371c00158a"}}, +{"image":{"type":"backdrop", +"size":"thumb", +"height":169, +"width":300, +"url":"http://cf1.imgobject.com/backdrops/58a/4d0e39fb5e73d6371c00158a/rec-thumb.jpg", +"id":"4d0e39fb5e73d6371c00158a"}}, +{"image":{"type":"backdrop", +"size":"original", +"height":1080, +"width":1920, +"url":"http://cf1.imgobject.com/backdrops/5f4/4d0e3a185e73d6370e0015f4/rec-original.jpg", +"id":"4d0e3a185e73d6370e0015f4"}}, +{"image":{"type":"backdrop", +"size":"poster", +"height":439, +"width":780, +"url":"http://cf1.imgobject.com/backdrops/5f4/4d0e3a185e73d6370e0015f4/rec-poster.jpg", +"id":"4d0e3a185e73d6370e0015f4"}}, +{"image":{"type":"backdrop", +"size":"thumb", +"height":169, +"width":300, +"url":"http://cf1.imgobject.com/backdrops/5f4/4d0e3a185e73d6370e0015f4/rec-thumb.jpg", +"id":"4d0e3a185e73d6370e0015f4"}}, +{"image":{"type":"backdrop", +"size":"original", +"height":1080, +"width":1920, +"url":"http://cf1.imgobject.com/backdrops/67f/4d0e3a395e73d6371600167f/rec-original.jpg", +"id":"4d0e3a395e73d6371600167f"}}, +{"image":{"type":"backdrop", +"size":"poster", +"height":439, +"width":780, +"url":"http://cf1.imgobject.com/backdrops/67f/4d0e3a395e73d6371600167f/rec-poster.jpg", +"id":"4d0e3a395e73d6371600167f"}}, +{"image":{"type":"backdrop", +"size":"thumb", +"height":169, +"width":300, +"url":"http://cf1.imgobject.com/backdrops/67f/4d0e3a395e73d6371600167f/rec-thumb.jpg", +"id":"4d0e3a395e73d6371600167f"}}], +"cast":[{"name":"Manuela Velasco", +"job":"Actor", +"department":"Actors", +"character":"Angela Vidal", +"id":34793, +"order":0, +"cast_id":1, +"url":"http://www.themoviedb.org/person/34793", +"profile":"http://cf1.imgobject.com/profiles/390/4c0157fa017a3c702d001390/manuela-velasco-thumb.jpg"}, +{"name":"Carlos Lasarte", +"job":"Actor", +"department":"Actors", +"character":"C\u00e9sar", +"id":54519, +"order":2, +"cast_id":3, +"url":"http://www.themoviedb.org/person/54519", +"profile":"http://cf1.imgobject.com/profiles/ba6/4d27aa297b9aa134d3001ba6/carlos-lasarte-thumb.jpg"}, +{"name":"Pablo Rosso", +"job":"Actor", +"department":"Actors", +"character":"Marcos", +"id":54520, +"order":3, +"cast_id":4, +"url":"http://www.themoviedb.org/person/54520", +"profile":""}, +{"name":"David Vert", +"job":"Actor", +"department":"Actors", +"character":"Alex", +"id":54521, +"order":4, +"cast_id":5, +"url":"http://www.themoviedb.org/person/54521", +"profile":"http://cf1.imgobject.com/profiles/c7e/4d27aad57b9aa134cb001c7e/david-vert-thumb.jpg"}, +{"name":"Vicente Gil", +"job":"Actor", +"department":"Actors", +"character":"Polizist", +"id":54522, +"order":5, +"cast_id":6, +"url":"http://www.themoviedb.org/person/54522", +"profile":"http://cf1.imgobject.com/profiles/c86/4d27ab237b9aa134cb001c86/vicente-gil-thumb.jpg"}, +{"name":"Martha Carbonell", +"job":"Actor", +"department":"Actors", +"character":"Frau Izquierdo", +"id":54523, +"order":6, +"cast_id":7, +"url":"http://www.themoviedb.org/person/54523", +"profile":"http://cf1.imgobject.com/profiles/c90/4d27ab777b9aa134cb001c90/martha-carbonell-thumb.jpg"}, +{"name":"Carlos Vicente", +"job":"Actor", +"department":"Actors", +"character":"Guillem", +"id":54524, +"order":7, +"cast_id":8, +"url":"http://www.themoviedb.org/person/54524", +"profile":"http://cf1.imgobject.com/profiles/b0f/4d27abcc7b9aa134cf001b0f/carlos-vicente-thumb.jpg"}, +{"name":"Ferran Terraza", +"job":"Actor", +"department":"Actors", +"character":"Manu", +"id":54532, +"order":8, +"cast_id":22, +"url":"http://www.themoviedb.org/person/54532", +"profile":"http://cf1.imgobject.com/profiles/129/4c4bfbab7b9aa1237f000129/ferran-terraza-thumb.jpg"}, +{"name":"Jorge Yamam", +"job":"Actor", +"department":"Actors", +"character":"Sergio", +"id":147878, +"order":9, +"cast_id":23, +"url":"http://www.themoviedb.org/person/147878", +"profile":"http://cf1.imgobject.com/profiles/cbb/4d27ac677b9aa134dc001cbb/jorge-yamam-thumb.jpg"}, +{"name":"Jaume Balaguer\u00f3", +"job":"Director", +"department":"Directing", +"character":"", +"id":54525, +"order":0, +"cast_id":9, +"url":"http://www.themoviedb.org/person/54525", +"profile":""}, +{"name":"Paco Plaza", +"job":"Director", +"department":"Directing", +"character":"", +"id":54526, +"order":0, +"cast_id":10, +"url":"http://www.themoviedb.org/person/54526", +"profile":""}, +{"name":"Jaume Balaguer\u00f3", +"job":"Screenplay", +"department":"Writing", +"character":"", +"id":54525, +"order":0, +"cast_id":11, +"url":"http://www.themoviedb.org/person/54525", +"profile":""}, +{"name":"Paco Plaza", +"job":"Screenplay", +"department":"Writing", +"character":"", +"id":54526, +"order":0, +"cast_id":12, +"url":"http://www.themoviedb.org/person/54526", +"profile":""}, +{"name":"Luis Berdejo", +"job":"Screenplay", +"department":"Writing", +"character":"", +"id":54527, +"order":0, +"cast_id":13, +"url":"http://www.themoviedb.org/person/54527", +"profile":""}, +{"name":"Julio Fern\u00e1ndez", +"job":"Producer", +"department":"Production", +"character":"", +"id":17083, +"order":0, +"cast_id":14, +"url":"http://www.themoviedb.org/person/17083", +"profile":""}, +{"name":"Carlos Fern\u00e1ndez", +"job":"Executive Producer", +"department":"Production", +"character":"", +"id":37950, +"order":0, +"cast_id":15, +"url":"http://www.themoviedb.org/person/37950", +"profile":""}, +{"name":"Alberto Marini", +"job":"Producer", +"department":"Production", +"character":"", +"id":54528, +"order":0, +"cast_id":16, +"url":"http://www.themoviedb.org/person/54528", +"profile":""}, +{"name":"Pablo Rosso", +"job":"Director of Photography", +"department":"Camera", +"character":"", +"id":54520, +"order":0, +"cast_id":17, +"url":"http://www.themoviedb.org/person/54520", +"profile":""}, +{"name":"Gemma Fauria", +"job":"Set Designer", +"department":"Art", +"character":"", +"id":54529, +"order":0, +"cast_id":18, +"url":"http://www.themoviedb.org/person/54529", +"profile":""}, +{"name":"David Gallart", +"job":"Editor", +"department":"Editing", +"character":"", +"id":28500, +"order":0, +"cast_id":19, +"url":"http://www.themoviedb.org/person/28500", +"profile":""}, +{"name":"Xavier Mas", +"job":"Sound Designer", +"department":"Sound", +"character":"", +"id":54530, +"order":0, +"cast_id":20, +"url":"http://www.themoviedb.org/person/54530", +"profile":""}, +{"name":"Gl\u00f2ria Viguer", +"job":"Costume Design", +"department":"Costume \u0026 Make-Up", +"character":"", +"id":54531, +"order":0, +"cast_id":21, +"url":"http://www.themoviedb.org/person/54531", +"profile":""}], +"version":150, +"last_modified_at":"2011-02-20 23:16:57"}] + */ + + public void mapToPerson(Map data, Person person) { + try { + person.setName((String) data.get("name")); + person.setBirthday(toDate(data, "birthday", "yyyy-MM-dd")); + person.setBirthplace((String) data.get("birthplace")); + String biography = (String) data.get("biography"); + person.setBiography(limit(biography,500)); + person.setVersion((Integer) data.get("version")); + person.setProfileImageUrl(selectImageUrl((List) data.get("profile"), "profile", "profile")); + person.setLastModified(toDate(data,"last_modified_at","yyyy-MM-dd HH:mm:ss")); + } catch (Exception e) { + throw new MovieDbException("Failed to map json for person", e); + } + } + + private String limit(String text, int limit) { + if (text==null || text.length() < limit) return text; + return text.substring(0,limit); + } + +/* + [{"popularity":3, +"name":"Glenn Strange", +"known_as":[{"name":"George Glenn Strange"}, +{"name":"Glen Strange"}, +{"name":"Glen 'Peewee' Strange"}, +{"name":"Peewee Strange"}, +{"name":"'Peewee' Strange"}], +"id":30112, +"biography":"", +"known_movies":4, +"birthday":"1899-08-16", +"birthplace":"Weed, + New Mexico, + USA", +"url":"http://www.themoviedb.org/person/30112", +"filmography":[{"name":"Bud Abbott Lou Costello Meet Frankenstein", +"id":3073, +"job":"Actor", +"department":"Actors", +"character":"The Frankenstein Monster", +"cast_id":23, +"url":"http://www.themoviedb.org/movie/3073", +"poster":"http://cf1.imgobject.com/posters/4ca/4bc9185d017a3c57fe0094ca/bud-abbott-lou-costello-meet-frankenstein-cover.jpg", +"adult":false, +"release":"1948-06-15"}, +{"name":"Arizona Days (1937)", +"id":22367, +"job":"Actor", +"department":"Actors", +"character":"Henchman Pete ", +"cast_id":12, +"url":"http://www.themoviedb.org/movie/22367", +"poster":"", +"adult":false, +"release":"1937-01-30"}, +{"name":"House of Dracula", +"id":30793, +"job":"Actor", +"department":"Actors", +"character":"The Frankenstein Monster", +"cast_id":3, +"url":"http://www.themoviedb.org/movie/30793", +"poster":"http://cf1.imgobject.com/posters/7cf/4bc97660017a3c57fe0367cf/house-of-dracula-cover.jpg", +"adult":false, +"release":"1945-01-01"}, +{"name":"The Fargo Kid", +"id":38704, +"job":"Actor", +"department":"Actors", +"character":"Sheriff Dave", +"cast_id":24, +"url":"http://www.themoviedb.org/movie/38704", +"poster":"http://cf1.imgobject.com/posters/04e/4d74018a5e73d6021d00004e/the-fargo-kid-cover.jpg", +"adult":false, +"release":"1940-12-06"}], +"profile":[], +"version":19, +"last_modified_at":"2011-03-07 13:02:35"}] +*/ + + + public Roles mapToRole(String roleString) { + if (roleString.equals("Actor")) { + return Roles.ACTS_IN; + } + if (roleString.equals("Director")) { + return Roles.DIRECTED; + } + return null; + } +} diff --git a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/movieimport/MovieDbLocalStorage.java b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/movieimport/MovieDbLocalStorage.java new file mode 100644 index 000000000..199c47986 --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/movieimport/MovieDbLocalStorage.java @@ -0,0 +1,95 @@ +package org.neo4j.cineasts.movieimport; + +import org.codehaus.jackson.map.ObjectMapper; + +import java.io.*; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +public class MovieDbLocalStorage { + + private String storagePath; + protected ObjectMapper mapper; + + public MovieDbLocalStorage(String storagePath) { + this.storagePath = storagePath; + ensureStorageDirectoryExists(); + mapper = new ObjectMapper(); + } + + private void ensureStorageDirectoryExists() { + File storageDirectory = new File(storagePath); + if (!storageDirectory.isDirectory()) { + if (!storageDirectory.mkdirs()) { + throw new RuntimeException("Failed to create storage dir"); + } + } + } + + public boolean hasMovie(String movieId) { + return fileForMovie(movieId).exists(); + } + + private File fileForMovie(String movieId) { + return new File(storagePath, String.format("movie_%s.json", movieId)); + } + + public Map loadMovie(String movieId) { + File storageFile = fileForMovie(movieId); + return loadJsonValue(storageFile); + } + + private Map loadJsonValue(File storageFile) { + try { + final Object value = mapper.readValue(storageFile, Object.class); + if (value instanceof List) { + List list = (List) value; + if (list.isEmpty() || list.get(0).equals("Nothing found.")) return Collections.singletonMap("not_found", System.currentTimeMillis()); + return asMap(list.get(0)); + } + return asMap(value); + } catch (Exception e) { + throw new MovieDbException("Failed to load JSON from storage for file " + storageFile.getPath(), e); + } + } + + private Map asMap(Object value) { + if (value instanceof Map) { + return (Map) value; + } + final String typeInformation = value == null ? "null" : value.getClass().getSimpleName(); + throw new MovieDbException("Wrong movie data format, expected Map/JSON-Object but was "+ typeInformation); + } + + public void storeMovie(String movieId, Object movieData) { + File storageFile = fileForMovie(movieId); + storeJsonValue(movieData, storageFile); + } + + private void storeJsonValue(Object jsonData, File storageFile) { + try { + mapper.writeValue(storageFile,jsonData); + } catch (Exception e) { + throw new MovieDbException("Failed to store JSON to storage for file " + storageFile.getPath(), e); + } + } + + public boolean hasPerson(String personId) { + return fileForPerson(personId).exists(); + } + + private File fileForPerson(String personId) { + return new File(storagePath, String.format("person_%s.json", personId)); + } + + public Map loadPerson(String personId) { + File storageFile = fileForPerson(personId); + return loadJsonValue(storageFile); + } + + public void storePerson(String personId, Object personJson) { + File storageFile = fileForPerson(personId); + storeJsonValue(personJson, storageFile); + } +} diff --git a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/repository/MovieRepository.java b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/repository/MovieRepository.java new file mode 100644 index 000000000..b619e9cc7 --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/repository/MovieRepository.java @@ -0,0 +1,12 @@ +package org.neo4j.cineasts.repository; + +import org.neo4j.cineasts.domain.Movie; +import org.springframework.data.graph.neo4j.repository.GraphRepository; +import org.springframework.data.graph.neo4j.repository.NamedIndexRepository; + +/** + * @author mh + * @since 02.04.11 + */ +public interface MovieRepository extends GraphRepository, NamedIndexRepository { +} diff --git a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/repository/PersonRepository.java b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/repository/PersonRepository.java new file mode 100644 index 000000000..98d278ec4 --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/repository/PersonRepository.java @@ -0,0 +1,11 @@ +package org.neo4j.cineasts.repository; + +import org.neo4j.cineasts.domain.Person; +import org.springframework.data.graph.neo4j.repository.GraphRepository; + +/** + * @author mh + * @since 02.04.11 + */ +public interface PersonRepository extends GraphRepository { +} diff --git a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/repository/UserRepository.java b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/repository/UserRepository.java new file mode 100644 index 000000000..166a1e4c6 --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/repository/UserRepository.java @@ -0,0 +1,11 @@ +package org.neo4j.cineasts.repository; + +import org.neo4j.cineasts.domain.User; +import org.springframework.data.graph.neo4j.repository.GraphRepository; + +/** + * @author mh + * @since 02.04.11 + */ +public interface UserRepository extends GraphRepository { +} diff --git a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/service/CineastsRepository.java b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/service/CineastsRepository.java new file mode 100644 index 000000000..4ee5fa4ec --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/service/CineastsRepository.java @@ -0,0 +1,62 @@ +package org.neo4j.cineasts.service; + +import org.neo4j.cineasts.domain.Movie; +import org.neo4j.cineasts.domain.Person; +import org.neo4j.cineasts.domain.Rating; +import org.neo4j.cineasts.domain.User; +import org.neo4j.cineasts.repository.MovieRepository; +import org.neo4j.cineasts.repository.PersonRepository; +import org.neo4j.helpers.collection.ClosableIterable; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +/** + * @author mh + * @since 04.03.11 + */ +@Repository +@Transactional +public class CineastsRepository { + + @Autowired private PersonRepository personRepository; + @Autowired private MovieRepository movieRepository; + + + public Movie getMovie(String id) { + return movieRepository.findByPropertyValue("id", id); + } + + public List findMovies(String query, int max) { + if (query.isEmpty()) return Collections.emptyList(); + if (max < 1 || max > 1000) max = 100; + + ClosableIterable searchResult = movieRepository.findAllByQuery("search", "title", query); + List result=new ArrayList(max); + for (Movie movie : searchResult) { + result.add(movie); + if (--max == 0) break; + } + searchResult.close(); + return result; + } + + public Person getPerson(String id) { + return personRepository.findByPropertyValue("id",id); + } + + public Rating rateMovie(Movie movie, User user, int stars, String comment) { + if (user == null || movie==null) return null; + return user.rate(movie, stars,comment); + } + + public Map recommendMovies(User user, final int ratingDistance) { + final FriendsMovieRecommendations movieRecommendations = new FriendsMovieRecommendations(ratingDistance); + return movieRecommendations.getRecommendationsFor(user); + } +} diff --git a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/service/CineastsUserDetails.java b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/service/CineastsUserDetails.java new file mode 100644 index 000000000..0bad6f7c3 --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/service/CineastsUserDetails.java @@ -0,0 +1,62 @@ +package org.neo4j.cineasts.service; + +import org.neo4j.cineasts.domain.User; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; + +/** +* @author mh +* @since 07.03.11 +*/ +public class CineastsUserDetails implements UserDetails { + private final User user; + + public CineastsUserDetails(User user) { + this.user = user; + } + + @Override + public Collection getAuthorities() { + User.Roles[] roles = user.getRole(); + if (roles ==null) return Collections.emptyList(); + return Arrays.asList(roles); + } + + @Override + public String getPassword() { + return user.getPassword(); + } + + @Override + public String getUsername() { + return user.getLogin(); + } + + @Override + public boolean isAccountNonExpired() { + return true; + } + + @Override + public boolean isAccountNonLocked() { + return true; + } + + @Override + public boolean isCredentialsNonExpired() { + return true; + } + + @Override + public boolean isEnabled() { + return true; + } + + public User getUser() { + return user; + } +} diff --git a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/service/CineastsUserDetailsService.java b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/service/CineastsUserDetailsService.java new file mode 100644 index 000000000..3f4e81a67 --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/service/CineastsUserDetailsService.java @@ -0,0 +1,77 @@ +package org.neo4j.cineasts.service; + +import org.neo4j.cineasts.domain.User; +import org.neo4j.cineasts.repository.UserRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataAccessException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * @author mh + * @since 06.03.11 + */ +@Service +public class CineastsUserDetailsService implements UserDetailsService { + + @Autowired + private UserRepository userRepository; + + @Override + public UserDetails loadUserByUsername(String login) throws UsernameNotFoundException, DataAccessException { + final User user = findUser(login); + if (user==null) throw new UsernameNotFoundException("Username not found",login); + return new CineastsUserDetails(user); + } + + public User findUser(String login) { + return userRepository.findByPropertyValue("login",login); + } + + + public User getUserFromSession() { + SecurityContext context = SecurityContextHolder.getContext(); + Authentication authentication = context.getAuthentication(); + Object principal = authentication.getPrincipal(); + if (principal instanceof CineastsUserDetails) { + CineastsUserDetails userDetails = (CineastsUserDetails) principal; + return userDetails.getUser(); + } + return null; + } + + @Transactional + public User register(String login, String name, String password) { + User found = findUser(login); + if (found!=null) throw new RuntimeException("Login already taken: "+login); + if (name==null || name.isEmpty()) throw new RuntimeException("No name provided."); + if (password==null || password.isEmpty()) throw new RuntimeException("No password provided."); + User user=userRepository.save(new User(login,name,password,User.Roles.ROLE_USER)); + setUserInSession(user); + return user; + } + + private void setUserInSession(User user) { + SecurityContext context = SecurityContextHolder.getContext(); + CineastsUserDetails userDetails = new CineastsUserDetails(user); + UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, user.getPassword(),userDetails.getAuthorities()); + context.setAuthentication(authentication); + + } + + @Transactional + public void addFriend(String login) { + User friend = findUser(login); + User user = getUserFromSession(); + if (!user.equals(friend)) { + user.addFriend(friend); + } + } +} diff --git a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/service/DatabasePopulator.java b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/service/DatabasePopulator.java new file mode 100644 index 000000000..2867b2207 --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/service/DatabasePopulator.java @@ -0,0 +1,54 @@ +package org.neo4j.cineasts.service; + +import org.neo4j.kernel.AbstractGraphDatabase; +import org.neo4j.cineasts.domain.*; +import org.neo4j.cineasts.movieimport.MovieDbImportService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.graph.neo4j.support.GraphDatabaseContext; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; + +import static java.util.Arrays.asList; + +/** + * @author mh + * @since 04.03.11 + */ +@Service +public class DatabasePopulator { + + @Autowired + GraphDatabaseContext ctx; + @Autowired + CineastsRepository repository; + + @Autowired + MovieDbImportService importService; + private final static Logger log = LoggerFactory.getLogger(DatabasePopulator.class); + + @Transactional + public List populateDatabase() { + User me = new User("micha", "Micha", "password", User.Roles.ROLE_ADMIN,User.Roles.ROLE_USER).persist(); + User ollie = new User("ollie", "Olliver", "password",User.Roles.ROLE_USER).persist(); + me.addFriend(ollie); + List ids = asList(19995 , 194, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 13, 20526, 11, 1893, 1892, 1894, 168, 193, 200, 157, 152, 201, 154, 12155, 58, 285, 118, 22, 392, 5255, 568, 9800, 497, 101, 120, 121, 122); + List result=new ArrayList(ids.size()); + for (Integer id : ids) { + result.add(importService.importMovie(String.valueOf(id))); + } + + //me.rate(repository.getMovie("13"),5,"Inspiring"); + me.rate(repository.getMovie("603"),5,"Best of the series"); + return result; + } + + @Transactional + public void cleanDb() { + new Neo4jDatabaseCleaner((AbstractGraphDatabase) ctx.getGraphDatabaseService()).cleanDb(); + } +} diff --git a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/service/FriendsMovieRecommendations.java b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/service/FriendsMovieRecommendations.java new file mode 100644 index 000000000..8fe13d786 --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/service/FriendsMovieRecommendations.java @@ -0,0 +1,74 @@ +package org.neo4j.cineasts.service; + +import org.neo4j.cineasts.domain.Movie; +import org.neo4j.cineasts.domain.Rating; +import org.neo4j.cineasts.domain.User; +import org.neo4j.graphdb.traversal.Evaluators; +import org.neo4j.graphdb.traversal.TraversalDescription; +import org.neo4j.kernel.Traversal; +import org.neo4j.kernel.Uniqueness; +import org.springframework.data.graph.core.EntityPath; + +import java.util.HashMap; +import java.util.Map; + +import static org.neo4j.graphdb.DynamicRelationshipType.withName; + +/** + * @author mh + * @since 04.04.11 + */ +public class FriendsMovieRecommendations { + private final Map ratings = new HashMap(); + private final int ratingDistance; + + public static class MovieRating { + int stars; + int count; + public void update(Rating rating, int weight) { + this.stars += rating.getStars()*weight; + this.count += weight; + } + public int average() { + return count == 0 ? 0 : stars / count; + } + public String toString() { + return String.valueOf(average()); + } + + } + public FriendsMovieRecommendations(int ratingDistance) { + this.ratingDistance = ratingDistance; + } + + public Map getRecommendationsFor(User user) { + TraversalDescription traversal = Traversal.description().breadthFirst() + .uniqueness(Uniqueness.NODE_GLOBAL).relationships(withName(User.FRIEND)) + .evaluator(Evaluators.toDepth(ratingDistance)).evaluator(Evaluators.excludeStartPosition()); + + Iterable result = user.findAllPathsByTraversal(traversal); + Iterable> friends = (Iterable>)result; + for (EntityPath path : friends) { + int weight = ratingDistance - path.length(); + User friend = path.endEntity(); + aggregateRatings(friend,weight); + } + for (Rating rating : user.getRatings()) { + ratings.remove(rating.getMovie()); + } + return ratings; + } + + private void aggregateRatings(User friend, int weight) { + for (Rating rating : friend.getRatings()) { + obtainRating(rating.getMovie()).update(rating, weight); + } + } + + private MovieRating obtainRating(Movie movie) { + if (!ratings.containsKey(movie)) { + ratings.put(movie, new MovieRating()); + } + return ratings.get(movie); + } +} diff --git a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/service/MovieRecommendations.java b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/service/MovieRecommendations.java new file mode 100644 index 000000000..ac262f5de --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/service/MovieRecommendations.java @@ -0,0 +1,82 @@ +package org.neo4j.cineasts.service; + +import org.neo4j.cineasts.domain.Movie; +import org.neo4j.cineasts.domain.User; +import org.neo4j.cineasts.repository.MovieRepository; +import org.neo4j.graphdb.Path; +import org.neo4j.graphdb.Relationship; +import org.neo4j.graphdb.traversal.Evaluation; +import org.neo4j.graphdb.traversal.Evaluator; +import org.neo4j.graphdb.traversal.TraversalDescription; +import org.neo4j.kernel.Traversal; +import org.neo4j.kernel.Uniqueness; + +import java.util.HashMap; +import java.util.Map; + +import static org.neo4j.graphdb.Direction.OUTGOING; +import static org.neo4j.graphdb.DynamicRelationshipType.withName; + +/** +* @author mh +* @since 04.04.11 +*/ +class MovieRecommendations implements Evaluator { + private final Map ratings=new HashMap(); + private final int ratingDistance; + private MovieRepository movieRepository; + + public MovieRecommendations(MovieRepository movieRepository, int ratingDistance) { + this.movieRepository = movieRepository; + this.ratingDistance = ratingDistance; + } + + public Map getRecommendationsFor(User user) { + TraversalDescription traversal= Traversal.description().breadthFirst() + .uniqueness(Uniqueness.NODE_PATH) + .relationships(withName(User.FRIEND)) + .relationships(withName(User.RATED), OUTGOING) + .evaluator(this); + return averageRecommendations(user, traversal); + } + + private Map averageRecommendations(User user, TraversalDescription traversal) { // todo sort, limit + Map result=new HashMap(); + for (Movie movie : movieRepository.findAllByTraversal(user, traversal)) { + final int[] rating = ratings.get(movie.getNodeId()); + result.put(movie, rating[1]==0 ? 0 : rating[0]/rating[1]); + } + return result; + } + + @Override + public Evaluation evaluate(Path path) { + final int distance = path.length() - 1; + if (distance > ratingDistance) return Evaluation.EXCLUDE_AND_PRUNE; + Relationship rated = path.lastRelationship(); + if (rated != null && rated.getType().name().equals(User.RATED)) { + if (distance == 0) return Evaluation.EXCLUDE_AND_PRUNE; // my rated movies + updateRating(rated, distance); + return Evaluation.INCLUDE_AND_PRUNE; + } + System.out.println(); + return Evaluation.EXCLUDE_AND_CONTINUE; + } + + private void updateRating(Relationship rated, int distance) { + final long movieId = rated.getEndNode().getId(); + int[] rating = obtainRating(movieId); + + int weight = ratingDistance - distance; + final Integer stars = (Integer) rated.getProperty("stars", 0); + rating[0] += weight * stars; + rating[1] += weight; + } + + private int[] obtainRating(long movieId) { + if (!ratings.containsKey(movieId)) { + ratings.put(movieId,new int[2]); + } + return ratings.get(movieId); + } +} diff --git a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/service/Neo4jDatabaseCleaner.java b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/service/Neo4jDatabaseCleaner.java new file mode 100644 index 000000000..15d995459 --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/service/Neo4jDatabaseCleaner.java @@ -0,0 +1,67 @@ +package org.neo4j.cineasts.service; + +import org.neo4j.graphdb.Direction; +import org.neo4j.graphdb.Node; +import org.neo4j.graphdb.Relationship; +import org.neo4j.graphdb.Transaction; +import org.neo4j.graphdb.index.IndexManager; +import org.neo4j.kernel.AbstractGraphDatabase; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +/** + * @author mh + * @since 02.03.11 + */ +public class Neo4jDatabaseCleaner { + private AbstractGraphDatabase graph; + + public Neo4jDatabaseCleaner(AbstractGraphDatabase graph) { + this.graph = graph; + } + + public Map cleanDb() { + Map result = new HashMap(); + Transaction tx = graph.beginTx(); + try { + removeNodes(result); + clearIndex(result); + tx.success(); + } finally { + tx.finish(); + } + return result; + } + + private void removeNodes(Map result) { + Node refNode = graph.getReferenceNode(); + int nodes = 0, relationships = 0; + for (Node node : graph.getAllNodes()) { + for (Relationship rel : node.getRelationships(Direction.OUTGOING)) { + rel.delete(); + relationships++; + } + if (!refNode.equals(node)) { + node.delete(); + nodes++; + } + } + result.put("nodes", nodes); + result.put("relationships", relationships); + + } + + private void clearIndex(Map result) { + IndexManager indexManager = graph.index(); + result.put("node-indexes", Arrays.asList(indexManager.nodeIndexNames())); + result.put("relationship-indexes", Arrays.asList(indexManager.relationshipIndexNames())); + for (String ix : indexManager.nodeIndexNames()) { + indexManager.forNodes(ix).delete(); + } + for (String ix : indexManager.relationshipIndexNames()) { + indexManager.forRelationships(ix).delete(); + } + } +} diff --git a/spring-data-neo4j-examples/cineasts/src/main/resources/log4j.properties b/spring-data-neo4j-examples/cineasts/src/main/resources/log4j.properties new file mode 100644 index 000000000..37867140a --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/resources/log4j.properties @@ -0,0 +1,7 @@ +log4j.rootLogger=warn, stdout + +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout + +#log4j.category.org.springframework.web=DEBUG + diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/applicatioContext-security.xml b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/applicatioContext-security.xml new file mode 100644 index 000000000..9f1321d68 --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/applicatioContext-security.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/applicationContext.xml b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/applicationContext.xml new file mode 100644 index 000000000..905bce08d --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/applicationContext.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/decorators.xml b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/decorators.xml new file mode 100644 index 000000000..1dab375ce --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/decorators.xml @@ -0,0 +1,8 @@ + + + / + + + /* + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/dispatcherServlet-servlet.xml b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/dispatcherServlet-servlet.xml new file mode 100644 index 000000000..fe4e70b5a --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/dispatcherServlet-servlet.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/actors/show.jsp b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/actors/show.jsp new file mode 100644 index 000000000..8c2c40129 --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/actors/show.jsp @@ -0,0 +1,35 @@ +<%@ page session="false" %> +<%@ taglib uri="http://www.springframework.org/tags" prefix="s" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> +<%--@elvariable id="actor" type="org.neo4j.cineasts.domain.Actor"--%> + + +
+
+
+
+

${actor.name}

+

Born in ${actor.birthplace}.

+
+
+
+
+

Biography

+

${actor.biography}

+

Roles

+ + + +
+
+ +

Actor cannot be found.

+
+
diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/auth/deniedpage.jsp b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/auth/deniedpage.jsp new file mode 100644 index 000000000..7057a169d --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/auth/deniedpage.jsp @@ -0,0 +1,7 @@ +<%@ page contentType="text/html;charset=UTF-8" language="java" %> + + + Access denied + + Unfortunately you are not authorized to see this page. + diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/auth/loginpage.jsp b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/auth/loginpage.jsp new file mode 100644 index 000000000..a14df31cf --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/auth/loginpage.jsp @@ -0,0 +1,36 @@ +<%@ page import="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter" %> +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> +<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %> +<%@ taglib uri="http://www.springframework.org/tags" prefix="spring" %> + +<%@ page language="java" contentType="text/html; charset=UTF-8" +pageEncoding="UTF-8"%> + + + + + Login + + + +

Login

+
${error}
+ +
+

+ + value="${sessionScope['SPRING_SECURITY_LAST_USERNAME']}" /> +

+

+ + +

+

+ Remember me +

+ +

+ Register + + diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/auth/registerpage.jsp b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/auth/registerpage.jsp new file mode 100644 index 000000000..4a9c2d6e0 --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/auth/registerpage.jsp @@ -0,0 +1,37 @@ +<%@ page import="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter" %> +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> +<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %> +<%@ taglib uri="http://www.springframework.org/tags" prefix="spring" %> + +<%@ page language="java" contentType="text/html; charset=UTF-8" +pageEncoding="UTF-8"%> + + + + + Login + + + +

Login

+
${error}
+ +
+

+ + +

+

+ + +

+

+ + +

+ +
+
+ Login + + diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/decorators/frontpage.jsp b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/decorators/frontpage.jsp new file mode 100644 index 000000000..4d82b031f --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/decorators/frontpage.jsp @@ -0,0 +1,30 @@ +<%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" + prefix="decorator" %> +<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> + + + + + Cineasts.net - <decorator:title default="Welcome" /> + + + <%@ include file="/WEB-INF/views/includes/style.jsp" %> + <%@ include file="/WEB-INF/views/includes/js.jsp" %> + + + +
+ +
+ <%@ include file="/WEB-INF/views/includes/footer.jsp" %> + + diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/decorators/main.jsp b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/decorators/main.jsp new file mode 100644 index 000000000..96d6d65c6 --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/decorators/main.jsp @@ -0,0 +1,31 @@ +<%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" + prefix="decorator" %> +<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> + + + + + Cineasts.net - <decorator:title default="Welcome" /> + + + <%@ include file="/WEB-INF/views/includes/style.jsp" %> + <%@ include file="/WEB-INF/views/includes/js.jsp" %> + + + +
+ +
+ <%@ include file="/WEB-INF/views/includes/footer.jsp" %> + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/import/result.jsp b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/import/result.jsp new file mode 100644 index 000000000..5c9f63b43 --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/import/result.jsp @@ -0,0 +1,15 @@ +<%@ page session="false" %> +<%@ taglib uri="http://www.springframework.org/tags" prefix="s" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> + +

Results for importing movies: "${ids}"

+ +

Imported of ${fn:length(movies)} movies took ${duration} seconds.

+ +
+ +
${entry.key}
+
${entry.value}
+
+
diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/includes/footer.jsp b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/includes/footer.jsp new file mode 100644 index 000000000..57861b0d0 --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/includes/footer.jsp @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/includes/header-frontpage.jsp b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/includes/header-frontpage.jsp new file mode 100644 index 000000000..c851575ab --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/includes/header-frontpage.jsp @@ -0,0 +1,3 @@ +<%@ page contentType="text/html;charset=UTF-8" language="java" session="false" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> + diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/includes/header.jsp b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/includes/header.jsp new file mode 100644 index 000000000..c851575ab --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/includes/header.jsp @@ -0,0 +1,3 @@ +<%@ page contentType="text/html;charset=UTF-8" language="java" session="false" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> + diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/includes/header_login.jsp b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/includes/header_login.jsp new file mode 100644 index 000000000..844a034fe --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/includes/header_login.jsp @@ -0,0 +1,24 @@ +<%@ page contentType="text/html;charset=UTF-8" language="java" session="false" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> + + diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/includes/js.jsp b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/includes/js.jsp new file mode 100644 index 000000000..e69de29bb diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/includes/links.jsp b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/includes/links.jsp new file mode 100644 index 000000000..e69de29bb diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/includes/navigation.jsp b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/includes/navigation.jsp new file mode 100644 index 000000000..81c2a4e9b --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/includes/navigation.jsp @@ -0,0 +1,15 @@ +<%@ page contentType="text/html;charset=UTF-8" language="java" session="false" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> + + diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/includes/search.jsp b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/includes/search.jsp new file mode 100644 index 000000000..0aebd4917 --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/includes/search.jsp @@ -0,0 +1,5 @@ + diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/includes/style.jsp b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/includes/style.jsp new file mode 100644 index 000000000..1d77d9f54 --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/includes/style.jsp @@ -0,0 +1,4 @@ + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/index.jsp b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/index.jsp new file mode 100644 index 000000000..049b8fe23 --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/index.jsp @@ -0,0 +1,11 @@ +<%@ page contentType="text/html;charset=UTF-8" language="java" session="false" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +
+

Welcome to Cineasts.net

+
+
+ + +
+
+
\ No newline at end of file diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/movies/list.jsp b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/movies/list.jsp new file mode 100644 index 000000000..0aabbaaf0 --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/movies/list.jsp @@ -0,0 +1,26 @@ +<%@ page session="false" %> +<%@ taglib uri="http://www.springframework.org/tags" prefix="s" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> + +

Results for "${query}"

+ + + + + + +

No movies found for query "${query}".

+
+
diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/movies/show.jsp b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/movies/show.jsp new file mode 100644 index 000000000..9e47500bc --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/movies/show.jsp @@ -0,0 +1,170 @@ +<%@ page session="false" %> +<%@ taglib uri="http://www.springframework.org/tags" prefix="s" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> +<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> + + +${movie.title} + + + +
+
+ <%--@elvariable id="movie" type="org.neo4j.cineasts.domain.Movie"--%> + + +
"/>
+
+

${movie.title} (${movie.year}) ${stars} stars

+
+

<${movie.tagline}

+
+
+ +
+

Movie facts

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Language${movie.language}
Runtime${movie.runtime} Minutes
Genre${movie.genre}
Other sitesTheMovieDb.org | + IMDb +
Buy DVDs & Books">Amazon | + ">CineButler +
In Cinemas">Google Movies +
+
+ +
+ +

Trailers

+ + + + + + + + + +
+
+ +
+

Release info

+ +
    +
  • + + + + + + + + + + + + + + + +
    Released
    Homepage
    Studio${movie.studio}
    +
  • +
+
+ +
+
+
+
+

Overview

+

${movie.description}

+ +

Cast

+ + +
+
+ +

Reviews

+ + +
"> +

Give + + + + to "${movie.title}" saying: + + + +

+
+ +
+ + + +
+
+
+
+ +

No movie found

+

The movie you were looking for could not be found.

+
+
+ diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/user/index.jsp b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/user/index.jsp new file mode 100644 index 000000000..700045c24 --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/user/index.jsp @@ -0,0 +1,103 @@ +<%--@elvariable id="recommendations" type="java.util.Map"--%> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> +<%@ page contentType="text/html;charset=UTF-8" language="java" %> +<%--@elvariable id="user" type="org.neo4j.cineasts.domain.User"--%> + + + Profile + + + +
+
+
" />
+
+

Hi ${user.name}!

+

${user.info}

+
+
+
+ + + +

Your friends

+
    + +
  • + ">" /> +
    +

    ">

    +

    ${friend.info}

    +
    +
    +
  • +
    +
+
+ +

You don't have any friends yet

+
+
+
+
+
+
+

Your rated movies

+
+ +
+

${fn:length(ratings)}

+
+ +
+ +
+

Your recommendations

+
+
+

${fn:length(recommendations)}

+
+ +
+
+
+ + + diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/user/public.jsp b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/user/public.jsp new file mode 100644 index 000000000..9b46bae21 --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/views/user/public.jsp @@ -0,0 +1,86 @@ +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> + +<%@ page contentType="text/html;charset=UTF-8" language="java" %> +<%--@elvariable id="user" type="org.neo4j.cineasts.domain.User"--%> + + + Profile for ${name} + + +
+
+
" />
+
+

${name}

+

${profiled.info}

+
+
+
+ +

${name}'s friends

+ + + + + +
    + +
  • + ">" /> +
    +

    ">

    +

    ${friend.info}

    +
    +
    +
  • +
    +
+
+ + ${name} has no friends. + +
+
+ +
+ Add ${name} as a friend. +
+
+
+
+ +
+
+
+

${name}'s rated movies

+
+
+

${fn:length(ratings)}

+
+ + + +
+
+
+ + diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/web.xml b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 000000000..f2420a9a0 --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,58 @@ + + + + + contextConfigLocation + + /WEB-INF/applicatioContext-security.xml + /WEB-INF/applicationContext.xml + + + + + org.springframework.web.context.ContextLoaderListener + + + + sitemesh + + com.opensymphony.module.sitemesh.filter.PageFilter + + + + + springSecurityFilterChain + org.springframework.web.filter.DelegatingFilterProxy + + + + springSecurityFilterChain + /* + + + + sitemesh + /* + + + + dispatcherServlet + org.springframework.web.servlet.DispatcherServlet + 1 + + + + dispatcherServlet + / + + + + index.jsp + + + + 60 + + diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/images/actor-picture-frame.png b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/actor-picture-frame.png new file mode 100644 index 000000000..cb58bc5a9 Binary files /dev/null and b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/actor-picture-frame.png differ diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/images/cineasts.png b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/cineasts.png new file mode 100644 index 000000000..e7778456b Binary files /dev/null and b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/cineasts.png differ diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/images/filmroll-horizontal.png b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/filmroll-horizontal.png new file mode 100644 index 000000000..e4d71d2c2 Binary files /dev/null and b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/filmroll-horizontal.png differ diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/images/filmroll-vertical-full.png b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/filmroll-vertical-full.png new file mode 100644 index 000000000..3270bbd07 Binary files /dev/null and b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/filmroll-vertical-full.png differ diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/images/header-curtain.png b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/header-curtain.png new file mode 100644 index 000000000..5b23f8ec7 Binary files /dev/null and b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/header-curtain.png differ diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/images/header-splash-bg.png b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/header-splash-bg.png new file mode 100644 index 000000000..e4f78a20a Binary files /dev/null and b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/header-splash-bg.png differ diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/images/logo-splash.png b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/logo-splash.png new file mode 100644 index 000000000..2d1815a1e Binary files /dev/null and b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/logo-splash.png differ diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/images/logo.png b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/logo.png new file mode 100644 index 000000000..98fbfde7c Binary files /dev/null and b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/logo.png differ diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/images/logo/neo4j.png b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/logo/neo4j.png new file mode 100644 index 000000000..c96c298ed Binary files /dev/null and b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/logo/neo4j.png differ diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/images/logo/springdata.jpg b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/logo/springdata.jpg new file mode 100644 index 000000000..a45ae83da Binary files /dev/null and b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/logo/springdata.jpg differ diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/images/logo/springdatagraph.png b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/logo/springdatagraph.png new file mode 100644 index 000000000..df46c007f Binary files /dev/null and b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/logo/springdatagraph.png differ diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/images/logo/springsource.png b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/logo/springsource.png new file mode 100644 index 000000000..e573cde33 Binary files /dev/null and b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/logo/springsource.png differ diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/images/movie-placeholder.png b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/movie-placeholder.png new file mode 100644 index 000000000..cc73fce08 Binary files /dev/null and b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/movie-placeholder.png differ diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/images/neo4j.png b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/neo4j.png new file mode 100644 index 000000000..ee5cac71c Binary files /dev/null and b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/neo4j.png differ diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/images/profile-placeholder-small.png b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/profile-placeholder-small.png new file mode 100644 index 000000000..44dc7e19f Binary files /dev/null and b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/profile-placeholder-small.png differ diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/images/profile-placeholder.png b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/profile-placeholder.png new file mode 100644 index 000000000..66ff4f73d Binary files /dev/null and b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/profile-placeholder.png differ diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/images/rated_0.png b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/rated_0.png new file mode 100644 index 000000000..bf5766366 Binary files /dev/null and b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/rated_0.png differ diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/images/rated_1.png b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/rated_1.png new file mode 100644 index 000000000..48730c132 Binary files /dev/null and b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/rated_1.png differ diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/images/rated_2.png b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/rated_2.png new file mode 100644 index 000000000..b91aa3345 Binary files /dev/null and b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/rated_2.png differ diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/images/rated_3.png b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/rated_3.png new file mode 100644 index 000000000..fe3eb1757 Binary files /dev/null and b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/rated_3.png differ diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/images/rated_4.png b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/rated_4.png new file mode 100644 index 000000000..2e55bb019 Binary files /dev/null and b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/rated_4.png differ diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/images/rated_5.png b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/rated_5.png new file mode 100644 index 000000000..faddfa4a1 Binary files /dev/null and b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/rated_5.png differ diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/images/rating-active.png b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/rating-active.png new file mode 100644 index 000000000..50b708b33 Binary files /dev/null and b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/rating-active.png differ diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/images/rating-disabled.png b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/rating-disabled.png new file mode 100644 index 000000000..32cfa2c85 Binary files /dev/null and b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/rating-disabled.png differ diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/images/searchbar-big-searchicon.png b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/searchbar-big-searchicon.png new file mode 100644 index 000000000..eca23c8e7 Binary files /dev/null and b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/searchbar-big-searchicon.png differ diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/images/searchbar-big.png b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/searchbar-big.png new file mode 100644 index 000000000..faf80be44 Binary files /dev/null and b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/searchbar-big.png differ diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/images/springdata.jpg b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/springdata.jpg new file mode 100644 index 000000000..90f4de574 Binary files /dev/null and b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/springdata.jpg differ diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/images/springdatagraph.png b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/springdatagraph.png new file mode 100644 index 000000000..1718b3475 Binary files /dev/null and b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/springdatagraph.png differ diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/images/springsource.png b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/springsource.png new file mode 100644 index 000000000..36b42b001 Binary files /dev/null and b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/springsource.png differ diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/images/star.png b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/star.png new file mode 100644 index 000000000..983454b95 Binary files /dev/null and b/spring-data-neo4j-examples/cineasts/src/main/webapp/images/star.png differ diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/resources/forms.css b/spring-data-neo4j-examples/cineasts/src/main/webapp/resources/forms.css new file mode 100644 index 000000000..2f3103131 --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/webapp/resources/forms.css @@ -0,0 +1,13 @@ +label { + display: block; + float: left; + width: 120px; +} + +/** + * Label for radio buttons, normal buttons and checkboxes. + */ +label.button-label { + display:inline; + float:none; +} diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/resources/grid.css b/spring-data-neo4j-examples/cineasts/src/main/webapp/resources/grid.css new file mode 100644 index 000000000..881cf609a --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/webapp/resources/grid.css @@ -0,0 +1,18 @@ +.span-1 { width: 6.958%; float:left; margin-right:1.5%; } +.span-2 { width: 15.416%; float:left; margin-right:1.5%; } +.span-3 { width: 23.875%; float:left; margin-right:1.5%; } +.span-4 { width: 32.333%; float:left; margin-right:1.5%; } +.span-5 { width: 40.791%; float:left; margin-right:1.5%; } +.span-6 { width: 49.250%; float:left; margin-right:1.5%; } +.span-7 { width: 57.708%; float:left; margin-right:1.5%; } +.span-8 { width: 66.166%; float:left; margin-right:1.5%; } +.span-9 { width: 74.625%; float:left; margin-right:1.5%; } +.span-10 { width: 83.083%; float:left; margin-right:1.5%; } +.span-11 { width: 91.541%; float:left; margin-right:1.5%; } +.span-12 { width: 100%; float:left; margin-right:0%; } + +.span-third { width: 32%; float:left; margin-right:2%; } +.span-half { width: 49%; float:left; margin-right:2%; } +.span-all { width: 100%; float:left; clear:right; } + +.last { clear:right; margin-right:0; } diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/resources/style.css b/spring-data-neo4j-examples/cineasts/src/main/webapp/resources/style.css new file mode 100644 index 000000000..316a5a2a5 --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/webapp/resources/style.css @@ -0,0 +1,328 @@ + +@import url(typography.css); +@import url(forms.css); +@import url(grid.css); + +* { + outline-style: none; +} + +body { + margin:0; + padding:0; + background : #010100; +} + +a img { border:0; } + +/** + * MAIN COMPONENTS + */ + +#header { + background: url(../images/header-curtain.png) repeat-y bottom center #010100; + border-bottom: 1px solid #5C5C45; +} + +#logo img { + padding: 10px 10px 0; +} + +#header-topbar { + height: 49px; + padding: 0 0 0 10px; + background: url(../images/filmroll-horizontal.png) repeat-x bottom left transparent; +} + +#header-splash { + text-align:center; + background: url(../images/header-splash-bg.png) repeat-x bottom center; +} + +#logo-splash { + position:relative; + top:4px; +} + + +#header-menu { + float: right; + color: #DDDDDD; + height:28px; + background:#0b0f07; + padding: 10px 10px; +} + +.search { + float:left; + padding:0 10px; +} + +.navigation { + float:left; +} + +.navigation a { + color: #d8d8d8; + text-decoration:none; + padding: 0 0 0 5px; +} + +#content { + padding: 10px; +} + +#footer { + text-align:center; + color: #999999; + font-size: 12px; + padding: 10px; + clear:both; +} + +#footer img { + padding: 10px; +} +/** + * SEARCH RESULTS + */ + +.search-results > li { + border-top: 1px solid #666666; + padding: 10px; +} + +.search-result-details { +/* float:left; + padding: 0px 10px; + */ +} + +/** + * PROFILE, ACTOR AND MOVIE PAGES + */ + +.profile-header { + clear:both; +} + +.profile-image { + float:left; +} + +.profile-image img { + width: 100px; +} +.actor-image img, .profile-image img, .friend-image img, .thumbnail img { + border: 1px solid #4C5C2A !important; +} + +.thumbnail { + display:block; + /* float:left;*/ +} +.thumbnail img { + height: 100px; +} + +.actor-framed-image { + background: url(../images/actor-picture-frame.png) no-repeat; + width:166px; + height:214px; + padding: 6px 60px 16px; +} + +.actor-sidebar { + padding: 0 56px; +} + +.profile-header-details { + float: left; + padding: 0 10px; +} + +.profile-feed { + background: none repeat scroll 0 0 #252525; + border: 5px solid #CACF81; + padding: 10px; +} + +.facts { + width:50%; + float:left; +} + +.movie-content-outer, .actor-content-outer { + background: url(../images/filmroll-vertical-full.png) no-repeat top right; + padding-right: 38px; +} + +.movie-content, .actor-content { + background: url(../images/filmroll-vertical-full.png) no-repeat top left; + padding: 0 10px 0 48px; + min-height:690px; +} + +.actors-list li { + width:100px; + float:left; +} + +.actors-list img { + height:92px; + display:block; +} + +.friends-list li { + border-top:1px solid #333; + padding: 5px 0; +} + +.friends-list .friend-image { + float:left; +} + +.friend-image img { + height: 64px; +} +.friends-list .friend-info { + float:left; + padding: 0 5px; +} + +.friends-list h3, .search-results h3 { + border:none; + margin: 5px 0; +} + +.friends-list h3 a, .search-results h3 a { + text-decoration:none; + color: #99CC33; +} + +.rated-movies-list h3 { + margin: 0; + padding: 5px 0; + float: left; +} + +.rated-movies-list h3 a { + color: #99CC33; + text-decoration:none; +} + +.rated-movies-list li { + position:relative; + height:20px; + padding:8px 0; +} + +.rated-movies-list .rating { +/* position:absolute; + right:0; + top:5px; +*/ + float: right; +} + +/** + * BIG SEARCH + */ + +#big-search-wrap { + padding: 20px 0; + text-align: center; +} + +.big-search { + background: url("../images/searchbar-big.png") no-repeat scroll 0 0 transparent; + border: 0 none; + height: 50px; + width: 480px; + font-size: 22px; + padding: 0 10px; +} + +.big-search-submit { + background: url("../images/searchbar-big-searchicon.png") no-repeat scroll 0 0 transparent; + border: 0 none; + color: transparent; + cursor: pointer; + height: 40px; + left: -75px; + position: relative; + width: 41px; +} + +/** + * RATINGS + */ + +.rating-input li, .rating-input lh { + float:left; +} + +.rating { + display: block; + height: 20px; + width: 110px; +} + +.rating li { + height: 28px; + width: 22px; + display:block; + float:left; + padding:0 2px; +} + +.rating li.active { + background: url("/images/rating-active.png") no-repeat scroll center 0 transparent; +} + +.rating li.disabled { +/* background: url("/images/rating-disabled.png") no-repeat scroll center 0 transparent; */ +} + +/** + * TABLES + */ + +table th { + text-align: left; +} + +/** + * LISTS + */ + +ul { + list-style:none; + padding:0; +} + +lh { + font-weight:bold; +} + +/** + * UTILS + */ + +.break { + clear:both; +} + + +/** + * ERRORS + */ + +.error { + color:red; +} + +a { + text-decoration: none; + color: #99CC33; +} diff --git a/spring-data-neo4j-examples/cineasts/src/main/webapp/resources/typography.css b/spring-data-neo4j-examples/cineasts/src/main/webapp/resources/typography.css new file mode 100644 index 000000000..7410d6f29 --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/main/webapp/resources/typography.css @@ -0,0 +1,32 @@ + +body { + font-family:tahoma,verdana,sans-serif,serif; + color: #666666; + font-size:13px; +} + +h2 { + color: #314718; /*#99CC33;*/ + font-size: 16px; + text-transform: uppercase; +} + +h3 { + color: #314718; /*#ff6600;*/ + font-size: 14px; + text-transform: uppercase; + border-bottom: 1px solid #333333; +} + +h4 { + margin: 5px 0; +} + +.tiny-link { + color: #222; + font-size:12px; + text-decoration:none; +} +.tiny-link:hover { + text-decoration:underline; +} diff --git a/spring-data-neo4j-examples/cineasts/src/test/java/org/neo4j/cineasts/domain/DomainTest.java b/spring-data-neo4j-examples/cineasts/src/test/java/org/neo4j/cineasts/domain/DomainTest.java new file mode 100644 index 000000000..114ec458c --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/test/java/org/neo4j/cineasts/domain/DomainTest.java @@ -0,0 +1,82 @@ +package org.neo4j.cineasts.domain; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.neo4j.cineasts.repository.MovieRepository; +import org.neo4j.cineasts.repository.UserRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Iterator; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * @author mh + * @since 04.03.11 + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration({"/movies-test-context.xml"}) +@Transactional +public class DomainTest { + + @Autowired + protected MovieRepository movieRepository; + @Autowired + protected UserRepository userRepository; + + @Before + public void setUp() throws Exception { + } + + @Test + public void actorCanPlayARoleInAMovie() { + Person tomHanks = new Person("1","Tom Hanks").persist(); + Movie forestGump = new Movie("1", "Forrest Gump").persist(); + + Role role = tomHanks.playedIn(forestGump, "Forrest"); + + Movie foundForestGump = this.movieRepository.findByPropertyValue(null, "id", "1"); + + assertEquals("created and looked up movie equal", forestGump, foundForestGump); + Role firstRole = foundForestGump.getRoles().iterator().next(); + assertEquals("role forrest",role, firstRole); + assertEquals("role forrest","Forrest", firstRole.getName()); + } + + @Test + public void canFindMovieByTitleQuery() { + Movie forestGump = new Movie("1", "Forrest Gump").persist(); + Iterator queryResults = movieRepository.findAllByQuery("search", "title", "Forre*").iterator(); + assertTrue("found movie by query",queryResults.hasNext()); + Movie foundMovie = queryResults.next(); + assertEquals("created and looked up movie equal", forestGump, foundMovie); + assertFalse("found only one movie by query", queryResults.hasNext()); + } + + @Test + public void userCanRateMovie() { + Movie movie= new Movie("1","Forrest Gump").persist(); + User user = new User("ich","Micha","password").persist(); + Rating awesome = user.rate(movie, 5, "Awesome"); + + + User foundUser = userRepository.findByPropertyValue("login", "ich"); + Rating rating = user.getRatings().iterator().next(); + assertEquals(awesome,rating); + assertEquals("Awesome",rating.getComment()); + assertEquals(5,rating.getStars()); + assertEquals(5,movie.getStars(),0); + } + @Test + public void canFindUserByLogin() { + User user = new User("ich","Micha","password").persist(); + User foundUser = userRepository.findByPropertyValue("login", "ich"); + assertEquals(user, foundUser); + } +} diff --git a/spring-data-neo4j-examples/cineasts/src/test/java/org/neo4j/cineasts/movieimport/MovieDbApiClientTest.java b/spring-data-neo4j-examples/cineasts/src/test/java/org/neo4j/cineasts/movieimport/MovieDbApiClientTest.java new file mode 100644 index 000000000..935c56c29 --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/test/java/org/neo4j/cineasts/movieimport/MovieDbApiClientTest.java @@ -0,0 +1,28 @@ +package org.neo4j.cineasts.movieimport; + +import org.junit.Test; + +import java.util.Map; + +import static org.junit.Assert.assertEquals; + +/** + * @author mh + * @since 13.03.11 + */ +public class MovieDbApiClientTest { + private static final String API_KEY = "926d2a79e82920b62f03b1cb57e532e6"; + + @Test + public void testGetMovie() throws Exception { + Map movie = new MovieDbApiClient(API_KEY).getMovie("2"); + assertEquals(2,movie.get("id")); + } + + @Test + public void testGetPerson() throws Exception { + Map person = new MovieDbApiClient(API_KEY).getPerson("30112"); + assertEquals(30112,person.get("id")); + + } +} diff --git a/spring-data-neo4j-examples/cineasts/src/test/java/org/neo4j/cineasts/movieimport/MovieDbImportServiceTest.java b/spring-data-neo4j-examples/cineasts/src/test/java/org/neo4j/cineasts/movieimport/MovieDbImportServiceTest.java new file mode 100644 index 000000000..4b590ec05 --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/test/java/org/neo4j/cineasts/movieimport/MovieDbImportServiceTest.java @@ -0,0 +1,51 @@ +package org.neo4j.cineasts.movieimport; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.neo4j.cineasts.domain.Movie; +import org.neo4j.cineasts.domain.Person; +import org.neo4j.cineasts.service.CineastsRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.transaction.annotation.Transactional; + +import static org.junit.Assert.assertEquals; + +/** + * @author mh + * @since 13.03.11 + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration({"/movies-test-context.xml"}) +@Transactional +public class MovieDbImportServiceTest { + + @Autowired + MovieDbImportService importService; + + @Autowired + CineastsRepository cineastsRepository; + + @Test + public void testImportMovie() throws Exception { + Movie movie = importService.importMovie("2"); + assertEquals("movie-id","2", movie.getId()); + assertEquals("movie-title","Ariel", movie.getTitle()); + } + + @Test + public void testImportMovieTwice() throws Exception { + Movie movie = importService.importMovie("2"); + Movie movie2 = importService.importMovie("2"); + final Movie foundMovie = cineastsRepository.getMovie("2"); + assertEquals("movie-id", movie, foundMovie); + } + + @Test + public void testImportPerson() throws Exception { + Person actor = importService.importPerson("105955"); + assertEquals("movie-id","105955", actor.getId()); + assertEquals("movie-title","George M. Williamson", actor.getName()); + } +} diff --git a/spring-data-neo4j-examples/cineasts/src/test/java/org/neo4j/cineasts/movieimport/MovieDbLocalStorageTest.java b/spring-data-neo4j-examples/cineasts/src/test/java/org/neo4j/cineasts/movieimport/MovieDbLocalStorageTest.java new file mode 100644 index 000000000..54bc6279b --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/test/java/org/neo4j/cineasts/movieimport/MovieDbLocalStorageTest.java @@ -0,0 +1,76 @@ +package org.neo4j.cineasts.movieimport; + +import org.junit.Before; +import org.junit.Test; + +import java.io.File; +import java.util.Collections; +import java.util.Map; + +import static java.util.Arrays.asList; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * @author mh + * @since 13.03.11 + */ +public class MovieDbLocalStorageTest { + + + private static final String ID = "111"; + private static final Map DATA = Collections.singletonMap("id", ID); + protected MovieDbLocalStorage storage; + + @Before + public void setUp() throws Exception { + storage = new MovieDbLocalStorage("target/data"); + } + + @Test + public void testHasMovie() throws Exception { + storage.storeMovie(ID,DATA); + assertEquals(true, storage.hasMovie(ID)); + } + + @Test + public void testLoadMovie() throws Exception { + storage.storeMovie(ID,DATA); + assertEquals(DATA,storage.loadMovie(ID)); + } + + @Test + public void testStoreMovie() throws Exception { + storage.storeMovie(ID,DATA); + assertEquals(true, new File("target/data/movie_"+ID+".json").exists()); + } + + @Test + public void testHasPerson() throws Exception { + storage.storePerson(ID,DATA); + assertEquals(true, storage.hasPerson(ID)); + } + + @Test + public void testLoadPerson() throws Exception { + storage.storePerson(ID,DATA); + assertEquals(DATA,storage.loadPerson(ID)); + } + @Test + public void testLoadPersonFromList() throws Exception { + storage.storePerson(ID,asList(DATA)); + assertEquals(DATA,storage.loadPerson(ID)); + } + @Test + public void testLoadPersonFromInvalidList() throws Exception { + storage.storePerson(ID, asList("Nothing found.")); + final Map personData = storage.loadPerson(ID); + assertTrue("person unexpectedly found", personData.containsKey("not_found")); + } + + @Test + public void testStorePerson() throws Exception { + storage.storePerson(ID,DATA); + assertEquals(true, new File("target/data/person_"+ID+".json").exists()); + } +} diff --git a/spring-data-neo4j-examples/cineasts/src/test/java/org/neo4j/cineasts/service/MoviesRepositoryTest.java b/spring-data-neo4j-examples/cineasts/src/test/java/org/neo4j/cineasts/service/MoviesRepositoryTest.java new file mode 100644 index 000000000..71157b1e0 --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/test/java/org/neo4j/cineasts/service/MoviesRepositoryTest.java @@ -0,0 +1,56 @@ +package org.neo4j.cineasts.service; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.neo4j.cineasts.domain.Movie; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.transaction.annotation.Transactional; + +import java.util.HashSet; +import java.util.List; + +import static java.util.Arrays.asList; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * @author mh + * @since 04.03.11 + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration({"/movies-test-context.xml"}) +@Transactional +public class MoviesRepositoryTest { + @Autowired + CineastsRepository repository; + + @Test + public void testGetMovie() throws Exception { + Movie movie = new Movie("1", "Test-Movie").persist(); + Movie found = repository.getMovie("1"); + assertEquals("movie found by id", movie, found); + + } + + @Test + public void testFindTwoMovies() throws Exception { + Movie movie1 = new Movie("1", "Test-Movie1").persist(); + Movie movie2 = new Movie("2", "Test-Movie2").persist(); + Movie movie3 = new Movie("3", "Another-Movie3").persist(); + List found = repository.findMovies("Test*", 2); + assertEquals("2 movies found",2,found.size()); + assertEquals("2 correct movies found by query", new HashSet(asList(movie1, movie2)), new HashSet(found)); + } + + @Test + public void testFindTwoMoviesButRestrictToOne() throws Exception { + Movie movie1 = new Movie("1", "Test-Movie1").persist(); + Movie movie2 = new Movie("2", "Test-Movie2").persist(); + Movie movie3 = new Movie("3", "Another-Movie3").persist(); + List found = repository.findMovies("Test*", 1); + assertEquals("1 movie found",1,found.size()); + assertTrue("1 correct movie found by query", found.get(0).getTitle().startsWith("Test")); + } +} diff --git a/spring-data-neo4j-examples/cineasts/src/test/resources/movies-test-context.xml b/spring-data-neo4j-examples/cineasts/src/test/resources/movies-test-context.xml new file mode 100644 index 000000000..67707dd1e --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/src/test/resources/movies-test-context.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/hello-worlds/.gitignore b/spring-data-neo4j-examples/hello-worlds/.gitignore new file mode 100644 index 000000000..524484fd3 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.gitignore @@ -0,0 +1,10 @@ +lib +.ivy +.gradle +target +*.ipr +*.iml +*.iws +.classpath +.project + diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/.name b/spring-data-neo4j-examples/hello-worlds/.idea/.name new file mode 100644 index 000000000..cf4b8f6db --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/.name @@ -0,0 +1 @@ +spring-data-neo4j-hello-worlds \ No newline at end of file diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/ant.xml b/spring-data-neo4j-examples/hello-worlds/.idea/ant.xml new file mode 100644 index 000000000..2581ca3fe --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/ant.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/compiler.xml b/spring-data-neo4j-examples/hello-worlds/.idea/compiler.xml new file mode 100644 index 000000000..b978c89c7 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/compiler.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/encodings.xml b/spring-data-neo4j-examples/hello-worlds/.idea/encodings.xml new file mode 100644 index 000000000..e206d70d8 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/encodings.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__aopalliance_aopalliance_1_0.xml b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__aopalliance_aopalliance_1_0.xml new file mode 100644 index 000000000..30ff5cb79 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__aopalliance_aopalliance_1_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__asm_asm_3_1.xml b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__asm_asm_3_1.xml new file mode 100644 index 000000000..3386f109a --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__asm_asm_3_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__cglib_cglib_2_2.xml b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__cglib_cglib_2_2.xml new file mode 100644 index 000000000..01d9b10a4 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__cglib_cglib_2_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__cglib_cglib_nodep_2_2.xml b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__cglib_cglib_nodep_2_2.xml new file mode 100644 index 000000000..a8b52958a --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__cglib_cglib_nodep_2_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__commons_logging_commons_logging_1_1_1.xml b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__commons_logging_commons_logging_1_1_1.xml new file mode 100644 index 000000000..b770f56aa --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__commons_logging_commons_logging_1_1_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__javax_validation_validation_api_1_0_0_GA.xml b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__javax_validation_validation_api_1_0_0_GA.xml new file mode 100644 index 000000000..4b644e911 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__javax_validation_validation_api_1_0_0_GA.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__junit_junit_4_8_1.xml b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__junit_junit_4_8_1.xml new file mode 100644 index 000000000..bb76199a8 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__junit_junit_4_8_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__log4j_log4j_1_2_15.xml b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__log4j_log4j_1_2_15.xml new file mode 100644 index 000000000..c6024af8c --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__log4j_log4j_1_2_15.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_apache_geronimo_specs_geronimo_jta_1_1_spec_1_1_1.xml b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_apache_geronimo_specs_geronimo_jta_1_1_spec_1_1_1.xml new file mode 100644 index 000000000..a6f25dbed --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_apache_geronimo_specs_geronimo_jta_1_1_spec_1_1_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_apache_lucene_lucene_core_3_1_0.xml b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_apache_lucene_lucene_core_3_1_0.xml new file mode 100644 index 000000000..4e829c195 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_apache_lucene_lucene_core_3_1_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_aspectj_aspectjrt_1_6_12_M1.xml b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_aspectj_aspectjrt_1_6_12_M1.xml new file mode 100644 index 000000000..2d9334521 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_aspectj_aspectjrt_1_6_12_M1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_hibernate_javax_persistence_hibernate_jpa_2_0_api_1_0_0_Final.xml b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_hibernate_javax_persistence_hibernate_jpa_2_0_api_1_0_0_Final.xml new file mode 100644 index 000000000..6b42b8a5d --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_hibernate_javax_persistence_hibernate_jpa_2_0_api_1_0_0_Final.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_neo4j_neo4j_1_4_1.xml b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_neo4j_neo4j_1_4_1.xml new file mode 100644 index 000000000..90c242e10 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_neo4j_neo4j_1_4_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_neo4j_neo4j_graph_algo_1_4_1.xml b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_neo4j_neo4j_graph_algo_1_4_1.xml new file mode 100644 index 000000000..461ca858c --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_neo4j_neo4j_graph_algo_1_4_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_neo4j_neo4j_graph_matching_1_4_1.xml b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_neo4j_neo4j_graph_matching_1_4_1.xml new file mode 100644 index 000000000..93779392a --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_neo4j_neo4j_graph_matching_1_4_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_neo4j_neo4j_jmx_1_4_1.xml b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_neo4j_neo4j_jmx_1_4_1.xml new file mode 100644 index 000000000..0b939d857 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_neo4j_neo4j_jmx_1_4_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_neo4j_neo4j_kernel_1_4_1.xml b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_neo4j_neo4j_kernel_1_4_1.xml new file mode 100644 index 000000000..e513a6129 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_neo4j_neo4j_kernel_1_4_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_neo4j_neo4j_kernel_test_jar_tests_1_4_1.xml b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_neo4j_neo4j_kernel_test_jar_tests_1_4_1.xml new file mode 100644 index 000000000..ad6ee5185 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_neo4j_neo4j_kernel_test_jar_tests_1_4_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_neo4j_neo4j_lucene_index_1_4_1.xml b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_neo4j_neo4j_lucene_index_1_4_1.xml new file mode 100644 index 000000000..423b04b85 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_neo4j_neo4j_lucene_index_1_4_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_neo4j_neo4j_udc_1_4_1.xml b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_neo4j_neo4j_udc_1_4_1.xml new file mode 100644 index 000000000..b321a14e2 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_neo4j_neo4j_udc_1_4_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_slf4j_jcl_over_slf4j_1_6_1.xml b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_slf4j_jcl_over_slf4j_1_6_1.xml new file mode 100644 index 000000000..55545f247 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_slf4j_jcl_over_slf4j_1_6_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_slf4j_slf4j_api_1_6_1.xml b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_slf4j_slf4j_api_1_6_1.xml new file mode 100644 index 000000000..38036e9fd --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_slf4j_slf4j_api_1_6_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_slf4j_slf4j_log4j12_1_6_1.xml b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_slf4j_slf4j_log4j12_1_6_1.xml new file mode 100644 index 000000000..2fbfdab3b --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_slf4j_slf4j_log4j12_1_6_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_data_spring_data_commons_core_1_2_0_BUILD_SNAPSHOT.xml b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_data_spring_data_commons_core_1_2_0_BUILD_SNAPSHOT.xml new file mode 100644 index 000000000..b232f6136 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_data_spring_data_commons_core_1_2_0_BUILD_SNAPSHOT.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_data_spring_data_neo4j_2_0_0_BUILD_SNAPSHOT.xml b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_data_spring_data_neo4j_2_0_0_BUILD_SNAPSHOT.xml new file mode 100644 index 000000000..8e37bc85f --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_data_spring_data_neo4j_2_0_0_BUILD_SNAPSHOT.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_spring_aop_3_0_5_RELEASE.xml b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_spring_aop_3_0_5_RELEASE.xml new file mode 100644 index 000000000..bbcf452ef --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_spring_aop_3_0_5_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_spring_asm_3_0_5_RELEASE.xml b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_spring_asm_3_0_5_RELEASE.xml new file mode 100644 index 000000000..8aa82f511 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_spring_asm_3_0_5_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_spring_aspects_3_0_5_RELEASE.xml b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_spring_aspects_3_0_5_RELEASE.xml new file mode 100644 index 000000000..592e96d6b --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_spring_aspects_3_0_5_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_spring_beans_3_0_5_RELEASE.xml b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_spring_beans_3_0_5_RELEASE.xml new file mode 100644 index 000000000..92c357190 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_spring_beans_3_0_5_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_spring_context_3_0_5_RELEASE.xml b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_spring_context_3_0_5_RELEASE.xml new file mode 100644 index 000000000..6e46b78e9 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_spring_context_3_0_5_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_spring_context_support_3_0_5_RELEASE.xml b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_spring_context_support_3_0_5_RELEASE.xml new file mode 100644 index 000000000..5abf9a967 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_spring_context_support_3_0_5_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_spring_core_3_0_5_RELEASE.xml b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_spring_core_3_0_5_RELEASE.xml new file mode 100644 index 000000000..ff34813c8 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_spring_core_3_0_5_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_spring_expression_3_0_5_RELEASE.xml b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_spring_expression_3_0_5_RELEASE.xml new file mode 100644 index 000000000..2efab15e6 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_spring_expression_3_0_5_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_spring_jdbc_3_0_5_RELEASE.xml b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_spring_jdbc_3_0_5_RELEASE.xml new file mode 100644 index 000000000..71b1fa696 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_spring_jdbc_3_0_5_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_spring_orm_3_0_5_RELEASE.xml b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_spring_orm_3_0_5_RELEASE.xml new file mode 100644 index 000000000..168e438b6 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_spring_orm_3_0_5_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_spring_test_3_0_5_RELEASE.xml b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_spring_test_3_0_5_RELEASE.xml new file mode 100644 index 000000000..f3fb1fc73 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_spring_test_3_0_5_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_spring_tx_3_0_5_RELEASE.xml b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_spring_tx_3_0_5_RELEASE.xml new file mode 100644 index 000000000..792cf3baa --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/libraries/Maven__org_springframework_spring_tx_3_0_5_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/misc.xml b/spring-data-neo4j-examples/hello-worlds/.idea/misc.xml new file mode 100644 index 000000000..a11e495ba --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/misc.xml @@ -0,0 +1,222 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + http://www.w3.org/1999/xhtml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/modules.xml b/spring-data-neo4j-examples/hello-worlds/.idea/modules.xml new file mode 100644 index 000000000..80e996e43 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/modules.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/scopes/scope_settings.xml b/spring-data-neo4j-examples/hello-worlds/.idea/scopes/scope_settings.xml new file mode 100644 index 000000000..922003b84 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/scopes/scope_settings.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/vcs.xml b/spring-data-neo4j-examples/hello-worlds/.idea/vcs.xml new file mode 100644 index 000000000..def6a6a18 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/vcs.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/spring-data-neo4j-examples/hello-worlds/.idea/workspace.xml b/spring-data-neo4j-examples/hello-worlds/.idea/workspace.xml new file mode 100644 index 000000000..66b9c7cf3 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.idea/workspace.xml @@ -0,0 +1,618 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + localhost + 5050 + + + + + + + + 1317159960107 + 1317159960107 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spring-data-neo4j-examples/hello-worlds/.settings/org.eclipse.jdt.core.prefs b/spring-data-neo4j-examples/hello-worlds/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..9c2f16ee4 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,6 @@ +#Wed Jan 05 13:47:14 EST 2011 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/spring-data-neo4j-examples/hello-worlds/.settings/org.maven.ide.eclipse.prefs b/spring-data-neo4j-examples/hello-worlds/.settings/org.maven.ide.eclipse.prefs new file mode 100644 index 000000000..4fc343d50 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/.settings/org.maven.ide.eclipse.prefs @@ -0,0 +1,9 @@ +#Wed Jan 05 13:47:13 EST 2011 +activeProfiles= +eclipse.preferences.version=1 +fullBuildGoals=process-test-resources +includeModules=false +resolveWorkspaceProjects=true +resourceFilterGoals=process-resources resources\:testResources +skipCompilerPlugin=true +version=1 diff --git a/spring-data-neo4j-examples/hello-worlds/README.md b/spring-data-neo4j-examples/hello-worlds/README.md new file mode 100644 index 000000000..1e6cc0223 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/README.md @@ -0,0 +1,10 @@ +Hello Worlds +============ + +A simple Spring Data Neo4j example with just enough code to +do something that works. + +Build and Run +------------- + +`mvn clean package exec:java` diff --git a/spring-data-neo4j-examples/hello-worlds/build.gradle b/spring-data-neo4j-examples/hello-worlds/build.gradle new file mode 100644 index 000000000..c4b693f2d --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/build.gradle @@ -0,0 +1,27 @@ +sourceCompatibility = 1.6 +targetCompatibility = 1.6 + +apply plugin: 'idea' +apply plugin: 'eclipse' + + +springVersion = "3.0.5.RELEASE" +springDataNeo4jVersion = "1.1.0.RELEASE" +aspectjVersion = "1.6.11.RELEASE" + +apply from:'https://github.com/SpringSource/spring-data-neo4j/raw/master/build/gradle/springdataneo4j.gradle' + +configurations { + runtime + testCompile +} +repositories { + mavenCentral() + mavenLocal() + mavenRepo urls: "http://maven.springframework.org/release" +} + + +dependencies{ + testCompile group:"junit", name: "junit", version: "4.8" +} diff --git a/spring-data-neo4j-examples/hello-worlds/build.xml b/spring-data-neo4j-examples/hello-worlds/build.xml new file mode 100644 index 000000000..60a0d7f3d --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/build.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/hello-worlds/pom.xml b/spring-data-neo4j-examples/hello-worlds/pom.xml new file mode 100644 index 000000000..8e2b61b71 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/pom.xml @@ -0,0 +1,177 @@ + + 4.0.0 + + org.springframework.data.examples + spring-data-neo4j-hello-worlds + 2.0.0-SNAPSHOT + jar + + Spring Data Neo4j hello-worlds + + + UTF-8 + 3.0.5.RELEASE + 1.6.12.M1 + 1.6.1 + UTF-8 + 2.0.0.BUILD-SNAPSHOT + + + + + spring-maven-release + Spring Maven Release Repository + http://maven.springframework.org/release + + + spring-maven-snapshot + Spring Maven Snapshot Repository + + true + + http://maven.springframework.org/snapshot + + + spring-maven-milestone + Spring Maven Milestone Repository + http://maven.springframework.org/milestone + + + neo4j-public-repository + http://m2.neo4j.org/ + Publicly available Maven 2 repository for Neo4j + + + + + + spring-maven-release + Spring Maven Release Repository + http://maven.springframework.org/release + + + spring-maven-milestone + Spring Maven Milestone Repository + http://maven.springframework.org/milestone + + + + + + junit + junit + 4.8.1 + test + + + org.springframework + spring-test + ${spring.version} + test + + + commons-logging + commons-logging + + + + + org.springframework.data + spring-data-neo4j + ${spring-data-neo4j.version} + + + cglib + cglib-nodep + 2.2 + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.1 + + 1.6 + 1.6 + + + + + + org.codehaus.mojo + aspectj-maven-plugin + 1.0 + + true + + + org.springframework + spring-aspects + + + org.springframework.data + spring-data-neo4j + + + 1.6 + 1.6 + + + + + compile + test-compile + + + + + + org.aspectj + aspectjrt + ${aspectj.version} + + + org.aspectj + aspectjtools + ${aspectj.version} + + + + + + + org.apache.maven.plugins + maven-idea-plugin + 2.2 + + true + true + + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.2 + + + + exec + + + + + org.springframework.data.neo4j.examples.hellograph.App + + + + + + diff --git a/spring-data-neo4j-examples/hello-worlds/settings/install-ivy.xml b/spring-data-neo4j-examples/hello-worlds/settings/install-ivy.xml new file mode 100644 index 000000000..314d20d9a --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/settings/install-ivy.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spring-data-neo4j-examples/hello-worlds/settings/ivy.xml b/spring-data-neo4j-examples/hello-worlds/settings/ivy.xml new file mode 100644 index 000000000..2564c1bf5 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/settings/ivy.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/spring-data-neo4j-examples/hello-worlds/settings/ivysettings.xml b/spring-data-neo4j-examples/hello-worlds/settings/ivysettings.xml new file mode 100644 index 000000000..b534a933c --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/settings/ivysettings.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/spring-data-neo4j-examples/hello-worlds/settings/path.xml b/spring-data-neo4j-examples/hello-worlds/settings/path.xml new file mode 100644 index 000000000..3d49c706b --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/settings/path.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spring-data-neo4j-examples/hello-worlds/src/main/java/org/springframework/data/neo4j/examples/hellograph/App.java b/spring-data-neo4j-examples/hello-worlds/src/main/java/org/springframework/data/neo4j/examples/hellograph/App.java new file mode 100644 index 000000000..16f3f3449 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/src/main/java/org/springframework/data/neo4j/examples/hellograph/App.java @@ -0,0 +1,39 @@ +package org.springframework.data.neo4j.examples.hellograph; + +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +/** + * Hello world(s)! + *

+ * An example application for exploring Spring Data Neo4j. + */ +public class App +{ + + public static void main( String[] args ) + { + + ConfigurableApplicationContext applicationContext = + new ClassPathXmlApplicationContext( "/spring/helloWorldContext.xml"); + + WorldRepositoryImpl galaxy = applicationContext.getBean(WorldRepositoryImpl.class); + + Iterable worlds = galaxy.makeSomeWorlds(); + + World homeWorld = worlds.iterator().next(); + System.out.println("At home on: " + homeWorld); + + World foundHomeWorld = galaxy.findWorldNamed( homeWorld.getName() ); + System.out.println( "found home world: " + foundHomeWorld ); + + Iterable worldsBeyond = galaxy.exploreWorldsBeyond( homeWorld ); + for (World world : worldsBeyond) { + System.out.println( "found worlds beyond: " + world ); + } + + applicationContext.close(); + + } + +} diff --git a/spring-data-neo4j-examples/hello-worlds/src/main/java/org/springframework/data/neo4j/examples/hellograph/MyWorldRepository.java b/spring-data-neo4j-examples/hello-worlds/src/main/java/org/springframework/data/neo4j/examples/hellograph/MyWorldRepository.java new file mode 100644 index 000000000..ead3954a6 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/src/main/java/org/springframework/data/neo4j/examples/hellograph/MyWorldRepository.java @@ -0,0 +1,23 @@ +package org.springframework.data.neo4j.examples.hellograph; + +import org.springframework.transaction.annotation.Transactional; + +import java.util.Collection; + +/** + * @author mh + * @since 01.04.11 + */ +public interface MyWorldRepository { + @Transactional + Collection makeSomeWorlds(); + + @Transactional + World world(String name, int moons); + + World findWorldNamed(String name); + + Iterable findWorldsWithMoons(int moonCount); + + Iterable exploreWorldsBeyond(World homeWorld); +} diff --git a/spring-data-neo4j-examples/hello-worlds/src/main/java/org/springframework/data/neo4j/examples/hellograph/RelationshipTypes.java b/spring-data-neo4j-examples/hello-worlds/src/main/java/org/springframework/data/neo4j/examples/hellograph/RelationshipTypes.java new file mode 100644 index 000000000..6f66f5f37 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/src/main/java/org/springframework/data/neo4j/examples/hellograph/RelationshipTypes.java @@ -0,0 +1,6 @@ +package org.springframework.data.neo4j.examples.hellograph; + +public abstract class RelationshipTypes +{ + public static final String REACHABLE_BY_ROCKET = "REACHABLE_BY_ROCKET"; +} diff --git a/spring-data-neo4j-examples/hello-worlds/src/main/java/org/springframework/data/neo4j/examples/hellograph/World.java b/spring-data-neo4j-examples/hello-worlds/src/main/java/org/springframework/data/neo4j/examples/hellograph/World.java new file mode 100644 index 000000000..7f34379e5 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/src/main/java/org/springframework/data/neo4j/examples/hellograph/World.java @@ -0,0 +1,63 @@ +package org.springframework.data.neo4j.examples.hellograph; + + +import org.neo4j.graphdb.Direction; +import org.springframework.data.neo4j.annotation.Indexed; +import org.springframework.data.neo4j.annotation.NodeEntity; +import org.springframework.data.neo4j.annotation.RelatedTo; + +import java.util.Set; + +/** + * A Spring Data Neo4j enhanced World entity. + *

+ * This is the initial POJO in the Universe. + */ +@NodeEntity +public class World +{ + @Indexed + private String name; + + @Indexed(indexName = "moon-index") + private int moons; + + @RelatedTo(type = "REACHABLE_BY_ROCKET", elementClass = World.class, direction = Direction.BOTH) + private Set reachableByRocket; + + public World( String name, int moons ) + { + this.name = name; + this.moons = moons; + } + + public World() + { + } + + public String getName() + { + return name; + } + + public int getMoons() + { + return moons; + } + + @Override + public String toString() + { + return String.format("World{name='%s, moons=%d}", name, moons); + } + + public void addRocketRouteTo( World otherWorld ) + { + relateTo( otherWorld, RelationshipTypes.REACHABLE_BY_ROCKET ); + } + + public boolean canBeReachedFrom( World otherWorld ) + { + return reachableByRocket.contains( otherWorld ); + } +} diff --git a/spring-data-neo4j-examples/hello-worlds/src/main/java/org/springframework/data/neo4j/examples/hellograph/WorldCounter.java b/spring-data-neo4j-examples/hello-worlds/src/main/java/org/springframework/data/neo4j/examples/hellograph/WorldCounter.java new file mode 100644 index 000000000..7ff6e2e91 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/src/main/java/org/springframework/data/neo4j/examples/hellograph/WorldCounter.java @@ -0,0 +1,20 @@ +package org.springframework.data.neo4j.examples.hellograph; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author mh + * @since 17.02.11 + */ +public class WorldCounter { + + public Map countMoons(Iterable worlds) { + Map moons = new HashMap(); + for (World world : worlds) { + moons.put(world.getName(), world.getMoons()); + } + return moons; + } + +} diff --git a/spring-data-neo4j-examples/hello-worlds/src/main/java/org/springframework/data/neo4j/examples/hellograph/WorldRepository.java b/spring-data-neo4j-examples/hello-worlds/src/main/java/org/springframework/data/neo4j/examples/hellograph/WorldRepository.java new file mode 100644 index 000000000..f529c4d67 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/src/main/java/org/springframework/data/neo4j/examples/hellograph/WorldRepository.java @@ -0,0 +1,11 @@ +package org.springframework.data.neo4j.examples.hellograph; + +import org.springframework.data.neo4j.repository.GraphRepository; +import org.springframework.data.neo4j.repository.NamedIndexRepository; + +/** + * @author mh + * @since 01.04.11 + */ +public interface WorldRepository extends MyWorldRepository, GraphRepository, NamedIndexRepository { +} diff --git a/spring-data-neo4j-examples/hello-worlds/src/main/java/org/springframework/data/neo4j/examples/hellograph/WorldRepositoryImpl.java b/spring-data-neo4j-examples/hello-worlds/src/main/java/org/springframework/data/neo4j/examples/hellograph/WorldRepositoryImpl.java new file mode 100644 index 000000000..8ccb106f7 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/src/main/java/org/springframework/data/neo4j/examples/hellograph/WorldRepositoryImpl.java @@ -0,0 +1,73 @@ +package org.springframework.data.neo4j.examples.hellograph; + +import org.neo4j.graphdb.Direction; +import org.neo4j.graphdb.traversal.TraversalDescription; +import org.neo4j.kernel.Traversal; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.Collection; + +import static org.neo4j.graphdb.DynamicRelationshipType.withName; +import static org.springframework.data.neo4j.examples.hellograph.RelationshipTypes.REACHABLE_BY_ROCKET; + +/** + * Spring Data Neo4j backed application context for Worlds. + */ +public class WorldRepositoryImpl implements MyWorldRepository { + + @Autowired private WorldRepository worldRepository; + + @Override + @Transactional + public Collection makeSomeWorlds() { + ArrayList newWorlds = new ArrayList(); + + // solar worlds + newWorlds.add(world("Mercury", 0)); + newWorlds.add(world("Venus", 0)); + World earth = world("Earth", 1); + newWorlds.add(earth); + World mars = world("Mars", 2); + mars.addRocketRouteTo(earth); + newWorlds.add(mars); + newWorlds.add(world("Jupiter", 63)); + newWorlds.add(world("Saturn", 62)); + newWorlds.add(world("Uranus", 27)); + newWorlds.add(world("Neptune", 13)); + + // Norse worlds + newWorlds.add(world("Alfheimr", 0)); + newWorlds.add(world("Midgard", 1)); + newWorlds.add(world("Muspellheim", 2)); + newWorlds.add(world("Asgard", 63)); + newWorlds.add(world("Hel", 62)); + + return newWorlds; + } + + + @Override + @Transactional + public World world(String name, int moons) { + return new World(name, moons).persist(); + } + + @Override + public World findWorldNamed(String name) { + return worldRepository.findByPropertyValue("name", name); + } + + @Override + public Iterable findWorldsWithMoons(int moonCount) { + return worldRepository.findAllByPropertyValue("moon-index", "moons", moonCount); + } + + @Override + public Iterable exploreWorldsBeyond(World homeWorld) { + TraversalDescription traversal = Traversal.description().relationships(withName(REACHABLE_BY_ROCKET), Direction.OUTGOING); + return worldRepository.findAllByTraversal(homeWorld, traversal); + } + +} diff --git a/spring-data-neo4j-examples/hello-worlds/src/main/resources/log4j.properties b/spring-data-neo4j-examples/hello-worlds/src/main/resources/log4j.properties new file mode 100644 index 000000000..beb86feab --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/src/main/resources/log4j.properties @@ -0,0 +1,7 @@ +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout + +# Print the date in ISO 8601 format +log4j.appender.stdout.layout.ConversionPattern=%d [%t] %-5p %c - %m%n + +log4j.rootLogger=ERROR, stdout diff --git a/spring-data-neo4j-examples/hello-worlds/src/main/resources/spring/helloWorldContext.xml b/spring-data-neo4j-examples/hello-worlds/src/main/resources/spring/helloWorldContext.xml new file mode 100644 index 000000000..74b29e2b5 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/src/main/resources/spring/helloWorldContext.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + diff --git a/spring-data-neo4j-examples/hello-worlds/src/test/java/org/springframework/data/neo4j/examples/hellograph/WorldCounterTest.java b/spring-data-neo4j-examples/hello-worlds/src/test/java/org/springframework/data/neo4j/examples/hellograph/WorldCounterTest.java new file mode 100644 index 000000000..5902abc92 --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/src/test/java/org/springframework/data/neo4j/examples/hellograph/WorldCounterTest.java @@ -0,0 +1,45 @@ +package org.springframework.data.neo4j.examples.hellograph; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.neo4j.support.GraphDatabaseContext; +import org.springframework.data.neo4j.support.node.Neo4jHelper; +import org.springframework.test.annotation.Rollback; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.transaction.BeforeTransaction; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Map; + +import static java.util.Arrays.asList; +import static org.junit.Assert.assertEquals; + +/** + * @author mh + * @since 17.02.11 + * Added to check for some aspectj-snapshot build errors. + */ +@ContextConfiguration(locations = "classpath:spring/helloWorldContext.xml") +@RunWith(SpringJUnit4ClassRunner.class) +@Transactional +public class WorldCounterTest { + + @Autowired + private GraphDatabaseContext graphDatabaseContext; + + @Rollback(false) + @BeforeTransaction + public void clearDatabase() + { + Neo4jHelper.cleanDb(graphDatabaseContext); + } + + @Test + public void testCountMoons() throws Exception { + WorldCounter counter = new WorldCounter(); + Map result = counter.countMoons(asList(new World("earth", 1))); + assertEquals("earth has one moon",(Integer)1,result.get("earth")); + } +} diff --git a/spring-data-neo4j-examples/hello-worlds/src/test/java/org/springframework/data/neo4j/examples/hellograph/WorldRepositoryTest.java b/spring-data-neo4j-examples/hello-worlds/src/test/java/org/springframework/data/neo4j/examples/hellograph/WorldRepositoryTest.java new file mode 100644 index 000000000..a12bba0dd --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/src/test/java/org/springframework/data/neo4j/examples/hellograph/WorldRepositoryTest.java @@ -0,0 +1,129 @@ +package org.springframework.data.neo4j.examples.hellograph; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.neo4j.core.NodeBacked; +import org.springframework.data.neo4j.support.GraphDatabaseContext; +import org.springframework.data.neo4j.support.node.Neo4jHelper; +import org.springframework.test.annotation.Rollback; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.transaction.BeforeTransaction; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Collection; + +import static junit.framework.Assert.assertEquals; +import static org.hamcrest.CoreMatchers.anyOf; +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.*; +import static org.junit.internal.matchers.StringContains.containsString; + +/** + * Exploratory testing of Spring Data Neo4j using + * the WorldRepositoryImpl. + */ +@ContextConfiguration(locations = "classpath:spring/helloWorldContext.xml") +@RunWith(SpringJUnit4ClassRunner.class) +@Transactional +public class WorldRepositoryTest +{ + + @Autowired + private WorldRepository galaxy; + + @Autowired + private GraphDatabaseContext graphDatabaseContext; + + @Rollback(false) + @BeforeTransaction + public void clearDatabase() + { + Neo4jHelper.cleanDb(graphDatabaseContext); + } + + @Test + public void shouldAllowDirectWorldCreation() + { + assertEquals(0, (long) galaxy.count()); + World myWorld = new World( "mine", 0 ).persist(); + assertEquals(1, (long) galaxy.count()); + Iterable foundWorlds = galaxy.findAll(); + World mine = foundWorlds.iterator().next(); + assertEquals(myWorld.getName(), mine.getName()); + } + + @Test + public void shouldPopulateGalaxyWithWorlds() + { + Iterable worlds = galaxy.makeSomeWorlds(); + assertNotNull( worlds ); + } + + + @Test + public void shouldHaveCorrectNumberOfWorlds() + { + galaxy.makeSomeWorlds(); + assertEquals(13, (long) galaxy.count()); + } + + @Test + public void shouldFindWorldsById() + { + for ( World w : galaxy.makeSomeWorlds() ) + { + assertNotNull(galaxy.findOne(((NodeBacked) w).getNodeId())); + } + } + + @Test + public void shouldFindAllWorlds() + { + Collection madeWorlds = galaxy.makeSomeWorlds(); + Iterable foundWorlds = galaxy.findAll(); + + int countOfFoundWorlds = 0; + for ( World foundWorld : foundWorlds ) + { + assertTrue( madeWorlds.contains( foundWorld ) ); + countOfFoundWorlds++; + } + + assertEquals( madeWorlds.size(), countOfFoundWorlds ); + } + + @Test + public void shouldFindWorldsByName() + { + for ( World w : galaxy.makeSomeWorlds() ) + { + assertNotNull( galaxy.findWorldNamed( w.getName() ) ); + } + } + + @SuppressWarnings("unchecked") + @Test + public void shouldFindWorldsWith1Moon() + { + galaxy.makeSomeWorlds(); + for ( World worldWithOneMoon : galaxy.findWorldsWithMoons( 1 ) ) + { + assertThat( worldWithOneMoon.getName(), is( anyOf( containsString( "Earth" ), containsString( "Midgard" ) ) ) ); + } + } + + @Test + public void shouldReachMarsFromEarth() + { + galaxy.makeSomeWorlds(); + + World earth = galaxy.findWorldNamed( "Earth" ); + World mars = galaxy.findWorldNamed( "Mars" ); + + assertTrue( mars.canBeReachedFrom( earth ) ); + assertTrue( earth.canBeReachedFrom( mars ) ); + } + +} diff --git a/spring-data-neo4j-examples/hello-worlds/src/test/java/org/springframework/data/neo4j/examples/hellograph/WorldTest.java b/spring-data-neo4j-examples/hello-worlds/src/test/java/org/springframework/data/neo4j/examples/hellograph/WorldTest.java new file mode 100644 index 000000000..1de8664cd --- /dev/null +++ b/spring-data-neo4j-examples/hello-worlds/src/test/java/org/springframework/data/neo4j/examples/hellograph/WorldTest.java @@ -0,0 +1,52 @@ +package org.springframework.data.neo4j.examples.hellograph; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.neo4j.examples.hellograph.World; +import org.springframework.data.neo4j.support.GraphDatabaseContext; +import org.springframework.data.neo4j.support.node.Neo4jHelper; +import org.springframework.test.annotation.Rollback; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.transaction.BeforeTransaction; +import org.springframework.transaction.annotation.Transactional; + +import static org.junit.Assert.assertNull; + +/** + * Exploratory unit-tests for the Spring Data Neo4j annotated World entity. + * + * Since the World is a @NodeEntity, the SpringDataGraph must + * be setup before you can even create instances of the POJO. + */ +@ContextConfiguration(locations = "classpath:spring/helloWorldContext.xml") +@RunWith(SpringJUnit4ClassRunner.class) +@Transactional +public class WorldTest +{ + + @Autowired + private GraphDatabaseContext graphDatabaseContext; + + @Rollback(false) + @BeforeTransaction + public void clearDatabase() + { + Neo4jHelper.cleanDb(graphDatabaseContext); + } + + @Test + public void shouldBeSimpleToCreateNewEntities() + { + @SuppressWarnings("unused") + World w = new World(); + } + + @Test + public void shouldHaveNullNameUsingDefaultConstructor() + { + World w = new World(); + assertNull(w.getName()); + } +} diff --git a/spring-data-neo4j-examples/imdb/.gitignore b/spring-data-neo4j-examples/imdb/.gitignore new file mode 100644 index 000000000..7519330a1 --- /dev/null +++ b/spring-data-neo4j-examples/imdb/.gitignore @@ -0,0 +1,5 @@ +/target/ +*.ipr +*.iws +*.iml + diff --git a/spring-data-neo4j-examples/imdb/README.md b/spring-data-neo4j-examples/imdb/README.md new file mode 100644 index 000000000..7bebf8c3a --- /dev/null +++ b/spring-data-neo4j-examples/imdb/README.md @@ -0,0 +1,63 @@ +The IMDB Example Application for Neo4j written with Spring Datastore Graph +========================================================================== + +![Web UI](http://github.com/neo4j-examples/spring-datastore-graph-imdb/raw/master/doc/images/IMDB1.png) + + +This application serves as a boilerplate to illustrate the use of annotations to persist objects in Spring to Neo4j, along the lines of + + + @NodeEntity + public class Actor { + @GraphProperty(index = true) + private String name; + + @RelatedTo(type="ACTS_IN",elementClass = Movie.class) + + private Set movies; + static final String NAME_INDEX = "name"; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Iterable getMovies() { + return movies; + } + + public Role getRole(final Movie inMovie) { + return (Role)getRelationshipTo((Movie)inMovie, Role.class, RelTypes.ACTS_IN.name()); + } + + @Override + public String toString() { + return "Actor '" + this.getName() + "'"; + } + } + +Which produces a graph similar to + +![Graph](http://wiki.neo4j.org/images/5/53/Imdb.screenshot.actor.png) + + + +The documentation of the IMDB Example domain is found at [http://wiki.neo4j.org/content/IMDB_Example] + + +Run build and run the example: + git clone git://github.com/neo4j-examples/spring-datastore-graph-imdb.git + cd spring-datastore-graph-imdb + mvn clean install jetty:run + +browse to [http://localhost:8080/imdb/setup.html](http://localhost:8080/imdb/setup.html), insert the data and wait until it is completed (that may take some seconds). After that, you should be able to surf the data and look for actors and movies. + +Stop the application with + mvn jetty:stop + +If you inspect the graph using Neoclipse, +node-icons are found in +src/test/resources/icons diff --git a/spring-data-neo4j-examples/imdb/doc/images/IMDB1.png b/spring-data-neo4j-examples/imdb/doc/images/IMDB1.png new file mode 100644 index 000000000..5ea3ec647 Binary files /dev/null and b/spring-data-neo4j-examples/imdb/doc/images/IMDB1.png differ diff --git a/spring-data-neo4j-examples/imdb/pom.xml b/spring-data-neo4j-examples/imdb/pom.xml new file mode 100644 index 000000000..755967b75 --- /dev/null +++ b/spring-data-neo4j-examples/imdb/pom.xml @@ -0,0 +1,439 @@ + + + 4.0.0 + org.neo4j.examples + imdb + war + 2.0.0-BUILD-SNAPSHOT + imdb + + 3.0.5.RELEASE + 1.6.12.M1 + 1.6.1 + UTF-8 + 2.0.0.BUILD-SNAPSHOT + + + + + spring-maven-release + Spring Maven Release Repository + http://maven.springframework.org/release + + + spring-maven-snapshot + Spring Maven Snapshot Repository + + true + + http://maven.springframework.org/snapshot + + + spring-maven-milestone + Spring Maven Milestone Repository + http://maven.springframework.org/milestone + + + neo4j-public-repository + http://m2.neo4j.org/ + Publicly available Maven 2 repository for Neo4j + + + + + spring-maven-release + Spring Maven Release Repository + http://maven.springframework.org/release + + + spring-maven-milestone + Spring Maven Milestone Repository + http://maven.springframework.org/milestone + + + + + + junit + junit + 4.8.1 + test + + + log4j + log4j + 1.2.16 + + + org.slf4j + slf4j-api + ${slf4j.version} + + + org.slf4j + jcl-over-slf4j + ${slf4j.version} + + + org.slf4j + slf4j-log4j12 + ${slf4j.version} + + + org.aspectj + aspectjrt + ${aspectj.version} + + + org.aspectj + aspectjweaver + ${aspectj.version} + + + javax.servlet + servlet-api + 2.5 + provided + + + net.sf.flexjson + flexjson + 2.0 + + + + org.springframework + spring-core + ${spring.version} + + + commons-logging + commons-logging + + + + + org.springframework + spring-test + ${spring.version} + test + + + commons-logging + commons-logging + + + + + org.springframework + spring-context + ${spring.version} + + + org.springframework + spring-aop + ${spring.version} + + + org.springframework + spring-aspects + ${spring.version} + + + org.springframework + spring-tx + ${spring.version} + + + org.springframework.data + spring-data-neo4j + ${data-graph.version} + + + javax.validation + validation-api + 1.0.0.GA + + + org.hibernate + hibernate-validator + 4.0.2.GA + + + javax.xml.bind + jaxb-api + + + com.sun.xml.bind + jaxb-impl + + + + + org.apache.tiles + tiles-core + 2.2.1 + + + commons-logging + commons-logging + + + + + org.apache.tiles + tiles-jsp + 2.2.1 + + + org.springframework + spring-web + ${spring.version} + + + commons-logging + commons-logging + + + + + org.springframework + spring-webmvc + ${spring.version} + + + commons-logging + commons-logging + + + + + org.springframework.webflow + spring-js + 2.1.1.RELEASE + + + org.springframework + spring-beans + + + org.springframework + spring-context + + + org.springframework + spring-core + + + org.springframework + spring-context-support + + + commons-logging + commons-logging + + + + + commons-digester + commons-digester + 2.0 + + + commons-logging + commons-logging + + + + + commons-fileupload + commons-fileupload + 1.2.1 + + + commons-logging + commons-logging + + + + + javax.servlet + jstl + 1.2 + + + javax.el + el-api + 1.0 + provided + + + joda-time + joda-time + 1.6 + + + + + + org.apache.maven.plugins + maven-war-plugin + 2.1-beta-1 + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.1 + + 1.6 + 1.6 + + + + org.apache.maven.plugins + maven-resources-plugin + 2.4.2 + + UTF-8 + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.5 + + + **/*_Roo_* + + + + + org.apache.maven.plugins + maven-assembly-plugin + 2.2-beta-5 + + + jar-with-dependencies + + + + + org.apache.maven.plugins + maven-deploy-plugin + 2.5 + + + + org.apache.maven.plugins + maven-eclipse-plugin + 2.7 + + + true + false + 2.0 + + + org.eclipse.ajdt.core.ajbuilder + + org.springframework.aspects + + + + org.springframework.ide.eclipse.core.springbuilder + + + + org.eclipse.ajdt.ui.ajnature + com.springsource.sts.roo.core.nature + org.springframework.ide.eclipse.core.springnature + + + + + org.apache.maven.plugins + maven-idea-plugin + 2.2 + + true + true + + + + org.codehaus.mojo + tomcat-maven-plugin + 1.0 + + + org.mortbay.jetty + jetty-maven-plugin + 7.1.2.v20100523 + + + /${project.name} + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-dependencies + package + + copy-dependencies + + + ${project.build.directory}/deps + false + false + true + + + + + + org.codehaus.mojo + aspectj-maven-plugin + 1.0 + + true + + + org.springframework + spring-aspects + + + org.springframework.data + spring-data-neo4j + + + 1.6 + 1.6 + + + + + compile + test-compile + + + + + + org.aspectj + aspectjrt + ${aspectj.version} + + + org.aspectj + aspectjtools + ${aspectj.version} + + + + + + diff --git a/spring-data-neo4j-examples/imdb/src/main/assembly/imdb-src.xml b/spring-data-neo4j-examples/imdb/src/main/assembly/imdb-src.xml new file mode 100644 index 000000000..07a2e0379 --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/assembly/imdb-src.xml @@ -0,0 +1,26 @@ + + src + + tar.gz + zip + + + + + README* + LICENSE* + NOTICE* + pom.xml + + true + + + src + true + + **/main/model/** + **/main/assembly/** + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/domain/Actor.java b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/domain/Actor.java new file mode 100644 index 000000000..f9b3569ac --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/domain/Actor.java @@ -0,0 +1,47 @@ +package org.neo4j.examples.imdb.domain; + +import org.springframework.data.neo4j.annotation.Indexed; +import org.springframework.data.neo4j.annotation.NodeEntity; +import org.springframework.data.neo4j.annotation.RelatedTo; + +import java.util.Set; + +// START SNIPPET: ActorClass +@NodeEntity +public class Actor { + @Indexed + private String name; + + @RelatedTo(type = "ACTS_IN", elementClass = Movie.class) + private Set movies; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Set getMovies() { + return movies; + } + + public Role getRole(final Movie inMovie) { + return getRelationshipTo(inMovie, Role.class, RelTypes.ACTS_IN.name()); + } + + @Override + public String toString() { + return "Actor '" + this.getName() + "'"; + } + + public void actsIn(Movie movie, final String role) { + relateTo(movie, Role.class, RelTypes.ACTS_IN.name()).play(role); + } + + public int getMovieCount() { + return getMovies().size(); + } +} +// END SNIPPET: ActorClass diff --git a/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/domain/ActorRepository.java b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/domain/ActorRepository.java new file mode 100644 index 000000000..fc9317c49 --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/domain/ActorRepository.java @@ -0,0 +1,11 @@ +package org.neo4j.examples.imdb.domain; + + +import org.springframework.data.neo4j.repository.GraphRepository; + +/** + * @author mh + * @since 01.04.11 + */ +public interface ActorRepository extends GraphRepository { +} diff --git a/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/domain/ImdbSearchEngine.java b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/domain/ImdbSearchEngine.java new file mode 100644 index 000000000..60c3e48c7 --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/domain/ImdbSearchEngine.java @@ -0,0 +1,11 @@ +package org.neo4j.examples.imdb.domain; + +public interface ImdbSearchEngine { + void indexActor(Actor actor); + + void indexMovie(Movie movie); + + Actor searchActor(String name); + + Movie searchMovie(String title); +} diff --git a/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/domain/ImdbSearchEngineImpl.java b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/domain/ImdbSearchEngineImpl.java new file mode 100644 index 000000000..7fce7e5c3 --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/domain/ImdbSearchEngineImpl.java @@ -0,0 +1,98 @@ +package org.neo4j.examples.imdb.domain; + +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.*; + +/** + * example-implementation of an in-graph index using splitted names and titles and Lookup - Entities + * representing them to navigate to the "indexed" entities via their relationships. + * Lookup[word] - name.part -*> Actor | Lookup[word] - title.part -*> Movie + */ +public class ImdbSearchEngineImpl implements ImdbSearchEngine { + + @Autowired + private LookupRepository lookupRepository; + + public void indexActor(Actor actor) { + for (Lookup lookup : obtainLookups(actor.getName())) { + lookup.addActor(actor); + } + } + + public void indexMovie(Movie movie) { + String name = movie.getTitle(); + for (Lookup lookup : obtainLookups(name)) { + lookup.addMovie(movie); + } + } + + public Actor searchActor(String name) { + Set result = null; + for (Lookup lookup : findLookups(name)) { + result = merge(result, lookup.getActors()); + } + return firstOrMax(result, new Comparator() { + public int compare(Actor actor1, Actor actor2) { + return actor1.getMovieCount() - actor2.getMovieCount(); + } + }); + } + + + public Movie searchMovie(String title) { + Set result = null; + for (Lookup lookup : findLookups(title)) { + result = merge(result, lookup.getMovies()); + } + return firstOrMax(result, new Comparator(){ + public int compare(Movie movie1, Movie movie2) { + return movie1.getActorsCount() - movie2.getActorsCount(); + } + }); + } + + private List obtainLookups(String name) { + List result = new ArrayList(); + for (String part : splitSearchString(name)) { + Lookup lookup = findLookup(part); + if (lookup == null) { + result.add((Lookup) new Lookup(part).persist()); + } else { + result.add(lookup); + } + } + return result; + } + + private T firstOrMax(Set result, Comparator comparator) { + if (result == null || result.isEmpty()) return null; + return Collections.max(result, comparator); + } + + private Set merge(Set result, Collection values) { + if (result == null) { + return new HashSet(values); + } + + result.retainAll(values); + return result; + } + + private List findLookups(String name) { + List result = new ArrayList(); + for (String part : splitSearchString(name)) { + Lookup lookup = findLookup(part); + if (lookup != null) result.add(lookup); + } + return result; + } + + private Lookup findLookup(String part) { + return lookupRepository.findByPropertyValue("word", part); + } + + private String[] splitSearchString(final String value) { + return value.toLowerCase(Locale.ENGLISH).split("[^\\w]+"); + } +} diff --git a/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/domain/ImdbService.java b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/domain/ImdbService.java new file mode 100644 index 000000000..59f084b11 --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/domain/ImdbService.java @@ -0,0 +1,58 @@ +package org.neo4j.examples.imdb.domain; + +import java.util.List; + +public interface ImdbService { + /** + * Store a new actor in the graph and add the name to the index. + * + * @param name + * @return the new actor + */ + Actor createActor(String name); + + /** + * Store a new movie and add the title to the index. + * + * @param title title of the movie + * @param year year of release + * @return the new movie + */ + Movie createMovie(String title, int year); + + /** + * Returns the actor with the given name or null + * if not found. + * + * @param name name of actor + * @return actor or null if not found + */ + Actor getActor(String name); + + /** + * Return the movie with given title or null if + * not found. + * + * @param title movie title + * @return movie or null if not found + */ + Movie getMovie(String title); + + Movie getExactMovie(String title); + + /** + * Returns a list with first element {@link Actor} followed by {@link Movie} + * ending with an {@link Actor}. The list is one of the shortest paths + * between the actor and actor Kevin Bacon. + * + * @param actor name of actor to find shortest path to Kevin Bacon + * @return one of the shortest paths to Kevin Bacon + */ + List getBaconPath(Actor actor); + + /** + * Add a relationship from some node to the reference node. + * Will make it easy and fast to retrieve this node. + */ + void setupReferenceRelationship(); +} diff --git a/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/domain/ImdbServiceImpl.java b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/domain/ImdbServiceImpl.java new file mode 100644 index 000000000..3a6283864 --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/domain/ImdbServiceImpl.java @@ -0,0 +1,91 @@ +package org.neo4j.examples.imdb.domain; + +import org.neo4j.graphalgo.GraphAlgoFactory; +import org.neo4j.graphdb.Node; +import org.neo4j.graphdb.Path; +import org.neo4j.kernel.StandardExpander; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.neo4j.support.GraphDatabaseContext; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.NoSuchElementException; + +class ImdbServiceImpl implements ImdbService { + @Autowired + private GraphDatabaseContext graphDatabaseContext; + @Autowired + private ImdbSearchEngine searchEngine; + @Autowired + private MovieRepository movieRepository; + @Autowired + private ActorRepository actorRepository; + + public Actor createActor(final String name) { + final Actor actor = new Actor().persist(); + actor.setName(name); + searchEngine.indexActor(actor); + return actor; + } + + public Movie createMovie(final String title, final int year) { + final Movie movie = new Movie().persist(); + movie.setTitle(title); + movie.setYear(year); + searchEngine.indexMovie(movie); + return movie; + } + + public Actor getActor(final String name) { + Actor actor = actorRepository.findByPropertyValue("name", name); + if (actor != null) return actor; + return searchEngine.searchActor(name); + } + + public Movie getMovie(final String title) { + Movie movie = getExactMovie(title); + if (movie != null) return movie; + + return searchEngine.searchMovie(title); + } + + public Movie getExactMovie(final String title) { + return movieRepository.findByPropertyValue("title", title); + } + + + @Transactional + public void setupReferenceRelationship() { + Node referenceNode = graphDatabaseContext.getReferenceNode(); + Actor bacon = actorRepository.findByPropertyValue("name", "Bacon, Kevin"); + + if (bacon == null) throw new NoSuchElementException("Unable to find Kevin Bacon actor"); + + referenceNode.createRelationshipTo(bacon.getPersistentState(), RelTypes.IMDB); + } + + public List getBaconPath(final Actor actor) { + if (actor == null) throw new IllegalArgumentException("Null actor"); + + Actor bacon = actorRepository.findByPropertyValue("name", "Bacon, Kevin"); + + Path path = GraphAlgoFactory.shortestPath(StandardExpander.DEFAULT.add(RelTypes.ACTS_IN), 10).findSinglePath(bacon.getPersistentState(), actor.getPersistentState()); + if (path==null) return Collections.emptyList(); + return convertNodesToActorsAndMovies(path); + } + + private List convertNodesToActorsAndMovies(final Path list) { + final List actorAndMovieList = new LinkedList(); + int mod = 0; + for (Node node : list.nodes()) { + if (mod++ % 2 == 0) { + actorAndMovieList.add(graphDatabaseContext.createEntityFromState(node, Actor.class)); + } else { + actorAndMovieList.add(graphDatabaseContext.createEntityFromState(node, Movie.class)); + } + } + return actorAndMovieList; + } +} \ No newline at end of file diff --git a/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/domain/Lookup.java b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/domain/Lookup.java new file mode 100644 index 000000000..1472ea679 --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/domain/Lookup.java @@ -0,0 +1,67 @@ +package org.neo4j.examples.imdb.domain; + +import org.springframework.data.neo4j.annotation.Indexed; +import org.springframework.data.neo4j.annotation.NodeEntity; +import org.springframework.data.neo4j.annotation.RelatedTo; + +import java.util.Set; + +/** + * @author mh + * @since 16.03.11 + */ +@NodeEntity +public class Lookup { + private + @Indexed + String word; + private int count; + + @RelatedTo(elementClass = Movie.class, type = "title.part") + private Set movies; + @RelatedTo(elementClass = Actor.class, type = "name.part") + private Set actors; + + public Lookup(String word) { + this.word = word; + } + + public Lookup() { + } + + public void addActor(Actor actor) { + relateTo(actor, "name.part"); + count++; + } + + public void addMovie(Movie movie) { + this.movies.add(movie); + count++; + } + + public String getWord() { + return word; + } + + public int getCount() { + return count; + } + + public Set getMovies() { + return movies; + } + + public Set getActors() { + return actors; + } + + public Movie getMovie() { + Set allMovies = getMovies(); + return allMovies != null && !allMovies.isEmpty() ? allMovies.iterator().next() : null; + } + + public Actor getActor() { + Set allActors = getActors(); + return allActors != null && !allActors.isEmpty() ? allActors.iterator().next() : null; + } +} diff --git a/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/domain/LookupRepository.java b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/domain/LookupRepository.java new file mode 100644 index 000000000..beebc5a3f --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/domain/LookupRepository.java @@ -0,0 +1,11 @@ +package org.neo4j.examples.imdb.domain; + + +import org.springframework.data.neo4j.repository.GraphRepository; + +/** + * @author mh + * @since 01.04.11 + */ +public interface LookupRepository extends GraphRepository { +} diff --git a/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/domain/Movie.java b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/domain/Movie.java new file mode 100644 index 000000000..bbf554cd6 --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/domain/Movie.java @@ -0,0 +1,49 @@ +package org.neo4j.examples.imdb.domain; + +import org.neo4j.graphdb.Direction; +import org.springframework.data.neo4j.annotation.Indexed; +import org.springframework.data.neo4j.annotation.NodeEntity; +import org.springframework.data.neo4j.annotation.RelatedTo; + +import java.util.Set; + +// START SNIPPET: MovieClass +@NodeEntity +public class Movie { + @Indexed + String title; + int year; + + @RelatedTo(type = "ACTS_IN", elementClass = Actor.class, direction = Direction.INCOMING) + Set actors; + + public Set getActors() { + return actors; + } + + @Override + public String toString() { + return String.format("%s (%d)", getTitle(), getYear()); + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public int getYear() { + return year; + } + + public void setYear(int year) { + this.year = year; + } + + int getActorsCount() { + return getActors().size(); + } +} +// END SNIPPET: MovieClass diff --git a/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/domain/MovieRepository.java b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/domain/MovieRepository.java new file mode 100644 index 000000000..4668650b6 --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/domain/MovieRepository.java @@ -0,0 +1,10 @@ +package org.neo4j.examples.imdb.domain; + +import org.springframework.data.neo4j.repository.GraphRepository; + +/** + * @author mh + * @since 01.04.11 + */ +public interface MovieRepository extends GraphRepository { +} diff --git a/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/domain/RelTypes.java b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/domain/RelTypes.java new file mode 100644 index 000000000..fa1acb060 --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/domain/RelTypes.java @@ -0,0 +1,7 @@ +package org.neo4j.examples.imdb.domain; + +import org.neo4j.graphdb.RelationshipType; + +public enum RelTypes implements RelationshipType { + ACTS_IN, IMDB +} diff --git a/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/domain/Role.java b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/domain/Role.java new file mode 100644 index 000000000..cc820588d --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/domain/Role.java @@ -0,0 +1,36 @@ +package org.neo4j.examples.imdb.domain; + +import org.springframework.data.neo4j.annotation.EndNode; +import org.springframework.data.neo4j.annotation.RelationshipEntity; +import org.springframework.data.neo4j.annotation.StartNode; + +@RelationshipEntity +public class Role { + String role; + @StartNode + Actor actor; + @EndNode + Movie movie; + + @Override + public String toString() { + return String.format("%s-[%s]->%s", this.getActor(), role, this.getMovie()); + } + + public Actor getActor() { + return actor; + } + + public Movie getMovie() { + return movie; + } + + public String getName() { + return role; + } + + public Role play(String name) { + this.role = name; + return this; + } +} diff --git a/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/parser/ActorData.java b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/parser/ActorData.java new file mode 100644 index 000000000..50be67085 --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/parser/ActorData.java @@ -0,0 +1,25 @@ +package org.neo4j.examples.imdb.parser; + +public class ActorData { + private final String name; + private final RoleData[] movieRoles; + + /** + * Create container for actor data. + * + * @param name name of actor + * @param movieRoles movie roles of actor + */ + ActorData(final String name, final RoleData[] movieRoles) { + this.movieRoles = movieRoles; + this.name = name; + } + + public String getName() { + return name; + } + + public RoleData[] getMovieRoles() { + return movieRoles; + } +} diff --git a/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/parser/ImdbParser.java b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/parser/ImdbParser.java new file mode 100644 index 000000000..76c06e5d9 --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/parser/ImdbParser.java @@ -0,0 +1,223 @@ +package org.neo4j.examples.imdb.parser; + +import org.springframework.core.io.ClassPathResource; + +import java.io.*; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.zip.GZIPInputStream; +import java.util.zip.ZipInputStream; + +/** + * A ImdbParser can parse the movie and actor/actress lists from + * the imdb text data (http://www.imdb.com/interfaces). It uses an + * {@link ImdbReader} forwarding the parsed information. + */ +public class ImdbParser { + private static final String MOVIES_MARKER = "MOVIES LIST"; + private static final int MOVIES_SKIPS = 2; + private static final String ACTRESSES_MARKER = "THE ACTRESSES LIST"; + private static final int ACTRESS_SKIPS = 4; + private static final String ACTOR_MARKER = "THE ACTORS LIST"; + private static final int ACTOR_SKIPS = 4; + private static final int BUFFER_SIZE = 200; + private final ImdbReader reader; + + /** + * Create a new Imdb parser. + * + * @param reader reader this parser will use to forward events to + */ + public ImdbParser(final ImdbReader reader) { + if (reader == null) { + throw new IllegalArgumentException("Null ImdbReader"); + } + this.reader = reader; + } + + /** + * Parsers a tab-separated movie list file, each line containing a movie + * title and the year the movie was released. The file can be .gz or .zip + * compressed, and must then have the corresponding file extension. + * + * @param file name of movie list file + * @throws IOException if unable to open the movie list file + */ + public String parseMovies(final String file) throws IOException { + final List buffer = new LinkedList(); + if (file == null) { + throw new IllegalArgumentException("Null movie file"); + } + BufferedReader fileReader = getFileReader(file, MOVIES_MARKER, + MOVIES_SKIPS); + String line = fileReader.readLine(); + int movieCount = 0; + while (line != null) { + // get rid of blank lines and TV shows + if ("".equals(line) || line.indexOf("(TV)") != -1) { + line = fileReader.readLine(); + continue; + } + final int yearSep = line.indexOf('\t'); + if (yearSep > 0) { + final String title = line.substring(0, yearSep).trim(); + String yearString = line.substring(yearSep).trim(); + if (yearString.length() > 4) { + yearString = yearString.substring(0, 4); + } + if (yearString.length() == 0 || yearString.charAt(0) == '?' + || title.contains("{") || title.startsWith("\"")) { + line = fileReader.readLine(); + continue; + } + final int year = Integer.parseInt(yearString); + buffer.add(new MovieData(title, year)); + movieCount++; + if (movieCount % BUFFER_SIZE == 0) { + reader.newMovies(buffer); + buffer.clear(); + } + } + line = fileReader.readLine(); + } + reader.newMovies(buffer); + return (movieCount + " movies parsed and injected."); + } + + /** + * Parsers a tab-separated actors list file. A line begins with actor name + * then followed by a tab and a movie title the actor acted in. Additional + * movies the current actor acted in are found on the following line that + * starts with a tab followed by the movie title. + * + * @param actorFile name of actor list file + * @param actressFile TODO + * @throws IOException if unable to open actor list file + */ + public String parseActors(final String actorFile, final String actressFile) + throws IOException { + if (actorFile == null) { + throw new IllegalArgumentException("Null actor file"); + } + if (actressFile == null) { + throw new IllegalArgumentException("Null actress file"); + } + String result = ""; + BufferedReader fileReader = getFileReader(actorFile, ACTOR_MARKER, + ACTOR_SKIPS); + result += "Actors: " + parseActorItems(fileReader) + "\n"; + fileReader.close(); + fileReader = getFileReader(actressFile, ACTRESSES_MARKER, + ACTRESS_SKIPS); + result += "Actresses: " + parseActorItems(fileReader); + return result; + } + + private String parseActorItems(BufferedReader fileReader) + throws IOException { + String line = fileReader.readLine(); + String currentActor = null; + final List buffer = new LinkedList(); + final List movies = new ArrayList(); + int movieCount = 0; + int actorCount = 0; + while (line != null) { + // get rid of blank lines + if ("".equals(line)) { + line = fileReader.readLine(); + continue; + } + int actorSep = line.indexOf('\t'); + if (actorSep >= 0) { + String actor = line.substring(0, actorSep).trim(); + if (!"".equals(actor)) { + if (movies.size() > 0) { + buffer.add(new ActorData(currentActor, movies + .toArray(new RoleData[movies.size()]))); + actorCount++; + movies.clear(); + } + currentActor = actor; + } + String title = line.substring(actorSep).trim(); + if (title.length() == 0 || title.contains("{") + || title.startsWith("\"") || title.contains("????")) { + line = fileReader.readLine(); + continue; + } + int characterStart = title.indexOf('['); + int characterEnd = title.indexOf(']'); + String character = null; + if (characterStart > 0 && characterEnd > characterStart) { + character = title.substring(characterStart + 1, + characterEnd); + } + int creditStart = title.indexOf('<'); + // int creditEnd = title.indexOf( '>' ); + // String credit = null; + // if ( creditStart > 0 && creditEnd > creditStart ) + // { + // credit = title.substring( creditStart + 1, creditEnd ); + // } + if (characterStart > 0) { + title = title.substring(0, characterStart).trim(); + } else if (creditStart > 0) { + title = title.substring(0, creditStart).trim(); + } + int spaces = title.indexOf(" "); + if (spaces > 0) { + if (title.charAt(spaces - 1) == ')' + && title.charAt(spaces + 2) == '(') { + title = title.substring(0, spaces).trim(); + } + } + movies.add(new RoleData(title, character)); + movieCount++; + if (movieCount % BUFFER_SIZE == 0) { + reader.newActors(buffer); + buffer.clear(); + } + } + line = fileReader.readLine(); + } + reader.newActors(buffer); + return (actorCount + " added including " + movieCount + " characters parsed and injected."); + } + + /** + * Get file reader that corresponds to file extension. + * + * @param file the file name + * @param pattern TODO + * @param skipLines TODO + * @return a file reader that uncompresses data if needed + * @throws IOException + * @throws FileNotFoundException + */ + private BufferedReader getFileReader(final String file, String pattern, + int skipLines) throws IOException, FileNotFoundException { + BufferedReader fileReader; + // support compressed files + if (file.endsWith(".gz")) { + fileReader = new BufferedReader(new InputStreamReader( + new GZIPInputStream(new ClassPathResource(file).getInputStream()))); + } else if (file.endsWith(".zip")) { + fileReader = new BufferedReader(new InputStreamReader( + new ZipInputStream(new ClassPathResource(file).getInputStream()))); + } else { + fileReader = new BufferedReader(new FileReader(file)); + } + + String line = ""; + while (!pattern.equals(line)) { + line = fileReader.readLine(); + } + for (int i = 0; i < skipLines; i++) { + line = fileReader.readLine(); + } + + return fileReader; + } + +} diff --git a/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/parser/ImdbReader.java b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/parser/ImdbReader.java new file mode 100644 index 000000000..04ec5f3ac --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/parser/ImdbReader.java @@ -0,0 +1,26 @@ +package org.neo4j.examples.imdb.parser; + +import java.util.List; + +/** + * Reads events from the {@link ImdbParser}. + */ +public interface ImdbReader { + /** + * Creates new movies with specified title and + * year from a {@link MovieData} list. + * Every movie will be indexed. + * + * @param movieList movies to create and index + */ + void newMovies(List movieList); + + /** + * Creates new actors specifying what movies the actors acted in + * from a {@link ActorData} list. + * Every actor will be indexed. + * + * @param actorList actors to create and index + */ + void newActors(List actorList); +} diff --git a/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/parser/ImdbReaderImpl.java b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/parser/ImdbReaderImpl.java new file mode 100644 index 000000000..41b926751 --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/parser/ImdbReaderImpl.java @@ -0,0 +1,41 @@ +package org.neo4j.examples.imdb.parser; + +import org.neo4j.examples.imdb.domain.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +class ImdbReaderImpl implements ImdbReader { + @Autowired + private ImdbService imdbService; + + @Transactional + public void newActors(final List actorList) { + for (ActorData actorData : actorList) { + newActor(actorData.getName(), actorData.getMovieRoles()); + } + } + + @Transactional + public void newMovies(final List movieList) { + for (MovieData movieData : movieList) { + newMovie(movieData.getTitle(), movieData.getYear()); + } + } + + private void newMovie(final String title, final int year) { + imdbService.createMovie(title, year); + } + + private void newActor(final String name, final RoleData[] movieRoles) { + final Actor actor = imdbService.createActor(name); + for (RoleData movieRole : movieRoles) { + final Movie movie = imdbService.getExactMovie(movieRole.getTitle()); + if (movie != null) { + actor.actsIn(movie, movieRole.getRole()); + } + } + } + +} diff --git a/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/parser/MovieData.java b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/parser/MovieData.java new file mode 100644 index 000000000..d388ffe47 --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/parser/MovieData.java @@ -0,0 +1,25 @@ +package org.neo4j.examples.imdb.parser; + +public class MovieData { + private final String title; + private final int year; + + /** + * Create container for movie data. + * + * @param title title of movie + * @param year release year of movie + */ + MovieData(final String title, final int year) { + this.title = title; + this.year = year; + } + + public String getTitle() { + return title; + } + + public int getYear() { + return year; + } +} diff --git a/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/parser/RoleData.java b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/parser/RoleData.java new file mode 100644 index 000000000..51317da96 --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/parser/RoleData.java @@ -0,0 +1,33 @@ +package org.neo4j.examples.imdb.parser; + +/** + * Holds information about what role an actor has in a movie + */ +public class RoleData { + private final String title; + private final String role; + + RoleData(final String title, final String role) { + this.title = title; + this.role = role; + } + + /** + * Returns the title of the movie, never null. + * + * @return title of the movie + */ + public String getTitle() { + return this.title; + } + + /** + * Returns the role the actor had in the movie, may be null + * if no information is available. + * + * @return actor role or null if information not avilable + */ + public String getRole() { + return this.role; + } +} diff --git a/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/web/ActorFindControllerDelegate.java b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/web/ActorFindControllerDelegate.java new file mode 100644 index 000000000..2edb297f7 --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/web/ActorFindControllerDelegate.java @@ -0,0 +1,89 @@ +package org.neo4j.examples.imdb.web; + +import org.neo4j.examples.imdb.domain.Actor; +import org.neo4j.examples.imdb.domain.ImdbService; +import org.neo4j.examples.imdb.domain.Movie; +import org.neo4j.examples.imdb.domain.Role; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; + +import javax.servlet.ServletException; +import java.util.*; + +public class ActorFindControllerDelegate implements FindControllerDelegate { + @Autowired + private ImdbService imdbService; + + public String getFieldName() { + return "name"; + } + + @Transactional + public void getModel(final Object command, final Map model) + throws ServletException { + final String name = ((ActorForm) command).getName(); + final Actor actor = imdbService.getActor(name); + populateModel(model, actor); + } + + private void populateModel(final Map model, + final Actor actor) { + if (actor == null) { + model.put("actorName", "No actor found"); + model.put("kevinBaconNumber", ""); + model.put("movieTitles", Collections.emptyList()); + } else { + model.put("actorName", actor.getName()); + final List baconPathList = imdbService.getBaconPath(actor); + model.put("kevinBaconNumber", baconPathList.size() / 2); + final Collection movieInfo = new TreeSet(); + for (Movie movie : actor.getMovies()) { + movieInfo.add(new MovieInfo(movie, actor.getRole(movie))); + } + model.put("movieInfo", movieInfo); + final List baconPath = new LinkedList(); + for (Object actorOrMovie : baconPathList) { + if (actorOrMovie instanceof Actor) { + baconPath.add(((Actor) actorOrMovie).getName()); + } else if (actorOrMovie instanceof Movie) { + baconPath.add(((Movie) actorOrMovie).getTitle()); + } + } + model.put("baconPath", baconPath); + } + } + + public static final class MovieInfo implements Comparable { + private String title; + private String role; + + MovieInfo(final Movie movie, final Role role) { + setTitle(movie.getTitle()); + if (role == null || role.getName() == null) { + setRole("(unknown)"); + } else { + setRole(role.getName()); + } + } + + public final void setTitle(final String title) { + this.title = title; + } + + public String getTitle() { + return title; + } + + public final void setRole(final String role) { + this.role = role; + } + + public String getRole() { + return role; + } + + public int compareTo(final MovieInfo otherMovieInfo) { + return getTitle().compareTo(otherMovieInfo.getTitle()); + } + } +} diff --git a/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/web/ActorForm.java b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/web/ActorForm.java new file mode 100644 index 000000000..b4fcc989d --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/web/ActorForm.java @@ -0,0 +1,13 @@ +package org.neo4j.examples.imdb.web; + +public class ActorForm { + private String name; + + public void setName(final String name) { + this.name = name; + } + + public String getName() { + return this.name; + } +} diff --git a/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/web/ActorInfo.java b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/web/ActorInfo.java new file mode 100644 index 000000000..69cdd1b53 --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/web/ActorInfo.java @@ -0,0 +1,42 @@ +package org.neo4j.examples.imdb.web; + +import org.neo4j.examples.imdb.domain.Actor; +import org.neo4j.examples.imdb.domain.Role; + +/** +* @author mh +* @since 01.04.11 +*/ +public final class ActorInfo implements Comparable { + private String name; + private String role; + + public ActorInfo(final Actor actor, final Role role) { + setName(actor.getName()); + if (role == null || role.getName() == null) { + setRole("(unknown)"); + } else { + setRole(role.getName()); + } + } + + public void setName(final String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setRole(final String role) { + this.role = role; + } + + public String getRole() { + return role; + } + + public int compareTo(ActorInfo otherActorInfo) { + return getName().compareTo(otherActorInfo.getName()); + } +} diff --git a/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/web/FindController.java b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/web/FindController.java new file mode 100644 index 000000000..2cdcc235c --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/web/FindController.java @@ -0,0 +1,31 @@ +package org.neo4j.examples.imdb.web; + +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.mvc.SimpleFormController; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import java.util.HashMap; +import java.util.Map; + +public class FindController extends SimpleFormController { + private final FindControllerDelegate delegate; + + public FindController(final FindControllerDelegate delegate) { + super(); + this.delegate = delegate; + } + + @Override + protected ModelAndView onSubmit(final Object command) throws ServletException { + final Map model = new HashMap(); + delegate.getModel(command, model); + return new ModelAndView(getSuccessView(), "model", model); + } + + @Override + protected boolean isFormSubmission(final HttpServletRequest request) { + final String field = request.getParameter(delegate.getFieldName()); + return field != null && field.trim().length() > 0; + } +} diff --git a/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/web/FindControllerDelegate.java b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/web/FindControllerDelegate.java new file mode 100644 index 000000000..ca126b39c --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/web/FindControllerDelegate.java @@ -0,0 +1,10 @@ +package org.neo4j.examples.imdb.web; + +import javax.servlet.ServletException; +import java.util.Map; + +public interface FindControllerDelegate { + void getModel(Object command, Map model) throws ServletException; + + String getFieldName(); +} \ No newline at end of file diff --git a/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/web/ImdbSetupControllerDelegate.java b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/web/ImdbSetupControllerDelegate.java new file mode 100644 index 000000000..ee4fa5bdc --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/web/ImdbSetupControllerDelegate.java @@ -0,0 +1,33 @@ +package org.neo4j.examples.imdb.web; + +import org.neo4j.examples.imdb.domain.ImdbService; +import org.neo4j.examples.imdb.parser.ImdbParser; +import org.neo4j.examples.imdb.parser.ImdbReader; +import org.springframework.beans.factory.annotation.Autowired; + +import javax.servlet.ServletException; +import java.io.IOException; +import java.util.Map; + +public class ImdbSetupControllerDelegate implements SetupControllerDelegate { + private static final String IMDB_DATADIR = "data/"; + @Autowired + private ImdbReader imdbReader; + @Autowired + private ImdbService imdbService; + + public void getModel(final Object command, final Map model) + throws ServletException { + + final ImdbParser parser = new ImdbParser(imdbReader); + StringBuffer message = new StringBuffer(200); + try { + message.append(parser.parseMovies(IMDB_DATADIR + "movies.list.gz")).append('\n'); + message.append(parser.parseActors(IMDB_DATADIR + "actors.list.gz", IMDB_DATADIR + "actresses.list.gz")).append('\n'); + imdbService.setupReferenceRelationship(); + } catch (IOException e) { + message.append("Something went wrong during the setup process:\n").append(e.getMessage()); + } + model.put("setupMessage", message.toString()); + } +} diff --git a/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/web/MovieFindControllerDelegate.java b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/web/MovieFindControllerDelegate.java new file mode 100644 index 000000000..e1dfc4fa7 --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/web/MovieFindControllerDelegate.java @@ -0,0 +1,80 @@ +package org.neo4j.examples.imdb.web; + +import org.neo4j.examples.imdb.domain.Actor; +import org.neo4j.examples.imdb.domain.ImdbService; +import org.neo4j.examples.imdb.domain.Movie; +import org.neo4j.examples.imdb.domain.Role; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; + +import javax.servlet.ServletException; +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +import java.util.TreeSet; + +public class MovieFindControllerDelegate implements FindControllerDelegate { + @Autowired + private ImdbService imdbService; + + public String getFieldName() { + return "title"; + } + + @Transactional + public void getModel(final Object command, final Map model) + throws ServletException { + final String title = ((MovieForm) command).getTitle(); + final Movie movie = imdbService.getMovie(title); + populateModel(model, movie); + } + + private void populateModel(final Map model, + final Movie movie) { + if (movie == null) { + model.put("movieTitle", "No movie found"); + model.put("actorNames", Collections.emptyList()); + } else { + model.put("movieTitle", movie.getTitle()); + final Collection actorInfo = new TreeSet(); + for (Actor actor : movie.getActors()) { + actorInfo.add(new ActorInfo(actor, actor.getRole(movie))); + } + model.put("actorInfo", actorInfo); + } + } + + public static final class ActorInfo implements Comparable { + private String name; + private String role; + + public ActorInfo(final Actor actor, final Role role) { + setName(actor.getName()); + if (role == null || role.getName() == null) { + setRole("(unknown)"); + } else { + setRole(role.getName()); + } + } + + public void setName(final String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setRole(final String role) { + this.role = role; + } + + public String getRole() { + return role; + } + + public int compareTo(ActorInfo otherActorInfo) { + return getName().compareTo(otherActorInfo.getName()); + } + } +} diff --git a/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/web/MovieForm.java b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/web/MovieForm.java new file mode 100644 index 000000000..d1af7adcc --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/web/MovieForm.java @@ -0,0 +1,13 @@ +package org.neo4j.examples.imdb.web; + +public class MovieForm { + private String title; + + public void setTitle(final String title) { + this.title = title; + } + + public String getTitle() { + return this.title; + } +} diff --git a/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/web/MovieInfo.java b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/web/MovieInfo.java new file mode 100644 index 000000000..287c1a33e --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/web/MovieInfo.java @@ -0,0 +1,42 @@ +package org.neo4j.examples.imdb.web; + +import org.neo4j.examples.imdb.domain.Movie; +import org.neo4j.examples.imdb.domain.Role; + +/** +* @author mh +* @since 01.04.11 +*/ +public final class MovieInfo implements Comparable { + private String title; + private String role; + + MovieInfo(final Movie movie, final Role role) { + setTitle(movie.getTitle()); + if (role == null || role.getName() == null) { + setRole("(unknown)"); + } else { + setRole(role.getName()); + } + } + + public final void setTitle(final String title) { + this.title = title; + } + + public String getTitle() { + return title; + } + + public final void setRole(final String role) { + this.role = role; + } + + public String getRole() { + return role; + } + + public int compareTo(final MovieInfo otherMovieInfo) { + return getTitle().compareTo(otherMovieInfo.getTitle()); + } +} diff --git a/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/web/SetupController.java b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/web/SetupController.java new file mode 100644 index 000000000..5b294b63b --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/web/SetupController.java @@ -0,0 +1,24 @@ +package org.neo4j.examples.imdb.web; + +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.mvc.SimpleFormController; + +import javax.servlet.ServletException; +import java.util.HashMap; +import java.util.Map; + +public class SetupController extends SimpleFormController { + private final SetupControllerDelegate delegate; + + public SetupController(final SetupControllerDelegate delegate) { + super(); + this.delegate = delegate; + } + + @Override + protected ModelAndView onSubmit(final Object command) throws ServletException { + final Map model = new HashMap(); + delegate.getModel(command, model); + return new ModelAndView(getSuccessView(), "model", model); + } +} diff --git a/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/web/SetupControllerDelegate.java b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/web/SetupControllerDelegate.java new file mode 100644 index 000000000..0c51d3dd8 --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/web/SetupControllerDelegate.java @@ -0,0 +1,10 @@ +package org.neo4j.examples.imdb.web; + +import javax.servlet.ServletException; +import java.util.Map; + +public interface SetupControllerDelegate { + void getModel(Object command, Map model) + throws ServletException; + +} diff --git a/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/web/SetupForm.java b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/web/SetupForm.java new file mode 100644 index 000000000..ae04568c9 --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/java/org/neo4j/examples/imdb/web/SetupForm.java @@ -0,0 +1,4 @@ +package org.neo4j.examples.imdb.web; + +public class SetupForm { +} diff --git a/spring-data-neo4j-examples/imdb/src/main/model/imdb.domain.impl.ucls b/spring-data-neo4j-examples/imdb/src/main/model/imdb.domain.impl.ucls new file mode 100644 index 000000000..21487deab --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/model/imdb.domain.impl.ucls @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/imdb/src/main/model/imdb.domain.interface.simple.ucls b/spring-data-neo4j-examples/imdb/src/main/model/imdb.domain.interface.simple.ucls new file mode 100644 index 000000000..dfb9108d9 --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/model/imdb.domain.interface.simple.ucls @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/imdb/src/main/model/imdb.domain.interface.ucls b/spring-data-neo4j-examples/imdb/src/main/model/imdb.domain.interface.ucls new file mode 100644 index 000000000..e58a89a33 --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/model/imdb.domain.interface.ucls @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/imdb/src/main/model/imdb.domain.service.search.ucls b/spring-data-neo4j-examples/imdb/src/main/model/imdb.domain.service.search.ucls new file mode 100644 index 000000000..22ed008db --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/model/imdb.domain.service.search.ucls @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/imdb/src/main/model/imdb.domain.service.ucls b/spring-data-neo4j-examples/imdb/src/main/model/imdb.domain.service.ucls new file mode 100644 index 000000000..8dc2132fe --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/model/imdb.domain.service.ucls @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/imdb/src/main/model/imdb.packages.ucls b/spring-data-neo4j-examples/imdb/src/main/model/imdb.packages.ucls new file mode 100644 index 000000000..b4f04ee4f --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/model/imdb.packages.ucls @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/imdb/src/main/model/imdb.parser.data.ucls b/spring-data-neo4j-examples/imdb/src/main/model/imdb.parser.data.ucls new file mode 100644 index 000000000..469eaf124 --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/model/imdb.parser.data.ucls @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/imdb/src/main/model/imdb.parser.ucls b/spring-data-neo4j-examples/imdb/src/main/model/imdb.parser.ucls new file mode 100644 index 000000000..bf5f2ec7d --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/model/imdb.parser.ucls @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/imdb/src/main/model/imdb.util.ucls b/spring-data-neo4j-examples/imdb/src/main/model/imdb.util.ucls new file mode 100644 index 000000000..d0908a9ca --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/model/imdb.util.ucls @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/imdb/src/main/model/imdb.web.find.ucls b/spring-data-neo4j-examples/imdb/src/main/model/imdb.web.find.ucls new file mode 100644 index 000000000..7d284a190 --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/model/imdb.web.find.ucls @@ -0,0 +1,140 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/imdb/src/main/model/imdb.web.setup.ucls b/spring-data-neo4j-examples/imdb/src/main/model/imdb.web.setup.ucls new file mode 100644 index 000000000..e077ad162 --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/model/imdb.web.setup.ucls @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/imdb/src/main/resources/data/actors.list.gz b/spring-data-neo4j-examples/imdb/src/main/resources/data/actors.list.gz new file mode 100644 index 000000000..4b5a4316f Binary files /dev/null and b/spring-data-neo4j-examples/imdb/src/main/resources/data/actors.list.gz differ diff --git a/spring-data-neo4j-examples/imdb/src/main/resources/data/actresses.list.gz b/spring-data-neo4j-examples/imdb/src/main/resources/data/actresses.list.gz new file mode 100644 index 000000000..e31a9e10d Binary files /dev/null and b/spring-data-neo4j-examples/imdb/src/main/resources/data/actresses.list.gz differ diff --git a/spring-data-neo4j-examples/imdb/src/main/resources/data/movies.list.gz b/spring-data-neo4j-examples/imdb/src/main/resources/data/movies.list.gz new file mode 100644 index 000000000..31e457ee3 Binary files /dev/null and b/spring-data-neo4j-examples/imdb/src/main/resources/data/movies.list.gz differ diff --git a/spring-data-neo4j-examples/imdb/src/main/webapp/META-INF/MANIFEST.MF b/spring-data-neo4j-examples/imdb/src/main/webapp/META-INF/MANIFEST.MF new file mode 100644 index 000000000..5e9495128 --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/webapp/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Class-Path: + diff --git a/spring-data-neo4j-examples/imdb/src/main/webapp/WEB-INF/imdb-app-servlet.xml b/spring-data-neo4j-examples/imdb/src/main/webapp/WEB-INF/imdb-app-servlet.xml new file mode 100644 index 000000000..8cb2acfa6 --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/webapp/WEB-INF/imdb-app-servlet.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/imdb/src/main/webapp/WEB-INF/tld/spring-form.tld b/spring-data-neo4j-examples/imdb/src/main/webapp/WEB-INF/tld/spring-form.tld new file mode 100644 index 000000000..4f6fd9fd4 --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/webapp/WEB-INF/tld/spring-form.tld @@ -0,0 +1,2252 @@ + + + + + + 2.5 + 1.2 + form + http://www.springframework.org/tags/form + Spring Framework JSP Form Tag Library + + + + form + org.springframework.web.servlet.tags.form.FormTag + JSP + Renders an HTML 'form' tag and exposes a binding path to inner tags for binding. + + id + false + true + HTML Standard Attribute + + + name + false + true + HTML Standard Attribute - added for backwards compatibility cases + + + htmlEscape + false + true + Enable/disable HTML escaping of rendered values. + + + cssClass + false + true + Equivalent to "class" - HTML Optional Attribute + + + cssStyle + false + true + Equivalent to "style" - HTML Optional Attribute + + + lang + false + true + HTML Standard Attribute + + + title + false + true + HTML Standard Attribute + + + dir + false + true + HTML Standard Attribute + + + onclick + false + true + HTML Event Attribute + + + ondblclick + false + true + HTML Event Attribute + + + onmousedown + false + true + HTML Event Attribute + + + onmouseup + false + true + HTML Event Attribute + + + onmouseover + false + true + HTML Event Attribute + + + onmousemove + false + true + HTML Event Attribute + + + onmouseout + false + true + HTML Event Attribute + + + onkeypress + false + true + HTML Event Attribute + + + onkeyup + false + true + HTML Event Attribute + + + onkeydown + false + true + HTML Event Attribute + + + + modelAttribute + false + true + Name of the model attribute under which the form object is exposed. + Defaults to 'command'. + + + commandName + false + true + Name of the model attribute under which the form object is exposed. + Defaults to 'command'. + + + action + false + true + HTML Required Attribute + + + method + false + true + HTML Optional Attribute + + + enctype + false + true + HTML Optional Attribute + + + onsubmit + false + true + HTML Event Attribute + + + onreset + false + true + HTML Event Attribute + + + acceptCharset + false + true + Specifies the list of character encodings for input data that is accepted by the server processing this form. The value is a space- and/or comma-delimited list of charset values. The client must interpret this list as an exclusive-or list, i.e., the server is able to accept any single character encoding per entity received. + + + + + + input + org.springframework.web.servlet.tags.form.InputTag + empty + Renders an HTML 'input' tag with type 'text' using the bound value. + + path + true + true + Path to property for data binding + + + id + false + true + HTML Standard Attribute + + + htmlEscape + false + true + Enable/disable HTML escaping of rendered values. + + + cssClass + false + true + Equivalent to "class" - HTML Optional Attribute + + + cssErrorClass + false + true + Equivalent to "class" - HTML Optional Attribute. Used when the bound field has errors. + + + cssStyle + false + true + Equivalent to "style" - HTML Optional Attribute + + + lang + false + true + HTML Standard Attribute + + + title + false + true + HTML Standard Attribute + + + dir + false + true + HTML Standard Attribute + + + tabindex + false + true + HTML Standard Attribute + + + disabled + false + true + HTML Optional Attribute. Setting the value of this attribute to 'true' (without the quotes) will disable the HTML element. + + + onclick + false + true + HTML Event Attribute + + + ondblclick + false + true + HTML Event Attribute + + + onmousedown + false + true + HTML Event Attribute + + + onmouseup + false + true + HTML Event Attribute + + + onmouseover + false + true + HTML Event Attribute + + + onmousemove + false + true + HTML Event Attribute + + + onmouseout + false + true + HTML Event Attribute + + + onkeypress + false + true + HTML Event Attribute + + + onkeyup + false + true + HTML Event Attribute + + + onkeydown + false + true + HTML Event Attribute + + + onfocus + false + true + HTML Event Attribute + + + onblur + false + true + HTML Event Attribute + + + onchange + false + true + HTML Event Attribute + + + accesskey + false + true + HTML Standard Attribute + + + + size + false + true + HTML Optional Attribute + + + maxlength + false + true + HTML Optional Attribute + + + alt + false + true + HTML Optional Attribute + + + onselect + false + true + HTML Event Attribute + + + readonly + false + true + HTML Optional Attribute. Setting the value of this attribute to 'true' (without the quotes) will make the HTML element readonly. + + + autocomplete + false + true + Common Optional Attribute + + + + + + password + org.springframework.web.servlet.tags.form.PasswordInputTag + empty + Renders an HTML 'input' tag with type 'password' using the bound value. + + path + true + true + Path to property for data binding + + + id + false + true + HTML Standard Attribute + + + htmlEscape + false + true + Enable/disable HTML escaping of rendered values. + + + cssClass + false + true + Equivalent to "class" - HTML Optional Attribute + + + cssErrorClass + false + true + Equivalent to "class" - HTML Optional Attribute. Used when the bound field has errors. + + + cssStyle + false + true + Equivalent to "style" - HTML Optional Attribute + + + lang + false + true + HTML Standard Attribute + + + title + false + true + HTML Standard Attribute + + + dir + false + true + HTML Standard Attribute + + + tabindex + false + true + HTML Standard Attribute + + + disabled + false + true + HTML Optional Attribute. Setting the value of this attribute to 'true' (without the quotes) will disable the HTML element. + + + onclick + false + true + HTML Event Attribute + + + ondblclick + false + true + HTML Event Attribute + + + onmousedown + false + true + HTML Event Attribute + + + onmouseup + false + true + HTML Event Attribute + + + onmouseover + false + true + HTML Event Attribute + + + onmousemove + false + true + HTML Event Attribute + + + onmouseout + false + true + HTML Event Attribute + + + onkeypress + false + true + HTML Event Attribute + + + onkeyup + false + true + HTML Event Attribute + + + onkeydown + false + true + HTML Event Attribute + + + onfocus + false + true + HTML Event Attribute + + + onblur + false + true + HTML Event Attribute + + + onchange + false + true + HTML Event Attribute + + + accesskey + false + true + HTML Standard Attribute + + + + size + false + true + HTML Optional Attribute + + + maxlength + false + true + HTML Optional Attribute + + + alt + false + true + HTML Optional Attribute + + + onselect + false + true + HTML Event Attribute + + + readonly + false + true + HTML Optional Attribute. Setting the value of this attribute to 'true' (without the quotes) will make the HTML element readonly. + + + autocomplete + false + true + Common Optional Attribute + + + + showPassword + false + true + Is the password value to be shown? Defaults to false. + + + + + + hidden + org.springframework.web.servlet.tags.form.HiddenInputTag + empty + Renders an HTML 'input' tag with type 'hidden' using the bound value. + + path + true + true + Path to property for data binding + + + id + false + true + HTML Standard Attribute + + + htmlEscape + false + true + Enable/disable HTML escaping of rendered values. + + + + + + select + org.springframework.web.servlet.tags.form.SelectTag + JSP + Renders an HTML 'select' element. Supports databinding to the selected option. + + path + true + true + Path to property for data binding + + + id + false + true + HTML Standard Attribute + + + htmlEscape + false + true + Enable/disable HTML escaping of rendered values. + + + cssClass + false + true + Equivalent to "class" - HTML Optional Attribute + + + cssErrorClass + false + true + Equivalent to "class" - HTML Optional Attribute. Used when the bound field has errors. + + + cssStyle + false + true + Equivalent to "style" - HTML Optional Attribute + + + lang + false + true + HTML Standard Attribute + + + title + false + true + HTML Standard Attribute + + + dir + false + true + HTML Standard Attribute + + + tabindex + false + true + HTML Standard Attribute + + + disabled + false + true + HTML Optional Attribute. Setting the value of this attribute to 'true' (without the quotes) will disable the HTML element. + + + onclick + false + true + HTML Event Attribute + + + ondblclick + false + true + HTML Event Attribute + + + onmousedown + false + true + HTML Event Attribute + + + onmouseup + false + true + HTML Event Attribute + + + onmouseover + false + true + HTML Event Attribute + + + onmousemove + false + true + HTML Event Attribute + + + onmouseout + false + true + HTML Event Attribute + + + onkeypress + false + true + HTML Event Attribute + + + onkeyup + false + true + HTML Event Attribute + + + onkeydown + false + true + HTML Event Attribute + + + onfocus + false + true + HTML Event Attribute + + + onblur + false + true + HTML Event Attribute + + + onchange + false + true + HTML Event Attribute + + + accesskey + false + true + HTML Standard Attribute + + + + items + false + true + The Collection, Map or array of objects used to generate the inner 'option' tags + + + itemValue + false + true + Name of the property mapped to 'value' attribute of the 'option' tag + + + itemLabel + false + true + Name of the property mapped to the inner text of the 'option' tag + + + size + false + true + HTML Optional Attribute + + + multiple + false + true + HTML Optional Attribute + + + + + + option + org.springframework.web.servlet.tags.form.OptionTag + JSP + Renders a single HTML 'option'. Sets 'selected' as appropriate based on bound value. + + value + java.lang.Object + The actual value bound to the 'value' attribute + + + displayValue + java.lang.String + The String representation of thr value bound to the 'value' attribute, taking into consideration + any PropertyEditor associated with the enclosing 'select' tag. + + + value + true + true + HTML Optional Attribute + + + label + false + true + HTML Optional Attribute + + + htmlEscape + false + true + Enable/disable HTML escaping of rendered values. + + + cssClass + false + true + Equivalent to "class" - HTML Optional Attribute + + + cssErrorClass + false + true + Equivalent to "class" - HTML Optional Attribute. Used when the bound field has errors. + + + cssStyle + false + true + Equivalent to "style" - HTML Optional Attribute + + + lang + false + true + HTML Standard Attribute + + + title + false + true + HTML Standard Attribute + + + dir + false + true + HTML Standard Attribute + + + tabindex + false + true + HTML Standard Attribute + + + disabled + false + true + HTML Optional Attribute. Setting the value of this attribute to 'true' (without the quotes) will disable the HTML element. + + + onclick + false + true + HTML Event Attribute + + + ondblclick + false + true + HTML Event Attribute + + + onmousedown + false + true + HTML Event Attribute + + + onmouseup + false + true + HTML Event Attribute + + + onmouseover + false + true + HTML Event Attribute + + + onmousemove + false + true + HTML Event Attribute + + + onmouseout + false + true + HTML Event Attribute + + + onkeypress + false + true + HTML Event Attribute + + + onkeyup + false + true + HTML Event Attribute + + + onkeydown + false + true + HTML Event Attribute + + + + + + options + org.springframework.web.servlet.tags.form.OptionsTag + empty + Renders a list of HTML 'option' tags. Sets 'selected' as appropriate based on bound + value. + + items + true + true + The Collection, Map or array of objects used to generate the inner 'option' tags + + + itemValue + false + true + Name of the property mapped to 'value' attribute of the 'option' tag + + + itemLabel + false + true + Name of the property mapped to the inner text of the 'option' tag + + + htmlEscape + false + true + Enable/disable HTML escaping of rendered values. + + + cssClass + false + true + Equivalent to "class" - HTML Optional Attribute + + + cssErrorClass + false + true + Equivalent to "class" - HTML Optional Attribute. Used when the bound field has errors. + + + cssStyle + false + true + Equivalent to "style" - HTML Optional Attribute + + + lang + false + true + HTML Standard Attribute + + + title + false + true + HTML Standard Attribute + + + dir + false + true + HTML Standard Attribute + + + tabindex + false + true + HTML Standard Attribute + + + disabled + false + true + HTML Optional Attribute. Setting the value of this attribute to 'true' (without the quotes) will disable the HTML element. + + + onclick + false + true + HTML Event Attribute + + + ondblclick + false + true + HTML Event Attribute + + + onmousedown + false + true + HTML Event Attribute + + + onmouseup + false + true + HTML Event Attribute + + + onmouseover + false + true + HTML Event Attribute + + + onmousemove + false + true + HTML Event Attribute + + + onmouseout + false + true + HTML Event Attribute + + + onkeypress + false + true + HTML Event Attribute + + + onkeyup + false + true + HTML Event Attribute + + + onkeydown + false + true + HTML Event Attribute + + + + + + radiobutton + org.springframework.web.servlet.tags.form.RadioButtonTag + empty + Renders an HTML 'input' tag with type 'radio'. + + path + true + true + Path to property for data binding + + + id + false + true + HTML Standard Attribute + + + htmlEscape + false + true + Enable/disable HTML escaping of rendered values. + + + cssClass + false + true + Equivalent to "class" - HTML Optional Attribute + + + cssErrorClass + false + true + Equivalent to "class" - HTML Optional Attribute. Used when the bound field has errors. + + + cssStyle + false + true + Equivalent to "style" - HTML Optional Attribute + + + lang + false + true + HTML Standard Attribute + + + title + false + true + HTML Standard Attribute + + + dir + false + true + HTML Standard Attribute + + + tabindex + false + true + HTML Standard Attribute + + + disabled + false + true + HTML Optional Attribute. Setting the value of this attribute to 'true' (without the quotes) will disable the HTML element. + + + onclick + false + true + HTML Event Attribute + + + ondblclick + false + true + HTML Event Attribute + + + onmousedown + false + true + HTML Event Attribute + + + onmouseup + false + true + HTML Event Attribute + + + onmouseover + false + true + HTML Event Attribute + + + onmousemove + false + true + HTML Event Attribute + + + onmouseout + false + true + HTML Event Attribute + + + onkeypress + false + true + HTML Event Attribute + + + onkeyup + false + true + HTML Event Attribute + + + onkeydown + false + true + HTML Event Attribute + + + onfocus + false + true + HTML Event Attribute + + + onblur + false + true + HTML Event Attribute + + + onchange + false + true + HTML Event Attribute + + + accesskey + false + true + HTML Standard Attribute + + + + value + false + true + HTML Optional Attribute + + + label + false + true + Value to be displayed as part of the tag + + + + + + radiobuttons + org.springframework.web.servlet.tags.form.RadioButtonsTag + empty + Renders multiple HTML 'input' tags with type 'radio'. + + path + true + true + Path to property for data binding + + + id + false + true + HTML Standard Attribute + + + htmlEscape + false + true + Enable/disable HTML escaping of rendered values. + + + cssClass + false + true + Equivalent to "class" - HTML Optional Attribute + + + cssErrorClass + false + true + Equivalent to "class" - HTML Optional Attribute. Used when the bound field has errors. + + + cssStyle + false + true + Equivalent to "style" - HTML Optional Attribute + + + lang + false + true + HTML Standard Attribute + + + title + false + true + HTML Standard Attribute + + + dir + false + true + HTML Standard Attribute + + + tabindex + false + true + HTML Standard Attribute + + + disabled + false + true + HTML Optional Attribute. Setting the value of this attribute to 'true' (without the quotes) will disable the HTML element. + + + onclick + false + true + HTML Event Attribute + + + ondblclick + false + true + HTML Event Attribute + + + onmousedown + false + true + HTML Event Attribute + + + onmouseup + false + true + HTML Event Attribute + + + onmouseover + false + true + HTML Event Attribute + + + onmousemove + false + true + HTML Event Attribute + + + onmouseout + false + true + HTML Event Attribute + + + onkeypress + false + true + HTML Event Attribute + + + onkeyup + false + true + HTML Event Attribute + + + onkeydown + false + true + HTML Event Attribute + + + onfocus + false + true + HTML Event Attribute + + + onblur + false + true + HTML Event Attribute + + + onchange + false + true + HTML Event Attribute + + + accesskey + false + true + HTML Standard Attribute + + + + items + true + true + The Collection, Map or array of objects used to generate the 'input' tags with type 'radio' + + + itemValue + false + true + Name of the property mapped to 'value' attribute of the 'input' tags with type 'radio' + + + itemLabel + false + true + Value to be displayed as part of the 'input' tags with type 'radio' + + + delimiter + false + true + Delimiter to use between each 'input' tag with type 'radio'. There is no delimiter by default. + + + element + false + true + Specifies the HTML element that is used to enclose each 'input' tag with type 'radio'. Defaults to 'span'. + + + + + + checkbox + org.springframework.web.servlet.tags.form.CheckboxTag + empty + Renders an HTML 'input' tag with type 'checkbox'. + + path + true + true + Path to property for data binding + + + id + false + true + HTML Standard Attribute + + + htmlEscape + false + true + Enable/disable HTML escaping of rendered values. + + + cssClass + false + true + Equivalent to "class" - HTML Optional Attribute + + + cssErrorClass + false + true + Equivalent to "class" - HTML Optional Attribute. Used when the bound field has errors. + + + cssStyle + false + true + Equivalent to "style" - HTML Optional Attribute + + + lang + false + true + HTML Standard Attribute + + + title + false + true + HTML Standard Attribute + + + dir + false + true + HTML Standard Attribute + + + tabindex + false + true + HTML Standard Attribute + + + disabled + false + true + HTML Optional Attribute. Setting the value of this attribute to 'true' (without the quotes) will disable the HTML element. + + + onclick + false + true + HTML Event Attribute + + + ondblclick + false + true + HTML Event Attribute + + + onmousedown + false + true + HTML Event Attribute + + + onmouseup + false + true + HTML Event Attribute + + + onmouseover + false + true + HTML Event Attribute + + + onmousemove + false + true + HTML Event Attribute + + + onmouseout + false + true + HTML Event Attribute + + + onkeypress + false + true + HTML Event Attribute + + + onkeyup + false + true + HTML Event Attribute + + + onkeydown + false + true + HTML Event Attribute + + + onfocus + false + true + HTML Event Attribute + + + onblur + false + true + HTML Event Attribute + + + onchange + false + true + HTML Event Attribute + + + accesskey + false + true + HTML Standard Attribute + + + + value + false + true + HTML Optional Attribute + + + label + false + true + Value to be displayed as part of the tag + + + + + + checkboxes + org.springframework.web.servlet.tags.form.CheckboxesTag + empty + Renders multiple HTML 'input' tags with type 'checkbox'. + + path + true + true + Path to property for data binding + + + id + false + true + HTML Standard Attribute + + + htmlEscape + false + true + Enable/disable HTML escaping of rendered values. + + + cssClass + false + true + Equivalent to "class" - HTML Optional Attribute + + + cssErrorClass + false + true + Equivalent to "class" - HTML Optional Attribute. Used when the bound field has errors. + + + cssStyle + false + true + Equivalent to "style" - HTML Optional Attribute + + + lang + false + true + HTML Standard Attribute + + + title + false + true + HTML Standard Attribute + + + dir + false + true + HTML Standard Attribute + + + tabindex + false + true + HTML Standard Attribute + + + disabled + false + true + HTML Optional Attribute. Setting the value of this attribute to 'true' (without the quotes) will disable the HTML element. + + + onclick + false + true + HTML Event Attribute + + + ondblclick + false + true + HTML Event Attribute + + + onmousedown + false + true + HTML Event Attribute + + + onmouseup + false + true + HTML Event Attribute + + + onmouseover + false + true + HTML Event Attribute + + + onmousemove + false + true + HTML Event Attribute + + + onmouseout + false + true + HTML Event Attribute + + + onkeypress + false + true + HTML Event Attribute + + + onkeyup + false + true + HTML Event Attribute + + + onkeydown + false + true + HTML Event Attribute + + + onfocus + false + true + HTML Event Attribute + + + onblur + false + true + HTML Event Attribute + + + onchange + false + true + HTML Event Attribute + + + accesskey + false + true + HTML Standard Attribute + + + + items + true + true + The Collection, Map or array of objects used to generate the 'input' tags with type 'checkbox' + + + itemValue + false + true + Name of the property mapped to 'value' attribute of the 'input' tags with type 'checkbox' + + + itemLabel + false + true + Value to be displayed as part of the 'input' tags with type 'checkbox' + + + delimiter + false + true + Delimiter to use between each 'input' tag with type 'checkbox'. There is no delimiter by default. + + + element + false + true + Specifies the HTML element that is used to enclose each 'input' tag with type 'checkbox'. Defaults to 'span'. + + + + + + textarea + org.springframework.web.servlet.tags.form.TextareaTag + empty + Renders an HTML 'textarea'. + + path + true + true + Path to property for data binding + + + id + false + true + HTML Standard Attribute + + + htmlEscape + false + true + Enable/disable HTML escaping of rendered values. + + + cssClass + false + true + Equivalent to "class" - HTML Optional Attribute + + + cssErrorClass + false + true + Equivalent to "class" - HTML Optional Attribute. Used when the bound field has errors. + + + cssStyle + false + true + Equivalent to "style" - HTML Optional Attribute + + + lang + false + true + HTML Standard Attribute + + + title + false + true + HTML Standard Attribute + + + dir + false + true + HTML Standard Attribute + + + tabindex + false + true + HTML Standard Attribute + + + disabled + false + true + HTML Optional Attribute. Setting the value of this attribute to 'true' (without the quotes) will disable the HTML element. + + + onclick + false + true + HTML Event Attribute + + + ondblclick + false + true + HTML Event Attribute + + + onmousedown + false + true + HTML Event Attribute + + + onmouseup + false + true + HTML Event Attribute + + + onmouseover + false + true + HTML Event Attribute + + + onmousemove + false + true + HTML Event Attribute + + + onmouseout + false + true + HTML Event Attribute + + + onkeypress + false + true + HTML Event Attribute + + + onkeyup + false + true + HTML Event Attribute + + + onkeydown + false + true + HTML Event Attribute + + + onfocus + false + true + HTML Event Attribute + + + onblur + false + true + HTML Event Attribute + + + onchange + false + true + HTML Event Attribute + + + accesskey + false + true + HTML Standard Attribute + + + + rows + false + true + HTML Required Attribute + + + cols + false + true + HTML Required Attribute + + + onselect + false + true + HTML Event Attribute + + + readonly + false + true + HTML Optional Attribute. Setting the value of this attribute to 'true' (without the quotes) will make the HTML element readonly. + + + + + + errors + org.springframework.web.servlet.tags.form.ErrorsTag + JSP + Renders field errors in an HTML 'span' tag. + + messages + java.util.List + + + path + false + true + Path to errors object for data binding + + + id + false + true + HTML Standard Attribute + + + htmlEscape + false + true + Enable/disable HTML escaping of rendered values. + + + delimiter + false + true + Delimiter for displaying multiple error messages. Defaults to the br tag. + + + cssClass + false + true + Equivalent to "class" - HTML Optional Attribute + + + cssStyle + false + true + Equivalent to "style" - HTML Optional Attribute + + + lang + false + true + HTML Standard Attribute + + + title + false + true + HTML Standard Attribute + + + dir + false + true + HTML Standard Attribute + + + tabindex + false + true + HTML Standard Attribute + + + onclick + false + true + HTML Event Attribute + + + ondblclick + false + true + HTML Event Attribute + + + onmousedown + false + true + HTML Event Attribute + + + onmouseup + false + true + HTML Event Attribute + + + onmouseover + false + true + HTML Event Attribute + + + onmousemove + false + true + HTML Event Attribute + + + onmouseout + false + true + HTML Event Attribute + + + onkeypress + false + true + HTML Event Attribute + + + onkeyup + false + true + HTML Event Attribute + + + onkeydown + false + true + HTML Event Attribute + + + element + false + true + Specifies the HTML element that is used to render the enclosing errors. + + + + + + label + org.springframework.web.servlet.tags.form.LabelTag + JSP + Renders a form field label in an HTML 'label' tag. + + path + true + true + Path to errors object for data binding + + + id + false + true + HTML Standard Attribute + + + htmlEscape + false + true + Enable/disable HTML escaping of rendered values. + + + for + false + true + HTML Standard Attribute + + + cssClass + false + true + Equivalent to "class" - HTML Optional Attribute. + + + cssErrorClass + false + true + Equivalent to "class" - HTML Optional Attribute. Used only when errors are present. + + + cssStyle + false + true + Equivalent to "style" - HTML Optional Attribute + + + lang + false + true + HTML Standard Attribute + + + title + false + true + HTML Standard Attribute + + + dir + false + true + HTML Standard Attribute + + + tabindex + false + true + HTML Standard Attribute + + + onclick + false + true + HTML Event Attribute + + + ondblclick + false + true + HTML Event Attribute + + + onmousedown + false + true + HTML Event Attribute + + + onmouseup + false + true + HTML Event Attribute + + + onmouseover + false + true + HTML Event Attribute + + + onmousemove + false + true + HTML Event Attribute + + + onmouseout + false + true + HTML Event Attribute + + + onkeypress + false + true + HTML Event Attribute + + + onkeyup + false + true + HTML Event Attribute + + + onkeydown + false + true + HTML Event Attribute + + + + diff --git a/spring-data-neo4j-examples/imdb/src/main/webapp/WEB-INF/web.xml b/spring-data-neo4j-examples/imdb/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 000000000..a6ce357d9 --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,31 @@ + + + + + + imdb-app + org.springframework.web.servlet.DispatcherServlet + 1 + + + + imdb-app + *.html + + + + index.jsp + + + + + /spring + /WEB-INF/tld/spring-form.tld + + + + diff --git a/spring-data-neo4j-examples/imdb/src/main/webapp/actor.png b/spring-data-neo4j-examples/imdb/src/main/webapp/actor.png new file mode 100644 index 000000000..9d2d50081 Binary files /dev/null and b/spring-data-neo4j-examples/imdb/src/main/webapp/actor.png differ diff --git a/spring-data-neo4j-examples/imdb/src/main/webapp/bg.png b/spring-data-neo4j-examples/imdb/src/main/webapp/bg.png new file mode 100644 index 000000000..29d110772 Binary files /dev/null and b/spring-data-neo4j-examples/imdb/src/main/webapp/bg.png differ diff --git a/spring-data-neo4j-examples/imdb/src/main/webapp/favicon.ico b/spring-data-neo4j-examples/imdb/src/main/webapp/favicon.ico new file mode 100644 index 000000000..58a83c6d8 Binary files /dev/null and b/spring-data-neo4j-examples/imdb/src/main/webapp/favicon.ico differ diff --git a/spring-data-neo4j-examples/imdb/src/main/webapp/gradient.png b/spring-data-neo4j-examples/imdb/src/main/webapp/gradient.png new file mode 100644 index 000000000..abdb086c4 Binary files /dev/null and b/spring-data-neo4j-examples/imdb/src/main/webapp/gradient.png differ diff --git a/spring-data-neo4j-examples/imdb/src/main/webapp/index.jsp b/spring-data-neo4j-examples/imdb/src/main/webapp/index.jsp new file mode 100644 index 000000000..b7a02fb16 --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/webapp/index.jsp @@ -0,0 +1,17 @@ +<%@ include file="/jsp/include.jsp"%> +<%@ include file="/jsp/head.jsp"%> + +IMDB powered by Neo + + +

IMDB powered by Neo4j

+ + + + + diff --git a/spring-data-neo4j-examples/imdb/src/main/webapp/jsp/actor-list.jsp b/spring-data-neo4j-examples/imdb/src/main/webapp/jsp/actor-list.jsp new file mode 100644 index 000000000..71f825c98 --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/webapp/jsp/actor-list.jsp @@ -0,0 +1,21 @@ +<%@ include file="/jsp/include.jsp"%> +<%@ include file="/jsp/head.jsp"%> + +<c:out value="${model.movieTitle}" /> : IMDB powered by Neo4j + + +

+

Actors

+
    + + + + +
  • as
  • +
    +
+<%@ include file="/jsp/menu.jsp"%> + + diff --git a/spring-data-neo4j-examples/imdb/src/main/webapp/jsp/actor.jsp b/spring-data-neo4j-examples/imdb/src/main/webapp/jsp/actor.jsp new file mode 100644 index 000000000..ab3287f14 --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/webapp/jsp/actor.jsp @@ -0,0 +1,16 @@ +<%@ include file="/jsp/include.jsp"%> +<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%> +<%@ include file="/jsp/head.jsp"%> + +IMDB powered by Neo4j + + +

IMDB powered by Neo4j

+ +
Find actor
+
+
+<%@ include file="/jsp/menu.jsp"%> + + diff --git a/spring-data-neo4j-examples/imdb/src/main/webapp/jsp/head.jsp b/spring-data-neo4j-examples/imdb/src/main/webapp/jsp/head.jsp new file mode 100644 index 000000000..35200828e --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/webapp/jsp/head.jsp @@ -0,0 +1,9 @@ +<%@ page language="java" contentType="text/html; charset=ISO-8859-1" + pageEncoding="ISO-8859-1"%> + + + + + + + diff --git a/spring-data-neo4j-examples/imdb/src/main/webapp/jsp/include.jsp b/spring-data-neo4j-examples/imdb/src/main/webapp/jsp/include.jsp new file mode 100644 index 000000000..8f1115e11 --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/webapp/jsp/include.jsp @@ -0,0 +1,3 @@ +<%@ page session="false"%> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> \ No newline at end of file diff --git a/spring-data-neo4j-examples/imdb/src/main/webapp/jsp/menu.jsp b/spring-data-neo4j-examples/imdb/src/main/webapp/jsp/menu.jsp new file mode 100644 index 000000000..dc452990d --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/webapp/jsp/menu.jsp @@ -0,0 +1 @@ + diff --git a/spring-data-neo4j-examples/imdb/src/main/webapp/jsp/movie-list.jsp b/spring-data-neo4j-examples/imdb/src/main/webapp/jsp/movie-list.jsp new file mode 100644 index 000000000..106613ae9 --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/webapp/jsp/movie-list.jsp @@ -0,0 +1,47 @@ +<%@ include file="/jsp/include.jsp"%> +<%@ include file="/jsp/head.jsp"%> + +<c:out value="${model.actorName}" /> : IMDB powered by Neo4j + + +

+ +

Kevin Bacon number:

+

Bacon path

+ +

Movies

+
    + + + + +
  • in
  • +
    +
+
+<%@ include file="/jsp/menu.jsp"%> + + diff --git a/spring-data-neo4j-examples/imdb/src/main/webapp/jsp/movie.jsp b/spring-data-neo4j-examples/imdb/src/main/webapp/jsp/movie.jsp new file mode 100644 index 000000000..13c4539ff --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/webapp/jsp/movie.jsp @@ -0,0 +1,16 @@ +<%@ include file="/jsp/include.jsp"%> +<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%> +<%@ include file="/jsp/head.jsp"%> + +IMDB powered by Neo4j + + +

IMDB powered by Neo4j

+ +
Find movie
+
+
+<%@ include file="/jsp/menu.jsp"%> + + diff --git a/spring-data-neo4j-examples/imdb/src/main/webapp/jsp/setup-message.jsp b/spring-data-neo4j-examples/imdb/src/main/webapp/jsp/setup-message.jsp new file mode 100644 index 000000000..e1be252c9 --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/webapp/jsp/setup-message.jsp @@ -0,0 +1,13 @@ +<%@ include file="/jsp/include.jsp"%> +<%@ include file="/jsp/head.jsp"%> + +Setup : IMDB powered by Neo4j + + +

IMDB Setup

+

Result

+
+

+<%@ include file="/jsp/menu.jsp"%> + + diff --git a/spring-data-neo4j-examples/imdb/src/main/webapp/jsp/setup.jsp b/spring-data-neo4j-examples/imdb/src/main/webapp/jsp/setup.jsp new file mode 100644 index 000000000..372668ddc --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/webapp/jsp/setup.jsp @@ -0,0 +1,15 @@ +<%@ include file="/jsp/include.jsp"%> +<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%> +<%@ include file="/jsp/head.jsp"%> + +IMDB powered by Neo4j + + +

IMDB powered by Neo4j

+ +
Inject data into the graph +
+
+<%@ include file="/jsp/menu.jsp"%> + + diff --git a/spring-data-neo4j-examples/imdb/src/main/webapp/menu.png b/spring-data-neo4j-examples/imdb/src/main/webapp/menu.png new file mode 100644 index 000000000..800b9e848 Binary files /dev/null and b/spring-data-neo4j-examples/imdb/src/main/webapp/menu.png differ diff --git a/spring-data-neo4j-examples/imdb/src/main/webapp/movie.png b/spring-data-neo4j-examples/imdb/src/main/webapp/movie.png new file mode 100644 index 000000000..64e7a3075 Binary files /dev/null and b/spring-data-neo4j-examples/imdb/src/main/webapp/movie.png differ diff --git a/spring-data-neo4j-examples/imdb/src/main/webapp/setup.png b/spring-data-neo4j-examples/imdb/src/main/webapp/setup.png new file mode 100644 index 000000000..22ff49571 Binary files /dev/null and b/spring-data-neo4j-examples/imdb/src/main/webapp/setup.png differ diff --git a/spring-data-neo4j-examples/imdb/src/main/webapp/style.css b/spring-data-neo4j-examples/imdb/src/main/webapp/style.css new file mode 100644 index 000000000..3e3320a72 --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/main/webapp/style.css @@ -0,0 +1,118 @@ +html { + font-size: 100% +} + +body { + color: #353535; + text-align: left; + font: 0.75em/1.5 sans-serif; + background: #fffdfb url(/imdb/bg.png) repeat-x; + margin-top: 4em; + margin-left: 8em; +} + +.inputField { + padding: 5px; + border: 0; + border-bottom: 1px solid #cccccc; + background: #FFFFFF url(/imdb/gradient.png) repeat-x; + font: normal 14px "trebuchet ms", helvetica, sans-serif; + color: #454743; +} + +.inputField:hover { + border-bottom: 1px solid #333; +} + +label { + font: 13px "trebuchet ms", helvetica, sans-serif; + color: #0c9b92; + margin-right: 0.5em; +} + +p { + color: #5f5f5f; +} + +a:link { + color: #0c9b92; +} + +a:visited { + color: #00a18a; +} + +a:hover { + +} + +h1 { + color: #006380; + padding-top: 0.5em; + line-height: 1.2; +} + +#menu { + clear: left; + padding-top: 1.5em; +} + +ul { + padding-left: 0; +} + +li { + color: #656565; + list-style-type: none; + background: url(/imdb/menu.png) no-repeat; + padding-left: 20px; + line-height: 20px; +} + +.actor { + background-image: url(/imdb/actor.png); +} + +.actors li,.movies li { + float: left; + width: 15em; + height: 7em; + background-color: #F8F8F8; + border: 1px solid #D6D6D6; + background-position: 6px 6px; + margin: 10px; + padding: 0.5em 0.5em 0.5em 30px; + overflow: hidden; +} + +li.actor em { + display: block; +} + +.movies a { + display: block; +} + +.movie { + background-image: url(/imdb/movie.png); +} + +.setup { + background-image: url(/imdb/setup.png); +} + +fieldset { + border: 1px solid #afafaf; + padding: 1em; +} + +legend { + font-weight: bold; + background-repeat: no-repeat; + background-position: 4px 0; + padding: 0 6px 0 24px; +} + +pre { + font-size: 1.5em; +} \ No newline at end of file diff --git a/spring-data-neo4j-examples/imdb/src/site/apt/index.apt b/spring-data-neo4j-examples/imdb/src/site/apt/index.apt new file mode 100644 index 000000000..ee2573fa7 --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/site/apt/index.apt @@ -0,0 +1,28 @@ +The Neo4j - Datastore Graph IMDB Example + + Imagine a number of actors, acting in Movies and thus forming a graph of relationships between Actors and Movies. The + Spring Datastore Graph project provides an annotation-based approach to map objects onto Neo4j. The current annotations + supported (still subject to change) are: + + * @NodeEntity - class annotation for POJOs backed by a graph node. + + * @RelationshipEntity - class annotation for POJOs containing relationship properties. + + * @GraphProperty - field annotation used to specify indexing. + + * @RelatedTo - for fields denoting relationships (either one-to-one or one-to-many). + + * @StartNode - the start node for a @GraphRelationship.. + + * @EndNode - the end node for a @GraphRelationship. + + In order to persist objects in Spring into Neo4j, simply do something like this (the full code is available over at the + {{{http://github.com/neo4j-examples/spring-datastore-graph-imdb} Spring Datastore Graph IMDB example}}: + +%{source-code|snippet=MovieClass|file=src/main/java/org/neo4j/examples/imdb/domain/Movie.java} + + and the Actor class, + +%{source-code|snippet=ActorClass|file=src/main/java/org/neo4j/examples/imdb/domain/Actor.java} + + This will produce something like {{{http://wiki.neo4j.org/images/5/53/Imdb.screenshot.actor.png} this graph}} \ No newline at end of file diff --git a/spring-data-neo4j-examples/imdb/src/site/site.xml b/spring-data-neo4j-examples/imdb/src/site/site.xml new file mode 100644 index 000000000..0c01dac59 --- /dev/null +++ b/spring-data-neo4j-examples/imdb/src/site/site.xml @@ -0,0 +1,33 @@ + + + + + ${project.name} + images/logos/logo-dark.png + http://neo4j.org/ + + + + + + + + + + + + + + + + + + + + ${skinGroupId} + ${skinArtifactId} + ${skinVersion} + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/imdb/src/test/resources/icons/ACTS_IN.INCOMING.png b/spring-data-neo4j-examples/imdb/src/test/resources/icons/ACTS_IN.INCOMING.png new file mode 100644 index 000000000..64e7a3075 Binary files /dev/null and b/spring-data-neo4j-examples/imdb/src/test/resources/icons/ACTS_IN.INCOMING.png differ diff --git a/spring-data-neo4j-examples/imdb/src/test/resources/icons/ACTS_IN.OUTGOING.png b/spring-data-neo4j-examples/imdb/src/test/resources/icons/ACTS_IN.OUTGOING.png new file mode 100644 index 000000000..9d2d50081 Binary files /dev/null and b/spring-data-neo4j-examples/imdb/src/test/resources/icons/ACTS_IN.OUTGOING.png differ diff --git a/spring-data-neo4j-examples/imdb/src/test/resources/icons/IMDB.OUTGOING.png b/spring-data-neo4j-examples/imdb/src/test/resources/icons/IMDB.OUTGOING.png new file mode 100644 index 000000000..a46fb2220 Binary files /dev/null and b/spring-data-neo4j-examples/imdb/src/test/resources/icons/IMDB.OUTGOING.png differ diff --git a/spring-data-neo4j-examples/imdb/src/test/resources/icons/PART_OF_NAME.OUTGOING.png b/spring-data-neo4j-examples/imdb/src/test/resources/icons/PART_OF_NAME.OUTGOING.png new file mode 100644 index 000000000..d072d3cbe Binary files /dev/null and b/spring-data-neo4j-examples/imdb/src/test/resources/icons/PART_OF_NAME.OUTGOING.png differ diff --git a/spring-data-neo4j-examples/imdb/src/test/resources/icons/PART_OF_TITLE.OUTGOING.png b/spring-data-neo4j-examples/imdb/src/test/resources/icons/PART_OF_TITLE.OUTGOING.png new file mode 100644 index 000000000..d072d3cbe Binary files /dev/null and b/spring-data-neo4j-examples/imdb/src/test/resources/icons/PART_OF_TITLE.OUTGOING.png differ diff --git a/spring-data-neo4j-examples/myrestaurants-original/.classpath b/spring-data-neo4j-examples/myrestaurants-original/.classpath new file mode 100644 index 000000000..18876e3e8 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/.classpath @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/spring-data-neo4j-examples/myrestaurants-original/.gitignore b/spring-data-neo4j-examples/myrestaurants-original/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/spring-data-neo4j-examples/myrestaurants-original/.project b/spring-data-neo4j-examples/myrestaurants-original/.project new file mode 100644 index 000000000..b384d034e --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/.project @@ -0,0 +1,44 @@ + + myrestaurants-original + + + + + org.eclipse.wst.jsdt.core.javascriptValidator + + + org.eclipse.ajdt.core.ajbuilder + + + org.eclipse.wst.common.project.facet.core.builder + + + org.eclipse.wst.validation.validationbuilder + + + org.springframework.ide.eclipse.core.springbuilder + + + org.eclipse.ajdt.core.ajbuilder + + + aspectPath + org.springframework.aspects + + + + + org.maven.ide.eclipse.maven2Builder + + + + org.eclipse.ajdt.ui.ajnature + org.springframework.ide.eclipse.core.springnature + org.maven.ide.eclipse.maven2Nature + org.eclipse.wst.common.project.facet.core.nature + org.eclipse.jdt.core.javanature + org.eclipse.wst.common.modulecore.ModuleCoreNature + org.eclipse.jem.workbench.JavaEMFNature + org.eclipse.wst.jsdt.core.jsNature + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-original/.settings/.jsdtscope b/spring-data-neo4j-examples/myrestaurants-original/.settings/.jsdtscope new file mode 100644 index 000000000..b13d30357 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/.settings/.jsdtscope @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/spring-data-neo4j-examples/myrestaurants-original/.settings/org.eclipse.jdt.core.prefs b/spring-data-neo4j-examples/myrestaurants-original/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..e045805a8 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,6 @@ +#Tue Sep 28 12:45:37 EDT 2010 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/spring-data-neo4j-examples/myrestaurants-original/.settings/org.eclipse.wst.common.component b/spring-data-neo4j-examples/myrestaurants-original/.settings/org.eclipse.wst.common.component new file mode 100644 index 000000000..e5c6743f7 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/.settings/org.eclipse.wst.common.component @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/spring-data-neo4j-examples/myrestaurants-original/.settings/org.eclipse.wst.common.project.facet.core.xml b/spring-data-neo4j-examples/myrestaurants-original/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..708f4a79d --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/spring-data-neo4j-examples/myrestaurants-original/.settings/org.eclipse.wst.jsdt.ui.superType.container b/spring-data-neo4j-examples/myrestaurants-original/.settings/org.eclipse.wst.jsdt.ui.superType.container new file mode 100644 index 000000000..3bd5d0a48 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/.settings/org.eclipse.wst.jsdt.ui.superType.container @@ -0,0 +1 @@ +org.eclipse.wst.jsdt.launching.baseBrowserLibrary \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-original/.settings/org.eclipse.wst.jsdt.ui.superType.name b/spring-data-neo4j-examples/myrestaurants-original/.settings/org.eclipse.wst.jsdt.ui.superType.name new file mode 100644 index 000000000..05bd71b6e --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/.settings/org.eclipse.wst.jsdt.ui.superType.name @@ -0,0 +1 @@ +Window \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-original/.settings/org.eclipse.wst.validation.prefs b/spring-data-neo4j-examples/myrestaurants-original/.settings/org.eclipse.wst.validation.prefs new file mode 100644 index 000000000..55e002061 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/.settings/org.eclipse.wst.validation.prefs @@ -0,0 +1,10 @@ +#Tue Oct 05 19:38:41 EDT 2010 +DELEGATES_PREFERENCE=delegateValidatorList +USER_BUILD_PREFERENCE=enabledBuildValidatorListorg.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyValidator;org.eclipse.jst.j2ee.internal.web.validation.UIWarValidator; +USER_MANUAL_PREFERENCE=enabledManualValidatorListorg.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyValidator;org.eclipse.jst.j2ee.internal.web.validation.UIWarValidator; +USER_PREFERENCE=overrideGlobalPreferencestruedisableAllValidationfalseversion1.2.200.v201005271900 +eclipse.preferences.version=1 +override=true +suspend=false +vals/org.eclipse.jst.jsp.core.JSPContentValidator/global=FF01 +vf.version=3 diff --git a/spring-data-neo4j-examples/myrestaurants-original/.settings/org.maven.ide.eclipse.prefs b/spring-data-neo4j-examples/myrestaurants-original/.settings/org.maven.ide.eclipse.prefs new file mode 100644 index 000000000..76b3ad97f --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/.settings/org.maven.ide.eclipse.prefs @@ -0,0 +1,9 @@ +#Tue Sep 28 12:45:37 EDT 2010 +activeProfiles= +eclipse.preferences.version=1 +fullBuildGoals=process-test-resources +includeModules=false +resolveWorkspaceProjects=true +resourceFilterGoals=process-resources resources\:testResources +skipCompilerPlugin=true +version=1 diff --git a/spring-data-neo4j-examples/myrestaurants-original/pom.xml b/spring-data-neo4j-examples/myrestaurants-original/pom.xml new file mode 100644 index 000000000..78a39f77e --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/pom.xml @@ -0,0 +1,513 @@ + + + 4.0.0 + com.springone.myrestaurants + myrestaurants-original + war + 0.1.0.BUILD-SNAPSHOT + myrestaurants-original + + 3.0.4.RELEASE + 1.6.10.M1 + 1.6.1 + UTF-8 + 3.0.2.RELEASE + + + + spring-maven-release + Spring Maven Release Repository + http://maven.springframework.org/release + + + spring-maven-milestone + Spring Maven Milestone Repository + http://maven.springframework.org/milestone + + + JBoss Repo + https://repository.jboss.org/nexus/content/repositories/releases + JBoss Repo + + + + + spring-maven-release + Spring Maven Release Repository + http://maven.springframework.org/release + + + spring-maven-milestone + Spring Maven Milestone Repository + http://maven.springframework.org/milestone + + + + + + junit + junit + 4.8.1 + test + + + log4j + log4j + 1.2.16 + + + org.slf4j + slf4j-api + ${slf4j.version} + + + org.slf4j + jcl-over-slf4j + ${slf4j.version} + + + org.slf4j + slf4j-log4j12 + ${slf4j.version} + + + org.aspectj + aspectjrt + ${aspectj.version} + + + javax.servlet + servlet-api + 2.5 + provided + + + net.sf.flexjson + flexjson + 2.0 + + + + org.springframework + spring-core + ${spring.version} + + + commons-logging + commons-logging + + + + + org.springframework + spring-test + ${spring.version} + test + + + commons-logging + commons-logging + + + + + org.springframework + spring-context + ${spring.version} + + + org.springframework + spring-aop + ${spring.version} + + + org.springframework + spring-aspects + ${spring.version} + + + org.springframework + spring-tx + ${spring.version} + + + org.hibernate + hibernate-core + 3.5.5-Final + + + org.hibernate + hibernate-entitymanager + 3.5.5-Final + + + cglib + cglib + + + dom4j + dom4j + + + + + org.hibernate.javax.persistence + hibernate-jpa-2.0-api + 1.0.0.Final + + + org.hibernate + hibernate-validator + 4.1.0.Final + + + javax.xml.bind + jaxb-api + + + com.sun.xml.bind + jaxb-impl + + + + + javax.validation + validation-api + 1.0.0.GA + + + cglib + cglib-nodep + 2.2 + + + javax.transaction + jta + 1.1 + + + org.springframework + spring-jdbc + ${spring.version} + + + org.springframework + spring-orm + ${spring.version} + + + commons-pool + commons-pool + 1.5.4 + + + commons-logging + commons-logging + + + + + commons-dbcp + commons-dbcp + 1.3 + + + commons-logging + commons-logging + + + commons-pool + commons-pool + + + xerces + xerces + + + xerces + xercesImpl + + + xml-apis + xml-apis + + + + + org.apache.tiles + tiles-core + 2.2.1 + + + commons-logging + commons-logging + + + + + org.apache.tiles + tiles-jsp + 2.2.1 + + + org.springframework + spring-web + ${spring.version} + + + commons-logging + commons-logging + + + + + org.springframework + spring-webmvc + ${spring.version} + + + commons-logging + commons-logging + + + + + org.springframework.webflow + spring-js + 2.1.1.RELEASE + + + org.springframework + spring-beans + + + org.springframework + spring-context + + + org.springframework + spring-core + + + org.springframework + spring-context-support + + + commons-logging + commons-logging + + + + + commons-digester + commons-digester + 2.0 + + + commons-logging + commons-logging + + + + + commons-fileupload + commons-fileupload + 1.2.1 + + + commons-logging + commons-logging + + + + + javax.servlet + jstl + 1.2 + + + javax.el + el-api + 1.0 + provided + + + joda-time + joda-time + 1.6 + + + org.springframework.security + spring-security-core + ${spring-security.version} + + + commons-logging + commons-logging + + + + + org.springframework.security + spring-security-config + ${spring-security.version} + + + commons-logging + commons-logging + + + + + org.springframework.security + spring-security-web + ${spring-security.version} + + + org.springframework.security + spring-security-taglibs + ${spring-security.version} + + + org.hsqldb + hsqldb + 2.0.0 + + + + + + org.apache.maven.plugins + maven-war-plugin + 2.1-beta-1 + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.1 + + 1.6 + 1.6 + + + + org.codehaus.mojo + aspectj-maven-plugin + 1.0 + + + + org.aspectj + aspectjrt + ${aspectj.version} + + + org.aspectj + aspectjtools + ${aspectj.version} + + + + + + compile + test-compile + + + + + true + + + org.springframework + spring-aspects + + + 1.6 + 1.6 + + + + org.apache.maven.plugins + maven-resources-plugin + 2.4.2 + + UTF-8 + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.5 + + + org.apache.maven.plugins + maven-assembly-plugin + 2.2-beta-5 + + + jar-with-dependencies + + + + + org.apache.maven.plugins + maven-deploy-plugin + 2.5 + + + + org.apache.maven.plugins + maven-eclipse-plugin + 2.7 + + true + false + 2.0 + + + org.eclipse.ajdt.core.ajbuilder + + org.springframework.aspects + + + + org.springframework.ide.eclipse.core.springbuilder + + + + org.eclipse.ajdt.ui.ajnature + org.springframework.ide.eclipse.core.springnature + + + + + org.apache.maven.plugins + maven-idea-plugin + 2.2 + + true + true + + + + org.codehaus.mojo + tomcat-maven-plugin + 1.0 + + + org.mortbay.jetty + jetty-maven-plugin + 7.1.2.v20100523 + + + /${project.name} + + + + + + diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/java/com/springone/myrestaurants/dao/RestaurantDao.java b/spring-data-neo4j-examples/myrestaurants-original/src/main/java/com/springone/myrestaurants/dao/RestaurantDao.java new file mode 100644 index 000000000..7bb6463e4 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/java/com/springone/myrestaurants/dao/RestaurantDao.java @@ -0,0 +1,37 @@ +package com.springone.myrestaurants.dao; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; + +import org.springframework.stereotype.Repository; + +import com.springone.myrestaurants.domain.Restaurant; + +@Repository +public class RestaurantDao { + + @PersistenceContext + private EntityManager entityManager; + + public Restaurant findRestaurant(Long id) { + if (id == null) return null; + return entityManager.find(Restaurant.class, id); + } + + @SuppressWarnings("unchecked") + public List findAllRestaurants() { + return entityManager.createQuery("select o from Restaurant o").getResultList(); + } + + @SuppressWarnings("unchecked") + public List findRestaurantEntries(int firstResult, int maxResults) { + return entityManager.createQuery("select o from Restaurant o").setFirstResult(firstResult).setMaxResults(maxResults).getResultList(); + } + + public long countRestaurants() { + return ((Number) entityManager.createQuery("select count(o) from Restaurant o").getSingleResult()).longValue(); + } + +} diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/java/com/springone/myrestaurants/dao/UserAccountDao.java b/spring-data-neo4j-examples/myrestaurants-original/src/main/java/com/springone/myrestaurants/dao/UserAccountDao.java new file mode 100644 index 000000000..edba9b4f5 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/java/com/springone/myrestaurants/dao/UserAccountDao.java @@ -0,0 +1,47 @@ +package com.springone.myrestaurants.dao; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.persistence.Query; + +import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Transactional; + +import com.springone.myrestaurants.domain.UserAccount; + +@Repository +public class UserAccountDao { + + @PersistenceContext + private EntityManager entityManager; + + public UserAccount findUserAccount(Long id) { + if (id == null) return null; + return entityManager.find(UserAccount.class, id); + } + + public UserAccount findByName(String name) { + if (name == null) return null; + Query q = entityManager.createQuery("SELECT u FROM UserAccount u WHERE u.userName = :username"); + q.setParameter("username", name); + + java.util.List resultList = q.getResultList(); + if (resultList.size() > 0) + { + return (UserAccount) resultList.get(0); + } + return null; + } + + @Transactional + public void persist(UserAccount userAccount) { + this.entityManager.persist(userAccount); + } + + @Transactional + public UserAccount merge(UserAccount userAccount) { + UserAccount merged = this.entityManager.merge(userAccount); + this.entityManager.flush(); + return merged; + } +} diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/java/com/springone/myrestaurants/domain/Restaurant.java b/spring-data-neo4j-examples/myrestaurants-original/src/main/java/com/springone/myrestaurants/domain/Restaurant.java new file mode 100644 index 000000000..cbe69a11f --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/java/com/springone/myrestaurants/domain/Restaurant.java @@ -0,0 +1,88 @@ +package com.springone.myrestaurants.domain; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Version; + +@Entity +public class Restaurant { + + private String name; + + private String city; + + private String state; + + private String zipCode; + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getCity() { + return this.city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getState() { + return this.state; + } + + public void setState(String state) { + this.state = state; + } + + public String getZipCode() { + return this.zipCode; + } + + public void setZipCode(String zipCode) { + this.zipCode = zipCode; + } + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + @Column(name = "id") + private Long id; + + @Version + @Column(name = "version") + private Integer version; + + public Long getId() { + return this.id; + } + + public void setId(Long id) { + this.id = id; + } + + public Integer getVersion() { + return this.version; + } + + public void setVersion(Integer version) { + this.version = version; + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("Id: ").append(getId()).append(", "); + sb.append("Version: ").append(getVersion()).append(", "); + sb.append("Name: ").append(getName()).append(", "); + sb.append("City: ").append(getCity()).append(", "); + sb.append("State: ").append(getState()).append(", "); + sb.append("ZipCode: ").append(getZipCode()); + return sb.toString(); + } +} diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/java/com/springone/myrestaurants/domain/UserAccount.java b/spring-data-neo4j-examples/myrestaurants-original/src/main/java/com/springone/myrestaurants/domain/UserAccount.java new file mode 100644 index 000000000..c2e6d6237 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/java/com/springone/myrestaurants/domain/UserAccount.java @@ -0,0 +1,113 @@ +package com.springone.myrestaurants.domain; + +import java.util.Date; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.ManyToMany; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.persistence.Version; + +import org.springframework.format.annotation.DateTimeFormat; + +@Entity +@Table(name = "user_account") +public class UserAccount { + + private String userName; + + private String firstName; + + private String lastName; + + @Temporal(TemporalType.TIMESTAMP) + @DateTimeFormat(style = "S-") + private Date birthDate; + + @ManyToMany(cascade = CascadeType.ALL) + private Set favorites = new java.util.HashSet(); + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + @Column(name = "id") + private Long id; + + @Version + @Column(name = "version") + private Integer version; + + public Long getId() { + return this.id; + } + + public void setId(Long id) { + this.id = id; + } + + public Integer getVersion() { + return this.version; + } + + public void setVersion(Integer version) { + this.version = version; + } + + public String getUserName() { + return this.userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getFirstName() { + return this.firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return this.lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public Date getBirthDate() { + return this.birthDate; + } + + public void setBirthDate(Date birthDate) { + this.birthDate = birthDate; + } + + public Set getFavorites() { + return this.favorites; + } + + public void setFavorites(Set favorites) { + this.favorites = favorites; + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("Id: ").append(getId()).append(", "); + sb.append("Version: ").append(getVersion()).append(", "); + sb.append("UserName: ").append(getUserName()).append(", "); + sb.append("FirstName: ").append(getFirstName()).append(", "); + sb.append("LastName: ").append(getLastName()).append(", "); + sb.append("BirthDate: ").append(getBirthDate()).append(", "); + sb.append("Favorites: ").append(getFavorites() == null ? "null" : getFavorites().size()); + return sb.toString(); + } +} diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/java/com/springone/myrestaurants/web/BaseApplicationController.java b/spring-data-neo4j-examples/myrestaurants-original/src/main/java/com/springone/myrestaurants/web/BaseApplicationController.java new file mode 100644 index 000000000..3bb10f357 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/java/com/springone/myrestaurants/web/BaseApplicationController.java @@ -0,0 +1,53 @@ +package com.springone.myrestaurants.web; + +import org.joda.time.format.DateTimeFormat; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.i18n.LocaleContextHolder; +import org.springframework.core.convert.converter.Converter; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.ModelAttribute; + +import com.springone.myrestaurants.dao.RestaurantDao; +import com.springone.myrestaurants.dao.UserAccountDao; +import com.springone.myrestaurants.domain.Restaurant; +import com.springone.myrestaurants.domain.UserAccount; + +public class BaseApplicationController { + + @Autowired + RestaurantDao restaurantDao; + + @Autowired + UserAccountDao userAccountDao; + + @ModelAttribute("currentUserAccountId") + public String populateCurrentUserName() { + String currentUser = SecurityContextHolder.getContext() + .getAuthentication().getName(); + UserAccount userAccount = userAccountDao.findByName(currentUser); + if (userAccount != null) { + return userAccount.getId().toString(); + } else { + return "USER-ID-NOT-AVAILABLE"; + } + } + + void addDateTimeFormatPatterns(Model model) { + model.addAttribute( + "userAccount_birthdate_date_format", + DateTimeFormat.patternForStyle("S-", + LocaleContextHolder.getLocale())); + } + + protected Converter getRestaurantConverter() { + return new Converter() { + public String convert(Restaurant restaurant) { + return new StringBuilder().append(restaurant.getName()) + .append(" ").append(restaurant.getCity()).append(" ") + .append(restaurant.getState()).toString(); + } + }; + } + +} diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/java/com/springone/myrestaurants/web/RestaurantController.java b/spring-data-neo4j-examples/myrestaurants-original/src/main/java/com/springone/myrestaurants/web/RestaurantController.java new file mode 100644 index 000000000..b536facc4 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/java/com/springone/myrestaurants/web/RestaurantController.java @@ -0,0 +1,68 @@ +package com.springone.myrestaurants.web; + +import org.springframework.core.convert.support.GenericConversionService; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.WebDataBinder; +import org.springframework.web.bind.annotation.InitBinder; +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.RequestParam; + +import com.springone.myrestaurants.domain.Restaurant; +import com.springone.myrestaurants.domain.UserAccount; + +@RequestMapping("/restaurants") +@Controller +public class RestaurantController extends BaseApplicationController { + + + @RequestMapping(value = "/{id}", method = RequestMethod.GET) + public String show(@PathVariable("id") Long id, Model model) { + model.addAttribute("restaurant", restaurantDao.findRestaurant(id)); + model.addAttribute("itemId", id); + return "restaurants/show"; + } + + @RequestMapping(method = RequestMethod.GET) + public String list(@RequestParam(value = "page", required = false) Integer page, + @RequestParam(value = "size", required = false) Integer size, + Model model) { + if (page != null || size != null) { + int sizeNo = size == null ? 10 : size.intValue(); + model.addAttribute("restaurants", restaurantDao.findRestaurantEntries(page == null ? 0 : (page.intValue() - 1) * sizeNo, sizeNo)); + float nrOfPages = (float) restaurantDao.countRestaurants() / sizeNo; + model.addAttribute("maxPages", (int) ((nrOfPages > (int) nrOfPages || nrOfPages == 0.0) ? nrOfPages + 1 : nrOfPages)); + } else { + model.addAttribute("restaurants", restaurantDao.findAllRestaurants()); + } + return "restaurants/list"; + } + + @RequestMapping(value = "/{id}/{userId}", params = "favorite", method = RequestMethod.PUT) + public String addFavoriteRestaurant(@PathVariable("id") Long id, + @PathVariable("userId") Long userId, + Model model) { + Restaurant restaurant = this.restaurantDao.findRestaurant(id); + UserAccount account = this.userAccountDao.findUserAccount(userId); + account.getFavorites().add(restaurant); + this.userAccountDao.persist(account); + addDateTimeFormatPatterns(model); + model.addAttribute("useraccount", account); + model.addAttribute("itemId", id); + return "redirect:/useraccounts/" + account.getId(); + } + + + + + @InitBinder + void registerConverters(WebDataBinder binder) { + if (binder.getConversionService() instanceof GenericConversionService) { + GenericConversionService conversionService = (GenericConversionService) binder.getConversionService(); + conversionService.addConverter(getRestaurantConverter()); + } + } + +} diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/java/com/springone/myrestaurants/web/SignUpController.java b/spring-data-neo4j-examples/myrestaurants-original/src/main/java/com/springone/myrestaurants/web/SignUpController.java new file mode 100644 index 000000000..9875e3200 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/java/com/springone/myrestaurants/web/SignUpController.java @@ -0,0 +1,114 @@ +package com.springone.myrestaurants.web; + +import java.util.Collection; + +import javax.validation.Valid; + +import org.springframework.core.convert.converter.Converter; +import org.springframework.core.convert.support.GenericConversionService; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +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; + +import com.springone.myrestaurants.domain.Restaurant; +import com.springone.myrestaurants.domain.UserAccount; + +@RequestMapping("/useraccounts") +@Controller +public class SignUpController extends BaseApplicationController { + + + @RequestMapping(method = RequestMethod.POST) + public String create(@Valid UserAccount userAccount, BindingResult result, Model model) { + if (result.hasErrors()) { + model.addAttribute("userAccount", userAccount); + addDateTimeFormatPatterns(model); + return "useraccounts/create"; + } + userAccountDao.persist(userAccount); + return "redirect:/useraccounts/" + userAccount.getId(); + } + + @RequestMapping(params = "form", method = RequestMethod.GET) + public String createForm(Model model) { + model.addAttribute("userAccount", new UserAccount()); + addDateTimeFormatPatterns(model); + return "useraccounts/create"; + } + + + @RequestMapping(value = "/{id}", method = RequestMethod.GET) + public String show(@PathVariable("id") Long id, Model model) { + addDateTimeFormatPatterns(model); + model.addAttribute("useraccount", userAccountDao.findUserAccount(id)); + model.addAttribute("itemId", id); + return "useraccounts/show"; + } + + @RequestMapping(method = RequestMethod.PUT) + public String update(@Valid UserAccount userAccount, BindingResult result, Model model) { + if (result.hasErrors()) { + model.addAttribute("userAccount", userAccount); + addDateTimeFormatPatterns(model); + return "useraccounts/update"; + } + userAccountDao.merge(userAccount); + return "redirect:/useraccounts/" + userAccount.getId(); + } + + @RequestMapping(value = "/{id}", params = "form", method = RequestMethod.GET) + public String updateForm(@PathVariable("id") Long id, Model model) { + model.addAttribute("userAccount", userAccountDao.findUserAccount(id)); + addDateTimeFormatPatterns(model); + return "useraccounts/update"; + } + + @RequestMapping(value = "/{username}", params = "form2", method = RequestMethod.GET) + public String updateForm(@PathVariable("username") String userName, Model model) { + UserAccount userAccount = userAccountDao.findByName(userName); + model.addAttribute("userAccount", userAccount); + addDateTimeFormatPatterns(model); + return "useraccounts/update"; + } + + + + @ModelAttribute("restaurants") + public Collection populateRestaurants() { + return restaurantDao.findAllRestaurants(); + } + + + Converter getRestaurantConverterFromString() { + return new Converter() { + public Restaurant convert(String id) { + return restaurantDao.findRestaurant(Long.valueOf(id)); + } + }; + } + + Converter getUserAccountConverter() { + return new Converter() { + public String convert(UserAccount userAccount) { + return new StringBuilder().append(userAccount.getUserName()).append(" ").append(userAccount.getFirstName()).append(" ").append(userAccount.getLastName()).toString(); + } + }; + } + + @InitBinder + void registerConverters(WebDataBinder binder) { + if (binder.getConversionService() instanceof GenericConversionService) { + GenericConversionService conversionService = (GenericConversionService) binder.getConversionService(); + conversionService.addConverter(getRestaurantConverter()); + conversionService.addConverter(getUserAccountConverter()); + conversionService.addConverter(getRestaurantConverterFromString()); + } + } + +} diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/resources/META-INF/persistence.xml b/spring-data-neo4j-examples/myrestaurants-original/src/main/resources/META-INF/persistence.xml new file mode 100644 index 000000000..cc5b976d9 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/resources/META-INF/persistence.xml @@ -0,0 +1,12 @@ + + + + org.hibernate.ejb.HibernatePersistence + + + + + + + + diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/resources/META-INF/spring/applicationContext-security.xml b/spring-data-neo4j-examples/myrestaurants-original/src/main/resources/META-INF/spring/applicationContext-security.xml new file mode 100644 index 000000000..54e54fd11 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/resources/META-INF/spring/applicationContext-security.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/resources/META-INF/spring/applicationContext.xml b/spring-data-neo4j-examples/myrestaurants-original/src/main/resources/META-INF/spring/applicationContext.xml new file mode 100644 index 000000000..7ae1d3d68 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/resources/META-INF/spring/applicationContext.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/resources/META-INF/spring/database.properties b/spring-data-neo4j-examples/myrestaurants-original/src/main/resources/META-INF/spring/database.properties new file mode 100644 index 000000000..b9a17c86b --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/resources/META-INF/spring/database.properties @@ -0,0 +1,4 @@ +database.driverClassName=org.hsqldb.jdbcDriver +database.url=jdbc:hsqldb:hsql://localhost:9001 +database.username=sa +database.password= diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/resources/log4j.properties b/spring-data-neo4j-examples/myrestaurants-original/src/main/resources/log4j.properties new file mode 100644 index 000000000..369a4c7c6 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/resources/log4j.properties @@ -0,0 +1,20 @@ +log4j.rootLogger=error, stdout + +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout + +# Print the date in ISO 8601 format +log4j.appender.stdout.layout.ConversionPattern=%d [%t] %-5p %c - %m%n + +log4j.appender.R=org.apache.log4j.RollingFileAppender +log4j.appender.R.File=application.log + +log4j.appender.R.MaxFileSize=100KB +# Keep one backup file +log4j.appender.R.MaxBackupIndex=1 + +log4j.appender.R.layout=org.apache.log4j.PatternLayout +log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n + +log4j.category.org.springframework.jdbc=INFO + diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/resources/restaurants-sample-data.sql b/spring-data-neo4j-examples/myrestaurants-original/src/main/resources/restaurants-sample-data.sql new file mode 100644 index 000000000..a30dbb9de --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/resources/restaurants-sample-data.sql @@ -0,0 +1,50 @@ +insert into restaurant (name, city, state, zip_code, version) values('Subway', 'Plymouth', 'WI', '53073', 1); +insert into restaurant (name, city, state, zip_code, version) values('Boston Market', 'Gaithersburg', 'MD', '20877', 1); +insert into restaurant (name, city, state, zip_code, version) values('Subway Subs', 'Santa Teresa', 'NM', '88008', 1); +insert into restaurant (name, city, state, zip_code, version) values('Arby''s Roast Beef Restaurant', 'Klamath Falls', 'OR', '97603', 1); +insert into restaurant (name, city, state, zip_code, version) values('Bellefleur Winery & Restaurant', 'Carlsbad', 'CA', '92008', 1); +insert into restaurant (name, city, state, zip_code, version) values('Huddle House', 'Calhoun', 'GA', '30701', 1); +insert into restaurant (name, city, state, zip_code, version) values('John Browne''s Pub & Eatery', 'Indianapolis', 'IN', '46235', 1); +insert into restaurant (name, city, state, zip_code, version) values('Ling''s Express', 'Milwaukee', 'WI', '53217', 1); +insert into restaurant (name, city, state, zip_code, version) values('Chubys''s', 'Odell', 'OR', '97044', 1); +insert into restaurant (name, city, state, zip_code, version) values('Bojangles', 'Columbia', 'SC', '29203', 1); +insert into restaurant (name, city, state, zip_code, version) values('NPC International', 'Memphis', 'TN', '38134', 1); +insert into restaurant (name, city, state, zip_code, version) values('Pancake Cafe', 'Naperville', 'IL', '60540', 1); +insert into restaurant (name, city, state, zip_code, version) values('Hong & Kong Restaurant', 'Chelmsford', 'MA', '01824', 1); +insert into restaurant (name, city, state, zip_code, version) values('The Chicken Cooperative', 'Ketchum', 'OK', '74349', 1); +insert into restaurant (name, city, state, zip_code, version) values('Subway', 'Lonoke', 'AR', '72086', 1); +insert into restaurant (name, city, state, zip_code, version) values('Domino''s Pizza', 'Loveland', 'CO', '80537', 1); +insert into restaurant (name, city, state, zip_code, version) values('Carl''s Jr', 'Peoria', 'IL', '61615', 1); +insert into restaurant (name, city, state, zip_code, version) values('El Toro Bar & Grill', 'Shawnee', 'KS', '66216', 1); +insert into restaurant (name, city, state, zip_code, version) values('Subway Sandwiches & Salads', 'New Orleans', 'LA', '70123', 1); +insert into restaurant (name, city, state, zip_code, version) values('Subway', 'Decatur', 'GA', '30030', 1); +insert into restaurant (name, city, state, zip_code, version) values('Arby''s', 'Indianapolis', 'IN', '46268', 1); +insert into restaurant (name, city, state, zip_code, version) values('China King', 'Cedar Rapids', 'IA', '52404', 1); +insert into restaurant (name, city, state, zip_code, version) values('Subway Sandwiches & Salads', 'Knoxville', 'TN', '37924', 1); +insert into restaurant (name, city, state, zip_code, version) values('Luciano Italian Restaurant', 'Oakton', 'VA', '22124', 1); +insert into restaurant (name, city, state, zip_code, version) values('Fruition', 'Portland', 'OR', '97210', 1); +insert into restaurant (name, city, state, zip_code, version) values('Blough''s Delicatessen', 'Davidsville', 'PA', '15928', 1); +insert into restaurant (name, city, state, zip_code, version) values('Hardee''s of Murfreesboro No 4', 'Murfreesboro', 'TN', '37128', 1); +insert into restaurant (name, city, state, zip_code, version) values('Dairy Queen restaurant ', 'Carter Lake', 'IA', '51510', 1); +insert into restaurant (name, city, state, zip_code, version) values('Imperial Wok Chinese Restaurant', 'Shreveport', 'LA', '71118', 1); +insert into restaurant (name, city, state, zip_code, version) values('Hardee''s', 'Waldorf', 'MD', '20601', 1); +insert into restaurant (name, city, state, zip_code, version) values('Cinnabon', 'Gainesville', 'FL', '32605', 1); +insert into restaurant (name, city, state, zip_code, version) values('Angle Inn Restaurant', 'Rockford', 'IL', '61103', 1); +insert into restaurant (name, city, state, zip_code, version) values('Casey''s Carry Out Pizza', 'Thomson', 'IL', '61285', 1); +insert into restaurant (name, city, state, zip_code, version) values('Sonic Drive In', 'Salt Lake City', 'UT', '84118', 1); +insert into restaurant (name, city, state, zip_code, version) values('Mcdonald''s restaurant ', 'Racine', 'WI', '53406', 1); +insert into restaurant (name, city, state, zip_code, version) values('Huhot Mongolian Grill', 'Omaha', 'NE', '68154', 1); +insert into restaurant (name, city, state, zip_code, version) values('Giovanni''s Pizzeria', 'Las Vegas', 'NV', '89123', 1); +insert into restaurant (name, city, state, zip_code, version) values('Bangkok Royal', 'Waco', 'TX', '76706', 1); +insert into restaurant (name, city, state, zip_code, version) values('Golden Coin Bake Shop & Restaurant', 'Waipahu', 'HI', '96797', 1); +insert into restaurant (name, city, state, zip_code, version) values('Cristaudo''s Grand Avenue', 'Carbondale', 'IL', '62901', 1); +insert into restaurant (name, city, state, zip_code, version) values('O''Charley''s Restaurant', 'Independence', 'MO', '64057', 1); +insert into restaurant (name, city, state, zip_code, version) values('A1 Ocean Cafe', 'San Francisco', 'CA', '94104', 1); +insert into restaurant (name, city, state, zip_code, version) values('Alberto''s Mexican Food', 'Corona', 'CA', '92880', 1); +insert into restaurant (name, city, state, zip_code, version) values('Beach Dog Computer Center', 'Hilo', 'HI', '96720', 1); +insert into restaurant (name, city, state, zip_code, version) values('Burger King', 'Houston', 'TX', '77070', 1); +insert into restaurant (name, city, state, zip_code, version) values('Fox River Brew Pub', 'Oshkosh', 'WI', '54901', 1); +insert into restaurant (name, city, state, zip_code, version) values('Buffas Delicatessen', 'New York', 'NY', '10012', 1); +insert into restaurant (name, city, state, zip_code, version) values('Maria''s Mexican Bistro Inc', 'Brooklyn', 'NY', '11215', 1); +insert into restaurant (name, city, state, zip_code, version) values('Sue''s Restaurant', 'Providence', 'RI', '02903', 1); +insert into restaurant (name, city, state, zip_code, version) values('Dairy Queen Brazier', 'Cameron', 'MO', '64429', 1); \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/resources/schema.sql b/spring-data-neo4j-examples/myrestaurants-original/src/main/resources/schema.sql new file mode 100644 index 000000000..a788dd2c9 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/resources/schema.sql @@ -0,0 +1,8 @@ +CREATE TABLE restaurant ( + id BIGINT IDENTITY PRIMARY KEY, + name VARCHAR(255), + version BIGINT, + zip_code VARCHAR(255), + city VARCHAR(255), + state VARCHAR(255) + ); \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/META-INF/MANIFEST.MF b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/META-INF/MANIFEST.MF new file mode 100644 index 000000000..5e9495128 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Class-Path: + diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/classes/alt.properties b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/classes/alt.properties new file mode 100644 index 000000000..48df87ff7 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/classes/alt.properties @@ -0,0 +1 @@ +styleSheet=resources/styles/alt.css diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/classes/standard.properties b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/classes/standard.properties new file mode 100644 index 000000000..d8dc0164d --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/classes/standard.properties @@ -0,0 +1 @@ +styleSheet=resources/styles/standard.css diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/i18n/application.properties b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/i18n/application.properties new file mode 100644 index 000000000..81ead0928 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/i18n/application.properties @@ -0,0 +1,29 @@ +#Updated at Wed Sep 22 21:53:31 EDT 2010 +#Wed Sep 22 21:53:31 EDT 2010 +label_com_springone_myrestaurants_domain_useraccount_username=User Name +label_com_springone_myrestaurants_domain_useraccount_birthdate=Birth Date +label_com_springone_myrestaurants_domain_useraccount_favorites=Favorites +label_com_springone_myrestaurants_domain_restaurant_city=City +menu_item_restaurant_new_label=Restaurant +menu_item_restaurant_fav_label=Restaurants +label_com_springone_myrestaurants_domain_useraccount_lastname=Last Name +menu_item_useraccount_new_label=User Account +label_com_springone_myrestaurants_domain_restaurant_plural=Restaurants +label_com_springone_myrestaurants_domain_restaurant_id=Id +label_com_springone_myrestaurants_domain_useraccount=User Account +label_com_springone_myrestaurants_domain_restaurant_name=Name +label_com_springone_myrestaurants_domain_restaurant=Restaurant +menu_item_restaurant_list_label=Restaurants +menu_category_restaurant_label=Restaurant +label_com_springone_myrestaurants_domain_useraccount_plural=User Accounts +label_com_springone_myrestaurants_domain_useraccount_version=Version +label_com_springone_myrestaurants_domain_useraccount_firstname=First Name +menu_category_useraccount_label=User Account +label_com_springone_myrestaurants_domain_restaurant_state=State +menu_item_useraccount_list_label=User Accounts +label_com_springone_myrestaurants_domain_restaurant_zipcode=Zip Code +menu_item_useraccount_login_label=User Account +menu_item_useraccount_logout_label=User Account +label_com_springone_myrestaurants_domain_restaurant_version=Version +label_com_springone_myrestaurants_domain_useraccount_id=Id +application_name=MyRestaurants diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/i18n/messages.properties b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/i18n/messages.properties new file mode 100644 index 000000000..154d5aa0a --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/i18n/messages.properties @@ -0,0 +1,94 @@ +#menu +global_menu_login=Log in +global_menu_logout=Log out +global_menu_new=Create a new {0} +global_menu_list=List all {0} +global_menu_find=Find by {0} +global_language_switch=Switch language to {0} +global_language=Language +global_sponsored=Sponsored by SpringSource +global_theme=Theme +global_theme_alt=alt +global_theme_standard=standard +global_generic={0} +user_menu_new=Sign up for a {0} +restaurant_menu_fav=Manage favorite {0} + +#welcome page +welcome_titlepane=Welcome to {0} +welcome_h3=Welcome to {0} +welcome_text=This is a sample application created for SpringOne 2010 to showcase the new and tasty Spring and Neo4J integration features. Enjoy! + +#entity labels +entity_list_all=List all {0} +entity_show=Show {0} +entity_create=Create new {0} +entity_update=Update {0} +entity_favorite=Favorite {0} +entity_delete=Delete {0} +entity_find=Find by {0} +entity_not_found=No {0} found. +entity_not_found_single=No {0} found with this id. +entity_dependency_required=The following dependencies need to be created first: +entity_reference_not_managed=This relationship is managed from the {0} side. + +#button labels +button_home=Home +button_save=Save +button_update=Update +button_find=Find +button_cancel=Cancel +button_proceed=Proceed +button_submit=Submit +button_reset=Reset +button_end=End +button_showmessage=Show Message +button_showstacktrace=Show Stack Trace +button_showcookie=Show Cookie + +#field labels +field_simple_validation=Enter {0} {1} +field_invalid_email=Please enter a valid email +field_invalid_number=Number with \\'-\\' or \\'.\\' allowed +field_invalid_integer=Integer numbers only +field_invalid=Please enter valid {0} +field_required=required + +#list labels +list_first=First Page +list_next=Next Page +list_previous=Previous Page +list_last=Last Page +list_page=Page {0} of {1} +list_size=List results per page: + +#selenium +selenium_menu_test_suite=Test Suite + +#exception +exception_message=Exception Message +exception_stacktrace=Exception Stack Trace +exception_cookie=Cookies +exception_details=Details + +#dataAccessFailure_jspx +error_dataaccessfailure_title=Data access failure +error_dataaccessfailure_problemdescription=Sorry, a problem occurred while accessing the database. + +#resourceNotFound_jspx +error_resourcenotfound_title=Requested Resource Not Found +error_resourcenotfound_problemdescription=Sorry, we did not find the resource you were looking for. + +#uncaughtException_jspx +error_uncaughtexception_title=Internal Error +error_uncaughtexception_problemdescription=Sorry, we encountered an internal error. + +#security +security_login_title=Spring Security Login +security_login_message=Please sign in with your user name and password. +security_login_form_name=Name +security_login_form_name_message=Enter your user name +security_login_form_password=Password +security_login_form_password_message=Enter your password +security_login_unsuccessful=Your login attempt was not successful, try again. Reason: +security_logout=Logout \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/layouts/default.jspx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/layouts/default.jspx new file mode 100644 index 000000000..d68496e5f --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/layouts/default.jspx @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + <spring:message code="welcome_h3" arguments="${app_name}" /> + + + +
+ + +
+ + +
+
+ + diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/layouts/layouts.xml b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/layouts/layouts.xml new file mode 100644 index 000000000..3c9d6d4bb --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/layouts/layouts.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/spring/webmvc-config.xml b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/spring/webmvc-config.xml new file mode 100644 index 000000000..b03864904 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/spring/webmvc-config.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + dataAccessFailure + resourceNotFound + resourceNotFound + resourceNotFound + + + + + + + + + + + + + /WEB-INF/layouts/layouts.xml + + /WEB-INF/views/**/views.xml + + + + diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/create.tagx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/create.tagx new file mode 100644 index 000000000..37e006781 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/create.tagx @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+
+
\ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/dependency.tagx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/dependency.tagx new file mode 100644 index 000000000..86011b91a --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/dependency.tagx @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + +

+ +

+
+
+
+
\ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/fields/checkbox.tagx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/fields/checkbox.tagx new file mode 100644 index 000000000..3e7c0604e --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/fields/checkbox.tagx @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + ${field} + + +
+ + + + + + + + + + +
+
+
+
\ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/fields/column.tagx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/fields/column.tagx new file mode 100644 index 000000000..11e9c56c4 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/fields/column.tagx @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/fields/datetime.tagx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/fields/datetime.tagx new file mode 100644 index 000000000..ec4adbf68 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/fields/datetime.tagx @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${field} + + + + + + + +
+ + + + + + + +
+ +
+
+ + + + + + + + + + + +
+
+
+
\ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/fields/display.tagx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/fields/display.tagx new file mode 100644 index 000000000..4e4f86e43 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/fields/display.tagx @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + + + + + +
+
+
+
+
\ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/fields/editor.tagx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/fields/editor.tagx new file mode 100644 index 000000000..959a5fb41 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/fields/editor.tagx @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${field} + + + +
+ + +
+ + +
+
+
+
\ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/fields/input.tagx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/fields/input.tagx new file mode 100644 index 000000000..de26cefde --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/fields/input.tagx @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${field} + + +
+ + + + + + + +
+ +
+
+ + + + + + + + + + + +
+
+
+
\ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/fields/reference.tagx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/fields/reference.tagx new file mode 100644 index 000000000..89695122a --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/fields/reference.tagx @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + +
+ + + + + + + + ${fn:escapeXml(add_message)} + + + + + ( + + ) + +
+
+ +
+
\ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/fields/select.tagx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/fields/select.tagx new file mode 100644 index 000000000..09122bb0d --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/fields/select.tagx @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${field} + + +
+ + + + + + + + + + + +
+ +
+
+
+ + + + + + + +
+ +
+
+
+
+ + + + + + +
+ + + +
+
+
+ +
+
\ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/fields/simple.tagx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/fields/simple.tagx new file mode 100644 index 000000000..390afa45f --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/fields/simple.tagx @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + +
+
+
+
\ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/fields/table.tagx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/fields/table.tagx new file mode 100644 index 000000000..99c0989a8 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/fields/table.tagx @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + + + + + ${fn:escapeXml(show_label)} + + + + + + + + + ${fn:escapeXml(update_label)} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
\ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/fields/textarea.tagx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/fields/textarea.tagx new file mode 100644 index 000000000..f8f05b67d --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/fields/textarea.tagx @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${field} + + + +
+ + +
+ + +
+
+ +
+
\ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/find.tagx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/find.tagx new file mode 100644 index 000000000..8644d776c --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/find.tagx @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+
+
\ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/list.tagx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/list.tagx new file mode 100644 index 000000000..3202f2bc9 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/list.tagx @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/show.tagx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/show.tagx new file mode 100644 index 000000000..5dfa3784e --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/show.tagx @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/update.tagx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/update.tagx new file mode 100644 index 000000000..1dfdf45eb --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/form/update.tagx @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + +
+
+
+
\ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/menu/category.tagx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/menu/category.tagx new file mode 100644 index 000000000..f6383f513 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/menu/category.tagx @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + +
  • +

    + +

    +
      + +
    +
  • + +
    +
    \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/menu/item.tagx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/menu/item.tagx new file mode 100644 index 000000000..b0c466e65 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/menu/item.tagx @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + +
  • + + + + +
  • + +
    +
    \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/menu/menu.tagx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/menu/menu.tagx new file mode 100644 index 000000000..9c3f2e7c8 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/menu/menu.tagx @@ -0,0 +1,13 @@ + + + + + + + + +
      + +
    +
    +
    \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/util/language.tagx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/util/language.tagx new file mode 100644 index 000000000..aa1cd5adb --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/util/language.tagx @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + ${fn:escapeXml(lang_label)} + + + + diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/util/load-scripts.tagx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/util/load-scripts.tagx new file mode 100644 index 000000000..a89a63292 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/util/load-scripts.tagx @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/util/pagination.tagx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/util/pagination.tagx new file mode 100644 index 000000000..b4d394ce0 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/util/pagination.tagx @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${i} + + + + + + + + + + + + + + + ${first_label} + + + + + + + + + + + ${previous_label} + + + + + + + + + + + + + + ${next_label} + + + + + + + + + + + ${last_label} + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/util/panel.tagx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/util/panel.tagx new file mode 100644 index 000000000..e8a43fc69 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/util/panel.tagx @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + ${id} + + + + ${openPane} + + + + ${title} + + + +
    + + +
    +
    +
    diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/util/placeholder.tagx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/util/placeholder.tagx new file mode 100644 index 000000000..65ee2e4b7 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/util/placeholder.tagx @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/util/theme.tagx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/util/theme.tagx new file mode 100644 index 000000000..fe0c628aa --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/tags/util/theme.tagx @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + ${theme_standard} + + + + + + + + + + + + ${theme_alt} + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/dataAccessFailure.jspx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/dataAccessFailure.jspx new file mode 100644 index 000000000..e815684ea --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/dataAccessFailure.jspx @@ -0,0 +1,29 @@ +
    + + + +

    ${fn:escapeXml(title)}

    +

    + +

    + +

    +

    + +

    + + + + + + + + +
    +
    +
    +

    +
    +
    +
    + diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/footer.jspx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/footer.jspx new file mode 100644 index 000000000..89af49c71 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/footer.jspx @@ -0,0 +1,36 @@ + + diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/header.jspx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/header.jspx new file mode 100644 index 000000000..fea815207 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/header.jspx @@ -0,0 +1,10 @@ + \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/index-template.jspx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/index-template.jspx new file mode 100644 index 000000000..871bc55ca --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/index-template.jspx @@ -0,0 +1,10 @@ +
    + + + + +

    + +

    +
    +
    \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/index.jspx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/index.jspx new file mode 100644 index 000000000..75ce000a4 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/index.jspx @@ -0,0 +1,13 @@ +
    + + + + +

    + +

    +

    + +

    +
    +
    \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/login.jspx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/login.jspx new file mode 100644 index 000000000..df4b9bc4b --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/login.jspx @@ -0,0 +1,59 @@ +
    + + + + +
    +

    + + + . +

    +
    +
    + +

    + +

    +
    + +
    +
    + + + + +
    +
    +
    + + + + +
    +
    +
    + + + + + +
    +
    +
    +
    + diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/menu.jspx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/menu.jspx new file mode 100644 index 000000000..eadb91b36 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/menu.jspx @@ -0,0 +1,36 @@ + + diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/resourceNotFound.jspx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/resourceNotFound.jspx new file mode 100644 index 000000000..fce7f5b03 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/resourceNotFound.jspx @@ -0,0 +1,28 @@ +
    + + + +

    ${fn:escapeXml(title)}

    +

    + +

    + +

    +

    + +

    + + + + + + + + +
    +
    +
    +

    +
    +
    +
    \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/restaurants/create.jspx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/restaurants/create.jspx new file mode 100644 index 000000000..3a5a1da07 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/restaurants/create.jspx @@ -0,0 +1,11 @@ + +
    + + + + + + + + +
    diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/restaurants/list.jspx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/restaurants/list.jspx new file mode 100644 index 000000000..d927c3334 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/restaurants/list.jspx @@ -0,0 +1,12 @@ + +
    + + + + + + + + + +
    diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/restaurants/show.jspx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/restaurants/show.jspx new file mode 100644 index 000000000..8dc605306 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/restaurants/show.jspx @@ -0,0 +1,10 @@ + +
    + + + + + + + +
    diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/restaurants/update.jspx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/restaurants/update.jspx new file mode 100644 index 000000000..2f785b808 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/restaurants/update.jspx @@ -0,0 +1,10 @@ + +
    + + + + + + + +
    diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/restaurants/views.xml b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/restaurants/views.xml new file mode 100644 index 000000000..7467779c7 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/restaurants/views.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/uncaughtException.jspx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/uncaughtException.jspx new file mode 100644 index 000000000..2196d3886 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/uncaughtException.jspx @@ -0,0 +1,28 @@ +
    + + + +

    ${fn:escapeXml(title)}

    +

    + +

    + +

    +

    + +

    + + + + + + + + +
    +
    +
    +

    +
    +
    +
    \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/useraccounts/create.jspx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/useraccounts/create.jspx new file mode 100644 index 000000000..638992ac2 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/useraccounts/create.jspx @@ -0,0 +1,11 @@ + +
    + + + + + + + + +
    diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/useraccounts/list.jspx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/useraccounts/list.jspx new file mode 100644 index 000000000..209518bc3 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/useraccounts/list.jspx @@ -0,0 +1,13 @@ + +
    + + + + + + + + + + +
    diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/useraccounts/show.jspx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/useraccounts/show.jspx new file mode 100644 index 000000000..fe2b3fbf1 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/useraccounts/show.jspx @@ -0,0 +1,11 @@ + +
    + + + + + + + + +
    diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/useraccounts/update.jspx b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/useraccounts/update.jspx new file mode 100644 index 000000000..78a36af99 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/useraccounts/update.jspx @@ -0,0 +1,11 @@ + +
    + + + + + + + + +
    diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/useraccounts/views.xml b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/useraccounts/views.xml new file mode 100644 index 000000000..6e5f648c8 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/useraccounts/views.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/views.xml b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/views.xml new file mode 100644 index 000000000..e92932a94 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/views/views.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/web.xml b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 000000000..5fe5a1054 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,110 @@ + + + + + myrestaurants-original + + Roo generated myrestaurants application + + + + + defaultHtmlEscape + true + + + + contextConfigLocation + classpath*:META-INF/spring/applicationContext*.xml + + + + Spring OpenEntityManagerInViewFilter + org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter + + + + + + + + springSecurityFilterChain + org.springframework.web.filter.DelegatingFilterProxy + + + CharacterEncodingFilter + org.springframework.web.filter.CharacterEncodingFilter + + encoding + UTF-8 + + + forceEncoding + true + + + + + HttpMethodFilter + org.springframework.web.filter.HiddenHttpMethodFilter + + + Spring OpenEntityManagerInViewFilter + /* + + + + + + springSecurityFilterChain + /* + + + CharacterEncodingFilter + /* + + + + HttpMethodFilter + /* + + + + + org.springframework.web.context.ContextLoaderListener + + + + + myrestaurants + org.springframework.web.servlet.DispatcherServlet + + contextConfigLocation + /WEB-INF/spring/webmvc-config.xml + + 1 + + + + myrestaurants + / + + + + 10 + + + + / + + + + java.lang.Exception + /uncaughtException + + + + 404 + /resourceNotFound + + diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/add.png b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/add.png new file mode 100644 index 000000000..d5bfa0719 Binary files /dev/null and b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/add.png differ diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/banner-graphic.png b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/banner-graphic.png new file mode 100644 index 000000000..0019d000a Binary files /dev/null and b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/banner-graphic.png differ diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/create.png b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/create.png new file mode 100644 index 000000000..d5bfa0719 Binary files /dev/null and b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/create.png differ diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/delete.png b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/delete.png new file mode 100644 index 000000000..1514d51a3 Binary files /dev/null and b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/delete.png differ diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/en.png b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/en.png new file mode 100644 index 000000000..ff701e19f Binary files /dev/null and b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/en.png differ diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/fav-del.png b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/fav-del.png new file mode 100644 index 000000000..faca5ba94 Binary files /dev/null and b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/fav-del.png differ diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/fav-new.png b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/fav-new.png new file mode 100644 index 000000000..e87e2b101 Binary files /dev/null and b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/fav-new.png differ diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/favicon.ico b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/favicon.ico new file mode 100644 index 000000000..c2f2b6ccd Binary files /dev/null and b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/favicon.ico differ diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/list.png b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/list.png new file mode 100644 index 000000000..acc30b853 Binary files /dev/null and b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/list.png differ diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/resultset_first.png b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/resultset_first.png new file mode 100644 index 000000000..b03eaf8b5 Binary files /dev/null and b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/resultset_first.png differ diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/resultset_last.png b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/resultset_last.png new file mode 100644 index 000000000..8ec894784 Binary files /dev/null and b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/resultset_last.png differ diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/resultset_next.png b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/resultset_next.png new file mode 100644 index 000000000..e252606d3 Binary files /dev/null and b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/resultset_next.png differ diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/resultset_previous.png b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/resultset_previous.png new file mode 100644 index 000000000..18f9cc109 Binary files /dev/null and b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/resultset_previous.png differ diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/show.png b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/show.png new file mode 100644 index 000000000..2f193889f Binary files /dev/null and b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/show.png differ diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/spring-logo.png b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/spring-logo.png new file mode 100644 index 000000000..1088a02cd Binary files /dev/null and b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/spring-logo.png differ diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/springsource-logo.png b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/springsource-logo.png new file mode 100644 index 000000000..e170f8abf Binary files /dev/null and b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/springsource-logo.png differ diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/update.png b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/update.png new file mode 100644 index 000000000..046811ed7 Binary files /dev/null and b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/images/update.png differ diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/styles/alt.css b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/styles/alt.css new file mode 100644 index 000000000..c562d00ac --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/styles/alt.css @@ -0,0 +1,362 @@ +/* main elements */ + +body,div,td { + font-family: Arial, Helvetica, sans-serif; + font-size: 12px; + color: #666; +} + +body { + background-color: #fff; + text-align: center; +} + +#header { + margin-bottom: 1em; +} + +#wrapper { + width:800px; + min-width: 800px; + max-width: 800px; + margin-right: auto; + margin-left: auto; + + /* fix max-width incompatibility in IE6 */ + width:expression(document.body.clientWidth > 800? "800px": "auto" ); + + overflow:hidden; + display:block; +} + +/* header and footer elements */ + +#main { + overflow:hidden; + display:box; +} + +#menu { + background: #eee; + position:relative; + float:right; + left:0px; + width:220px; + margin-left:15px; +} + +#menu ul{ + list-style: none; + margin: 0; + padding: 0; +} + +#menu ul li{ + padding: 0px; +} + + +#menu a, #menu h2 { + display: block; + margin: 0; + padding: 2px 6px; + color:#FFFFFF; +} + +#menu h2 { + color: #fff; + background: #F71220; + text-transform: uppercase; + font-weight:bold; + font-size: 12px; +} + +#menu a { + color: #666666; + background: #efefef; + text-decoration: none; + padding: 2px 12px; +} + +#menu a:hover { + color: #F71220; + background: #fff; +} + +#footer { + background:#fff; + border:none; + margin-top:15px; + border-top:1px solid #999999; +} + +#footer .new { + float:left; +} + +#footer a:link {color: #7db223;} + +.quicklinks { + clear:both; + padding-bottom: 15px +} +.quicklinks span { + float: right; +} + +label { + width:100px; + float:left; + margin-left: 5px; + margin-top: 0px; +} + +input { + height:20px; +} + +input, textarea, select { + border:1px solid #B3B3B3; +} + +input.image { + border: none; + height: auto; +} + +submit { + height:25px; +} + +div { + text-align: left; +} + +div .box { + display:block; + margin-left:105px; +} + +/* menu elements*/ + +a.menu, a.menu:link, a.menu:visited {display:block; width:150px; height:25px;} + +/* text styles */ + +h1,h2,h3 { + font-family: Helvetica, sans-serif; + color: #7db223; +} + +h1 { + font-size: 20px; + line-height: 26px; +} + +h2 { + font-size: 18px; + line-height: 20px; +} + +h3 { + font-size: 15px; + line-height: 21px; + color:#555; +} + +h4 { + font-size: 14px; + line-height: 20px; +} + +.errors { + color: red; + font-weight: bold; + display: block; + margin-left: 105px; +} + +a { + text-decoration: underline; + font-size: 12px; +} + +a img { + border: 0 none; + vertical-align: middle; +} + +tr:nth-child(odd) { + background-color: #FFFFFF; +} + +tr:nth-child(even) { + background-color: #EFEFEF; +} + +a:link { + color: #7db223; +} + +a:hover { + color: #456314; +} + +a:active { + color: #7db223; +} + +a:visited { + color: #7db223; +} + +li { + padding-top: 5px; + text-align: left; +} + +ul li { + margin:0 0 0.25em 0; + padding:0; +} +/* table elements */ + +table { + background: #EEEEEE; + margin: 2px 0 0 0; + border: 1px solid #BBBBBB; + border-collapse: collapse; + width: 100% +} + +table table { + margin: -5px 0; + border: 0px solid #e0e7d3; + width: 100%; +} + +table td,table th { + padding: 2px; + border: 1px solid #CCCCCC; +} + +table td form { + text-align:center; + vertical-align: middle; + margin: 0px; +} + +table th { + font-size: 0.9em; + text-align: left; + font-weight: bold; + color: #FFF; + background: #999; +} + +table thead { + font-weight: bold; + font-style: italic; + background-color: #BBBBBB; +} + +table a:link {color: #303030;} + +caption { + caption-side: top; + width: auto; + text-align: left; + font-size: 12px; + color: #848f73; + padding-bottom: 4px; +} + +fieldset { + background: #e0e7d3; + padding: 8px; + padding-bottom: 22px; + border: none; + width: 560px; +} + +fieldset label { + width: 70px; + float: left; + margin-top: 1.7em; + margin-left: 20px; +} + +fieldset textfield { + margin: 3px; + height: 20px; + background: #e0e7d3; +} + +fieldset textarea { + margin: 3px; + height: 165px; + background: #e0e7d3; +} + +fieldset input { + margin: 3px; + height: 20px; + background: #e0e7d3; +} + +fieldset table { + width: 100%; +} + +fieldset th { + padding-left: 25px; +} + +.table-buttons { + background-color:#fff; + border:none; +} + +.table-buttons td { + border:none; +} + +.submit input { + border: 1px solid #BBBBBB; + color:#777777; + padding:2px 7px; + font-size:11px; + text-transform:uppercase; + font-weight:bold; + height:24px; +} + +.updated { + background:#ecf1e5; + font-size:11px; + margin-left:2px; + border:4px solid #ecf1e5; +} + +.updated td { + padding:2px 8px; + font-size:11px; + color:#888888; +} + +.dijitTextArea{ + min-height:5.5em !important; + max-height:22em !important; + overflow-y: auto !important; + max-width: 175px; +} + +.RichTextEditable{ + min-height:18em !important; + max-height:18em !important; +} + +.flag { + height: 11px; + width: 16px; +} \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/styles/standard.css b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/styles/standard.css new file mode 100644 index 000000000..d1a65be31 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-original/src/main/webapp/styles/standard.css @@ -0,0 +1,366 @@ +/* main elements */ + +body,div,td { + font-family: Arial, Helvetica, sans-serif; + font-size: 12px; + color: #666; +} + +body { + background-color: #fff; + text-align: center; +} + +#header { + margin-bottom: 1em; +} + +#wrapper { + width:800px; + min-width: 800px; + max-width: 800px; + margin-right: auto; + margin-left: auto; + + /* fix max-width incompatibility in IE6 */ + width:expression(document.body.clientWidth > 800? "800px": "auto" ); + + overflow:hidden; + display:block; +} + +/* header and footer elements */ + +#main { + overflow:hidden; + display:box; +} + +#menu { + background: #eee; + position:relative; + float:left; + left:0px; + width:220px; + margin-right:15px; +} + +#menu ul{ + list-style: none; + margin: 0; + padding: 0; +} + +#menu ul li{ + padding: 0px; +} + + +#menu a, #menu h2 { + display: block; + margin: 0; + padding: 2px 6px; + color:#FFFFFF; +} + +#menu h2 { + color: #fff; + background: #492FFC; + text-transform: uppercase; + font-weight:bold; + font-size: 12px; +} + +#menu a { + color: #666666; + background: #efefef; + text-decoration: none; + padding: 2px 12px; +} + +#menu a:hover { + color: #492FFC; + background: #fff; +} + +#footer { + background:#fff; + border:none; + margin-top:15px; + border-top:1px solid #999999; +} + +#footer .new { + float:left; +} + +#footer a:link {color: #7db223;} + +.quicklinks { + clear:both; + padding-bottom: 15px +} +.quicklinks span { + float: right; +} + +table.navigation { + border: 0px; +} + +label { + width:100px; + float:left; + margin-left: 5px; + margin-top: 0px; +} + +input { + height:20px; +} + +input, textarea, select { + border:1px solid #B3B3B3; +} + +input.image { + border: none; + height: auto; +} + +submit { + height:25px; +} + +div { + text-align: left; +} + +div .box { + display:block; + margin-left:105px; +} + +/* menu elements*/ + +a.menu, a.menu:link, a.menu:visited {display:block; width:150px; height:25px;} + +/* text styles */ + +h1,h2,h3 { + font-family: Helvetica, sans-serif; + color: #7db223; +} + +h1 { + font-size: 20px; + line-height: 26px; +} + +h2 { + font-size: 18px; + line-height: 20px; +} + +h3 { + font-size: 15px; + line-height: 21px; + color:#555; +} + +h4 { + font-size: 14px; + line-height: 20px; +} + +.errors { + color: red; + font-weight: bold; + display: block; + margin-left: 105px; +} + +a { + text-decoration: underline; + font-size: 12px; +} + +a img { + border: 0 none; + vertical-align: middle; +} + +tr:nth-child(odd) { + background-color: #FFFFFF; +} + +tr:nth-child(even) { + background-color: #EFEFEF; +} + +a:link { + color: #7db223; +} + +a:hover { + color: #456314; +} + +a:active { + color: #7db223; +} + +a:visited { + color: #7db223; +} + +li { + padding-top: 5px; + text-align: left; +} + +ul li { + margin:0 0 0.25em 0; + padding:0; +} +/* table elements */ + +table { + background: #EEEEEE; + margin: 2px 0 0 0; + border: 1px solid #BBBBBB; + border-collapse: collapse; + width: 100% +} + +table table { + margin: -5px 0; + border: 0px solid #e0e7d3; + width: 100%; +} + +table td,table th { + padding: 2px; + border: 1px solid #CCCCCC; +} + +table td form { + text-align:center; + vertical-align: middle; + margin: 0px; +} + +table th { + font-size: 0.9em; + text-align: left; + font-weight: bold; + color: #FFF; + background: #999; +} + +table thead { + font-weight: bold; + font-style: italic; + background-color: #BBBBBB; +} + +table a:link {color: #303030;} + +caption { + caption-side: top; + width: auto; + text-align: left; + font-size: 12px; + color: #848f73; + padding-bottom: 4px; +} + +fieldset { + background: #e0e7d3; + padding: 8px; + padding-bottom: 22px; + border: none; + width: 560px; +} + +fieldset label { + width: 70px; + float: left; + margin-top: 1.7em; + margin-left: 20px; +} + +fieldset textfield { + margin: 3px; + height: 20px; + background: #e0e7d3; +} + +fieldset textarea { + margin: 3px; + height: 165px; + background: #e0e7d3; +} + +fieldset input { + margin: 3px; + height: 20px; + background: #e0e7d3; +} + +fieldset table { + width: 100%; +} + +fieldset th { + padding-left: 25px; +} + +.table-buttons { + background-color:#fff; + border:none; +} + +.table-buttons td { + border:none; +} + +.submit input { + border: 1px solid #BBBBBB; + color:#777777; + padding:2px 7px; + font-size:11px; + text-transform:uppercase; + font-weight:bold; + height:24px; +} + +.updated { + background:#ecf1e5; + font-size:11px; + margin-left:2px; + border:4px solid #ecf1e5; +} + +.updated td { + padding:2px 8px; + font-size:11px; + color:#888888; +} + +.dijitTextArea{ + min-height:5.5em !important; + max-height:22em !important; + overflow-y: auto !important; + max-width: 175px; +} + +.RichTextEditable{ + min-height:18em !important; + max-height:18em !important; +} + +.flag { + height: 11px; + width: 16px; +} \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-social/.classpath b/spring-data-neo4j-examples/myrestaurants-social/.classpath new file mode 100644 index 000000000..8ca155bb0 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/.classpath @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/spring-data-neo4j-examples/myrestaurants-social/.gitignore b/spring-data-neo4j-examples/myrestaurants-social/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/spring-data-neo4j-examples/myrestaurants-social/.project b/spring-data-neo4j-examples/myrestaurants-social/.project new file mode 100644 index 000000000..376234672 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/.project @@ -0,0 +1,58 @@ + + + myrestaurants-social + + + + + + org.eclipse.wst.jsdt.core.javascriptValidator + + + + + org.eclipse.ajdt.core.ajbuilder + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.eclipse.wst.validation.validationbuilder + + + + + org.eclipse.ajdt.core.ajbuilder + + + aspectPath + org.springframework.aspects + + + + + org.springframework.ide.eclipse.core.springbuilder + + + + + org.maven.ide.eclipse.maven2Builder + + + + + + org.maven.ide.eclipse.maven2Nature + org.eclipse.wst.common.project.facet.core.nature + org.eclipse.ajdt.ui.ajnature + org.eclipse.jdt.core.javanature + org.eclipse.wst.common.modulecore.ModuleCoreNature + org.eclipse.jem.workbench.JavaEMFNature + org.springframework.ide.eclipse.core.springnature + org.eclipse.wst.jsdt.core.jsNature + + diff --git a/spring-data-neo4j-examples/myrestaurants-social/.settings/.jsdtscope b/spring-data-neo4j-examples/myrestaurants-social/.settings/.jsdtscope new file mode 100644 index 000000000..b13d30357 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/.settings/.jsdtscope @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/spring-data-neo4j-examples/myrestaurants-social/.settings/org.eclipse.jdt.core.prefs b/spring-data-neo4j-examples/myrestaurants-social/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..e045805a8 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,6 @@ +#Tue Sep 28 12:45:37 EDT 2010 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/spring-data-neo4j-examples/myrestaurants-social/.settings/org.eclipse.jst.jsp.core.prefs b/spring-data-neo4j-examples/myrestaurants-social/.settings/org.eclipse.jst.jsp.core.prefs new file mode 100644 index 000000000..91726735a --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/.settings/org.eclipse.jst.jsp.core.prefs @@ -0,0 +1,30 @@ +#Mon Oct 04 16:27:22 EDT 2010 +eclipse.preferences.version=1 +validateFragments=false +validation.actions-missing-required-attribute=1 +validation.actions-non-empty-inline-tag=2 +validation.actions-unexpected-rtexprvalue=2 +validation.actions-unknown-attribute=2 +validation.directive-include-fragment-file-not-found=-1 +validation.directive-include-fragment-file-not-specified=-1 +validation.directive-taglib-duplicate-prefixes-different-uris=-1 +validation.directive-taglib-duplicate-prefixes-same-uris=-1 +validation.directive-taglib-missing-prefix=-1 +validation.directive-taglib-missing-uri-or-tagdir=-1 +validation.directive-taglib-unresolvable-uri-or-tagdir=-1 +validation.el-general-syntax=1 +validation.el-lexical-failure=-1 +validation.java-=-1 +validation.java-local-variable-is-never-used=-1 +validation.java-null-local-variable-reference=-1 +validation.java-potential-null-local-variable-reference=-1 +validation.java-unused-import=-1 +validation.translation-tag-class-not-found=2 +validation.translation-tei-class-not-found=2 +validation.translation-tei-class-not-instantiated=2 +validation.translation-tei-class-runtime-exception=2 +validation.translation-tei-message=1 +validation.translation-usebean-ambiguous-type-info=2 +validation.translation-usebean-invalid-id=1 +validation.translation-usebean-missing-type-info=1 +validation.use-project-settings=true diff --git a/spring-data-neo4j-examples/myrestaurants-social/.settings/org.eclipse.wst.common.component b/spring-data-neo4j-examples/myrestaurants-social/.settings/org.eclipse.wst.common.component new file mode 100644 index 000000000..daa748eb5 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/.settings/org.eclipse.wst.common.component @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/spring-data-neo4j-examples/myrestaurants-social/.settings/org.eclipse.wst.common.project.facet.core.xml b/spring-data-neo4j-examples/myrestaurants-social/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..708f4a79d --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/spring-data-neo4j-examples/myrestaurants-social/.settings/org.eclipse.wst.jsdt.ui.superType.container b/spring-data-neo4j-examples/myrestaurants-social/.settings/org.eclipse.wst.jsdt.ui.superType.container new file mode 100644 index 000000000..3bd5d0a48 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/.settings/org.eclipse.wst.jsdt.ui.superType.container @@ -0,0 +1 @@ +org.eclipse.wst.jsdt.launching.baseBrowserLibrary \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-social/.settings/org.eclipse.wst.jsdt.ui.superType.name b/spring-data-neo4j-examples/myrestaurants-social/.settings/org.eclipse.wst.jsdt.ui.superType.name new file mode 100644 index 000000000..05bd71b6e --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/.settings/org.eclipse.wst.jsdt.ui.superType.name @@ -0,0 +1 @@ +Window \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-social/.settings/org.eclipse.wst.validation.prefs b/spring-data-neo4j-examples/myrestaurants-social/.settings/org.eclipse.wst.validation.prefs new file mode 100644 index 000000000..e13c1a099 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/.settings/org.eclipse.wst.validation.prefs @@ -0,0 +1,10 @@ +#Mon Oct 04 16:34:14 EDT 2010 +DELEGATES_PREFERENCE=delegateValidatorList +USER_BUILD_PREFERENCE=enabledBuildValidatorListorg.eclipse.jst.j2ee.internal.web.validation.UIWarValidator;org.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyValidator; +USER_MANUAL_PREFERENCE=enabledManualValidatorListorg.eclipse.jst.j2ee.internal.web.validation.UIWarValidator;org.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyValidator; +USER_PREFERENCE=overrideGlobalPreferencestruedisableAllValidationfalseversion1.2.200.v201005271900 +eclipse.preferences.version=1 +override=true +suspend=false +vals/org.eclipse.jst.jsp.core.JSPContentValidator/global=FF01 +vf.version=3 diff --git a/spring-data-neo4j-examples/myrestaurants-social/.settings/org.eclipse.wst.ws.service.policy.prefs b/spring-data-neo4j-examples/myrestaurants-social/.settings/org.eclipse.wst.ws.service.policy.prefs new file mode 100644 index 000000000..4332f1638 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/.settings/org.eclipse.wst.ws.service.policy.prefs @@ -0,0 +1,3 @@ +#Wed Sep 29 14:35:52 EDT 2010 +eclipse.preferences.version=1 +org.eclipse.wst.ws.service.policy.projectEnabled=false diff --git a/spring-data-neo4j-examples/myrestaurants-social/.settings/org.maven.ide.eclipse.prefs b/spring-data-neo4j-examples/myrestaurants-social/.settings/org.maven.ide.eclipse.prefs new file mode 100644 index 000000000..7ec30560c --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/.settings/org.maven.ide.eclipse.prefs @@ -0,0 +1,9 @@ +#Tue Oct 05 19:39:51 EDT 2010 +activeProfiles= +eclipse.preferences.version=1 +fullBuildGoals=process-test-resources +includeModules=false +resolveWorkspaceProjects=true +resourceFilterGoals=process-resources resources\:testResources +skipCompilerPlugin=true +version=1 diff --git a/spring-data-neo4j-examples/myrestaurants-social/pom.xml b/spring-data-neo4j-examples/myrestaurants-social/pom.xml new file mode 100644 index 000000000..3d2eb3bac --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/pom.xml @@ -0,0 +1,534 @@ + + + 4.0.0 + com.springone.myrestaurants + myrestaurants-social + war + 2.0.0.BUILD-SNAPSHOT + myrestaurants-social + + 3.0.5.RELEASE + 2.0.0.BUILD-SNAPSHOT + 1.6.12.M1 + 1.6.1 + UTF-8 + 3.0.2.RELEASE + + + + spring-maven-release + Spring Maven Release Repository + http://maven.springframework.org/release + + + spring-maven-milestone + Spring Maven Milestone Repository + http://maven.springframework.org/milestone + + + spring-maven-snapshot + + true + + Springframework Maven SNAPSHOT Repository + http://maven.springframework.org/snapshot + + + JBoss Repo + https://repository.jboss.org/nexus/content/repositories/releases + JBoss Repo + + + + + spring-maven-release + Spring Maven Release Repository + http://maven.springframework.org/release + + + spring-maven-milestone + Spring Maven Milestone Repository + http://maven.springframework.org/milestone + + + + + + junit + junit + 4.8.1 + test + + + log4j + log4j + 1.2.16 + + + org.slf4j + slf4j-api + ${slf4j.version} + + + org.slf4j + jcl-over-slf4j + ${slf4j.version} + + + org.slf4j + slf4j-log4j12 + ${slf4j.version} + + + org.aspectj + aspectjrt + ${aspectj.version} + + + javax.servlet + servlet-api + 2.5 + provided + + + net.sf.flexjson + flexjson + 2.0 + + + + org.springframework + spring-core + ${spring.version} + + + commons-logging + commons-logging + + + + + org.springframework + spring-test + ${spring.version} + test + + + commons-logging + commons-logging + + + + + org.springframework + spring-context + ${spring.version} + + + org.springframework + spring-aop + ${spring.version} + + + org.springframework + spring-aspects + ${spring.version} + + + org.springframework + spring-tx + ${spring.version} + + + org.hibernate + hibernate-core + 3.5.5-Final + + + org.hibernate + hibernate-entitymanager + 3.5.5-Final + + + cglib + cglib + + + dom4j + dom4j + + + + + org.hibernate.javax.persistence + hibernate-jpa-2.0-api + 1.0.0.Final + + + org.hibernate + hibernate-validator + 4.1.0.Final + + + javax.xml.bind + jaxb-api + + + com.sun.xml.bind + jaxb-impl + + + + + javax.validation + validation-api + 1.0.0.GA + + + cglib + cglib-nodep + 2.2 + + + javax.transaction + jta + 1.1 + + + org.springframework + spring-jdbc + ${spring.version} + + + org.springframework + spring-orm + ${spring.version} + + + commons-pool + commons-pool + 1.5.4 + + + commons-logging + commons-logging + + + + + commons-dbcp + commons-dbcp + 1.3 + + + commons-logging + commons-logging + + + commons-pool + commons-pool + + + xerces + xerces + + + xerces + xercesImpl + + + xml-apis + xml-apis + + + + + org.apache.tiles + tiles-core + 2.2.1 + + + commons-logging + commons-logging + + + + + org.apache.tiles + tiles-jsp + 2.2.1 + + + org.springframework + spring-web + ${spring.version} + + + commons-logging + commons-logging + + + + + org.springframework + spring-webmvc + ${spring.version} + + + commons-logging + commons-logging + + + + + org.springframework.webflow + spring-js + 2.1.1.RELEASE + + + org.springframework + spring-beans + + + org.springframework + spring-context + + + org.springframework + spring-core + + + org.springframework + spring-context-support + + + commons-logging + commons-logging + + + + + commons-digester + commons-digester + 2.0 + + + commons-logging + commons-logging + + + + + commons-fileupload + commons-fileupload + 1.2.1 + + + commons-logging + commons-logging + + + + + javax.servlet + jstl + 1.2 + + + javax.el + el-api + 1.0 + provided + + + joda-time + joda-time + 1.6 + + + org.springframework.security + spring-security-core + ${spring-security.version} + + + commons-logging + commons-logging + + + + + org.springframework.security + spring-security-config + ${spring-security.version} + + + commons-logging + commons-logging + + + + + org.springframework.security + spring-security-web + ${spring-security.version} + + + org.springframework.security + spring-security-taglibs + ${spring-security.version} + + + org.hsqldb + hsqldb + 2.0.0 + + + org.springframework.data + spring-data-neo4j + ${spring-data-graph.version} + + + + + + org.apache.maven.plugins + maven-war-plugin + 2.1-beta-1 + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.1 + + 1.6 + 1.6 + + + + org.codehaus.mojo + aspectj-maven-plugin + 1.0 + + + + org.aspectj + aspectjrt + ${aspectj.version} + + + org.aspectj + aspectjtools + ${aspectj.version} + + + + + + compile + test-compile + + + + + true + + + org.springframework + spring-aspects + + + org.springframework.data + spring-data-neo4j + + + 1.6 + 1.6 + + + + org.apache.maven.plugins + maven-resources-plugin + 2.4.2 + + UTF-8 + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.5 + + always + + + + org.apache.maven.plugins + maven-assembly-plugin + 2.2-beta-5 + + + jar-with-dependencies + + + + + org.apache.maven.plugins + maven-deploy-plugin + 2.5 + + + + org.apache.maven.plugins + maven-eclipse-plugin + 2.7 + + true + false + 2.0 + + + org.eclipse.ajdt.core.ajbuilder + + org.springframework.aspects + + + + org.springframework.ide.eclipse.core.springbuilder + + + + org.eclipse.ajdt.ui.ajnature + org.springframework.ide.eclipse.core.springnature + + + + + org.apache.maven.plugins + maven-idea-plugin + 2.2 + + true + true + + + + org.codehaus.mojo + tomcat-maven-plugin + 1.0 + + + org.mortbay.jetty + jetty-maven-plugin + 7.1.2.v20100523 + + + /${project.name} + + + + + + diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/data/RestaurantRepository.java b/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/data/RestaurantRepository.java new file mode 100644 index 000000000..b7be3c10a --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/data/RestaurantRepository.java @@ -0,0 +1,46 @@ +package com.springone.myrestaurants.data; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; + +import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Transactional; + +import com.springone.myrestaurants.domain.Restaurant; + +@Repository +public class RestaurantRepository { + + @PersistenceContext + private EntityManager entityManager; + + @Transactional + public Restaurant findRestaurant(Long id) { + if (id == null) return null; + final Restaurant rest = entityManager.find(Restaurant.class, id); + if (rest != null) { + rest.persist(); + } + return rest; + } + + @SuppressWarnings("unchecked") + @Transactional(readOnly=true) + public List findAllRestaurants() { + return entityManager.createQuery("select o from Restaurant o").getResultList(); + } + + @SuppressWarnings("unchecked") + @Transactional(readOnly=true) + public List findRestaurantEntries(int firstResult, int maxResults) { + return entityManager.createQuery("select o from Restaurant o").setFirstResult(firstResult).setMaxResults(maxResults).getResultList(); + } + + @Transactional + public long countRestaurants() { + return ((Number) entityManager.createQuery("select count(o) from Restaurant o").getSingleResult()).longValue(); + } + +} diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/data/UserAccountRepository.java b/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/data/UserAccountRepository.java new file mode 100644 index 000000000..c3f097e1a --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/data/UserAccountRepository.java @@ -0,0 +1,79 @@ +package com.springone.myrestaurants.data; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.persistence.Query; + +import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Transactional; + +import com.springone.myrestaurants.domain.UserAccount; + +@Repository +public class UserAccountRepository { + + @PersistenceContext + private EntityManager entityManager; + + @Transactional + public UserAccount findUserAccount(Long id) { + if (id == null) return null; + final UserAccount userAccount = entityManager.find(UserAccount.class, id); + if (userAccount != null) { + userAccount.persist(); + } + return userAccount; + } + @Transactional + public UserAccount findByName(String name) { + if (name == null) return null; + Query q = entityManager.createQuery("SELECT u FROM UserAccount u WHERE u.userName = :username"); + q.setParameter("username", name); + + java.util.List resultList = q.getResultList(); + if (resultList.size() > 0) + { + final UserAccount userAccount = (UserAccount) resultList.get(0); + if (userAccount != null) { + userAccount.persist(); + } + return userAccount; + } + return null; + } + + @SuppressWarnings("unchecked") + @Transactional(readOnly=true) + public List findAllUserAccounts() { + return entityManager.createQuery("select o from UserAccount o").getResultList(); + } + + @SuppressWarnings("unchecked") + @Transactional(readOnly=true) + public List findUserAccountEntries(int firstResult, int maxResults) { + return entityManager.createQuery("select o from UserAccount o").setFirstResult(firstResult).setMaxResults(maxResults).getResultList(); + } + + + @Transactional + public long countUserAccounts() { + return ((Number) entityManager.createQuery("select count(o) from UserAccount o").getSingleResult()).longValue(); + } + + @Transactional + public void persist(UserAccount userAccount) { + this.entityManager.persist(userAccount); + this.entityManager.flush(); + userAccount.persist(); + } + + @Transactional + public UserAccount merge(UserAccount userAccount) { + userAccount.persist(); + UserAccount merged = this.entityManager.merge(userAccount); + this.entityManager.flush(); + return merged; + } +} diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/domain/RatedRestaurant.java b/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/domain/RatedRestaurant.java new file mode 100644 index 000000000..1efd8c14b --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/domain/RatedRestaurant.java @@ -0,0 +1,30 @@ +package com.springone.myrestaurants.domain; + +import java.util.ArrayList; +import java.util.Collection; + +/** + * @author Michael Hunger + * @since 02.10.2010 + */ +public class RatedRestaurant { + private final Restaurant restaurant; + private final Collection recommendations = new ArrayList(); + + public RatedRestaurant(final Restaurant restaurant) { + this.restaurant = restaurant; + } + + public void add(final Recommendation recommendation) { + recommendations.add(recommendation); + } + + public Collection getRecommendations() { + return recommendations; + } + + public Restaurant getRestaurant() { + return restaurant; + } +} + \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/domain/Recommendation.java b/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/domain/Recommendation.java new file mode 100644 index 000000000..cf8f5f2c2 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/domain/Recommendation.java @@ -0,0 +1,46 @@ +package com.springone.myrestaurants.domain; + +import org.springframework.data.neo4j.annotation.EndNode; +import org.springframework.data.neo4j.annotation.RelationshipEntity; +import org.springframework.data.neo4j.annotation.StartNode; + +@RelationshipEntity +public class Recommendation { + @StartNode + private UserAccount user; + @EndNode + private Restaurant restaurant; + + private int stars; + private String comment; + + + public Recommendation() { + } + + public void rate(int stars, String comment) { + this.stars = stars; + this.comment = comment; + } + + public int getStars() { + return stars; + } + + public String getComment() { + return comment; + } + + public UserAccount getUser() { + return user; + } + + public Restaurant getRestaurant() { + return restaurant; + } + + + + + +} diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/domain/Restaurant.java b/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/domain/Restaurant.java new file mode 100644 index 000000000..9a2001d91 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/domain/Restaurant.java @@ -0,0 +1,91 @@ +package com.springone.myrestaurants.domain; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Version; + +import org.springframework.data.neo4j.annotation.NodeEntity; + +@Entity +@NodeEntity(partial = true) +public class Restaurant { + + private String name; + + private String city; + + private String state; + + private String zipCode; + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getCity() { + return this.city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getState() { + return this.state; + } + + public void setState(String state) { + this.state = state; + } + + public String getZipCode() { + return this.zipCode; + } + + public void setZipCode(String zipCode) { + this.zipCode = zipCode; + } + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + @Column(name = "id") + private Long id; + + @Version + @Column(name = "version") + private Integer version; + + public Long getId() { + return this.id; + } + + public void setId(Long id) { + this.id = id; + } + + public Integer getVersion() { + return this.version; + } + + public void setVersion(Integer version) { + this.version = version; + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("Id: ").append(getId()).append(", "); + sb.append("Version: ").append(getVersion()).append(", "); + sb.append("Name: ").append(getName()).append(", "); + sb.append("City: ").append(getCity()).append(", "); + sb.append("State: ").append(getState()).append(", "); + sb.append("ZipCode: ").append(getZipCode()); + return sb.toString(); + } +} diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/domain/TopRatedRestaurantFinder.java b/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/domain/TopRatedRestaurantFinder.java new file mode 100644 index 000000000..8215cd003 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/domain/TopRatedRestaurantFinder.java @@ -0,0 +1,107 @@ +package com.springone.myrestaurants.domain; + +import org.neo4j.graphdb.*; +import org.neo4j.graphdb.traversal.TraversalDescription; +import org.neo4j.graphdb.traversal.Traverser; +import org.neo4j.helpers.Predicate; +import org.neo4j.kernel.Traversal; +import org.neo4j.kernel.impl.traversal.TraversalDescriptionImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.springframework.data.neo4j.support.GraphDatabaseContext; + +import java.util.*; + +/** + * @author Michael Hunger + * @since 02.10.2010 + */ +@Configurable +public class TopRatedRestaurantFinder { + + @Autowired + GraphDatabaseContext graphDatabaseContext; + + private static final int MAXIMUM_DEPTH = 5; + public Collection getTopNRatedRestaurants(final UserAccount user, final int n) { + final CalculateRatingPredicate calculateRatingPredicate = new CalculateRatingPredicate(); + final Node userNode=user.getPersistentState(); + final TraversalDescription traversalDescription = new TraversalDescriptionImpl() + .order(Traversal.postorderBreadthFirst()) + .prune(Traversal.pruneAfterDepth(MAXIMUM_DEPTH)) + .filter(calculateRatingPredicate) + .relationships(DynamicRelationshipType.withName("friends")); + final Traverser traverser = traversalDescription.traverse(userNode); + final Iterator it = traverser.nodes().iterator(); + while (it.hasNext()) { + it.next(); + } + return calculateRatingPredicate.getRecommendedRestaurants(n); + } + + private class CalculateRatingPredicate implements Predicate { + class AggregatedRecommendation implements Comparable { + private Node restaurant; + private Collection recommendations=new HashSet(); + double stars; + double sum; + + public AggregatedRecommendation(final Node restaurant) { + this.restaurant = restaurant; + } + + @Override + public int compareTo(final AggregatedRecommendation o) { + return stars < o.stars ? 1 : stars == o.stars ? 0 : -1; + } + + public void add(final Relationship recommendation, final int distance) { + if (recommendations.add(recommendation)) { + final Integer userStars = (Integer)recommendation.getProperty("stars", 0); + sum += userStars * Math.pow(0.5D,distance); + stars = sum / recommendations.size(); + } + } + + private RatedRestaurant toRatedRestaurant(final CalculateRatingPredicate calculateRatingPredicate) { + final RatedRestaurant ratedRestaurant = new RatedRestaurant(graphDatabaseContext.createEntityFromState(restaurant, Restaurant.class)); + for (final Relationship recommendation : recommendations) { + ratedRestaurant.add(graphDatabaseContext.createEntityFromState(recommendation, Recommendation.class)); + } + return ratedRestaurant; + } + } + + private final Map recommendedRestaurants=new HashMap(); + + public CalculateRatingPredicate() { + } + + public boolean accept(final Path path) { + final int distance = path.length(); + final Node friend = path.endNode(); + for (final Relationship recommendation : friend.getRelationships(DynamicRelationshipType.withName("recommends"))) { + final Node restaurant = recommendation.getEndNode(); + if (!recommendedRestaurants.containsKey(restaurant)) { + recommendedRestaurants.put(restaurant,new AggregatedRecommendation(restaurant)); + } + recommendedRestaurants.get(restaurant).add(recommendation,distance); + } + return true; + } + + public Collection getRecommendedRestaurants(final int n) { + final List sorted = new ArrayList(recommendedRestaurants.values()); + Collections.sort(sorted); + int index=0; + final Collection result=new ArrayList(n); + for (final AggregatedRecommendation aggregatedRecommendation : sorted) { + if (index == n) return result; + result.add(aggregatedRecommendation.toRatedRestaurant(this)); + index++; + } + return result; + } + + } +} diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/domain/TopRatedRestaurantTraverser.java b/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/domain/TopRatedRestaurantTraverser.java new file mode 100644 index 000000000..528b089d9 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/domain/TopRatedRestaurantTraverser.java @@ -0,0 +1,45 @@ +package com.springone.myrestaurants.domain; + +import org.neo4j.graphdb.DynamicRelationshipType; +import org.neo4j.graphdb.traversal.BranchOrderingPolicy; +import org.neo4j.graphdb.traversal.BranchSelector; +import org.neo4j.graphdb.traversal.TraversalBranch; +import org.neo4j.graphdb.traversal.TraversalDescription; +import org.neo4j.kernel.impl.traversal.TraversalDescriptionImpl; +import org.springframework.data.neo4j.core.FieldTraversalDescriptionBuilder; +import org.springframework.data.neo4j.core.NodeBacked; +import org.springframework.data.neo4j.mapping.Neo4JPersistentProperty; + +import java.lang.reflect.Field; + +/** + * @author Michael Hunger + * @since 02.10.2010 + * TODO: calculate a rating assigned to each restaurant that is the sum of its stars + * the stars are multiplied by pow(1/2,distance to startNode==path.depth) + */ +class TopRatedRestaurantTraverser implements FieldTraversalDescriptionBuilder { + @Override + public TraversalDescription build(NodeBacked start, Neo4JPersistentProperty field, String... params) { + return new TraversalDescriptionImpl() + .breadthFirst() + .relationships(DynamicRelationshipType.withName("friends")) + .order(new BranchOrderingPolicy() { + @Override + public BranchSelector create(final TraversalBranch startBranch) { + return new BranchSelector(){ + @Override + public TraversalBranch next() { + TraversalBranch branch=startBranch; + while (branch!=null) { + if (branch.depth() friends; + + @RelatedToVia(type = "recommends", elementClass = Recommendation.class) + Iterable recommendations; + + @GraphTraversal(traversalBuilder = TopRatedRestaurantTraverser.class, elementClass = Restaurant.class) + Iterable topRatedRestaurants; + + public Collection getTopNRatedRestaurants(int n) { + return new TopRatedRestaurantFinder().getTopNRatedRestaurants(this,n); + } + + public Collection getTop5RatedRestaurants() { + return getTopNRatedRestaurants(5); + } + + @Temporal(TemporalType.TIMESTAMP) + @DateTimeFormat(style = "S-") + private Date birthDate; + + public Set getFriends() { + return friends; + } + + public void setFriends(Set friends) { + this.friends = friends; + } + + @ManyToMany(cascade = CascadeType.ALL) + private Set favorites; + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + @Column(name = "id") + private Long id; + + @Version + @Column(name = "version") + private Integer version; + + public Long getId() { + return this.id; + } + + public void setId(Long id) { + this.id = id; + } + + public Integer getVersion() { + return this.version; + } + + public void setVersion(Integer version) { + this.version = version; + } + + public String getUserName() { + return this.userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getFirstName() { + return this.firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return this.lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getNickname() { + return nickname; + } + + public void setNickname(String nickname) { + this.nickname = nickname; + } + + public Date getBirthDate() { + return this.birthDate; + } + + public void setBirthDate(Date birthDate) { + this.birthDate = birthDate; + } + + public Set getFavorites() { + return this.favorites; + } + + public void setFavorites(Set favorites) { + this.favorites = favorites; + } + + @Transactional + public void knows(UserAccount friend) { + relateTo(friend, "friends"); + /* + if (friends==null) { + friends=new HashSet(); + } + else friends.add(friend); + */ + } + + @Transactional + public Recommendation rate(Restaurant restaurant, int stars, String comment) { + Recommendation recommendation = (Recommendation) relateTo(restaurant, Recommendation.class, "recommends"); + recommendation.rate(stars, comment); + return recommendation; + } + public Iterable getRecommendations() { + return recommendations; + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("Id: ").append(getId()).append(", "); + sb.append("Version: ").append(getVersion()).append(", "); + sb.append("UserName: ").append(getUserName()).append(", "); + sb.append("FirstName: ").append(getFirstName()).append(", "); + sb.append("LastName: ").append(getLastName()).append(", "); + sb.append("BirthDate: ").append(getBirthDate()).append(", "); + sb.append("Favorites: ").append(getFavorites() == null ? "null" : getFavorites().size()); + return sb.toString(); + } +} diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/web/BaseApplicationController.java b/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/web/BaseApplicationController.java new file mode 100644 index 000000000..ba29d67f6 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/web/BaseApplicationController.java @@ -0,0 +1,63 @@ +package com.springone.myrestaurants.web; + +import org.joda.time.format.DateTimeFormat; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.i18n.LocaleContextHolder; +import org.springframework.core.convert.converter.Converter; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.ModelAttribute; + +import com.springone.myrestaurants.data.RestaurantRepository; +import com.springone.myrestaurants.data.UserAccountRepository; +import com.springone.myrestaurants.domain.Restaurant; +import com.springone.myrestaurants.domain.UserAccount; + +@Transactional +public class BaseApplicationController { + + @Autowired + RestaurantRepository restaurantRepository; + + @Autowired + UserAccountRepository userAccountRepository; + + @ModelAttribute("currentUserAccountId") + public Long populateModelWithCurrentUserAccountIdAsLong() { + UserAccount userAccount = getCurrentUserAccount(); + if (userAccount != null) { + return userAccount.getId(); + } else { + return -1L; + } + } + + private UserAccount getCurrentUserAccount() { + String currentUser = SecurityContextHolder.getContext() + .getAuthentication().getName(); + UserAccount userAccount = userAccountRepository.findByName(currentUser); + if (userAccount != null) { + userAccount.persist(); + } + return userAccount; + } + + void addDateTimeFormatPatterns(Model model) { + model.addAttribute( + "userAccount_birthdate_date_format", + DateTimeFormat.patternForStyle("S-", + LocaleContextHolder.getLocale())); + } + + protected Converter getRestaurantConverter() { + return new Converter() { + public String convert(Restaurant restaurant) { + return new StringBuilder().append(restaurant.getName()) + .append(" ").append(restaurant.getCity()).append(" ") + .append(restaurant.getState()).toString(); + } + }; + } + +} diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/web/FriendController.java b/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/web/FriendController.java new file mode 100644 index 000000000..d1d6cdba7 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/web/FriendController.java @@ -0,0 +1,102 @@ +package com.springone.myrestaurants.web; + +import java.util.Set; + +import org.springframework.core.convert.converter.Converter; +import org.springframework.core.convert.support.GenericConversionService; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +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; +import org.springframework.web.bind.annotation.RequestParam; + +import com.springone.myrestaurants.domain.UserAccount; + +@RequestMapping("/friends") +@Controller +public class FriendController extends BaseApplicationController { + + + @RequestMapping(method = RequestMethod.POST) + public String create(FriendFormBean friend, + @ModelAttribute("currentUserAccountId") Long userId, + BindingResult result, Model model) { + if (result.hasErrors()) { + model.addAttribute("friend", friend); + return "friends/create"; + } + //TODO additional error checking + UserAccount account = this.userAccountRepository.findUserAccount(userId); + UserAccount friendAccount = this.userAccountRepository.findByName(friend.getUserName()); + if (friendAccount != null) { + account.getFriends().add(friendAccount); + } + return "redirect:/friends/" + friendAccount.getId(); + } + + @RequestMapping(params = "form", method = RequestMethod.GET) + public String createForm(Model model) { + model.addAttribute("friend", new FriendFormBean()); + return "friends/create"; + } + + @RequestMapping(value = "/{id}", method = RequestMethod.GET) + public String show(@PathVariable("id") Long id, Model model) { + UserAccount friendAccount = this.userAccountRepository.findUserAccount(id); + model.addAttribute("friend", friendAccount); + model.addAttribute("itemId", id); + return "friends/show"; + } + + @RequestMapping(method = RequestMethod.GET) + public String list(@RequestParam(value = "page", required = false) Integer page, + @RequestParam(value = "size", required = false) Integer size, + @ModelAttribute("currentUserAccountId") Long userId, + Model model) { + + UserAccount currentUser = this.userAccountRepository.findUserAccount(userId); + Set friends = currentUser.getFriends(); + model.addAttribute("friends", friends); + + return "friends/list"; + } + + @RequestMapping(value = "/{id}", method = RequestMethod.DELETE) + public String delete(@PathVariable("id") Long id, + @ModelAttribute("currentUserAccountId") Long userId, + @RequestParam(value = "page", required = false) Integer page, + @RequestParam(value = "size", required = false) Integer size, Model model) { + UserAccount account = this.userAccountRepository.findUserAccount(userId); + UserAccount friendAccount = this.userAccountRepository.findUserAccount(id); + if (account.getFriends().contains(friendAccount)) { + account.getFriends().remove(friendAccount); + } + model.addAttribute("page", (page == null) ? "1" : page.toString()); + model.addAttribute("size", (size == null) ? "10" : size.toString()); + return "redirect:/friends?page=" + ((page == null) ? "1" : page.toString()) + "&size=" + ((size == null) ? "10" : size.toString()); + } + + + Converter getUserAccountConverter() { + return new Converter() { + public String convert(UserAccount friend) { + return new StringBuilder().append(friend.getUserName()).toString(); + } + }; + } + + @InitBinder + void registerConverters(WebDataBinder binder) { + if (binder.getConversionService() instanceof GenericConversionService) { + GenericConversionService conversionService = (GenericConversionService) binder.getConversionService(); + conversionService.addConverter(getUserAccountConverter()); + } + } + + +} diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/web/FriendFormBean.java b/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/web/FriendFormBean.java new file mode 100644 index 000000000..05c89c314 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/web/FriendFormBean.java @@ -0,0 +1,26 @@ +package com.springone.myrestaurants.web; + +public class FriendFormBean { + + private long id; + + private String userName; + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + +} diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/web/RatedRestaurantBean.java b/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/web/RatedRestaurantBean.java new file mode 100644 index 000000000..6d813e65b --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/web/RatedRestaurantBean.java @@ -0,0 +1,52 @@ +package com.springone.myrestaurants.web; + +public class RatedRestaurantBean { + + private long id; + + // Restaurant name + private String name; + + private long recommendations; + + private double rating; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public long getId() { + return id; + } + + public void setId(long restaurantId) { + this.id = restaurantId; + } + + public long getRecommendations() { + return recommendations; + } + + public void setRecommendations(long recommendations) { + this.recommendations = recommendations; + } + + public double getRating() { + return rating; + } + + public void setRating(double rating) { + this.rating = rating; + } + + @Override + public String toString() { + return "RatedRestaurantBean [restaurantId=" + id + ", name=" + + name + ", rating=" + rating + "]"; + } + +} diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/web/RecommendationController.java b/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/web/RecommendationController.java new file mode 100644 index 000000000..c232b280d --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/web/RecommendationController.java @@ -0,0 +1,170 @@ +package com.springone.myrestaurants.web; + +import java.util.ArrayList; +import java.util.List; + +import com.springone.myrestaurants.domain.Recommendation; +import com.springone.myrestaurants.domain.Restaurant; +import com.springone.myrestaurants.domain.UserAccount; + +import org.springframework.ui.Model; +import org.springframework.validation.BindingResult; +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; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.stereotype.Controller; + +@RequestMapping("/recommendations") +@Controller +public class RecommendationController extends BaseApplicationController { + + @RequestMapping(value = "/{id}", method = RequestMethod.GET) + public String show(@PathVariable("id") Long recommendationId, + @ModelAttribute("currentUserAccountId") Long userId, + Model model) { + + Recommendation foundRec = findRecommendation(userId, recommendationId); + RecommendationFormBean bean = new RecommendationFormBean(); + if (foundRec != null) { + bean.setComments(foundRec.getComment()); + bean.setRating(foundRec.getStars()); + bean.setId(foundRec.getRelationshipId()); + Restaurant r = foundRec.getRestaurant(); + bean.setName(r.getName()); + bean.setRestaurantId(r.getId()); + } + model.addAttribute("recommendation", bean); + return "recommendations/show"; + } + + + private Recommendation findRecommendation(Long userId, + Long recommendationId) { + UserAccount account = this.userAccountRepository.findUserAccount(userId); + Iterable recs = account.getRecommendations(); + Recommendation foundRec = null; + for (Recommendation recommendation : recs) { + if (recommendation.getRelationshipId().equals(recommendationId)) { + foundRec = recommendation; + } + } + return foundRec; + } + + + @RequestMapping(method = RequestMethod.GET) + public String list(@RequestParam(value = "page", required = false) Integer page, + @RequestParam(value = "size", required = false) Integer size, + @ModelAttribute("currentUserAccountId") Long userId, + Model model) { + + UserAccount account = this.userAccountRepository.findUserAccount(userId); + Iterable recs = account.getRecommendations(); + //View expects a list with indexer access and properties that match those of the form bean. + List listRecs = new ArrayList(); + for (Recommendation recommendation : recs) { + RecommendationFormBean rfb = new RecommendationFormBean(); + final Restaurant restaurant = recommendation.getRestaurant(); + rfb.setComments(recommendation.getComment()); + rfb.setName(restaurant.getName()); + rfb.setRating(recommendation.getStars()); + rfb.setId(recommendation.getRelationshipId()); + rfb.setRestaurantId(restaurant.getId()); + listRecs.add(rfb); + } + model.addAttribute("recommendations", listRecs); + return "recommendations/list"; + } + + + @RequestMapping(method = RequestMethod.POST) + public String create(RecommendationFormBean recommendationFormBean, + @ModelAttribute("currentUserAccountId") Long userId, + BindingResult result, + Model model) { + + if (result.hasErrors()) { + model.addAttribute("recommendation", recommendationFormBean); + return "recommendations/create"; + } + long restaurantId = recommendationFormBean.getRestaurantId(); + Restaurant restaurant = this.restaurantRepository.findRestaurant(restaurantId); + UserAccount account = this.userAccountRepository.findUserAccount(userId); + Recommendation recommendation = account.rate(restaurant, + recommendationFormBean.getRating(), + recommendationFormBean.getComments()); + model.addAttribute("recommendationId", recommendation.getRelationshipId()); + return "redirect:/recommendations/" + recommendation.getRelationshipId(); + } + + @RequestMapping(value = "/{restaurantId}/{userId}", params = "form", method = RequestMethod.GET) + public String createForm(@PathVariable("restaurantId") Long restaurantId, + @PathVariable("userId") Long userId, + Model model) { + RecommendationFormBean recBean = new RecommendationFormBean(); + Restaurant restaurant = this.restaurantRepository.findRestaurant(restaurantId); + recBean.setRestaurantId(restaurantId); + recBean.setName(restaurant.getName()); + model.addAttribute("recommendation", recBean); + //currentUserId is part of the implicit model due to spring security + + //model.addAttribute("userId", userId.toString()); + return "recommendations/create"; ///" + restaurantId + "/" + userId; + } + + @RequestMapping(method = RequestMethod.PUT) + public String update(RecommendationFormBean recommendationFormBean, + @ModelAttribute("currentUserAccountId") Long userId, + BindingResult result, + Model model) { + if (result.hasErrors()) { + model.addAttribute("recommendation", recommendationFormBean); + return "recommendations/update"; + } + Recommendation foundRec = findRecommendation(userId, recommendationFormBean.getId()); + foundRec.rate(recommendationFormBean.getRating(), recommendationFormBean.getComments()); + model.addAttribute("itemId", recommendationFormBean.getId()); + return "redirect:/recommendations/" + recommendationFormBean.getId(); + } + + @RequestMapping(value = "/{id}", params = "form", method = RequestMethod.GET) + public String updateForm(@PathVariable("id") Long id, + @ModelAttribute("currentUserAccountId") Long userId, + Model model) { + Recommendation foundRec = findRecommendation(userId, id); + RecommendationFormBean recBean = new RecommendationFormBean(); + if (foundRec != null) { + recBean.setComments(foundRec.getComment()); + recBean.setId(foundRec.getRelationshipId()); + recBean.setRating(foundRec.getStars()); + recBean.setName(foundRec.getRestaurant().getName()); + recBean.setRestaurantId(foundRec.getRestaurant().getId()); + } + model.addAttribute("recommendation", recBean); + model.addAttribute("itemId", recBean.getId()); + return "recommendations/update"; + } + + @RequestMapping(value = "/{id}", method = RequestMethod.DELETE) + public String delete(@PathVariable("id") Long id, + @RequestParam(value = "page", required = false) Integer page, + @RequestParam(value = "size", required = false) Integer size, + @ModelAttribute("currentUserAccountId") Long userId, + Model model) { + Recommendation foundRec = findRecommendation(userId, id); + if (foundRec != null) { + if (foundRec.hasPersistentState()) { + foundRec.getPersistentState().delete(); + } + } + model.addAttribute("page", (page == null) ? "1" : page.toString()); + model.addAttribute("size", (size == null) ? "10" : size.toString()); + return "redirect:/recommendations?page=" + ((page == null) ? "1" : page.toString()) + "&size=" + ((size == null) ? "10" : size.toString()); + } + + + + +} diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/web/RecommendationFormBean.java b/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/web/RecommendationFormBean.java new file mode 100644 index 000000000..828ae94bc --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/web/RecommendationFormBean.java @@ -0,0 +1,61 @@ +package com.springone.myrestaurants.web; + +public class RecommendationFormBean { + + private long id; + + private long restaurantId; + + // Restaurant name + private String name; + + private int rating; + + private String comments; + + //ID is here as we need to mirror for the moment all the (graph) domain Recommendation properties in a simple javabean. + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public long getRestaurantId() { + return restaurantId; + } + + public void setRestaurantId(long restaurantId) { + this.restaurantId = restaurantId; + } + + public int getRating() { + return rating; + } + + + + public void setRating(int rating) { + this.rating = rating; + } + + public String getComments() { + return comments; + } + + public void setComments(String comments) { + this.comments = comments; + } +} diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/web/RestaurantController.java b/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/web/RestaurantController.java new file mode 100644 index 000000000..6bfb5c232 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/web/RestaurantController.java @@ -0,0 +1,72 @@ +package com.springone.myrestaurants.web; + +import java.util.List; + +import org.springframework.core.convert.support.GenericConversionService; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.WebDataBinder; +import org.springframework.web.bind.annotation.InitBinder; +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.RequestParam; + +import com.springone.myrestaurants.domain.Restaurant; +import com.springone.myrestaurants.domain.UserAccount; + +@RequestMapping("/restaurants") +@Controller +public class RestaurantController extends BaseApplicationController { + + + @RequestMapping(value = "/{id}", method = RequestMethod.GET) + public String show(@PathVariable("id") Long id, Model model) { + model.addAttribute("restaurant", restaurantRepository.findRestaurant(id)); + model.addAttribute("itemId", id); + return "restaurants/show"; + } + + @RequestMapping(method = RequestMethod.GET) + public String list(@RequestParam(value = "page", required = false) Integer page, + @RequestParam(value = "size", required = false) Integer size, + Model model) { + if (page != null || size != null) { + int sizeNo = size == null ? 10 : size.intValue(); + List rests = restaurantRepository.findRestaurantEntries(page == null ? 0 : (page.intValue() - 1) * sizeNo, sizeNo); + model.addAttribute("restaurants", rests); + float nrOfPages = (float) restaurantRepository.countRestaurants() / sizeNo; + model.addAttribute("maxPages", (int) ((nrOfPages > (int) nrOfPages || nrOfPages == 0.0) ? nrOfPages + 1 : nrOfPages)); + } else { + List rests = restaurantRepository.findAllRestaurants(); + model.addAttribute("restaurants", rests); + } + return "restaurants/list"; + } + + @RequestMapping(value = "/{id}/{userId}", params = "favorite", method = RequestMethod.PUT) + public String addFavoriteRestaurant(@PathVariable("id") Long id, + @PathVariable("userId") Long userId, + Model model) { + Restaurant restaurant = this.restaurantRepository.findRestaurant(id); + UserAccount account = this.userAccountRepository.findUserAccount(userId); + account.getFavorites().add(restaurant); + this.userAccountRepository.persist(account); + addDateTimeFormatPatterns(model); + model.addAttribute("useraccount", account); + model.addAttribute("itemId", id); + return "redirect:/useraccounts/" + account.getId(); + } + + + + + @InitBinder + void registerConverters(WebDataBinder binder) { + if (binder.getConversionService() instanceof GenericConversionService) { + GenericConversionService conversionService = (GenericConversionService) binder.getConversionService(); + conversionService.addConverter(getRestaurantConverter()); + } + } + +} diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/web/SignUpController.java b/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/web/SignUpController.java new file mode 100644 index 000000000..f4d10081e --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/web/SignUpController.java @@ -0,0 +1,115 @@ +package com.springone.myrestaurants.web; + +import java.util.Collection; + +import javax.validation.Valid; + +import org.springframework.core.convert.converter.Converter; +import org.springframework.core.convert.support.GenericConversionService; +import org.springframework.stereotype.Controller; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.ui.Model; +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; + +import com.springone.myrestaurants.domain.Restaurant; +import com.springone.myrestaurants.domain.UserAccount; + +@RequestMapping("/useraccounts") +@Controller +public class SignUpController extends BaseApplicationController { + + + @RequestMapping(method = RequestMethod.POST) + public String create(@Valid UserAccount userAccount, BindingResult result, Model model) { + if (result.hasErrors()) { + model.addAttribute("userAccount", userAccount); + addDateTimeFormatPatterns(model); + return "useraccounts/create"; + } + userAccountRepository.persist(userAccount); + return "redirect:/useraccounts/" + userAccount.getId(); + } + + @RequestMapping(params = "form", method = RequestMethod.GET) + public String createForm(Model model) { + model.addAttribute("userAccount", new UserAccount()); + addDateTimeFormatPatterns(model); + return "useraccounts/create"; + } + + + @RequestMapping(value = "/{id}", method = RequestMethod.GET) + public String show(@PathVariable("id") Long id, Model model) { + addDateTimeFormatPatterns(model); + model.addAttribute("useraccount", userAccountRepository.findUserAccount(id)); + model.addAttribute("itemId", id); + return "useraccounts/show"; + } + + @RequestMapping(method = RequestMethod.PUT) + public String update(@Valid UserAccount userAccount, BindingResult result, Model model) { + if (result.hasErrors()) { + model.addAttribute("userAccount", userAccount); + addDateTimeFormatPatterns(model); + return "useraccounts/update"; + } + final UserAccount mergedAccount = userAccountRepository.merge(userAccount); + return "redirect:/useraccounts/" + mergedAccount.getId(); + } + + @RequestMapping(value = "/{id}", params = "form", method = RequestMethod.GET) + public String updateForm(@PathVariable("id") Long id, Model model) { + model.addAttribute("userAccount", userAccountRepository.findUserAccount(id)); + addDateTimeFormatPatterns(model); + return "useraccounts/update"; + } + + @RequestMapping(value = "/{username}", params = "form2", method = RequestMethod.GET) + public String updateForm(@PathVariable("username") String userName, Model model) { + UserAccount userAccount = userAccountRepository.findByName(userName); + model.addAttribute("userAccount", userAccount); + addDateTimeFormatPatterns(model); + return "useraccounts/update"; + } + + + + @ModelAttribute("restaurants") + public Collection populateRestaurants() { + return restaurantRepository.findAllRestaurants(); + } + + + Converter getRestaurantConverterFromString() { + return new Converter() { + public Restaurant convert(String id) { + return restaurantRepository.findRestaurant(Long.valueOf(id)); + } + }; + } + + Converter getUserAccountConverter() { + return new Converter() { + public String convert(UserAccount userAccount) { + return new StringBuilder().append(userAccount.getUserName()).append(" ").append(userAccount.getFirstName()).append(" ").append(userAccount.getLastName()).toString(); + } + }; + } + + @InitBinder + void registerConverters(WebDataBinder binder) { + if (binder.getConversionService() instanceof GenericConversionService) { + GenericConversionService conversionService = (GenericConversionService) binder.getConversionService(); + conversionService.addConverter(getRestaurantConverter()); + conversionService.addConverter(getUserAccountConverter()); + conversionService.addConverter(getRestaurantConverterFromString()); + } + } + +} diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/web/TopNController.java b/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/web/TopNController.java new file mode 100644 index 000000000..384a7a47d --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/java/com/springone/myrestaurants/web/TopNController.java @@ -0,0 +1,68 @@ +package com.springone.myrestaurants.web; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.springframework.core.convert.converter.Converter; +import org.springframework.core.convert.support.GenericConversionService; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +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.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +import com.springone.myrestaurants.domain.RatedRestaurant; +import com.springone.myrestaurants.domain.Recommendation; +import com.springone.myrestaurants.domain.UserAccount; + +@RequestMapping("/topn") +@Controller +public class TopNController extends BaseApplicationController { + + + @RequestMapping(method = RequestMethod.GET) + public String list(@ModelAttribute("currentUserAccountId") Long userId, + Model model) { + UserAccount currentUser = this.userAccountRepository.findUserAccount(userId); + Collection top5 = currentUser.getTop5RatedRestaurants(); + List topn = new ArrayList(); + for (RatedRestaurant rr : top5) { + RatedRestaurantBean rrb = new RatedRestaurantBean(); + rrb.setId(rr.getRestaurant().getId()); + rrb.setName(rr.getRestaurant().getName()); + float totPoints = 0; + long count = 0; + for (Recommendation r : rr.getRecommendations()) { + totPoints += r.getStars(); + count++; + } + rrb.setRating(totPoints / count); + rrb.setRecommendations(count); + topn.add(rrb); + } + model.addAttribute("topn", topn); + + return "topn/list"; + } + + Converter getUserAccountConverter() { + return new Converter() { + public String convert(UserAccount friend) { + return new StringBuilder().append(friend.getUserName()).toString(); + } + }; + } + + @InitBinder + void registerConverters(WebDataBinder binder) { + if (binder.getConversionService() instanceof GenericConversionService) { + GenericConversionService conversionService = (GenericConversionService) binder.getConversionService(); + conversionService.addConverter(getUserAccountConverter()); + } + } + + +} diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/resources/META-INF/persistence.xml b/spring-data-neo4j-examples/myrestaurants-social/src/main/resources/META-INF/persistence.xml new file mode 100644 index 000000000..b9f07c365 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/resources/META-INF/persistence.xml @@ -0,0 +1,14 @@ + + + + org.hibernate.ejb.HibernatePersistence + com.springone.myrestaurants.domain.UserAccount + com.springone.myrestaurants.domain.Restaurant + + + + + + + + diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/resources/META-INF/spring/applicationContext-security.xml b/spring-data-neo4j-examples/myrestaurants-social/src/main/resources/META-INF/spring/applicationContext-security.xml new file mode 100644 index 000000000..54e54fd11 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/resources/META-INF/spring/applicationContext-security.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/resources/META-INF/spring/applicationContext.xml b/spring-data-neo4j-examples/myrestaurants-social/src/main/resources/META-INF/spring/applicationContext.xml new file mode 100644 index 000000000..a880f22bb --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/resources/META-INF/spring/applicationContext.xml @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/resources/META-INF/spring/database.properties b/spring-data-neo4j-examples/myrestaurants-social/src/main/resources/META-INF/spring/database.properties new file mode 100644 index 000000000..b9a17c86b --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/resources/META-INF/spring/database.properties @@ -0,0 +1,4 @@ +database.driverClassName=org.hsqldb.jdbcDriver +database.url=jdbc:hsqldb:hsql://localhost:9001 +database.username=sa +database.password= diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/resources/log4j.properties b/spring-data-neo4j-examples/myrestaurants-social/src/main/resources/log4j.properties new file mode 100644 index 000000000..1cc8580b6 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/resources/log4j.properties @@ -0,0 +1,22 @@ +log4j.rootLogger=error, stdout + +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout + +# Print the date in ISO 8601 format +log4j.appender.stdout.layout.ConversionPattern=%d [%t] %-5p %c - %m%n + +log4j.appender.R=org.apache.log4j.RollingFileAppender +log4j.appender.R.File=application.log + +log4j.appender.R.MaxFileSize=100KB +# Keep one backup file +log4j.appender.R.MaxBackupIndex=1 + +log4j.appender.R.layout=org.apache.log4j.PatternLayout +log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n + +log4j.category.org.springframework=WARN +log4j.category.org.springframework.datastore=ERROR +#log4j.category.org.neo4j=INFO + diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/resources/restaurants-sample-data.sql b/spring-data-neo4j-examples/myrestaurants-social/src/main/resources/restaurants-sample-data.sql new file mode 100644 index 000000000..a30dbb9de --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/resources/restaurants-sample-data.sql @@ -0,0 +1,50 @@ +insert into restaurant (name, city, state, zip_code, version) values('Subway', 'Plymouth', 'WI', '53073', 1); +insert into restaurant (name, city, state, zip_code, version) values('Boston Market', 'Gaithersburg', 'MD', '20877', 1); +insert into restaurant (name, city, state, zip_code, version) values('Subway Subs', 'Santa Teresa', 'NM', '88008', 1); +insert into restaurant (name, city, state, zip_code, version) values('Arby''s Roast Beef Restaurant', 'Klamath Falls', 'OR', '97603', 1); +insert into restaurant (name, city, state, zip_code, version) values('Bellefleur Winery & Restaurant', 'Carlsbad', 'CA', '92008', 1); +insert into restaurant (name, city, state, zip_code, version) values('Huddle House', 'Calhoun', 'GA', '30701', 1); +insert into restaurant (name, city, state, zip_code, version) values('John Browne''s Pub & Eatery', 'Indianapolis', 'IN', '46235', 1); +insert into restaurant (name, city, state, zip_code, version) values('Ling''s Express', 'Milwaukee', 'WI', '53217', 1); +insert into restaurant (name, city, state, zip_code, version) values('Chubys''s', 'Odell', 'OR', '97044', 1); +insert into restaurant (name, city, state, zip_code, version) values('Bojangles', 'Columbia', 'SC', '29203', 1); +insert into restaurant (name, city, state, zip_code, version) values('NPC International', 'Memphis', 'TN', '38134', 1); +insert into restaurant (name, city, state, zip_code, version) values('Pancake Cafe', 'Naperville', 'IL', '60540', 1); +insert into restaurant (name, city, state, zip_code, version) values('Hong & Kong Restaurant', 'Chelmsford', 'MA', '01824', 1); +insert into restaurant (name, city, state, zip_code, version) values('The Chicken Cooperative', 'Ketchum', 'OK', '74349', 1); +insert into restaurant (name, city, state, zip_code, version) values('Subway', 'Lonoke', 'AR', '72086', 1); +insert into restaurant (name, city, state, zip_code, version) values('Domino''s Pizza', 'Loveland', 'CO', '80537', 1); +insert into restaurant (name, city, state, zip_code, version) values('Carl''s Jr', 'Peoria', 'IL', '61615', 1); +insert into restaurant (name, city, state, zip_code, version) values('El Toro Bar & Grill', 'Shawnee', 'KS', '66216', 1); +insert into restaurant (name, city, state, zip_code, version) values('Subway Sandwiches & Salads', 'New Orleans', 'LA', '70123', 1); +insert into restaurant (name, city, state, zip_code, version) values('Subway', 'Decatur', 'GA', '30030', 1); +insert into restaurant (name, city, state, zip_code, version) values('Arby''s', 'Indianapolis', 'IN', '46268', 1); +insert into restaurant (name, city, state, zip_code, version) values('China King', 'Cedar Rapids', 'IA', '52404', 1); +insert into restaurant (name, city, state, zip_code, version) values('Subway Sandwiches & Salads', 'Knoxville', 'TN', '37924', 1); +insert into restaurant (name, city, state, zip_code, version) values('Luciano Italian Restaurant', 'Oakton', 'VA', '22124', 1); +insert into restaurant (name, city, state, zip_code, version) values('Fruition', 'Portland', 'OR', '97210', 1); +insert into restaurant (name, city, state, zip_code, version) values('Blough''s Delicatessen', 'Davidsville', 'PA', '15928', 1); +insert into restaurant (name, city, state, zip_code, version) values('Hardee''s of Murfreesboro No 4', 'Murfreesboro', 'TN', '37128', 1); +insert into restaurant (name, city, state, zip_code, version) values('Dairy Queen restaurant ', 'Carter Lake', 'IA', '51510', 1); +insert into restaurant (name, city, state, zip_code, version) values('Imperial Wok Chinese Restaurant', 'Shreveport', 'LA', '71118', 1); +insert into restaurant (name, city, state, zip_code, version) values('Hardee''s', 'Waldorf', 'MD', '20601', 1); +insert into restaurant (name, city, state, zip_code, version) values('Cinnabon', 'Gainesville', 'FL', '32605', 1); +insert into restaurant (name, city, state, zip_code, version) values('Angle Inn Restaurant', 'Rockford', 'IL', '61103', 1); +insert into restaurant (name, city, state, zip_code, version) values('Casey''s Carry Out Pizza', 'Thomson', 'IL', '61285', 1); +insert into restaurant (name, city, state, zip_code, version) values('Sonic Drive In', 'Salt Lake City', 'UT', '84118', 1); +insert into restaurant (name, city, state, zip_code, version) values('Mcdonald''s restaurant ', 'Racine', 'WI', '53406', 1); +insert into restaurant (name, city, state, zip_code, version) values('Huhot Mongolian Grill', 'Omaha', 'NE', '68154', 1); +insert into restaurant (name, city, state, zip_code, version) values('Giovanni''s Pizzeria', 'Las Vegas', 'NV', '89123', 1); +insert into restaurant (name, city, state, zip_code, version) values('Bangkok Royal', 'Waco', 'TX', '76706', 1); +insert into restaurant (name, city, state, zip_code, version) values('Golden Coin Bake Shop & Restaurant', 'Waipahu', 'HI', '96797', 1); +insert into restaurant (name, city, state, zip_code, version) values('Cristaudo''s Grand Avenue', 'Carbondale', 'IL', '62901', 1); +insert into restaurant (name, city, state, zip_code, version) values('O''Charley''s Restaurant', 'Independence', 'MO', '64057', 1); +insert into restaurant (name, city, state, zip_code, version) values('A1 Ocean Cafe', 'San Francisco', 'CA', '94104', 1); +insert into restaurant (name, city, state, zip_code, version) values('Alberto''s Mexican Food', 'Corona', 'CA', '92880', 1); +insert into restaurant (name, city, state, zip_code, version) values('Beach Dog Computer Center', 'Hilo', 'HI', '96720', 1); +insert into restaurant (name, city, state, zip_code, version) values('Burger King', 'Houston', 'TX', '77070', 1); +insert into restaurant (name, city, state, zip_code, version) values('Fox River Brew Pub', 'Oshkosh', 'WI', '54901', 1); +insert into restaurant (name, city, state, zip_code, version) values('Buffas Delicatessen', 'New York', 'NY', '10012', 1); +insert into restaurant (name, city, state, zip_code, version) values('Maria''s Mexican Bistro Inc', 'Brooklyn', 'NY', '11215', 1); +insert into restaurant (name, city, state, zip_code, version) values('Sue''s Restaurant', 'Providence', 'RI', '02903', 1); +insert into restaurant (name, city, state, zip_code, version) values('Dairy Queen Brazier', 'Cameron', 'MO', '64429', 1); \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/resources/schema.sql b/spring-data-neo4j-examples/myrestaurants-social/src/main/resources/schema.sql new file mode 100644 index 000000000..a788dd2c9 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/resources/schema.sql @@ -0,0 +1,8 @@ +CREATE TABLE restaurant ( + id BIGINT IDENTITY PRIMARY KEY, + name VARCHAR(255), + version BIGINT, + zip_code VARCHAR(255), + city VARCHAR(255), + state VARCHAR(255) + ); \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/META-INF/MANIFEST.MF b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/META-INF/MANIFEST.MF new file mode 100644 index 000000000..5e9495128 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Class-Path: + diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/classes/alt.properties b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/classes/alt.properties new file mode 100644 index 000000000..48df87ff7 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/classes/alt.properties @@ -0,0 +1 @@ +styleSheet=resources/styles/alt.css diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/classes/standard.properties b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/classes/standard.properties new file mode 100644 index 000000000..d8dc0164d --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/classes/standard.properties @@ -0,0 +1 @@ +styleSheet=resources/styles/standard.css diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/i18n/application.properties b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/i18n/application.properties new file mode 100644 index 000000000..6728984f4 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/i18n/application.properties @@ -0,0 +1,60 @@ +#Updated at Wed Sep 22 21:53:31 EDT 2010 +#Wed Sep 22 21:53:31 EDT 2010 +label_com_springone_myrestaurants_domain_useraccount_username=User Name +label_com_springone_myrestaurants_domain_useraccount_birthdate=Birth Date +label_com_springone_myrestaurants_domain_useraccount_favorites=Favorites +label_com_springone_myrestaurants_domain_restaurant_city=City +menu_item_restaurant_new_label=Restaurant +menu_item_restaurant_fav_label=Restaurants +label_com_springone_myrestaurants_domain_useraccount_lastname=Last Name +menu_item_useraccount_new_label=User Account +label_com_springone_myrestaurants_domain_restaurant_plural=Restaurants +label_com_springone_myrestaurants_domain_restaurant_id=Id +label_com_springone_myrestaurants_domain_useraccount=User Account +label_com_springone_myrestaurants_domain_restaurant_name=Name +label_com_springone_myrestaurants_domain_restaurant=Restaurant +menu_item_restaurant_list_label=Restaurants +menu_category_restaurant_label=Restaurant +label_com_springone_myrestaurants_domain_useraccount_plural=User Accounts +label_com_springone_myrestaurants_domain_useraccount_version=Version +label_com_springone_myrestaurants_domain_useraccount_firstname=First Name +label_com_springone_myrestaurants_domain_useraccount_nickname=Nickname +menu_category_useraccount_label=User Account +label_com_springone_myrestaurants_domain_restaurant_state=State +menu_item_useraccount_list_label=User Accounts +label_com_springone_myrestaurants_domain_restaurant_zipcode=Zip Code +menu_item_useraccount_login_label=User Account +menu_item_useraccount_logout_label=User Account +label_com_springone_myrestaurants_domain_restaurant_version=Version +label_com_springone_myrestaurants_domain_useraccount_id=Id +application_name=MyRestaurants + +label_com_springone_myrestaurants_domain_recommendation_name=Name +menu_category_recommendation_label=Recommendation +menu_item_recommendation_list_label=Recommendations +label_com_springone_myrestaurants_domain_recommendation_comments=Comments +label_com_springone_myrestaurants_domain_recommendation=Recommendation +label_com_springone_myrestaurants_domain_recommendation_rating=Rating +label_com_springone_myrestaurants_domain_recommendation_restaurantid=Restaurant Id +label_com_springone_myrestaurants_domain_recommendation_id=Id + +menu_item_recommendation_new_label=Recommendation +label_com_springone_myrestaurants_domain_recommendation_plural=Recommendations + +label_com_springone_myrestaurants_domain_friend_username=User Name +menu_category_friend_label=Friend +menu_item_friend_list_label=Friends +label_com_springone_myrestaurants_domain_friend_version=Version +menu_item_friend_new_label=Friend +label_com_springone_myrestaurants_domain_friend_id=Id +label_com_springone_myrestaurants_domain_friend_plural=Friends +label_com_springone_myrestaurants_domain_friend=Friend + +menu_item_topn_label=Top Rated Restaurants +label_com_springone_myrestaurants_domain_topn=RatedRestaurant +label_com_springone_myrestaurants_domain_topn_plural=Top Rated Restaurants +label_com_springone_myrestaurants_domain_topn_name=Name +label_com_springone_myrestaurants_domain_topn_comments=Comments +label_com_springone_myrestaurants_domain_topn_recommendations=Recommendations +label_com_springone_myrestaurants_domain_topn_rating=Avg. Rating +label_com_springone_myrestaurants_domain_topn_restaurantid=Restaurant Id diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/i18n/messages.properties b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/i18n/messages.properties new file mode 100644 index 000000000..70b234e2b --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/i18n/messages.properties @@ -0,0 +1,98 @@ +#menu +global_menu_login=Log in +global_menu_logout=Log out +global_menu_new=Create a new {0} +global_menu_list=List all {0} +global_menu_list_my=List my {0} +global_menu_list=List all {0} +global_menu_topn=List {0} +global_menu_find=Find by {0} +global_language_switch=Switch language to {0} +global_language=Language +global_sponsored=Sponsored by SpringSource +global_theme=Theme +global_theme_alt=alt +global_theme_standard=standard +global_generic={0} +user_menu_new=Sign up for a {0} +restaurant_menu_fav=Manage favorite {0} + +#welcome page +welcome_titlepane=Welcome to {0} +welcome_h3=Welcome to {0} +welcome_text=This is a sample application created for SpringOne 2010 to showcase the new and tasty Spring and Neo4J integration features. Enjoy! + +#entity labels +entity_list_all=List all {0} +entity_show=Show {0} +entity_create=Create new {0} +entity_update=Update {0} +entity_favorite=Favorite {0} +entity_recommend=Recommend {0} +entity_delete=Delete {0} +entity_find=Find by {0} +entity_not_found=No {0} found. +entity_not_found_single=No {0} found with this id. +entity_dependency_required=The following dependencies need to be created first: +entity_reference_not_managed=This relationship is managed from the {0} side. + +#button labels +button_home=Home +button_save=Save +button_update=Update +button_find=Find +button_cancel=Cancel +button_proceed=Proceed +button_submit=Submit +button_reset=Reset +button_end=End +button_showmessage=Show Message +button_showstacktrace=Show Stack Trace +button_showcookie=Show Cookie + +#field labels +field_simple_validation=Enter {0} {1} +field_invalid_email=Please enter a valid email +field_invalid_number=Number with \\'-\\' or \\'.\\' allowed +field_invalid_integer=Integer numbers only +field_invalid=Please enter valid {0} +field_required=required + +#list labels +list_first=First Page +list_next=Next Page +list_previous=Previous Page +list_last=Last Page +list_page=Page {0} of {1} +list_size=List results per page: + +#selenium +selenium_menu_test_suite=Test Suite + +#exception +exception_message=Exception Message +exception_stacktrace=Exception Stack Trace +exception_cookie=Cookies +exception_details=Details + +#dataAccessFailure_jspx +error_dataaccessfailure_title=Data access failure +error_dataaccessfailure_problemdescription=Sorry, a problem occurred while accessing the database. + +#resourceNotFound_jspx +error_resourcenotfound_title=Requested Resource Not Found +error_resourcenotfound_problemdescription=Sorry, we did not find the resource you were looking for. + +#uncaughtException_jspx +error_uncaughtexception_title=Internal Error +error_uncaughtexception_problemdescription=Sorry, we encountered an internal error. + +#security +security_login_title=Spring Security Login +security_login_message=Please sign in with your user name and password. +security_login_form_name=Name +security_login_form_name_message=Enter your user name +security_login_form_password=Password +security_login_form_password_message=Enter your password +security_login_unsuccessful=Your login attempt was not successful, try again. Reason: +security_logout=Logout \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/layouts/default.jspx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/layouts/default.jspx new file mode 100644 index 000000000..d68496e5f --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/layouts/default.jspx @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + <spring:message code="welcome_h3" arguments="${app_name}" /> + + + +
    + + +
    + + +
    +
    + + diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/layouts/layouts.xml b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/layouts/layouts.xml new file mode 100644 index 000000000..3c9d6d4bb --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/layouts/layouts.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/spring/webmvc-config.xml b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/spring/webmvc-config.xml new file mode 100644 index 000000000..b03864904 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/spring/webmvc-config.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + dataAccessFailure + resourceNotFound + resourceNotFound + resourceNotFound + + + + + + + + + + + + + /WEB-INF/layouts/layouts.xml + + /WEB-INF/views/**/views.xml + + + + diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/create.tagx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/create.tagx new file mode 100644 index 000000000..37e006781 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/create.tagx @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + +
    + + + +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/dependency.tagx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/dependency.tagx new file mode 100644 index 000000000..86011b91a --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/dependency.tagx @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + +

    + +

    +
    +
    +
    +
    \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/fields/checkbox.tagx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/fields/checkbox.tagx new file mode 100644 index 000000000..3e7c0604e --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/fields/checkbox.tagx @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + ${field} + + +
    + + + + + + + + + + +
    +
    +
    +
    \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/fields/column.tagx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/fields/column.tagx new file mode 100644 index 000000000..11e9c56c4 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/fields/column.tagx @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/fields/datetime.tagx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/fields/datetime.tagx new file mode 100644 index 000000000..ec4adbf68 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/fields/datetime.tagx @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${field} + + + + + + + +
    + + + + + + + +
    + +
    +
    + + + + + + + + + + + +
    +
    +
    +
    \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/fields/display.tagx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/fields/display.tagx new file mode 100644 index 000000000..4e4f86e43 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/fields/display.tagx @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + + + + + + + + + + +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/fields/editor.tagx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/fields/editor.tagx new file mode 100644 index 000000000..959a5fb41 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/fields/editor.tagx @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${field} + + + +
    + + +
    + + +
    +
    +
    +
    \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/fields/input.tagx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/fields/input.tagx new file mode 100644 index 000000000..de26cefde --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/fields/input.tagx @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${field} + + +
    + + + + + + + +
    + +
    +
    + + + + + + + + + + + +
    +
    +
    +
    \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/fields/reference.tagx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/fields/reference.tagx new file mode 100644 index 000000000..89695122a --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/fields/reference.tagx @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + +
    + + + + + + + + ${fn:escapeXml(add_message)} + + + + + ( + + ) + +
    +
    + +
    +
    \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/fields/select.tagx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/fields/select.tagx new file mode 100644 index 000000000..09122bb0d --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/fields/select.tagx @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${field} + + +
    + + + + + + + + + + + +
    + +
    +
    +
    + + + + + + + +
    + +
    +
    +
    +
    + + + + + + +
    + + + +
    +
    +
    + +
    +
    \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/fields/simple.tagx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/fields/simple.tagx new file mode 100644 index 000000000..390afa45f --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/fields/simple.tagx @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + +
    +
    +
    +
    \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/fields/table.tagx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/fields/table.tagx new file mode 100644 index 000000000..303d4f584 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/fields/table.tagx @@ -0,0 +1,179 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + + + + + + + + + + ${fn:escapeXml(show_label)} + + + + + + + + + ${fn:escapeXml(update_label)} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${fn:escapeXml(recommend_label)} + +
    + +
    + +
    \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/fields/textarea.tagx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/fields/textarea.tagx new file mode 100644 index 000000000..f8f05b67d --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/fields/textarea.tagx @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${field} + + + +
    + + +
    + + +
    +
    + +
    +
    \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/find.tagx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/find.tagx new file mode 100644 index 000000000..8644d776c --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/find.tagx @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + +
    + + + +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/list.tagx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/list.tagx new file mode 100644 index 000000000..3202f2bc9 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/list.tagx @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/show.tagx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/show.tagx new file mode 100644 index 000000000..5dfa3784e --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/show.tagx @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/update.tagx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/update.tagx new file mode 100644 index 000000000..1dfdf45eb --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/form/update.tagx @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + +
    +
    +
    +
    \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/menu/category.tagx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/menu/category.tagx new file mode 100644 index 000000000..f6383f513 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/menu/category.tagx @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + +
  • +

    + +

    +
      + +
    +
  • + +
    +
    \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/menu/item.tagx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/menu/item.tagx new file mode 100644 index 000000000..b0c466e65 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/menu/item.tagx @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + +
  • + + + + +
  • + +
    +
    \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/menu/menu.tagx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/menu/menu.tagx new file mode 100644 index 000000000..9c3f2e7c8 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/menu/menu.tagx @@ -0,0 +1,13 @@ + + + + + + + + +
      + +
    +
    +
    \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/util/language.tagx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/util/language.tagx new file mode 100644 index 000000000..aa1cd5adb --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/util/language.tagx @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + ${fn:escapeXml(lang_label)} + + + + diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/util/load-scripts.tagx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/util/load-scripts.tagx new file mode 100644 index 000000000..a89a63292 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/util/load-scripts.tagx @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/util/pagination.tagx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/util/pagination.tagx new file mode 100644 index 000000000..b4d394ce0 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/util/pagination.tagx @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${i} + + + + + + + + + + + + + + + ${first_label} + + + + + + + + + + + ${previous_label} + + + + + + + + + + + + + + ${next_label} + + + + + + + + + + + ${last_label} + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/util/panel.tagx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/util/panel.tagx new file mode 100644 index 000000000..e8a43fc69 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/util/panel.tagx @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + ${id} + + + + ${openPane} + + + + ${title} + + + +
    + + +
    +
    +
    diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/util/placeholder.tagx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/util/placeholder.tagx new file mode 100644 index 000000000..65ee2e4b7 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/util/placeholder.tagx @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/util/theme.tagx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/util/theme.tagx new file mode 100644 index 000000000..fe0c628aa --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/tags/util/theme.tagx @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + ${theme_standard} + + + + + + + + + + + + ${theme_alt} + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/dataAccessFailure.jspx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/dataAccessFailure.jspx new file mode 100644 index 000000000..e815684ea --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/dataAccessFailure.jspx @@ -0,0 +1,29 @@ +
    + + + +

    ${fn:escapeXml(title)}

    +

    + +

    + +

    +

    + +

    + + + + + + + + +
    +
    +
    +

    +
    +
    +
    + diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/footer.jspx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/footer.jspx new file mode 100644 index 000000000..89af49c71 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/footer.jspx @@ -0,0 +1,36 @@ + + diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/friends/create.jspx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/friends/create.jspx new file mode 100644 index 000000000..a7396cbd5 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/friends/create.jspx @@ -0,0 +1,8 @@ + +
    + + + + + +
    diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/friends/list.jspx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/friends/list.jspx new file mode 100644 index 000000000..478e0d9f5 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/friends/list.jspx @@ -0,0 +1,9 @@ + +
    + + + + + + +
    diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/friends/show.jspx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/friends/show.jspx new file mode 100644 index 000000000..f5ba8594b --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/friends/show.jspx @@ -0,0 +1,7 @@ + +
    + + + + +
    diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/friends/update.jspx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/friends/update.jspx new file mode 100644 index 000000000..22872f030 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/friends/update.jspx @@ -0,0 +1,7 @@ + +
    + + + + +
    diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/friends/views.xml b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/friends/views.xml new file mode 100644 index 000000000..1b2c30fab --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/friends/views.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/header.jspx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/header.jspx new file mode 100644 index 000000000..fea815207 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/header.jspx @@ -0,0 +1,10 @@ + \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/index-template.jspx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/index-template.jspx new file mode 100644 index 000000000..871bc55ca --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/index-template.jspx @@ -0,0 +1,10 @@ +
    + + + + +

    + +

    +
    +
    \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/index.jspx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/index.jspx new file mode 100644 index 000000000..75ce000a4 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/index.jspx @@ -0,0 +1,13 @@ +
    + + + + +

    + +

    +

    + +

    +
    +
    \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/login.jspx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/login.jspx new file mode 100644 index 000000000..df4b9bc4b --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/login.jspx @@ -0,0 +1,59 @@ +
    + + + + +
    +

    + + + . +

    +
    +
    + +

    + +

    +
    + +
    +
    + + + + +
    +
    +
    + + + + +
    +
    +
    + + + + + +
    +
    +
    +
    + diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/menu.jspx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/menu.jspx new file mode 100644 index 000000000..57d4c76ce --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/menu.jspx @@ -0,0 +1,44 @@ + + diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/recommendations/create.jspx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/recommendations/create.jspx new file mode 100644 index 000000000..7325295cf --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/recommendations/create.jspx @@ -0,0 +1,14 @@ + +
    + + + + + +
    + + +
    +
    + +
    diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/recommendations/list.jspx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/recommendations/list.jspx new file mode 100644 index 000000000..c92fcf06b --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/recommendations/list.jspx @@ -0,0 +1,11 @@ + +
    + + + + + + + + +
    diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/recommendations/show.jspx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/recommendations/show.jspx new file mode 100644 index 000000000..28e810b04 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/recommendations/show.jspx @@ -0,0 +1,9 @@ + +
    + + + + + + +
    diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/recommendations/update.jspx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/recommendations/update.jspx new file mode 100644 index 000000000..28e391ef4 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/recommendations/update.jspx @@ -0,0 +1,10 @@ + +
    + + + + + + + +
    diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/recommendations/views.xml b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/recommendations/views.xml new file mode 100644 index 000000000..54ede30ee --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/recommendations/views.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/resourceNotFound.jspx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/resourceNotFound.jspx new file mode 100644 index 000000000..fce7f5b03 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/resourceNotFound.jspx @@ -0,0 +1,28 @@ +
    + + + +

    ${fn:escapeXml(title)}

    +

    + +

    + +

    +

    + +

    + + + + + + + + +
    +
    +
    +

    +
    +
    +
    \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/restaurants/create.jspx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/restaurants/create.jspx new file mode 100644 index 000000000..3a5a1da07 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/restaurants/create.jspx @@ -0,0 +1,11 @@ + +
    + + + + + + + + +
    diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/restaurants/list.jspx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/restaurants/list.jspx new file mode 100644 index 000000000..872cfca28 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/restaurants/list.jspx @@ -0,0 +1,12 @@ + +
    + + + + + + + + + +
    diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/restaurants/show.jspx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/restaurants/show.jspx new file mode 100644 index 000000000..8dc605306 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/restaurants/show.jspx @@ -0,0 +1,10 @@ + +
    + + + + + + + +
    diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/restaurants/update.jspx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/restaurants/update.jspx new file mode 100644 index 000000000..2f785b808 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/restaurants/update.jspx @@ -0,0 +1,10 @@ + +
    + + + + + + + +
    diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/restaurants/views.xml b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/restaurants/views.xml new file mode 100644 index 000000000..7467779c7 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/restaurants/views.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/topn/list.jspx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/topn/list.jspx new file mode 100644 index 000000000..a8bea5ffd --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/topn/list.jspx @@ -0,0 +1,11 @@ + +
    + + + + + + + + +
    diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/topn/views.xml b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/topn/views.xml new file mode 100644 index 000000000..e5ca02a53 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/topn/views.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/uncaughtException.jspx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/uncaughtException.jspx new file mode 100644 index 000000000..2196d3886 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/uncaughtException.jspx @@ -0,0 +1,28 @@ +
    + + + +

    ${fn:escapeXml(title)}

    +

    + +

    + +

    +

    + +

    + + + + + + + + +
    +
    +
    +

    +
    +
    +
    \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/useraccounts/create.jspx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/useraccounts/create.jspx new file mode 100644 index 000000000..5da8545f9 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/useraccounts/create.jspx @@ -0,0 +1,12 @@ + +
    + + + + + + + + + +
    diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/useraccounts/list.jspx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/useraccounts/list.jspx new file mode 100644 index 000000000..209518bc3 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/useraccounts/list.jspx @@ -0,0 +1,13 @@ + +
    + + + + + + + + + + +
    diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/useraccounts/show.jspx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/useraccounts/show.jspx new file mode 100644 index 000000000..4c8349828 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/useraccounts/show.jspx @@ -0,0 +1,12 @@ + +
    + + + + + + + + + +
    diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/useraccounts/update.jspx b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/useraccounts/update.jspx new file mode 100644 index 000000000..ef6fe851c --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/useraccounts/update.jspx @@ -0,0 +1,12 @@ + +
    + + + + + + + + + +
    diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/useraccounts/views.xml b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/useraccounts/views.xml new file mode 100644 index 000000000..6e5f648c8 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/useraccounts/views.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/views.xml b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/views.xml new file mode 100644 index 000000000..e92932a94 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/views/views.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/web.xml b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 000000000..a03ba840a --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,110 @@ + + + + + myrestaurants-social + + Roo generated myrestaurants application + + + + + defaultHtmlEscape + true + + + + contextConfigLocation + classpath*:META-INF/spring/applicationContext*.xml + + + + Spring OpenEntityManagerInViewFilter + org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter + + + + + + + + springSecurityFilterChain + org.springframework.web.filter.DelegatingFilterProxy + + + CharacterEncodingFilter + org.springframework.web.filter.CharacterEncodingFilter + + encoding + UTF-8 + + + forceEncoding + true + + + + + HttpMethodFilter + org.springframework.web.filter.HiddenHttpMethodFilter + + + Spring OpenEntityManagerInViewFilter + /* + + + + + + springSecurityFilterChain + /* + + + CharacterEncodingFilter + /* + + + + HttpMethodFilter + /* + + + + + org.springframework.web.context.ContextLoaderListener + + + + + myrestaurants + org.springframework.web.servlet.DispatcherServlet + + contextConfigLocation + /WEB-INF/spring/webmvc-config.xml + + 1 + + + + myrestaurants + / + + + + 10 + + + + / + + + + java.lang.Exception + /uncaughtException + + + + 404 + /resourceNotFound + + diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/Thumbs.db b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/Thumbs.db new file mode 100644 index 000000000..8d73b1265 Binary files /dev/null and b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/Thumbs.db differ diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/add.png b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/add.png new file mode 100644 index 000000000..d5bfa0719 Binary files /dev/null and b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/add.png differ diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/banner-graphic.png b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/banner-graphic.png new file mode 100644 index 000000000..df9202123 Binary files /dev/null and b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/banner-graphic.png differ diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/create.png b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/create.png new file mode 100644 index 000000000..d5bfa0719 Binary files /dev/null and b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/create.png differ diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/delete.png b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/delete.png new file mode 100644 index 000000000..1514d51a3 Binary files /dev/null and b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/delete.png differ diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/en.png b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/en.png new file mode 100644 index 000000000..ff701e19f Binary files /dev/null and b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/en.png differ diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/fav-del.png b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/fav-del.png new file mode 100644 index 000000000..faca5ba94 Binary files /dev/null and b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/fav-del.png differ diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/fav-new.png b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/fav-new.png new file mode 100644 index 000000000..e87e2b101 Binary files /dev/null and b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/fav-new.png differ diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/favicon.ico b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/favicon.ico new file mode 100644 index 000000000..c2f2b6ccd Binary files /dev/null and b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/favicon.ico differ diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/list.png b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/list.png new file mode 100644 index 000000000..acc30b853 Binary files /dev/null and b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/list.png differ diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/recommend.gif b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/recommend.gif new file mode 100644 index 000000000..2434c2483 Binary files /dev/null and b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/recommend.gif differ diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/resultset_first.png b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/resultset_first.png new file mode 100644 index 000000000..b03eaf8b5 Binary files /dev/null and b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/resultset_first.png differ diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/resultset_last.png b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/resultset_last.png new file mode 100644 index 000000000..8ec894784 Binary files /dev/null and b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/resultset_last.png differ diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/resultset_next.png b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/resultset_next.png new file mode 100644 index 000000000..e252606d3 Binary files /dev/null and b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/resultset_next.png differ diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/resultset_previous.png b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/resultset_previous.png new file mode 100644 index 000000000..18f9cc109 Binary files /dev/null and b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/resultset_previous.png differ diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/show.png b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/show.png new file mode 100644 index 000000000..2f193889f Binary files /dev/null and b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/show.png differ diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/spring-logo.png b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/spring-logo.png new file mode 100644 index 000000000..1088a02cd Binary files /dev/null and b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/spring-logo.png differ diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/springsource-logo.png b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/springsource-logo.png new file mode 100644 index 000000000..e170f8abf Binary files /dev/null and b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/springsource-logo.png differ diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/thumbsup.png b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/thumbsup.png new file mode 100644 index 000000000..7bd4adeb2 Binary files /dev/null and b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/thumbsup.png differ diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/update.png b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/update.png new file mode 100644 index 000000000..046811ed7 Binary files /dev/null and b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/images/update.png differ diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/styles/alt.css b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/styles/alt.css new file mode 100644 index 000000000..c562d00ac --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/styles/alt.css @@ -0,0 +1,362 @@ +/* main elements */ + +body,div,td { + font-family: Arial, Helvetica, sans-serif; + font-size: 12px; + color: #666; +} + +body { + background-color: #fff; + text-align: center; +} + +#header { + margin-bottom: 1em; +} + +#wrapper { + width:800px; + min-width: 800px; + max-width: 800px; + margin-right: auto; + margin-left: auto; + + /* fix max-width incompatibility in IE6 */ + width:expression(document.body.clientWidth > 800? "800px": "auto" ); + + overflow:hidden; + display:block; +} + +/* header and footer elements */ + +#main { + overflow:hidden; + display:box; +} + +#menu { + background: #eee; + position:relative; + float:right; + left:0px; + width:220px; + margin-left:15px; +} + +#menu ul{ + list-style: none; + margin: 0; + padding: 0; +} + +#menu ul li{ + padding: 0px; +} + + +#menu a, #menu h2 { + display: block; + margin: 0; + padding: 2px 6px; + color:#FFFFFF; +} + +#menu h2 { + color: #fff; + background: #F71220; + text-transform: uppercase; + font-weight:bold; + font-size: 12px; +} + +#menu a { + color: #666666; + background: #efefef; + text-decoration: none; + padding: 2px 12px; +} + +#menu a:hover { + color: #F71220; + background: #fff; +} + +#footer { + background:#fff; + border:none; + margin-top:15px; + border-top:1px solid #999999; +} + +#footer .new { + float:left; +} + +#footer a:link {color: #7db223;} + +.quicklinks { + clear:both; + padding-bottom: 15px +} +.quicklinks span { + float: right; +} + +label { + width:100px; + float:left; + margin-left: 5px; + margin-top: 0px; +} + +input { + height:20px; +} + +input, textarea, select { + border:1px solid #B3B3B3; +} + +input.image { + border: none; + height: auto; +} + +submit { + height:25px; +} + +div { + text-align: left; +} + +div .box { + display:block; + margin-left:105px; +} + +/* menu elements*/ + +a.menu, a.menu:link, a.menu:visited {display:block; width:150px; height:25px;} + +/* text styles */ + +h1,h2,h3 { + font-family: Helvetica, sans-serif; + color: #7db223; +} + +h1 { + font-size: 20px; + line-height: 26px; +} + +h2 { + font-size: 18px; + line-height: 20px; +} + +h3 { + font-size: 15px; + line-height: 21px; + color:#555; +} + +h4 { + font-size: 14px; + line-height: 20px; +} + +.errors { + color: red; + font-weight: bold; + display: block; + margin-left: 105px; +} + +a { + text-decoration: underline; + font-size: 12px; +} + +a img { + border: 0 none; + vertical-align: middle; +} + +tr:nth-child(odd) { + background-color: #FFFFFF; +} + +tr:nth-child(even) { + background-color: #EFEFEF; +} + +a:link { + color: #7db223; +} + +a:hover { + color: #456314; +} + +a:active { + color: #7db223; +} + +a:visited { + color: #7db223; +} + +li { + padding-top: 5px; + text-align: left; +} + +ul li { + margin:0 0 0.25em 0; + padding:0; +} +/* table elements */ + +table { + background: #EEEEEE; + margin: 2px 0 0 0; + border: 1px solid #BBBBBB; + border-collapse: collapse; + width: 100% +} + +table table { + margin: -5px 0; + border: 0px solid #e0e7d3; + width: 100%; +} + +table td,table th { + padding: 2px; + border: 1px solid #CCCCCC; +} + +table td form { + text-align:center; + vertical-align: middle; + margin: 0px; +} + +table th { + font-size: 0.9em; + text-align: left; + font-weight: bold; + color: #FFF; + background: #999; +} + +table thead { + font-weight: bold; + font-style: italic; + background-color: #BBBBBB; +} + +table a:link {color: #303030;} + +caption { + caption-side: top; + width: auto; + text-align: left; + font-size: 12px; + color: #848f73; + padding-bottom: 4px; +} + +fieldset { + background: #e0e7d3; + padding: 8px; + padding-bottom: 22px; + border: none; + width: 560px; +} + +fieldset label { + width: 70px; + float: left; + margin-top: 1.7em; + margin-left: 20px; +} + +fieldset textfield { + margin: 3px; + height: 20px; + background: #e0e7d3; +} + +fieldset textarea { + margin: 3px; + height: 165px; + background: #e0e7d3; +} + +fieldset input { + margin: 3px; + height: 20px; + background: #e0e7d3; +} + +fieldset table { + width: 100%; +} + +fieldset th { + padding-left: 25px; +} + +.table-buttons { + background-color:#fff; + border:none; +} + +.table-buttons td { + border:none; +} + +.submit input { + border: 1px solid #BBBBBB; + color:#777777; + padding:2px 7px; + font-size:11px; + text-transform:uppercase; + font-weight:bold; + height:24px; +} + +.updated { + background:#ecf1e5; + font-size:11px; + margin-left:2px; + border:4px solid #ecf1e5; +} + +.updated td { + padding:2px 8px; + font-size:11px; + color:#888888; +} + +.dijitTextArea{ + min-height:5.5em !important; + max-height:22em !important; + overflow-y: auto !important; + max-width: 175px; +} + +.RichTextEditable{ + min-height:18em !important; + max-height:18em !important; +} + +.flag { + height: 11px; + width: 16px; +} \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/styles/standard.css b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/styles/standard.css new file mode 100644 index 000000000..d1a65be31 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/main/webapp/styles/standard.css @@ -0,0 +1,366 @@ +/* main elements */ + +body,div,td { + font-family: Arial, Helvetica, sans-serif; + font-size: 12px; + color: #666; +} + +body { + background-color: #fff; + text-align: center; +} + +#header { + margin-bottom: 1em; +} + +#wrapper { + width:800px; + min-width: 800px; + max-width: 800px; + margin-right: auto; + margin-left: auto; + + /* fix max-width incompatibility in IE6 */ + width:expression(document.body.clientWidth > 800? "800px": "auto" ); + + overflow:hidden; + display:block; +} + +/* header and footer elements */ + +#main { + overflow:hidden; + display:box; +} + +#menu { + background: #eee; + position:relative; + float:left; + left:0px; + width:220px; + margin-right:15px; +} + +#menu ul{ + list-style: none; + margin: 0; + padding: 0; +} + +#menu ul li{ + padding: 0px; +} + + +#menu a, #menu h2 { + display: block; + margin: 0; + padding: 2px 6px; + color:#FFFFFF; +} + +#menu h2 { + color: #fff; + background: #492FFC; + text-transform: uppercase; + font-weight:bold; + font-size: 12px; +} + +#menu a { + color: #666666; + background: #efefef; + text-decoration: none; + padding: 2px 12px; +} + +#menu a:hover { + color: #492FFC; + background: #fff; +} + +#footer { + background:#fff; + border:none; + margin-top:15px; + border-top:1px solid #999999; +} + +#footer .new { + float:left; +} + +#footer a:link {color: #7db223;} + +.quicklinks { + clear:both; + padding-bottom: 15px +} +.quicklinks span { + float: right; +} + +table.navigation { + border: 0px; +} + +label { + width:100px; + float:left; + margin-left: 5px; + margin-top: 0px; +} + +input { + height:20px; +} + +input, textarea, select { + border:1px solid #B3B3B3; +} + +input.image { + border: none; + height: auto; +} + +submit { + height:25px; +} + +div { + text-align: left; +} + +div .box { + display:block; + margin-left:105px; +} + +/* menu elements*/ + +a.menu, a.menu:link, a.menu:visited {display:block; width:150px; height:25px;} + +/* text styles */ + +h1,h2,h3 { + font-family: Helvetica, sans-serif; + color: #7db223; +} + +h1 { + font-size: 20px; + line-height: 26px; +} + +h2 { + font-size: 18px; + line-height: 20px; +} + +h3 { + font-size: 15px; + line-height: 21px; + color:#555; +} + +h4 { + font-size: 14px; + line-height: 20px; +} + +.errors { + color: red; + font-weight: bold; + display: block; + margin-left: 105px; +} + +a { + text-decoration: underline; + font-size: 12px; +} + +a img { + border: 0 none; + vertical-align: middle; +} + +tr:nth-child(odd) { + background-color: #FFFFFF; +} + +tr:nth-child(even) { + background-color: #EFEFEF; +} + +a:link { + color: #7db223; +} + +a:hover { + color: #456314; +} + +a:active { + color: #7db223; +} + +a:visited { + color: #7db223; +} + +li { + padding-top: 5px; + text-align: left; +} + +ul li { + margin:0 0 0.25em 0; + padding:0; +} +/* table elements */ + +table { + background: #EEEEEE; + margin: 2px 0 0 0; + border: 1px solid #BBBBBB; + border-collapse: collapse; + width: 100% +} + +table table { + margin: -5px 0; + border: 0px solid #e0e7d3; + width: 100%; +} + +table td,table th { + padding: 2px; + border: 1px solid #CCCCCC; +} + +table td form { + text-align:center; + vertical-align: middle; + margin: 0px; +} + +table th { + font-size: 0.9em; + text-align: left; + font-weight: bold; + color: #FFF; + background: #999; +} + +table thead { + font-weight: bold; + font-style: italic; + background-color: #BBBBBB; +} + +table a:link {color: #303030;} + +caption { + caption-side: top; + width: auto; + text-align: left; + font-size: 12px; + color: #848f73; + padding-bottom: 4px; +} + +fieldset { + background: #e0e7d3; + padding: 8px; + padding-bottom: 22px; + border: none; + width: 560px; +} + +fieldset label { + width: 70px; + float: left; + margin-top: 1.7em; + margin-left: 20px; +} + +fieldset textfield { + margin: 3px; + height: 20px; + background: #e0e7d3; +} + +fieldset textarea { + margin: 3px; + height: 165px; + background: #e0e7d3; +} + +fieldset input { + margin: 3px; + height: 20px; + background: #e0e7d3; +} + +fieldset table { + width: 100%; +} + +fieldset th { + padding-left: 25px; +} + +.table-buttons { + background-color:#fff; + border:none; +} + +.table-buttons td { + border:none; +} + +.submit input { + border: 1px solid #BBBBBB; + color:#777777; + padding:2px 7px; + font-size:11px; + text-transform:uppercase; + font-weight:bold; + height:24px; +} + +.updated { + background:#ecf1e5; + font-size:11px; + margin-left:2px; + border:4px solid #ecf1e5; +} + +.updated td { + padding:2px 8px; + font-size:11px; + color:#888888; +} + +.dijitTextArea{ + min-height:5.5em !important; + max-height:22em !important; + overflow-y: auto !important; + max-width: 175px; +} + +.RichTextEditable{ + min-height:18em !important; + max-height:18em !important; +} + +.flag { + height: 11px; + width: 16px; +} \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/test/java/com/springdeveloper/data/neo/PrintNeo4j.java b/spring-data-neo4j-examples/myrestaurants-social/src/test/java/com/springdeveloper/data/neo/PrintNeo4j.java new file mode 100644 index 000000000..e5901bf45 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/test/java/com/springdeveloper/data/neo/PrintNeo4j.java @@ -0,0 +1,61 @@ +package com.springdeveloper.data.neo; + +import org.neo4j.graphdb.GraphDatabaseService; +import org.neo4j.graphdb.Node; +import org.neo4j.graphdb.Relationship; +import org.neo4j.graphdb.RelationshipType; +import org.neo4j.graphdb.Transaction; +import org.neo4j.kernel.EmbeddedGraphDatabase; + + +public class PrintNeo4j { + + public static void main(String[] args) { + System.out.println("Hello Neo4j!"); +// GraphDatabaseService graphDb = new EmbeddedGraphDatabase( "target/data/test" ); + GraphDatabaseService graphDb = new EmbeddedGraphDatabase( "/Users/trisberg/neo4j/imdb" ); + Transaction tx = graphDb.beginTx(); + + tx = graphDb.beginTx(); + try { + for (Node n : graphDb.getAllNodes()) { + System.out.print("=> " + n.getId() + " :: "); + for (String s : n.getPropertyKeys()) { + System.out.print(" : " + s + " = " + n.getProperty(s)); + } + for (Relationship r : n.getRelationships()) { + long start = r.getStartNode().getId(); + long end = r.getEndNode().getId(); + if (n.getId() == start) { + System.out.print(" ** " + r.getType().name() + "--> " + end); + + } + if (n.getId() == end) { + System.out.print(" ** " + start + " <--" + r.getType().name()); + + } + for (String s : r.getPropertyKeys()) { + System.out.print(" :: " + s + " = " + r.getProperty(s)); + } + } + System.out.println("!"); + } + tx.success(); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + finally { + tx.finish(); + } + try { + Thread.sleep(5000); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + graphDb.shutdown(); + System.out.println("Done!"); + } + +} diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/test/java/com/springone/myrestaurants/data/AbstractTestWithUserAccount.java b/spring-data-neo4j-examples/myrestaurants-social/src/test/java/com/springone/myrestaurants/data/AbstractTestWithUserAccount.java new file mode 100644 index 000000000..d0d5afb88 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/test/java/com/springone/myrestaurants/data/AbstractTestWithUserAccount.java @@ -0,0 +1,77 @@ +package com.springone.myrestaurants.data; + +import java.util.Date; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.EntityTransaction; +import javax.persistence.PersistenceContext; +import javax.persistence.PersistenceUnit; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.Before; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.neo4j.support.GraphDatabaseContext; +import org.springframework.data.neo4j.support.node.Neo4jHelper; +import org.springframework.test.annotation.Rollback; +import org.springframework.test.context.transaction.AfterTransaction; +import org.springframework.test.context.transaction.BeforeTransaction; +import org.springframework.transaction.annotation.Transactional; + +import com.springone.myrestaurants.domain.UserAccount; + +public class AbstractTestWithUserAccount { + + protected final Log log = LogFactory.getLog(getClass()); + protected Long userId; + + @Autowired + private GraphDatabaseContext graphDatabaseContext; + + @PersistenceContext + protected EntityManager em; + + @PersistenceUnit + protected EntityManagerFactory emf; + + @BeforeTransaction + public void setUpBeforeTransaction() { + EntityManager setUpEm = emf.createEntityManager(); + EntityTransaction setUpTx = setUpEm.getTransaction(); + setUpTx.begin(); + UserAccount u = new UserAccount(); + u.setFirstName("Bubba"); + u.setLastName("Jones"); + u.setBirthDate(new Date()); + u.setUserName("user"); + setUpEm.persist(u); + setUpEm.flush(); + u.persist(); + this.userId = u.getId(); + setUpTx.commit(); + } + + @Before + public void setUp() throws Exception { + // em = emf.createEntityManager(); + } + + @Transactional + @BeforeTransaction + public void cleanDb() { + Neo4jHelper.cleanDb(graphDatabaseContext); + } + + @AfterTransaction + public void tearDown() { + EntityManager tearDownEm = emf.createEntityManager(); + EntityTransaction tearDownTx = tearDownEm.getTransaction(); + tearDownTx.begin(); + UserAccount u = tearDownEm.find(UserAccount.class, this.userId); + tearDownEm.remove(u); + tearDownEm.flush(); + tearDownTx.commit(); + } + +} \ No newline at end of file diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/test/java/com/springone/myrestaurants/data/RestaurantRepositoryTest.java b/spring-data-neo4j-examples/myrestaurants-social/src/test/java/com/springone/myrestaurants/data/RestaurantRepositoryTest.java new file mode 100644 index 000000000..919600266 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/test/java/com/springone/myrestaurants/data/RestaurantRepositoryTest.java @@ -0,0 +1,81 @@ +package com.springone.myrestaurants.data; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; + +import junit.framework.Assert; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.neo4j.support.GraphDatabaseContext; +import org.springframework.data.neo4j.support.node.Neo4jHelper; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.Rollback; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.transaction.BeforeTransaction; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.annotation.Transactional; + +import com.springone.myrestaurants.domain.Restaurant; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration +@DirtiesContext +public class RestaurantRepositoryTest { + + protected final Log log = LogFactory.getLog(getClass()); + + @Autowired + PlatformTransactionManager transactionManager; + + @Autowired + private GraphDatabaseContext graphDatabaseContext; + + @PersistenceContext + EntityManager em; + + @Autowired + RestaurantRepository repo; + + @Transactional + @BeforeTransaction + public void cleanDb() { + Neo4jHelper.cleanDb(graphDatabaseContext); + } + + @Transactional + @Test + public void testFindRestaurant() { + Restaurant r = repo.findRestaurant(1L); + Assert.assertNotNull("should have found something" ,r); + Assert.assertEquals("should have found the right one", "Boston Market", r.getName()); + } + + @Transactional + @Test + public void testFindAllRestaurants() { + List l = repo.findAllRestaurants(); + Assert.assertEquals("should have found them all", 50, l.size()); + } + + @Transactional + @Test + public void testFindRestaurantEntries() { + List l = repo.findRestaurantEntries(20, 10); + Assert.assertEquals("should have found correct number of entries", 10, l.size()); + } + + @Transactional + @Test + public void testCountRestaurants() { + long l = repo.countRestaurants(); + Assert.assertEquals("should be the correctnumber", 50, l); + } +} diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/test/java/com/springone/myrestaurants/data/UserAccountRelationshipsTest.java b/spring-data-neo4j-examples/myrestaurants-social/src/test/java/com/springone/myrestaurants/data/UserAccountRelationshipsTest.java new file mode 100644 index 000000000..ae702f9e8 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/test/java/com/springone/myrestaurants/data/UserAccountRelationshipsTest.java @@ -0,0 +1,92 @@ +package com.springone.myrestaurants.data; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Set; + +import junit.framework.Assert; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.transaction.annotation.Transactional; + +import com.springone.myrestaurants.domain.Recommendation; +import com.springone.myrestaurants.domain.Restaurant; +import com.springone.myrestaurants.domain.UserAccount; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration +@DirtiesContext +public class UserAccountRelationshipsTest extends AbstractTestWithUserAccount { + + @Autowired + UserAccountRepository userAccountRepo; + + @Autowired + RestaurantRepository restaurantRepository; + + @Transactional + @Test + public void listFriends() { + UserAccount user = userAccountRepo.findUserAccount(userId); + UserAccount newUser = new UserAccount(); + newUser.setFirstName("John"); + newUser.setLastName("Doe"); + newUser.setBirthDate(new Date()); + newUser.setNickname("Bubba"); + newUser.setUserName("jdoe"); + em.persist(newUser); + newUser.persist(); + Assert.assertEquals("Should have zero friends", 0, newUser.getFriends().size()); + newUser.getFriends().add(user); + Assert.assertEquals("Should have a list of friends", 1, newUser.getFriends().size()); + } + + @Transactional + @Test + public void testAddAndRemoveFriends() { + UserAccount user = userAccountRepo.findUserAccount(userId); + UserAccount newUser = new UserAccount(); + newUser.setFirstName("John"); + newUser.setLastName("Doe"); + newUser.setBirthDate(new Date()); + newUser.setNickname("Bubba"); + newUser.setUserName("jdoe"); + userAccountRepo.persist(newUser); + em.flush(); + newUser.persist(); + user.getFriends().add(newUser); + UserAccount updatedUser = userAccountRepo.findUserAccount(userId); + Assert.assertNotNull("should have found something" ,updatedUser); + Assert.assertEquals("user should now have correct number of friends", 1, updatedUser.getFriends().size()); + user.getFriends().remove(newUser); + Assert.assertEquals("user should now have correct number of friends", 0, updatedUser.getFriends().size()); + } + + @Transactional + @Test + public void testAddRecommendation() { + UserAccount user = userAccountRepo.findUserAccount(userId); + Restaurant rest = restaurantRepository.findRestaurant(22L); + user.rate(rest, 3, "Pretty Good"); + em.flush(); + UserAccount updatedUser = userAccountRepo.findUserAccount(userId); + Assert.assertNotNull("should have found something" ,updatedUser); + List recommendations = new ArrayList(); + for (Recommendation r : updatedUser.getRecommendations()) { + recommendations.add(r); + } + Assert.assertEquals("user should now have correct number of recommendations", 1, recommendations.size()); + Recommendation r = recommendations.get(0); + Assert.assertEquals("recommendation should have correct rating", 3, r.getStars()); + Assert.assertEquals("recommendation should have correct comment", "Pretty Good", r.getComment()); + Assert.assertEquals("recommendation should have correct restaurant id", new Long(22), r.getRestaurant().getId()); + Assert.assertEquals("recommendation should have correct restaurant name", "Subway Sandwiches & Salads", r.getRestaurant().getName()); + } + +} diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/test/java/com/springone/myrestaurants/data/UserAccountRepositoryTest.java b/spring-data-neo4j-examples/myrestaurants-social/src/test/java/com/springone/myrestaurants/data/UserAccountRepositoryTest.java new file mode 100644 index 000000000..e7992e792 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/test/java/com/springone/myrestaurants/data/UserAccountRepositoryTest.java @@ -0,0 +1,101 @@ +package com.springone.myrestaurants.data; + +import java.util.Date; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.EntityTransaction; +import javax.persistence.PersistenceContext; +import javax.persistence.PersistenceUnit; + +import junit.framework.Assert; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.Rollback; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.transaction.AfterTransaction; +import org.springframework.test.context.transaction.BeforeTransaction; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.annotation.Transactional; + +import com.springone.myrestaurants.domain.UserAccount; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration +@DirtiesContext +public class UserAccountRepositoryTest extends AbstractTestWithUserAccount { + + @Autowired + UserAccountRepository repo; + + @Transactional + @Test + public void testFindUser() { + UserAccount o = repo.findUserAccount(userId); + Assert.assertNotNull("should have found something" ,o); + Assert.assertEquals("should have found the right one", "user", o.getUserName()); + } + + @Transactional + @Test + public void testFindByName() { + UserAccount o = repo.findByName("user"); + Assert.assertNotNull("should have found something" ,o); + Assert.assertEquals("should have found the right one", "user", o.getUserName()); + } + + @Transactional + @Test + public void testPersist() { + UserAccount newUser = new UserAccount(); + newUser.setFirstName("John"); + newUser.setLastName("Doe"); + newUser.setBirthDate(new Date()); + newUser.setNickname("Bubba"); + newUser.setUserName("jdoe"); + repo.persist(newUser); + em.flush(); + List results = em.createNativeQuery("select id, user_name, first_name from user_account where user_name = ?") + .setParameter(1, newUser.getUserName()).getResultList(); + Assert.assertEquals("should have found the entry", 1, results.size()); + Assert.assertEquals("should have found the correct entry", "John", ((Object[])results.get(0))[2]); + UserAccount persistedUser = repo.findByName(newUser.getUserName()); + Assert.assertEquals("should have the correct value", newUser.getFirstName(), persistedUser.getFirstName()); + Assert.assertEquals("should have the correct value", newUser.getLastName(), persistedUser.getLastName()); + Assert.assertEquals("should have the correct value", newUser.getNickname(), persistedUser.getNickname()); + Assert.assertEquals("should have the correct value", newUser.getUserName(), persistedUser.getUserName()); + Assert.assertEquals("should have the correct value", newUser.getBirthDate(), persistedUser.getBirthDate()); + } + + @Transactional + @Test + public void testMerge() { + EntityManager separateTxEm = emf.createEntityManager(); + EntityTransaction separateTx = separateTxEm.getTransaction(); + separateTx.begin(); + UserAccount user = separateTxEm.find(UserAccount.class, userId); + separateTxEm.flush(); + Assert.assertTrue("entity is part of separate em", separateTxEm.contains(user)); + separateTx.commit(); + separateTxEm.detach(user); + Assert.assertFalse("entity is no longer part of separate em", separateTxEm.contains(user)); + Assert.assertFalse("entity is not part of main em", em.contains(user)); + user.setLastName("Hendrix"); + UserAccount mergedUser = repo.merge(user); + em.flush(); + Assert.assertTrue("entity is now part of main em", em.contains(mergedUser)); + List results = em.createNativeQuery("select id, user_name, last_name from user_account where id = ?") + .setParameter(1, userId).getResultList(); + Assert.assertEquals("should have found the entry", 1, results.size()); + Assert.assertEquals("should have found the updated entry", "Hendrix", ((Object[])results.get(0))[2]); + } + +} diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/test/java/com/springone/myrestaurants/domain/TopRatedRestaurantFinderTest.java b/spring-data-neo4j-examples/myrestaurants-social/src/test/java/com/springone/myrestaurants/domain/TopRatedRestaurantFinderTest.java new file mode 100644 index 000000000..3552839a9 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/test/java/com/springone/myrestaurants/domain/TopRatedRestaurantFinderTest.java @@ -0,0 +1,111 @@ +package com.springone.myrestaurants.domain; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.neo4j.graphdb.Node; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.neo4j.support.GraphDatabaseContext; +import org.springframework.data.neo4j.support.node.Neo4jHelper; +import org.springframework.jdbc.core.simple.SimpleJdbcTemplate; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.transaction.BeforeTransaction; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.annotation.Transactional; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.sql.DataSource; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import static java.util.Arrays.asList; + +/** + * @author Michael Hunger + * @since 02.10.2010 + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration +@DirtiesContext +@Transactional +public class TopRatedRestaurantFinderTest { + @Autowired + private GraphDatabaseContext graphDatabaseContext; + + @PersistenceContext + EntityManager em; + + @Autowired + DataSource dataSource; + + @Autowired + PlatformTransactionManager transactionManager; + + @Before + @BeforeTransaction + public void cleanDb() { + Neo4jHelper.cleanDb(graphDatabaseContext); + } + + @Test + public void returnsFriendsInOrder() { + final Restaurant a = restaurant("a"); + final Restaurant b = restaurant("b"); + final Restaurant c = restaurant("c"); + final UserAccount A = user("A"); + final UserAccount B1 = user("B1"); + final UserAccount B2 = user("B2"); + final UserAccount C1 = user("C1"); + Assert.assertNotNull("user has node", node(A)); + A.knows(B1); + A.knows(B2); + B1.knows(C1); + C1.rate(a, 1, ""); + C1.rate(b, 5, ""); + C1.rate(c, 3, ""); + final Node node = node(A); + final Collection topNRatedRestaurants = new TopRatedRestaurantFinder().getTopNRatedRestaurants(A, 5); + Collection result = new ArrayList(); + for (RatedRestaurant ratedRestaurant : topNRatedRestaurants) { + result.add(ratedRestaurant.getRestaurant()); + } + final Restaurant b2 = em.find(Restaurant.class, 2L); + Assert.assertNotNull(b2); + Assert.assertEquals(asList(b,c, a), result); + } + + private Node node(UserAccount a) { + return a.getPersistentState(); + } + + private UserAccount user(String name) { + UserAccount userAccount = new UserAccount(); + //userAccount.setId((long) name.hashCode()); + em.persist(userAccount); + em.flush(); + userAccount.persist(); + userAccount.setNickname(name); + return userAccount; + } + + private Restaurant restaurant(String name) { + Restaurant restaurant = new Restaurant(); + restaurant.setName(name); + //restaurant.setId((long) name.hashCode()); + em.persist(restaurant); + em.flush(); + restaurant.persist(); + return restaurant; + } + + private void dumpResults(String sql) { + final List> result = new SimpleJdbcTemplate(dataSource).queryForList(sql); + System.out.println("result = " + result); + } +} diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/test/resources/com/springone/myrestaurants/data/DataStore-context.xml b/spring-data-neo4j-examples/myrestaurants-social/src/test/resources/com/springone/myrestaurants/data/DataStore-context.xml new file mode 100644 index 000000000..28e4db540 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/test/resources/com/springone/myrestaurants/data/DataStore-context.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/test/resources/com/springone/myrestaurants/data/RestaurantRepositoryTest-context.xml b/spring-data-neo4j-examples/myrestaurants-social/src/test/resources/com/springone/myrestaurants/data/RestaurantRepositoryTest-context.xml new file mode 100644 index 000000000..363e18db7 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/test/resources/com/springone/myrestaurants/data/RestaurantRepositoryTest-context.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/test/resources/com/springone/myrestaurants/data/UserAccountRelationshipsTest-context.xml b/spring-data-neo4j-examples/myrestaurants-social/src/test/resources/com/springone/myrestaurants/data/UserAccountRelationshipsTest-context.xml new file mode 100644 index 000000000..363e18db7 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/test/resources/com/springone/myrestaurants/data/UserAccountRelationshipsTest-context.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/test/resources/com/springone/myrestaurants/data/UserAccountRepositoryTest-context.xml b/spring-data-neo4j-examples/myrestaurants-social/src/test/resources/com/springone/myrestaurants/data/UserAccountRepositoryTest-context.xml new file mode 100644 index 000000000..363e18db7 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/test/resources/com/springone/myrestaurants/data/UserAccountRepositoryTest-context.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/test/resources/com/springone/myrestaurants/domain/DataStore-context.xml b/spring-data-neo4j-examples/myrestaurants-social/src/test/resources/com/springone/myrestaurants/domain/DataStore-context.xml new file mode 100644 index 000000000..458cf7c15 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/test/resources/com/springone/myrestaurants/domain/DataStore-context.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + diff --git a/spring-data-neo4j-examples/myrestaurants-social/src/test/resources/com/springone/myrestaurants/domain/TopRatedRestaurantFinderTest-context.xml b/spring-data-neo4j-examples/myrestaurants-social/src/test/resources/com/springone/myrestaurants/domain/TopRatedRestaurantFinderTest-context.xml new file mode 100644 index 000000000..bdc13f954 --- /dev/null +++ b/spring-data-neo4j-examples/myrestaurants-social/src/test/resources/com/springone/myrestaurants/domain/TopRatedRestaurantFinderTest-context.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + diff --git a/spring-data-neo4j-examples/readme.md b/spring-data-neo4j-examples/readme.md new file mode 100644 index 000000000..a1a895e01 --- /dev/null +++ b/spring-data-neo4j-examples/readme.md @@ -0,0 +1,6 @@ +This repository contains examples for using the Spring Data Neo4j Library, +currently the examples all use the 1.0.0.M4 release. + +* HelloWorlds is a simple application showing the basic setup, annotations and usage +* Imdb is a graph based webapp for a movie - actor database using an older spring-web stack and an example for in graph indexes +* Myrestaurants-Social is a spring-roo generated and then modified restaurant - rating webapp that was extended using a social graph with ratings and recommendations