Java tutorial
package siddur.solidtrust.image; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.net.URLEncoder; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import java.util.concurrent.LinkedBlockingQueue; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.time.DateUtils; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.log4j.Logger; import org.apache.lucene.search.Query; import org.hibernate.search.jpa.FullTextEntityManager; import org.hibernate.search.jpa.FullTextQuery; import org.hibernate.search.jpa.Search; import org.hibernate.search.query.dsl.QueryBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Controller; import org.springframework.transaction.annotation.Transactional; import org.springframework.ui.Model; import org.springframework.util.FileCopyUtils; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.context.request.async.DeferredResult; import org.springframework.web.multipart.MultipartFile; import siddur.solidtrust.FileSystemUtil; import siddur.solidtrust.FreePersister; import siddur.solidtrust.SolidtrustConstants; import siddur.solidtrust.entity.AccessItem; import siddur.solidtrust.entity.ImageInfo; import siddur.solidtrust.entity.ImageProduct; import siddur.solidtrust.image.netcar.NetCarService; import siddur.solidtrust.site.ProductAPI.Product; @Controller public class ImageController { private final Logger log4j = Logger.getLogger(ImageController.class); private final LinkedBlockingQueue<DeferredResult<Object>> suspendedImageRequests = new LinkedBlockingQueue<DeferredResult<Object>>( 20); @PersistenceContext private EntityManager em; @Autowired private ImageProductService ipService; @Autowired private ImageFetcher imgFetcher; @Autowired private FreePersister free; @Autowired private CustomSearchExtractor extractor; @Autowired private NetCarService netCarService; @RequestMapping(value = "/image/search") @Transactional(readOnly = true) public String search(@RequestParam(value = "key", required = false) String key, @RequestParam(value = "type", required = false, defaultValue = "1") int type, @RequestParam(value = "page", required = false, defaultValue = "1") Integer pageIndex, Model model) throws Exception { int pageSize = 8; if (type == 1) { //Search by keywords if (!StringUtils.isEmpty(key)) { FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(em); QueryBuilder qb = fullTextEntityManager.getSearchFactory().buildQueryBuilder() .forEntity(ImageProduct.class).get(); Query query = qb.keyword().onFields("brand", "type", "arrangement", "buildYear") .matching(key.toLowerCase()).createQuery(); FullTextQuery persistenceQuery = fullTextEntityManager.createFullTextQuery(query, ImageProduct.class); persistenceQuery.setMaxResults(pageSize); persistenceQuery.setFirstResult((pageIndex - 1) * pageSize); @SuppressWarnings("unchecked") List<ImageProduct> ips = persistenceQuery.getResultList(); Pageable pageable = new PageRequest(pageIndex - 1, pageSize); Page<ImageProduct> page = new PageImpl<ImageProduct>(ips, pageable, persistenceQuery.getResultSize()); model.addAttribute("page", page); } } else if (type == 2) { //Search by license plate if (key != null) { ImageProduct ip = findImagesByLicensePlate(key); model.addAttribute("ip", ip); } } model.addAttribute("key", key); return "image/search"; } @RequestMapping(value = "/image/manage") @Transactional(readOnly = true) public String manage(@RequestParam(value = "type", required = false, defaultValue = "0") int type, @RequestParam(value = "daterange", required = false) String daterange, @RequestParam(value = "page", required = false, defaultValue = "1") Integer pageIndex, Model model) throws Exception { int pageSize = 8; Pageable pageable = new PageRequest(pageIndex - 1, pageSize); Page<ImageProduct> page = null; if (type == 0) { List<ImageProduct> list = em.createQuery("from ImageProduct", ImageProduct.class) .setFirstResult((pageIndex - 1) * pageSize).setMaxResults(pageSize).getResultList(); long count = em.createQuery("select count(ip) from ImageProduct ip", Long.class).getSingleResult(); page = new PageImpl<ImageProduct>(list, pageable, count); } else if (type == 1) { if (daterange.equals("")) { type = 0; } else { model.addAttribute("daterange", daterange); String[] dates = daterange.split(" - "); SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); Date from = formatter.parse(dates[0]); Date to = formatter.parse(dates[1]); to = DateUtils.addDays(to, 1); List<ImageProduct> list = em .createQuery("from ImageProduct ip where ip.createdAt between :from and :to", ImageProduct.class) .setParameter("from", from).setParameter("to", to) .setFirstResult((pageIndex - 1) * pageSize).setMaxResults(pageSize).getResultList(); long count = em.createQuery( "select count(ip) from ImageProduct ip where ip.createdAt between :from and :to", Long.class).setParameter("from", from).setParameter("to", to).getSingleResult(); page = new PageImpl<ImageProduct>(list, pageable, count); } } if (page != null) model.addAttribute("page", page); model.addAttribute("type", type); return "image/manage"; } @Transactional(readOnly = false) @RequestMapping(value = "/image/order/{id}") public @ResponseBody int order(@PathVariable(value = "id") int id, @RequestParam(value = "srcIndex") int src, @RequestParam(value = "tgtIndex") int tgt) { ImageProduct ip = em.find(ImageProduct.class, id); String srcUrl = getImage(ip, src); String tgtUrl = getImage(ip, tgt); setImage(ip, srcUrl, tgt); setImage(ip, tgtUrl, src); em.persist(ip); return 1; } @Transactional(readOnly = false) @RequestMapping(value = "/image/del/{id}") public @ResponseBody int delete(@PathVariable(value = "id") int id, Model model) throws Exception { ImageProduct ip = em.find(ImageProduct.class, id); em.remove(ip); log4j.info("Removed ImageProduct with ID:" + id); return 1; } @Transactional(readOnly = false) @RequestMapping(value = "/image/save") public @ResponseBody String save(@RequestParam(value = "index") int index, @RequestParam(value = "imageProductId") int imageProductId, @RequestParam(value = "url", required = false) String url, @RequestParam(value = "file", required = false) MultipartFile file, Model model) throws Exception { ImageInfo image = null; if (!StringUtils.isEmpty(url)) { CloseableHttpClient httpclient = HttpClients.createDefault(); try { image = extractor.persist(url, httpclient); } finally { httpclient.close(); } } else if (file != null) { image = extractor.persist(file); } if (image != null) { String filename = image.getUuid(); ImageProduct ip = em.find(ImageProduct.class, imageProductId); setImage(ip, filename, index); em.persist(ip); return filename; } return ""; } @RequestMapping(value = "/images/{filename:.+}") public void serveImage(HttpServletRequest req, HttpServletResponse resp, @PathVariable("filename") String filename, @RequestParam(value = "s", required = false) String scope) throws IOException { String filepath = filename; if (scope != null) { filepath = scope + "/" + filepath; } //404 File f = new File(FileSystemUtil.getImageDir(), filepath); if (!f.exists()) { resp.sendError(HttpServletResponse.SC_NOT_FOUND); return; } //304 long lastModifiedTimestamp = f.lastModified(); long ifModifiedSince = req.getDateHeader("If-Modified-Since"); boolean notModified = (ifModifiedSince >= (lastModifiedTimestamp / 1000 * 1000)); if (notModified) { resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED); return; } else { resp.setDateHeader("Last-Modified", lastModifiedTimestamp); } //length resp.setContentLength((int) f.length()); //content type resp.setContentType("image/jpg"); //response FileCopyUtils.copy(new FileInputStream(f), resp.getOutputStream()); } @RequestMapping(value = "/api/images") public @ResponseBody DeferredResult<Object> findCarImages(final @RequestParam("id") String id, HttpServletRequest request) { final String ip = request.getRemoteHost(); final String username = request.getAttribute(SolidtrustConstants.CLIENT_ID) + ""; final int port = request.getLocalPort(); final String address = request.getLocalAddr(); final DeferredResult<Object> result = new DeferredResult<>(2000L, "no data"); log4j.info("Id=" + id + " ,Remaining: " + suspendedImageRequests.remainingCapacity()); try { suspendedImageRequests.add(result); } catch (Exception e1) { result.setResult("Image service is overload"); return result; } result.onCompletion(new Runnable() { @Override public void run() { suspendedImageRequests.remove(result); } }); new Thread(new Runnable() { @Override public void run() { AccessItem ai = new AccessItem(); ai.setIp(ip); ai.setUsername(username); ai.setService(Product.IMAGES.getId()); ai.setRequest(id); ImageProduct ip = null; try { ip = findImagesByLicensePlate(id); } catch (Exception e) { ai.setStatus(-1); log4j.error(e.getMessage(), e); ai.setResponse(e.getMessage()); free.save(ai); return; } if (ip == null) { ai.setStatus(-1); ai.setResponse("Not found:" + id); free.save(ai); return; } ai.setResponse(ip.getId() + ""); free.save(ai); ImageProduct resp = addPrefix(port, address, ip); result.setResult(resp); } }).start(); return result; } @RequestMapping(value = "/api/images1") public @ResponseBody Object findCarImages1(final @RequestParam("id") String id, HttpServletRequest request) { final int port = request.getLocalPort(); final String address = request.getLocalAddr(); String username = request.getAttribute(SolidtrustConstants.CLIENT_ID) + ""; AccessItem ai = new AccessItem(); ai.setIp(request.getRemoteHost()); ai.setUsername(username); ai.setService(Product.IMAGES.getId()); ai.setRequest(id); ImageProduct ip = null; try { ip = findImagesByLicensePlate(id, false); ai.setResponse(ip.getImage1()); } catch (Exception e) { } if (ip == null) { ai.setStatus(-1); free.save(ai); return "no data"; } free.save(ai); String portStr = port == 80 ? "" : ":" + port; String prex = "http://" + address + portStr + "/solidtrust/images/"; ImageProduct resp = new ImageProduct(); resp.setArrangement(ip.getArrangement()); resp.setBrand(ip.getBrand()); resp.setType(ip.getType()); resp.setBuildYear(ip.getBuildYear()); if (ip.getImage1() != null) { resp.setImage1(prex + ip.getImage1()); } if (ip.getImage2() != null) { resp.setImage2(prex + ip.getImage2()); } if (ip.getImage3() != null) { resp.setImage3(prex + ip.getImage3()); } if (ip.getImage4() != null) { resp.setImage4(prex + ip.getImage4()); } return resp; } @RequestMapping(value = "/api/images2") public @ResponseBody Object findCarImages(final String brand, final String model, final String build, HttpServletRequest request) { final String ip = request.getRemoteHost(); final String username = request.getAttribute(SolidtrustConstants.CLIENT_ID) + ""; final int port = request.getLocalPort(); final String address = request.getLocalAddr(); AccessItem ai = new AccessItem(); ai.setIp(ip); ai.setUsername(username); ai.setService(Product.IMAGES2.getId()); ai.setRequest("Brand=" + brand + ", Model=" + model + ", Build=" + build); log4j.info("Brand=" + brand + ", Model=" + model + ", Build=" + build + " ,Remaining: " + suspendedImageRequests.remainingCapacity()); try { ImageProduct imageProduct = netCarService.search(brand, model, build); ai.setResponse(imageProduct.getImage1()); free.save(ai); return addPrefix(port, address, imageProduct); } catch (Exception e) { log4j.error(e.getMessage(), e); ai.setResponse(e.getMessage()); free.save(ai); } return "no data"; } private ImageProduct addPrefix(int port, String address, ImageProduct ip) { String portStr = port == 80 ? "" : ":" + port; String prex = "http://" + address + portStr + "/solidtrust/images/"; ImageProduct resp = new ImageProduct(); resp.setArrangement(ip.getArrangement()); resp.setBrand(ip.getBrand()); resp.setType(ip.getType()); resp.setBuildYear(ip.getBuildYear()); if (ip.getImage1() != null) { resp.setImage1(prex + ip.getImage1()); } if (ip.getImage2() != null) { resp.setImage2(prex + ip.getImage2()); } if (ip.getImage3() != null) { resp.setImage3(prex + ip.getImage3()); } if (ip.getImage4() != null) { resp.setImage4(prex + ip.getImage4()); } return resp; } private ImageProduct findImagesByLicensePlate(String id) throws Exception { return findImagesByLicensePlate(id, true); } private ImageProduct findImagesByLicensePlate(String id, boolean google) throws Exception { //convert azure car into image product ImageProduct ip = ipService.findImageProduct(id); if (ip == null) { return null; } //find image product in db ImageProduct db = ipService.findTheSame(ip); if (db != null) { ip = db; } else { //fetch image from netcarshow if (netCarService.search(ip)) { free.save(ip); log4j.info("Successfully fetch from NetCarShow: " + ip); return ip; } if (google) { searchByGoogleEngine(ip); } } return ip; } private void searchByGoogleEngine(ImageProduct ip) throws Exception { List<ImageInfo> images = null; //fetch image from google String q = buildQuery(ip); log4j.info("query: " + q); try { images = imgFetcher.fetch(URLEncoder.encode(q, "iso-8859-1"), 10, 3); } catch (Throwable e) { log4j.warn(e.getMessage(), e); } String lastQ = buildInteriorQuery(q); log4j.info("query interior: " + lastQ); List<ImageInfo> lasts = null; try { lasts = imgFetcher.fetch(URLEncoder.encode(lastQ, "iso-8859-1"), 4, 1); } catch (ResultException e) { log4j.warn(e.getMessage(), e); } if (lasts.size() > 0) { images.add(3, lasts.get(0)); } for (ImageInfo ii : images) { ii.setName(q); free.save(ii); } int size = images.size(); if (size >= 1) { ip.setImage1(images.get(0).getUuid()); } if (size >= 2) { ip.setImage2(images.get(1).getUuid()); } if (size >= 3) { ip.setImage3(images.get(2).getUuid()); } if (size >= 4) { ip.setImage4(images.get(3).getUuid()); } free.save(ip); } private String getImage(ImageProduct ip, int index) { if (index == 0) { return ip.getImage1(); } if (index == 1) { return ip.getImage2(); } if (index == 2) { return ip.getImage3(); } if (index == 3) { return ip.getImage4(); } return null; } private void setImage(ImageProduct ip, String img, int index) { if (index == 0) { ip.setImage1(img); } if (index == 1) { ip.setImage2(img); } if (index == 2) { ip.setImage3(img); } if (index == 3) { ip.setImage4(img); } } private String buildQuery(ImageProduct ip) { return ip.getBrand() + " " + ip.getType() + " " + ip.getArrangement() + " " + ip.getBuildYear(); } private String buildInteriorQuery(String query) { return query + " interior interior interior interior"; } }