package fr.gael.dhus.server.http.webapp.stub.controller; import java.io.File; import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import java.security.Principal; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletResponse; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.geotools.gml2.GMLConfiguration; import org.geotools.xml.Configuration; import org.geotools.xml.Parser; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 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.web.bind.annotation.RestController; import org.w3c.dom.Document; import org.xml.sax.InputSource; import com.spatial4j.core.context.jts.JtsSpatialContext; import com.spatial4j.core.context.jts.JtsSpatialContextFactory; import com.spatial4j.core.context.jts.ValidationRule; import com.spatial4j.core.shape.jts.JtsGeometry; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryFactory; import com.vividsolutions.jts.geom.LinearRing; import com.vividsolutions.jts.geom.MultiPolygon; import com.vividsolutions.jts.geom.Polygon; import fr.gael.dhus.database.object.MetadataIndex; import fr.gael.dhus.database.object.Product; import fr.gael.dhus.database.object.User; import fr.gael.dhus.server.http.webapp.stub.controller.stub_share.MetadataIndexData; import fr.gael.dhus.server.http.webapp.stub.controller.stub_share.ProductData; import fr.gael.dhus.server.http.webapp.stub.controller.stub_share.exceptions.ProductCartServiceException; import fr.gael.dhus.service.exception.UserNotExistingException; import fr.gael.dhus.spring.context.ApplicationContextProvider; import fr.gael.dhus.system.config.ConfigurationManager; import fr.gael.dhus.util.MetalinkBuilder; import fr.gael.dhus.util.MetalinkBuilder.MetalinkFileBuilder; @RestController public class StubCartController { private static Log logger = LogFactory.getLog(StubUserController.class); @Autowired private ConfigurationManager configurationManager; @RequestMapping (value = "/users/{userid}/cart/{cartid}/addproduct", method = RequestMethod.POST) public void addProductToCart(Principal principal, @PathVariable (value = "userid") String userid, @PathVariable (value = "cartid") String cartid, @RequestParam (value = "productId", defaultValue = "") Long pId) throws ProductCartServiceException { User user = (User) ((UsernamePasswordAuthenticationToken) principal). getPrincipal(); fr.gael.dhus.service.ProductCartService productCartService = ApplicationContextProvider.getBean( fr.gael.dhus.service.ProductCartService.class); try { productCartService.addProductToCart(user.getUUID(), pId); } catch (Exception e) { e.printStackTrace(); throw new ProductCartServiceException(e.getMessage()); } } @RequestMapping (value = "/users/{userid}/cart/{cartid}/removeproduct", method = RequestMethod.POST) public void removeProductFromCart(Principal principal, @PathVariable (value = "userid") String userid, @PathVariable (value = "cartid") String cartid, @RequestParam (value = "productId", defaultValue = "") Long pId) throws ProductCartServiceException { User user = (User) ((UsernamePasswordAuthenticationToken) principal). getPrincipal(); fr.gael.dhus.service.ProductCartService productCartService = ApplicationContextProvider.getBean( fr.gael.dhus.service.ProductCartService.class); try { productCartService.removeProductFromCart(user.getUUID(), pId); } catch (Exception e) { e.printStackTrace(); throw new ProductCartServiceException(e.getMessage()); } } @RequestMapping (value = "/users/{userid}/cart/{cartid}/getcartids", method = RequestMethod.GET) public List<Long> getProductsIdOfCart(Principal principal, @PathVariable (value = "userid") String userid, @PathVariable (value = "cartid") String cartid) throws ProductCartServiceException { User user = (User) ((UsernamePasswordAuthenticationToken) principal). getPrincipal(); fr.gael.dhus.service.ProductCartService productCartService = ApplicationContextProvider.getBean( fr.gael.dhus.service.ProductCartService.class); try { return productCartService.getProductsIdOfCart(user.getUUID()); } catch (Exception e) { e.printStackTrace(); throw new ProductCartServiceException(e.getMessage()); } } @RequestMapping (value = "/users/{userid}/carts/{cartid}", method = RequestMethod.GET) public List<ProductData> getProductsOfCart(Principal principal, @PathVariable (value = "userid") String userid, @PathVariable (value = "cartid") String cartid, @RequestParam (value = "offset", defaultValue = "") int start, @RequestParam (value = "count", defaultValue = "") int count) throws ProductCartServiceException { User user = (User) ((UsernamePasswordAuthenticationToken) principal). getPrincipal(); fr.gael.dhus.service.ProductCartService productCartService = ApplicationContextProvider.getBean( fr.gael.dhus.service.ProductCartService.class); fr.gael.dhus.service.ProductService productService = ApplicationContextProvider.getBean( fr.gael.dhus.service.ProductService.class); try { List<Product> products = productCartService.getProductsOfCart( user.getUUID(), start, count); ArrayList<ProductData> productDatas = new ArrayList<ProductData>(); Configuration configuration = new GMLConfiguration(); @SuppressWarnings ("unused") Parser parser = new Parser(configuration); if (products != null) { logger.info("products not null"); for (Product product : products) { if (product != null) { logger.info("product not null"); ProductData productData = new ProductData(product.getId(), product.getUuid(), product.getIdentifier()); // Set the Footprint if any productData.setFootprint(StubCartController. convertGMLToDoubleLonLat(product.getFootPrint())); ArrayList<String> summary = new ArrayList<String>(); ArrayList<MetadataIndexData> indexes = new ArrayList<MetadataIndexData>(); for (MetadataIndex index : productService.getIndexes(product.getId())) { MetadataIndexData category = new MetadataIndexData(index.getCategory(), null); int i = indexes.indexOf(category); if (i < 0) { category.addChild(new MetadataIndexData(index.getName(), index.getValue())); indexes.add(category); } else { indexes.get(i).addChild( new MetadataIndexData(index.getName(), index.getValue())); } if ("summary".equals(index.getCategory())) { summary.add(index.getName() + " : " + index.getValue()); Collections.sort(summary, null); } if ("Instrument".equalsIgnoreCase(index.getName())) { productData.setInstrument(index.getValue()); } if ("Product type".equalsIgnoreCase(index.getName())) { productData.setProductType(index.getValue()); } } productData.setSummary(summary); productData.setIndexes(indexes); productData.setHasQuicklook(product.getQuicklookFlag()); productData.setHasThumbnail(product.getThumbnailFlag()); productDatas.add(productData); } } } return productDatas; } catch (Exception e) { e.printStackTrace(); throw new ProductCartServiceException(e.getMessage()); } } @RequestMapping (value = "/users/{userid}/cart/{cartid}/getcount", method = RequestMethod.GET) public int countProductsInCart(Principal principal, @PathVariable (value = "userid") String userid, @PathVariable (value = "cartid") String cartid) throws ProductCartServiceException { User user = (User)((UsernamePasswordAuthenticationToken) principal). getPrincipal(); fr.gael.dhus.service.ProductCartService productCartService = ApplicationContextProvider.getBean( fr.gael.dhus.service.ProductCartService.class); try { return productCartService.countProductsInCart(user.getUUID()); } catch (Exception e) { e.printStackTrace(); throw new ProductCartServiceException(e.getMessage()); } } @RequestMapping (value = "/users/{userid}/cart/{cartid}/clear", method = RequestMethod.POST) public void clearCart(Principal principal, @PathVariable (value = "userid") String userid, @PathVariable (value = "cartid") String cartid) throws ProductCartServiceException { User user = (User) ((UsernamePasswordAuthenticationToken) principal). getPrincipal(); fr.gael.dhus.service.ProductCartService productCartService = ApplicationContextProvider.getBean( fr.gael.dhus.service.ProductCartService.class); try { productCartService.clearCart(user.getUUID()); } catch (Exception e) { e.printStackTrace(); throw new ProductCartServiceException(e.getMessage()); } } @RequestMapping (value = "/users/{userid}/cart/{cartid}/download", method = RequestMethod.GET) public void cartToMetalink(Principal principal, @PathVariable (value = "userid") String userid, @PathVariable (value = "cartid") String cartid, HttpServletResponse res) throws UserNotExistingException, IOException, ParserConfigurationException, TransformerException { User user = (User) ((UsernamePasswordAuthenticationToken) principal). getPrincipal(); fr.gael.dhus.service.ProductCartService productCartService = ApplicationContextProvider.getBean( fr.gael.dhus.service.ProductCartService.class); if (productCartService.hasProducts(user.getUUID())) return; res.setContentType("application/metalink+xml"); res.setHeader("Content-Disposition", "inline; filename=products" + MetalinkBuilder.FILE_EXTENSION); res.getWriter().println(makeMetalinkDocument( productCartService.getProductsOfCart(user.getUUID(), -1, -1))); } /** * Makes the metalink XML Document for given products. * * @throws ParserConfigurationException * @throws TransformerException */ private String makeMetalinkDocument(Iterable<Product> lp) throws ParserConfigurationException, TransformerException { MetalinkBuilder mb = new MetalinkBuilder(); for (Product p : lp) { String product_entity = configurationManager.getServerConfiguration().getExternalUrl() + "odata/v1/Products('" + p.getUuid() + "')/$value"; MetalinkFileBuilder fb = mb.addFile( new File(p.getDownload().getPath()).getName()). addUrl(product_entity, null, 0); if ( !p.getDownload().getChecksums().isEmpty()) { Map<String, String> checksums = p.getDownload().getChecksums(); for (String algo : checksums.keySet()) fb.setHash(algo, checksums.get(algo)); } } StringWriter sw = new StringWriter(); Document doc = mb.build(); Transformer transformer=TransformerFactory.newInstance().newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); transformer.transform(new DOMSource(doc), new StreamResult(sw)); return sw.toString(); } @RequestMapping (value = "/users/{userid}/cart/{cartid}/testcart", method = RequestMethod.GET) public String signupValidate( @PathVariable (value = "userid") String userid, @PathVariable (value = "cartid") String cartid) { return "hello from cart stub test webservice"; } public static Double[][][] convertGMLToDoubleLonLat(String gml) { if (gml == null || gml.trim().isEmpty()) return null; Configuration configuration = new GMLConfiguration(); Parser parser = new Parser(configuration); Geometry footprint; try { footprint = (Geometry) parser.parse(new InputSource(new StringReader(gml))); } catch (Exception e) { logger.error("Cannot read GML coordinates: " + (gml == null ? gml : gml.trim()), e); return null; } JtsSpatialContext ctx = JtsSpatialContext.GEO; GeometryFactory geometryFactory = ctx.getGeometryFactory(); List<Coordinate> sequence = new ArrayList<Coordinate>(); for (Coordinate coord : footprint.getCoordinates()) { ctx.verifyX(coord.y); ctx.verifyY(coord.x); sequence.add(new Coordinate(coord.y, coord.x)); } LinearRing shell = geometryFactory.createLinearRing(sequence.toArray( new Coordinate[sequence.size()])); Polygon p = geometryFactory.createPolygon(shell, null); JtsSpatialContextFactory factory = new JtsSpatialContextFactory(); ValidationRule validationRule = factory.validationRule; JtsGeometry jts; try { jts = ctx.makeShape(p, true, ctx.isAllowMultiOverlap()); if (validationRule != ValidationRule.none) jts.validate(); } catch (RuntimeException e) { // repair: if (validationRule == ValidationRule.repairConvexHull) { jts=ctx.makeShape(p.convexHull(), true, ctx.isAllowMultiOverlap()); } else if (validationRule == ValidationRule.repairBuffer0) { jts=ctx.makeShape(p.buffer(0), true, ctx.isAllowMultiOverlap()); } else { // TODO there are other smarter things we could do like repairing // inner holes and subtracting // from outer repaired shell; but we needn't try too hard. throw e; } } if (factory.autoIndex) jts.index(); Double[][][] pts; if (jts.getGeom() instanceof MultiPolygon) { pts=new Double[((MultiPolygon)jts.getGeom()).getNumGeometries()][][]; for (int j=0; j<((MultiPolygon)jts.getGeom()).getNumGeometries(); j++) { pts[j]=new Double[((MultiPolygon) jts.getGeom()).getGeometryN(j). getNumPoints()][2]; int i = 0; for (Coordinate coord:((MultiPolygon) jts.getGeom()). getGeometryN(j).getCoordinates()) { pts[j][i] = new Double[2]; pts[j][i][0] = coord.x; pts[j][i][1] = coord.y; i++; } } } else { pts = new Double[1][jts.getGeom().getNumPoints()][2]; int i = 0; for (Coordinate coord : jts.getGeom().getCoordinates()) { pts[0][i] = new Double[2]; pts[0][i][0] = coord.x; pts[0][i][1] = coord.y; i++; } } return pts; } }