Java tutorial
/* * * Copyright 2014 Jules White * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.magnum.dataup; import java.io.IOException; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.net.UnknownHostException; import java.util.Collection; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.atomic.AtomicLong; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.magnum.dataup.model.Video; import org.magnum.dataup.model.VideoStatus; import org.magnum.dataup.model.VideoStatus.VideoState; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.multipart.MultipartFile; @Controller // public class AnEmptyController { /** * You will need to create one or more Spring controllers to fulfill the * requirements of the assignment. If you use this file, please rename it * to something other than "AnEmptyController" * * ________ ________ ________ ________ ___ ___ ___ ________ ___ __ |\ ____\|\ __ \|\ __ \|\ ___ \ |\ \ |\ \|\ \|\ ____\|\ \|\ \ \ \ \___|\ \ \|\ \ \ \|\ \ \ \_|\ \ \ \ \ \ \ \\\ \ \ \___|\ \ \/ /|_ \ \ \ __\ \ \\\ \ \ \\\ \ \ \ \\ \ \ \ \ \ \ \\\ \ \ \ \ \ ___ \ \ \ \|\ \ \ \\\ \ \ \\\ \ \ \_\\ \ \ \ \____\ \ \\\ \ \ \____\ \ \\ \ \ \ \_______\ \_______\ \_______\ \_______\ \ \_______\ \_______\ \_______\ \__\\ \__\ \|_______|\|_______|\|_______|\|_______| \|_______|\|_______|\|_______|\|__| \|__| * */ public class VideoController { // Datastore objects to store/save videoes (from README.md) private Map<Long, Video> videos = new HashMap<Long, Video>(); private static final AtomicLong currentId = new AtomicLong(0L); // Used to read/write videos to a file private VideoFileManager videoDataMgr; /* #1 GET/video. * Returns the list of videos that have been added to the server as JSON. * Unmarshalled by the client into a collection<video>. */ @RequestMapping(value = VideoSvcApi.VIDEO_SVC_PATH, method = RequestMethod.GET) public @ResponseBody Collection<Video> getVideoList() { return videos.values(); } /* #2 POST /video. * Video metadata provided as json request body. * Returns JSON representation of the video object stored, along with updates made by * the server(generate unique identifier and data url of the binary (raw mpeg) data for * the video. */ @RequestMapping(value = VideoSvcApi.VIDEO_SVC_PATH, method = RequestMethod.POST) public @ResponseBody Video addVideo(@RequestBody Video v) { // Method from README.md checkAndSetId(v); System.out.println("Saving video: " + v.toString()); videos.put(v.getId(), v); v.setDataUrl(getDataUrl(v.getId())); return v; } /* #3 POST /video/{id}/data. * Binary mpeg data provided in a multipart request as a part with the key "data". * The id in the path must be replaced with the unique identifier generated by the server. * The Client first send a POST to /video to get the unique id og the created video object, before * sending a POST to /video/{id}data. * Returns a VideoStatus(VideoState.READY) if request succeed and otherwise return 404 error. * Id should be greater than 0. * If VideoDataManager already has the videodata give message about overwriting video(allowed). */ @RequestMapping(value = VideoSvcApi.VIDEO_DATA_PATH, method = RequestMethod.POST) public @ResponseBody VideoStatus setVideoData(@PathVariable(VideoSvcApi.ID_PARAMETER) long id, @RequestParam(VideoSvcApi.DATA_PARAMETER) MultipartFile videoData, HttpServletResponse response) throws IOException { System.out.println("Saving video rawData: " + Long.toString(id)); if (!videos.containsKey(id)) { System.out.println("Id for video not found"); response.setStatus(HttpStatus.NOT_FOUND.value()); } else if (id > 0) { System.out.println("Start saving video rawData: " + videos.get(id)); Video v = videos.get(id); if (videoDataMgr == null) { videoDataMgr = VideoFileManager.get(); } videoDataMgr.saveVideoData(v, videoData.getInputStream()); System.out.println("Video raw data was saved at id: " + v); } return new VideoStatus(VideoState.READY); } /* #4 GET /video/{id}/data. * Returns the binary mpeg data if found for the given identifier. * If video data id not found return 404 status code */ @RequestMapping(value = VideoSvcApi.VIDEO_DATA_PATH, method = RequestMethod.GET) public @ResponseBody void getVideoData(@PathVariable(VideoSvcApi.ID_PARAMETER) long id, HttpServletResponse response) throws IOException { if (!videos.containsKey(id)) { response.setStatus(HttpStatus.NOT_FOUND.value()); } else { Video v = videos.get(id); if (videoDataMgr == null) { videoDataMgr = VideoFileManager.get(); } videoDataMgr.copyVideoData(v, response.getOutputStream()); } } @RequestMapping(value = VideoSvcApi.VIDEO_UPDATE_PATH, method = RequestMethod.GET) public @ResponseBody Video updateVideo(@PathVariable(VideoSvcApi.ID_PARAMETER) long id, @RequestParam int star, HttpServletResponse response) { System.out.println("Rating video: " + id + " star " + star); Video video = videos.get(id); if (video != null) { video.setStar(video.getStar() + star); video.setRateTimes(video.getRateTimes() + 1); System.out.println("video ID: " + id + "current total stars are:" + video.getStar() + "rate time are: " + video.getRateTimes()); video.setAverageStar(video.getStar() / video.getRateTimes()); return video; } response.setStatus(HttpStatus.NOT_FOUND.value()); return null; } // Method from README.md private void checkAndSetId(Video entity) { if (entity.getId() == 0) { entity.setId(currentId.incrementAndGet()); } } // Method from README.md (generate data url for a video) private String getDataUrl(long videoId) { String url = getUrlBaseForLocalServer() + "/video/" + videoId + "/data"; return url; } // Method from README.md (Find the address of the server). private String getUrlBaseForLocalServer() { HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()) .getRequest(); InetAddress IP = null; try { IP = getLocalHostLANAddress(); } catch (UnknownHostException e) { e.printStackTrace(); } System.out.println("IP of my system is := " + IP.getHostAddress()); String base = "http://" + IP.getHostAddress() + ((request.getServerPort() != 80) ? ":" + request.getServerPort() : ""); System.out.println("dataUrl is :" + base); return base; } private static InetAddress getLocalHostLANAddress() throws UnknownHostException { try { InetAddress candidateAddress = null; // Iterate all NICs (network interface cards)... for (Enumeration ifaces = NetworkInterface.getNetworkInterfaces(); ifaces.hasMoreElements();) { NetworkInterface iface = (NetworkInterface) ifaces.nextElement(); // Iterate all IP addresses assigned to each card... for (Enumeration inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements();) { InetAddress inetAddr = (InetAddress) inetAddrs.nextElement(); if (!inetAddr.isLoopbackAddress()) { if (inetAddr.isSiteLocalAddress()) { // Found non-loopback site-local address. Return it immediately... return inetAddr; } else if (candidateAddress == null) { // Found non-loopback address, but not necessarily site-local. // Store it as a candidate to be returned if site-local address is not subsequently found... candidateAddress = inetAddr; // Note that we don't repeatedly assign non-loopback non-site-local addresses as candidates, // only the first. For subsequent iterations, candidate will be non-null. } } } } if (candidateAddress != null) { // We did not find a site-local address, but we found some other non-loopback address. // Server might have a non-site-local address assigned to its NIC (or it might be running // IPv6 which deprecates the "site-local" concept). // Return this non-loopback candidate address... return candidateAddress; } // At this point, we did not find a non-loopback address. // Fall back to returning whatever InetAddress.getLocalHost() returns... InetAddress jdkSuppliedAddress = InetAddress.getLocalHost(); if (jdkSuppliedAddress == null) { throw new UnknownHostException( "The JDK InetAddress.getLocalHost() method unexpectedly returned null."); } return jdkSuppliedAddress; } catch (Exception e) { UnknownHostException unknownHostException = new UnknownHostException( "Failed to determine LAN address: " + e); unknownHostException.initCause(e); throw unknownHostException; } } }