/***
* Copyright (c) 2009 Caelum - www.caelum.com.br/opensource
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package br.com.caelum.vraptor.musicjungle.controller;
import static br.com.caelum.vraptor.view.Results.http;
import static br.com.caelum.vraptor.view.Results.json;
import static br.com.caelum.vraptor.view.Results.representation;
import static br.com.caelum.vraptor.view.Results.xml;
import java.io.File;
import java.io.FileNotFoundException;
import javax.inject.Inject;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import br.com.caelum.vraptor.Controller;
import br.com.caelum.vraptor.Get;
import br.com.caelum.vraptor.Path;
import br.com.caelum.vraptor.Post;
import br.com.caelum.vraptor.Result;
import br.com.caelum.vraptor.musicjungle.dao.MusicDao;
import br.com.caelum.vraptor.musicjungle.dao.UserDao;
import br.com.caelum.vraptor.musicjungle.files.Musics;
import br.com.caelum.vraptor.musicjungle.interceptor.Public;
import br.com.caelum.vraptor.musicjungle.interceptor.UserInfo;
import br.com.caelum.vraptor.musicjungle.model.Music;
import br.com.caelum.vraptor.musicjungle.model.User;
import br.com.caelum.vraptor.observer.download.Download;
import br.com.caelum.vraptor.observer.download.FileDownload;
import br.com.caelum.vraptor.observer.upload.UploadedFile;
import br.com.caelum.vraptor.validator.Validator;
import com.google.common.base.Objects;
/**
* The resource <code>MusicController</code> handles all Music
* operations, such as adding new Musics, listing all, and so on.
*
* This is a RESTful Resource, so we will explain how to use REST
* on VRaptor 3 here.
*
* POST /musics -> adds a music
*
* GET /musics/{id} -> shows the music of given id
*/
@Controller
public class MusicController {
private static final Logger logger = LoggerFactory.getLogger(MusicController.class);
private final Result result;
private final Validator validator;
private final UserInfo userInfo;
private final MusicDao musicDao;
private final Musics musics;
private final UserDao userDao;
/**
* @deprecated CDI eyes only
*/
protected MusicController() {
this(null, null, null, null, null, null);
}
/**
* Receives dependencies through the constructor.
*
* @param userInfo info on the logged user.
* @param result VRaptor result handler.
* @param validator VRaptor validator.
* @param factory dao factory.
* @param userDao
*/
@Inject
public MusicController(MusicDao musicDao, UserInfo userInfo,
Result result, Validator validator, Musics musics, UserDao userDao) {
this.musicDao = musicDao;
this.result = result;
this.validator = validator;
this.userInfo = userInfo;
this.musics = musics;
this.userDao = userDao;
}
/**
* Accepts HTTP POST requests.
*
* URL: /musics
* View: /WEB-INF/jsp/music/add.jsp
*
* The method adds a new music and updates the user.
* We use POST HTTP verb when we want to create some resource.
*
* The <code>UploadedFile</code> is automatically handled
* by VRaptor's <code>MultipartInterceptor</code>.
*/
@Path("/musics")
@Post
public void add(final @NotNull @Valid Music music, UploadedFile file) {
validator.onErrorForwardTo(UsersController.class).home();
musicDao.add(music);
User currentUser = userInfo.getUser();
userDao.refresh(currentUser);
currentUser.add(music);
// is there a file?
if (file != null) {
// Let's save the file
musics.save(file, music);
logger.info("Uploaded file: {}", file.getFileName());
}
// you can add objects to result even in redirects. Added objects will
// survive one more request when redirecting.
result.include("notice", music.getTitle() + " music added");
result.redirectTo(UsersController.class).home();
}
/**
* Accepts HTTP GET requests.
*
* URL: /musics/{id}
* View: /WEB-INF/jsp/music/show.jsp
* Shows the page with information about given Music
*
* We should only use GET HTTP verb for safe operations. For
* instance, showing a Music has no side effects, so GET is fine.
*
* We can use templates for Paths, so VRaptor will automatically extract
* variables of the matched URI, and set the fields on parameters.
*
* In this case, GET /musics/15 will execute the method below, and
* there will be a parameter music.id=15 on request, causing music.getId()
* equal to 15.
*/
@Path("/musics/{music.id}")
@Get
public void show(Music music) {
result.include("music", musicDao.load(music));
}
/**
* Accepts HTTP GET requests.
*
* URL: /musics/search
* View: /WEB-INF/jsp/music/search.jsp
*
* Searches are not unique resources, so it is ok to use searches with
* query parameters.
*/
@Get("/musics/search")
public void search(Music music) {
String title = Objects.firstNonNull(music.getTitle(), "");
result.include("musics", this.musicDao.searchSimilarTitle(title));
}
@Path("/musics/download/{m.id}")
@Get
public Download download(Music m) throws FileNotFoundException {
Music music = musicDao.load(m);
File file = musics.getFile(music);
String contentType = "audio/mpeg";
String filename = music.getTitle() + ".mp3";
return new FileDownload(file, contentType, filename);
}
/**
* Show all list of registered musics in json format
*/
@Public @Path("/musics/list/json")
public void showAllMusicsAsJSON() {
result.use(json()).from(musicDao.listAll()).serialize();
}
/**
* Show all list of registered musics in xml format
*/
@Public @Path("/musics/list/xml")
public void showAllMusicsAsXML() {
result.use(xml()).from(musicDao.listAll()).serialize();
}
/**
* Show all list of registered musics in http format
*/
@Public @Path("/musics/list/http")
public void showAllMusicsAsHTTP() {
result.use(http()).body("<p class=\"content\">"+
musicDao.listAll().toString()+"</p>");
}
@Public @Path("/musics/list/form")
public void listForm() {}
@Public @Path("musics/listAs")
public void listAs() {
result.use(representation())
.from(musicDao.listAll()).serialize();
}
}